SHA1 Info.plist Checksum

Discussion in 'iOS Development' started by Axis, Aug 20, 2009.

  1. Axis

    Axis Super Moderator Staff Member

    Joined:
    Dec 2, 2007
    Messages:
    6,288
    Likes Received:
    133
    Device:
    iPhone 4S (White)
    For developers who want a passable method of crack protection, without spending valuable time engineering method of their own, this should be useful.

    This code only can prevent cracks utilizing the Info.plist of your application bundle. Any experienced cracker (with a good amount of time and effort) can crack your app without touching the Info.plist. However, the majority, if not all, "mainstream" cracking utilities go after the Info.plist. This code let's you compare the SHA1 checksum of the Info.plist at app launch with the stock checksum that you provide.

    [OBJC]
    //
    // Checksum.h
    //

    #import <Foundation/Foundation.h>
    #import <CommonCrypto/CommonDigest.h>


    @interface Checksum : NSObject {

    }

    + (NSString *)plistSHA1;

    @end
    [/OBJC]

    [OBJC]
    //
    // Checksum.m
    //

    #import "Checksum.h"


    @implementation Checksum


    + (NSString *)plistSHA1 {

    // define path of Info.plist
    NSString *path = [[NSBundle mainBundle] pathForResource

    Please Register or Log in to view images

    "Info" ofType

    Please Register or Log in to view images

    "plist"];

    NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath

    Please Register or Log in to view images

    ath];

    CC_SHA1_CTX sha1;

    CC_SHA1_Init(&sha1);

    BOOL finished = NO;

    NSData* fileData = [handle readDataToEndOfFile];
    while (!finished) {
    CC_SHA1_Update(&sha1, [fileData bytes], [fileData length]);
    if( [fileData length] == 0 )
    finished = YES;
    }
    unsigned char digest[CC_SHA1_DIGEST_LENGTH];
    CC_SHA1_Final(digest, &sha1);
    NSString* checksum = [NSString stringWithFormat: @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
    digest[0], digest[1],
    digest[2], digest[3],
    digest[4], digest[5],
    digest[6], digest[7],
    digest[8], digest[9],
    digest[10], digest[11],
    digest[12], digest[13],
    digest[14], digest[15],
    digest[16], digest[17],
    digest[18], digest[19] ];

    return checksum;
    }

    @end
    [/OBJC]

    If you need to adapt this to get the checksum of another file (say, you wanted to verify a file download), the code can easily be modified.

    Also, if you wanted the MD5, or other type of checksum, just read the CommonDigest.h file, and adapt the code. (once again, easy).

    The CommonDigest.h file is located at
    Code:
    /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/usr/include/CommonCrypto/CommonDigest.h 
    
    IMPORTANT: Don't implement this until you are finished coding your app. Otherwise, the checksum that you provide for comparison will change as you modify it, and it wouldn't be fun to worry about changing it in the code every time.

    Post any questions or comments.
  2. Pelaez-1

    Pelaez-1 New Member

    Joined:
    May 5, 2008
    Messages:
    822
    Likes Received:
    0
    Device:
    iPhone
    Can't just they hex edit the @"stockChecksum" to the new check sum?
  3. crizh4x

    crizh4x Active Member

    Joined:
    Sep 19, 2007
    Messages:
    4,474
    Likes Received:
    17
    Device:
    2G iPod touch
    Just run two checks. One on the Info.plist and then one on the binary itself to validate it. huzzah.
  4. Gamma

    Gamma Active Member

    Joined:
    Apr 2, 2008
    Messages:
    1,964
    Likes Received:
    3
    Device:
    iPod touch
    But after putting in the check for the binary, the checksum for the binary changes :/
  5. Axis

    Axis Super Moderator Staff Member

    Joined:
    Dec 2, 2007
    Messages:
    6,288
    Likes Received:
    133
    Device:
    iPhone 4S (White)
    You can get creative. I'm not going to spell it out for anyone, but don't be obvious with the placement. Perhaps pull it from multiple sources.
  6. crizh4x

    crizh4x Active Member

    Joined:
    Sep 19, 2007
    Messages:
    4,474
    Likes Received:
    17
    Device:
    2G iPod touch
    You can easily obfuscate your code... leaving it as a plain hash string would be rather easy but if you scramble it up... or run the hash through some sort of scrambler/descrambler... it would be just fine. There are tons of ways to fix this problem. Use your head

    Please Register or Log in to view images

  7. SkylarEC

    SkylarEC Super Moderator Emeritus Staff Member

    Joined:
    Sep 19, 2007
    Messages:
    6,642
    Likes Received:
    129
    [OBJC]while (!done) {
    NSData* fileData = [handle readDataToEndOfFile];
    CC_SHA1_Update(&sha1, [fileData bytes], [fileData length]);
    if( [fileData length] == 0 ) finished = YES;
    }[/OBJC]


    Notice the mistake in this loop? Please fix this before people start to try to implement this in their own code.


    ---------------------------------------


    Again, and this is just my two cents. You're all wasting your time focusin on the Info.plist. There are no Info.plist modifications needed for cracks.

    Furthermore, if you get to the point where this would stop anything, then your application has already been cracked. There are so, so, so many ways to get around your check here.

    You need to look into proactive solutions. You need to find ways to prevent your application from being cracked. Then, and only then, will you be reasonably safe.

    EDIT: And if you do find a solution, do NOT post it online. You'll only make cracking your application that much easier.
  8. Axis

    Axis Super Moderator Staff Member

    Joined:
    Dec 2, 2007
    Messages:
    6,288
    Likes Received:
    133
    Device:
    iPhone 4S (White)
    Valid points, but I did address most of them (albeit in a different tone) in my original post.

    I say "passable" because:
    You're right though - this won't stand a chance against anyone who knows what they're doing. However, a large (and growing) number of app pirates are 12 year olds who use rudimentary methods that revolve around the Info.plist. What I posted is enough to scare them away, or at least discourage them. Even if they realize that all the developer did was compare a checksum, most of them are too lazy to spend what would be hours for them cracking a one or two dollar app.

    Developers should accept that their apps will eventually be cracked. Therefore methods superior to what I posted should be developed and used. However, what I posted is for developers who don't have enough time to engineer a method of their own. Simply comparing checksums and if they don't match linking to the AppStore will make a difference in the bottom line. No doubt. Is it the best? Not by a long shot. Is it better than a SignerIdentity check? Certainly.
  9. Steaps

    Steaps New Member

    Joined:
    Oct 24, 2007
    Messages:
    5,074
    Likes Received:
    41
    Device:
    iPod touch
    You still forgot to fix the while loop

    Please Register or Log in to view images

    .
    (Switch "finished" to "done")
  10. Axis

    Axis Super Moderator Staff Member

    Joined:
    Dec 2, 2007
    Messages:
    6,288
    Likes Received:
    133
    Device:
    iPhone 4S (White)
    Thanks. Time to improve my sleep schedule.

    Please Register or Log in to view images

Share This Page