反破解

来源:互联网 发布:ubuntu安装rpm包管理器 编辑:程序博客网 时间:2024/04/28 20:31

这几段代码不长,所以要挨个看,最后写了一个综合起来的方法,但是因为木有破解的工具──XCrack, PoedCrack, C4Crack,Crackulous,曾尝试下了前两个工具,但是都是exe文件。所以无法验证这些09年的代码是否在当前还能用。



// one

这段是首先确定不是iphone模器,我可以捕进程id,来确定它不是root。基本上,任何候只要有人破解你的应用一些进程就会作root自动运行来执行程序。我可以简单的确定用不是root,这个方法的问题是,一些app并不会作root来运行,所以被破解的程序依然不会受影响。


#if !TARGET_IPHONE_SIMULATOR

int root = getgid();

if (root <= 10) {

//Pirated

}

#endif



// two

这段主要是来自另一位iphonedersdk‘er,基本上,这个方法结合了我所描述的两个方法。1.核plist文件的大小。2.加个甜蜜陷阱~

#define kInfoSize 500

//Place your NSLog Plist Size into the above Define statment

NSString* bundlePath = [[NSBundle mainBundle] bundlePath];

NSString* path = [NSString stringWithFormat:@"%@/Info.plist", bundlePath ];

NSDictionary *fileInfo = [[NSBundle mainBundle] infoDictionary];

NSFileManager *fileManager = [NSFileManager defaultManager];

NSDictionary *fileAttributes = [fileManager fileAttributesAtPath:path traverseLink:YES];


if (fileAttributes != nil) {

NSNumber *fileSize;

if(fileSize = [fileAttributes objectForKey:NSFileSize]){

NSLog(@"File Size:  %qi\n", [fileSize unsignedLongLongValue]);

//Best to see the File Size and change it accordingly first

NSString *cSID = [[NSString alloc] initWithFormat:@"%@%@%@%@%@",@"Si",@"gne",@"rIde",@"ntity",@""];

BOOL checkedforPir = false;

if([fileInfo objectForKey:cSID] == nil || [fileInfo objectForKey:cSID] != nil) {

if([fileSize unsignedLongLongValue] == kInfoSize) {

checkedforPir = true;

}

}

if(!checkedforPir){

//Pirated

}

[cSID release];

}

}


// three

这里做的就是验证一下_CodeSignatureCodeResourcesResourceRules.plist文件是否存在。任何候有人想破解应用时候,他会排斥这些文件,因会包括破解者的个人信息,当然,这个方法不是绝对的好,但是不会容易被破解。

NSString* bundlePath = [[NSBundle mainBundle] bundlePath];

BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:(@"%@/_CodeSignature", bundlePath)];

if (!fileExists) {

//Pirated

NSLog(@"Pirated");

}

BOOL fileExists2 = [[NSFileManager defaultManager] fileExistsAtPath:(@"%@/CodeResources", bundlePath)];

if (!fileExists2) {

//Pirated

NSLog(@"Pirated2");

}

BOOL fileExists3 = [[NSFileManager defaultManager] fileExistsAtPath:(@"%@/ResourceRules.plist", bundlePath)];

if (!fileExists3) {

//Pirated

NSLog(@"Pirated3");

}


// four

下面这个方法是很前沿的技术,我们这里根据info.plist和执行文件的时间戳来和PkgInfo文件的比较。当hacker破解了一个应用的时候,他们基本上都会改主要的文件或者info.plist。因此时间戳是个不错的判断方法。但是,下面的留言者有给作者提了一些疑问,是说这种方法存在漏洞,即使自己建立了一个非常clean的应用,时间上还是不能保证info.plist和执行文件的时间戳小于pkg文件的时间戳,所以给了作者一些建议,就是取两者差的绝对值,大于10min,就基本上确定应用是被破解了。

NSString* bundlePath = [[NSBundle mainBundle] bundlePath];

NSString* path = [NSString stringWithFormat:@"%@/Info.plist", bundlePath];

NSString* path2 = [NSString stringWithFormat:@"%@/AppName", bundlePath];

NSDate* infoModifiedDate = [[[NSFileManager defaultManager] fileAttributesAtPath:path traverseLink:YES] fileModificationDate];

NSDate* infoModifiedDate2 = [[[NSFileManager defaultManager] fileAttributesAtPath:path2 traverseLink:YES] fileModificationDate];

NSDate* pkgInfoModifiedDate = [[[NSFileManager defaultManager] fileAttributesAtPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"PkgInfo"] traverseLink:YES] fileModificationDate];

if(fabs([infoModifiedDate timeIntervalSinceReferenceDate] - [pkgInfoModifiedDate timeIntervalSinceReferenceDate]) > 600) {

//Pirated

}

if(fabs([infoModifiedDate2 timeIntervalSinceReferenceDate] - [pkgInfoModifiedDate timeIntervalSinceReferenceDate]) > 600) {

//Pirated

}


//five 

讲这一个方法的时候,我要说的是先把main.m的后改成.mm,因要将下面这段C++加在main.mm里面,这段代码确保在寻找消失的文件和时间戳中已经头晕了的我们在破解行开始之前就停止它!这是见过的最好的反破解方法。只要有破解的,它就会剥掉这个加密运行它,这个方法非常容易来检验你的执行程序是否被加密了。

#include<stdlib.h>

#include<stdio.h>

#include<dlfcn.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


int main (int argc, char *argv[]);


static BOOL is_encrypted () {

    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? */

            return YES;

        }

        cmd = (struct load_command *) ((uint8_t *) cmd + cmd->cmdsize);

    }

    /* Encryption info not found */

    return NO;

}






Last Code:

下面这段是根据上边的方法综合在一起的,因那个放在main.mm里面的方法有一定的局限性,所以暂时不用它,下面这个方法就是(判断“时间戳+消失的文件”)这个方法可以放在我们应用的任何地方!

-(void) crackCheck { 

NSString* bundlePath = [[NSBundle mainBundle] bundlePath];

NSString* path = [NSString stringWithFormat:@"%@/Info.plist", bundlePath];

NSString* path2 = [NSString stringWithFormat:@"%@/AppName", bundlePath];

NSDate* infoModifiedDate = [[[NSFileManager defaultManager] fileAttributesAtPath:path traverseLink:YES] fileModificationDate];

NSDate* infoModifiedDate2 = [[[NSFileManager defaultManager] fileAttributesAtPath:path2 traverseLink:YES] fileModificationDate];

NSDate* pkgInfoModifiedDate = [[[NSFileManager defaultManager] fileAttributesAtPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"PkgInfo"] traverseLink:YES] fileModificationDate];


if(fabs([infoModifiedDate timeIntervalSinceReferenceDate] - [pkgInfoModifiedDate timeIntervalSinceReferenceDate]) > 600) {

if (gameState == kGameStateRunning) {

gameState = kGameStatePaused;

if (crackedProgress.hidden) {

crackedProgress.hidden = NO;}

if (crackedAlert.hidden) {

crackedAlert.hidden = NO;}

}

}

if(fabs([infoModifiedDate2 timeIntervalSinceReferenceDate] - [pkgInfoModifiedDate timeIntervalSinceReferenceDate]) > 600) {

if (gameState == kGameStateRunning) {

gameState = kGameStatePaused;

if (crackedProgress.hidden) {

crackedProgress.hidden = NO;}

if (crackedAlert.hidden) {

crackedAlert.hidden = NO;}

}

BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:(@"%@/_CodeSignature", bundlePath)];

if (!fileExists) {

if (gameState == kGameStateRunning) {

gameState = kGameStatePaused;

if (crackedProgress.hidden) {

crackedProgress.hidden = NO;}

if (crackedAlert.hidden) {

crackedAlert.hidden = NO;}

}

}

BOOL fileExists2 = [[NSFileManager defaultManager] fileExistsAtPath:(@"%@/CodeResources", bundlePath)];

if (!fileExists2) {

if (gameState == kGameStateRunning) {

gameState = kGameStatePaused;

if (crackedProgress.hidden) {

crackedProgress.hidden = NO;}

if (crackedAlert.hidden) {

crackedAlert.hidden = NO;}

}

}

BOOL fileExists3 = [[NSFileManager defaultManager] fileExistsAtPath:(@"%@/ResourceRules.plist", bundlePath)];

if (!fileExists3) {

if (gameState == kGameStateRunning) {

gameState = kGameStatePaused;

if (crackedProgress.hidden) {

crackedProgress.hidden = NO;}

if (crackedAlert.hidden) {

crackedAlert.hidden = NO;}

}

}

}