简体   繁体   English

如何在不检查SignerIdentity的情况下检测应用程序是否已被破解?

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

There used to be a method to check if an application was purchased from the App Store, to protect against cracking: 曾经有一种方法来检查应用程序是否是从App Store购买的,以防止破解:

NSBundle *bundle = [NSBundle mainBundle]; 
NSDictionary *info = [bundle infoDictionary]; 
if ([info objectForKey: @"SignerIdentity"] != nil) 
{ /* do something */  }

but this method no longer works because the crackers have found ways around altering the Info.plist. 但这种方法不再有效,因为破解者已经找到了改变Info.plist的方法。 I'm aware of this older question , but the answers presented there rely on the above technique, which is no longer valid. 我知道这个较老的问题 ,但那里提出的答案依赖于上述技术,该技术已不再有效。

How can you detect whether your application was cracked or purchased legitimately from the App Store without reading the SignerIdentity from the Info.plist? 如何在不从Info.plist中读取SignerIdentity的情况下,如何从App Store中检测您的应用程序是否被破解或合法购买?

I like Mick's answer personally as it's short and simple. 我个人喜欢Mick的回答,因为它简短而简单。

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. Greg的回复无效--Mick的代码只检查应用程序是否可以打开该URL,因此不应该崩溃。

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). 从分析来看,这种方法已经阻止了成千上万的盗版用户,并且花了大约5分钟来实现,所以这样做的成本几乎没有 - 对我来说,我不在乎它是否增加了销售额(我确信它不是不管怎么说 - 更多的是我不希望人们从我的辛勤工作中挣脱出来。 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 在main.m

#import <dlfcn.h>
#import <mach-o/dyld.h>
#import <TargetConditionals.h>

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

The official Apple's answer: 官方Apple的答案:

Hello Dmitry,

Thank you for contacting Apple Developer Technical Support (DTS). 

DTS does not provide code-level support for DRM issues.  

Please try posting your inquiry to Apple Development Forum:

<https://devforums.apple.com>

While you were initially charged a Technical Support Incident (TSI) for this request, we have assigned a replacement TSI back to your account.

Thank you for understanding our support policies.

Best Regards,

Apple Developer Support 
Worldwide Developer Relations

I'd suggest a smaller code snippet that does the same thing as @user1353482 suggested (and the same way). 我建议使用一个较小的代码片段,它与@ user1353482建议的内容相同(以相同的方式)。 I'd write in comments, but code would be unreadable then. 我会写评论,但代码将无法读取。 Moreover, I may be wrong but it seems that additional defines is not needed anymore even when compiling for simulator (at least this works in xcode 4.5.1, target is 5.0). 此外,我可能是错的,但似乎不再需要额外的定义,即使在编译模拟器时(至少这在xcode 4.5.1中工作,目标是5.0)。

Please note that this code returns false on debug and adhoc binary, but we're talking about appstore, right? 请注意,此代码在debug和adhoc二进制文件中返回false,但我们正在讨论appstore,对吧? It's Apple who makes the final encryption and you're supposed to not try this at home :) 这是Apple的最终加密,你不应该在家里尝试这个:)

#include <execinfo.h>
#import <mach-o/ldsyms.h>

bool executableEncryption()
{
    const uint8_t *command = (const uint8_t *) (&_mh_execute_header + 1);
    for (uint32_t idx = 0; idx < _mh_execute_header.ncmds; ++idx)
    {
        if (((const struct load_command *) command)->cmd == LC_ENCRYPTION_INFO)
        {
            struct encryption_info_command *crypt_cmd = (struct encryption_info_command *) command;    
            if (crypt_cmd->cryptid < 1)
                return false;
            return true;
        }
        else
        {
            command += ((const struct load_command *) command)->cmdsize;
        }
    }
    return false;
}

While not a check to see if an Application was purchased from the App Store, I use this code to check to see if my application is running on a jailbroken device: 虽然没有检查是否从App Store购买了应用程序,但我使用此代码检查我的应用程序是否在越狱设备上运行:

+(BOOL)isJailbroken { 
    NSURL* url = [NSURL URLWithString:@"cydia://package/com.example.package"]; 
    return [[UIApplication sharedApplication] canOpenURL:url]; 
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM