There used to be a method to check if an application was purchased from the App Store, to protect against cracking:
NSBundle *bundle = [NSBundle mainBundle];
NS
I like Mick's answer personally as it's short and simple.
Greg's response isn't valid -- Mick's code only checks whether the App can open that URL so there should be no chance of crashing.
I've implemented the following in one of my apps before which does a more strict check of whether the app is encrypted or not, if it's not it's most likely a cracked app:
From analytics, this method has prevented thousands of pirated users for me and took maybe 5 minutes to implement so the cost of doing it was almost nothing -- for me, I didn't care if it increased sales (which I was sure it wasn't going to anyway--it's more that I don't want people freeloading off of my hard work). In addition, a good amount of my app's content feeds information after figuring out whether the app is pirated or not and returns junk data if it is.
In main.m
#import
#import
#import
#if TARGET_IPHONE_SIMULATOR && !defined(LC_ENCRYPTION_INFO)
#define LC_ENCRYPTION_INFO 0x21
struct encryption_info_command {
uint32_t cmd;
uint32_t cmdsize;
uint32_t cryptoff;
uint32_t cryptsize;
uint32_t cryptid;
};
#endif
static BOOL isEncrypted();
static BOOL isEncrypted () {
const struct mach_header *header;
Dl_info dlinfo;
/* Fetch the dlinfo for main() */
if (dladdr(main, &dlinfo) == 0 || dlinfo.dli_fbase == NULL) {
//NSLog(@"Could not find main() symbol (very odd)");
return NO;
}
header = dlinfo.dli_fbase;
/* Compute the image size and search for a UUID */
struct load_command *cmd = (struct load_command *) (header+1);
for (uint32_t i = 0; cmd != NULL && i < header->ncmds; i++) {
/* Encryption info segment */
if (cmd->cmd == LC_ENCRYPTION_INFO) {
struct encryption_info_command *crypt_cmd = (struct encryption_info_command *) cmd;
/* Check if binary encryption is enabled */
if (crypt_cmd->cryptid < 1) {
/* Disabled, probably pirated */
return NO;
}
/* Probably not pirated <-- can't say for certain, maybe theres a way around it */
return YES;
}
cmd = (struct load_command *) ((uint8_t *) cmd + cmd->cmdsize);
}
/* Encryption info not found */
return NO;
}