Archive for April 8th, 2009

Snippet: isCracked

Whilst we quite firmly believe that every second you spend implementing copy protection instead of things that, you know, actually make people want to buy your application are a striking misallocation of development resources, life as a contract programmer means that you do what your customers want, and it seems to be an unfortunate general rule that people are much more interested in upping the challenge and therefore the attraction for people who aren’t going to buy the application anyway than they are in actually making the application more attractive to people who will pay.

But perhaps we are unduly cynical.

Any-how, should you find yourself in the position of being tasked with implementing copy protection on an iPhone application, our condolences, and here is a snippet which may be of use.

#if HEARTBEAT_CHECK_PIRACY
+ (BOOL)isCracked {
#if TARGET_IPHONE_SIMULATOR
        return NO;
#else
        static BOOL isCracked = NO;
        static BOOL didCheck = NO;
        if(didCheck) return isCracked;#if HEARTBEAT_PIRACY_THRESHOLD >= 1   if([[[NSBundle mainBundle] infoDictionary] objectForKey:@"SignerIdentity"] != nil) {              #if HEARTBEAT_PIRACY_THRESHOLD >= 2              NSString* infoPath = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"];              if([[NSString stringWithContentsOfFile:infoPath encoding:NSUTF8StringEncoding error:NULL] rangeOfString:@"</plist>"].location != NSNotFound) {                        #if HEARTBEAT_PIRACY_THRESHOLD >= 3                      NSDate* infoModifiedDate = [[[NSFileManager defaultManager] fileAttributesAtPath:infoPath traverseLink:YES] fileModificationDate];                 NSDate* pkgInfoModifiedDate = [[[NSFileManager defaultManager] fileAttributesAtPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"PkgInfo"] traverseLink:YES] fileModificationDate];                  if([infoModifiedDate timeIntervalSinceReferenceDate] > [pkgInfoModifiedDate timeIntervalSinceReferenceDate]) {                     #endif              #endif                              isCracked = YES;           #if HEARTBEAT_PIRACY_THRESHOLD >= 2                      #if HEARTBEAT_PIRACY_THRESHOLD >= 3                      }                  #endif              }          #endif      }#endif      didCheck = YES;  return isCracked;#endif}#endif

We have no intention of bothering to actually implement it on our own initiative, so this isn’t a recommendation per se, but hey, it looks like it has a chance of working, so if you want something like that, there you go!

[EDIT: And here is a strategy for dealing with crack detection which has some smidgen of sensibility to it.]

Continue Reading →
0