How do I detect if an app has been cracked without examining the SignerIdentity?

前端 未结 4 1459
暖寄归人
暖寄归人 2021-01-30 05:03

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         


        
4条回答
  •  [愿得一人]
    2021-01-30 05:13

    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;
    }
    

提交回复
热议问题