1,通過(guò)對(duì)CodeResources讀取資源文件原始hash,和當(dāng)前hash進(jìn)行對(duì)比,判斷是否經(jīng)過(guò)篡改,被篡改過(guò)的文件應(yīng)從服務(wù)器重新請(qǐng)求資源文件進(jìn)行替換,或者引導(dǎo)用戶從正規(guī)渠道重新下載app。CodeResources文件是一個(gè)屬性列表,包含bundle中所有其他文件的列表。這個(gè)屬性列表可能有多個(gè)files,這是一個(gè)字典,其中鍵是文件名,值通常是Base64格式的散列值。如果鍵表示的文件是可選的,那么值本身也是一個(gè)字典,這個(gè)字典有一個(gè)hash鍵和一個(gè)optional鍵,如果文件被修改,其對(duì)應(yīng)的hash也會(huì)改變。所以CodeResources文件內(nèi)的hash可以用于判斷一個(gè)應(yīng)用程序是否完好無(wú)損。
2,可以通過(guò)檢測(cè)cryptid的值來(lái)檢測(cè)是否被篡改,篡改過(guò)cryptid的值為0。
3,
如果以上都滿足不了的話,可以自己對(duì)需要保護(hù)的重要文件做MD5hash校驗(yàn)。使用這個(gè)框架FileMD5Hash生成hash。通過(guò)對(duì)比原始文件的hash和當(dāng)前的hash來(lái)做判斷。只要文件的內(nèi)容有被改變,hash的值一定會(huì)變,目前的破解技術(shù)都會(huì)修改到系統(tǒng)文件、比如CodeResources、Info.plist。
舉個(gè)例子,給bundle里面所有的文件生成hash。
1.讀取bundle所有文件名
//獲得所有資源文件名
-(NSArray *)allFilesAtPath:(NSString *)dir{
NSMutableArray * arr = [NSMutableArray array];
NSFileManager * manager = [NSFileManager defaultManager];
NSArray *temp = [manager contentsOfDirectoryAtPath:dir error:nil];
for (NSString * fileName in temp) {
BOOL flag = YES;
NSString * fullpath = [dir stringByAppendingPathComponent:fileName];
if ([manager fileExistsAtPath:fullpath isDirectory:&flag]) {
if (!flag ) {
[arr addObject:fileName];
// NSLog(@"%@",fileName);
}
}
}
return arr;
}
//生成資源文件名及對(duì)應(yīng)的hash的字典, eg:@{@"appicon":@"wegdfser45t643232324234"};
-(NSDictionary *)getBundleFileHash{
NSMutableDictionary * dicHash = [NSMutableDictionary dictionary];
NSArray * fileArr = [self allFilesAtPath:[[NSBundle mainBundle]resourcePath]];
for (NSString * fileName in fileArr) {
//對(duì)應(yīng)的文件生成hash
NSString * HashString = [FileMD5Hash computeMD5HashOfFileInPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fileName]];
if (HashString != nil) {
[dicHash setObject:HashString forKey:fileName];
}
}
//所有資源文件的hash就保存在這數(shù)組里
return dicHash;
}