对于iOS来说,因为零碎是关闭的,APP上架须要通过App Store,安全性来说相当高。然而对于大厂和出名APP而言,他人给的平安保障永远没有本人做的来得虚浮。所以对于大厂、少部分企业级和金融领取类利用来说加固是相当重要的。上面是目前几个业余加固大厂提供的加固策略
网易
网易平安三板斧:第一板斧是防动态剖析,这里包含字符串加密、符号混同、代码逻辑混同和游戏存档加密;2.第二板斧是防动静调试、反调试和通信安全(数据加密);
第三板斧是外挂检测、减速挂、内存批改挂和主动工作挂等爱加密
safengine
几维平安
梆梆平安
本文将针对以上几点进行实现,对于一些不太容易实现的将会做方向性探讨
字符串加密代码混同(办法命,类命,变量名,符号表)代码逻辑混同反调试*字符串加密对字符串加密的形式目前我所理解到把握到的最牢靠形式就是用脚本将代码中的所有标记须要加密的字符串进行异或转换,这样代码中就不存在明文字符串了。当然第三方的字符串加密不可能这么简略,具体怎么做的我也不太分明。不过为了减少字符串加密的难度复杂性,咱们能够先将字符串用加密工具转换(例如AES、base64等)后的把加字符串放在工程中,并且把解密的钥匙放在工程中,用异或转换,把解密钥匙和加密后的字符串转换,这样就有2层保障,减少了复杂度。
首先咱们创立任意一个工程,在工程中写入上面的代码,并在每句打上断点,再抉择Xcode工具栏的Debug --> Debug Workflow --> Always Show Disassembly。这样你就能够在断点处进入汇编模式界面,最初运行程序/* 加密NSString字符串 */ NSString *str = @"Hello World"; NSLog(@"%@",str); /* 加密char*字符串 */ char* cStr = "Super Man"; NSLog(@"%s",cStr);你会发现,你的字符串内容裸露在了汇编模式中,这会导致他人在逆向剖析你的工程时能看见你的字符串内容,咱们个别接口、域名、加解密钥匙串、AppKey、AppId等比拟重要的货色会放在客户端用作字符串,这就很容易裸露进去。
步骤1首先须要在工程代码中进行批改,把上面的宏和decryptConfusionCS,decryptConstString函数放入代码中,用宏蕴含每个须要转换的字符串。/* 字符串混同解密函数,将char[] 模式字符数组和 aa异或运算揭秘 */extern char* decryptConfusionCS(char* string){ char* origin_string = string; while(*string) { *string ^= 0xAA; string++; } return origin_string;}/* 解密函数,返回的是NSString类型的 */extern NSString* decryptConstString(char* string){ /* 先执行decryptConfusionString函数解密字符串 */ char* str = decryptConfusionCS(string); /* 获取字符串的长度 */ unsigned long len = strlen(str); NSUInteger length = [[NSString stringWithFormat:@"%lu",len] integerValue]; NSString *resultString = [[NSString alloc]initWithBytes:str length:length encoding:NSUTF8StringEncoding]; return resultString;}/* * 应用heyujia_confusion宏管制加密解密 * 当heyujia_confusion宏被定义的时候,执行加密脚本,对字符串进行加密 * 当heyujia_confusion宏被删除或为定义时,执行解密脚本,对字符串解密 */#define heyujia_confusion#ifdef heyujia_confusion/* heyujia_confusion 宏被定义,那么就进行执行解密脚本 *//* confusion_NSSTRING宏的返回后果是NSString 类型的 */#define confusion_NSSTRING(string) decryptConstString(string)/* confusion_CSTRING宏的返回后果是char* 类型的 */#define confusion_CSTRING(string) decryptConfusionCS(string)#else/* heyujia_confusion 宏没有被定义,那么就执行加密脚本 *//* 加密NSString类型的 */#define confusion_NSSTRING(string) @string/* 加密char *类型的 */#define confusion_CSTRING(string) string#endif@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. /* 应用confusion_NSSTRING宏蕴含须要加密的NSString字符串 */ NSString *str = confusion_NSSTRING("Hello World"); NSLog(@"%@",str); /* 应用confusion_NSSTRING宏蕴含须要加密的char*字符串 */ char* cStr = confusion_CSTRING("Super Man"); NSLog(@"%s",cStr); }步骤2应用终端cd 到须要加密的工程目录下 执行touch confusion.py和 touch decrypt.py命令,生产加密和解密脚本文件步骤3把上面代码退出解密脚本confusion.py中#!/usr/bin/env python# encoding=utf8# -*- coding: utf-8 -*-# author by heyujia# 脚本将会用于对指定目录下的.h .m源码中的字符串进行转换# 替换所有字符串常量为加密的char数组,模式((char[]){1, 2, 3, 0})import importlibimport osimport reimport sys# replace替换字符串为((char[]){1, 2, 3, 0})的模式,同时让每个字节与0xAA异或进行加密# 当然能够不应用0xAA 应用其余的十六进制也行 例如0XBB、0X22、0X11def replace(match): string = match.group(2) + '\x00' replaced_string = '((char []) {' + ', '.join(["%i" % ((ord(c) ^ 0xAA) if c != '\0' else 0) for c in list(string)]) + '})' return match.group(1) + replaced_string + match.group(3)# obfuscate办法是批改传入文件源代码中用confusion_NSSTRING标记的所有字符串# 应用replace函数对字符串进行异或转换def obfuscate(file): with open(file, 'r') as f: code = f.read() f.close() code = re.sub(r'(confusion_NSSTRING\(|confusion_CSTRING\()"(.*?)"(\))', replace, code) code = re.sub(r'//#define ggh_confusion', '#define ggh_confusion', code) with open(file, 'w') as f: f.write(code) f.close()# openSrcFile办法是读取源码门路下的所有.h和.m 文件# 对每个文件执行obfuscate函数def openSrcFile(path): print("混同的门路为 "+ path) # this folder is custom for parent,dirnames,filenames in os.walk(path): #case 1: # for dirname in dirnames: # print((" parent folder is:" + parent).encode('utf-8')) # print((" dirname is:" + dirname).encode('utf-8')) #case 2 for filename in filenames: extendedName = os.path.splitext(os.path.join(parent,filename)) if (extendedName[1] == '.h' or extendedName[1] == '.m'): print("解决源代码文件: "+ os.path.join(parent,filename)) obfuscate(os.path.join(parent,filename))#这里须要批改源码的门路为本人工程的文件夹名称srcPath = '../daimahunxiao'if __name__ == '__main__': print("本脚本用于对源代码中被标记的字符串进行加密") if len(srcPath) > 0: openSrcFile(srcPath) else: print("请输出正确的源代码门路") sys.exit()步骤4 把上面的解密代码放入decrypt.py解密脚本中#!/usr/bin/env python# encoding=utf8# -*- coding: utf-8 -*-# author by heyujia# 解密脚本# 替换所有标记过的加密的char数组为字符串常量,""import importlibimport osimport reimport sys# 替换((char[]){1, 2, 3, 0})的模式为字符串,同时让每个数组值与0xAA异或进行解密def replace(match): string = match.group(2) decodeConfusion_string = "" for numberStr in list(string.split(',')): if int(numberStr) != 0: decodeConfusion_string = decodeConfusion_string + "%c" % (int(numberStr) ^ 0xAA) replaced_string = '\"' + decodeConfusion_string + '\"' print("replaced_string = " + replaced_string) return match.group(1) + replaced_string + match.group(3)# 批改源代码,退出字符串加密的函数def obfuscate(file): with open(file, 'r') as f: code = f.read() f.close() code = re.sub(r'(confusion_NSSTRING\(|confusion_CSTRING\()\(\(char \[\]\) \{(.*?)\}\)(\))', replace, code) code = re.sub(r'[/]*#define ggh_confusion', '//#define ggh_confusion', code) with open(file, 'w') as f: f.write(code) f.close()#读取源码门路下的所有.h和.m 文件def openSrcFile(path): print("解密门路: "+ path) # this folder is custom for parent,dirnames,filenames in os.walk(path): #case 1: # for dirname in dirnames: # print((" parent folder is:" + parent).encode('utf-8')) # print((" dirname is:" + dirname).encode('utf-8')) #case 2 for filename in filenames: extendedName = os.path.splitext(os.path.join(parent,filename)) #读取所有.h和.m 的源文件 if (extendedName[1] == '.h' or extendedName[1] == '.m'): print("已解密文件:"+ os.path.join(parent,filename)) obfuscate(os.path.join(parent,filename))#源码门路srcPath = '../daimahunxiao'if __name__ == '__main__': print("字符串解混同脚本,将被标记过的char数组转为字符串,并和0xAA异或。还原代码") if len(srcPath) > 0: openSrcFile(srcPath) else: print("请输出正确的源代码门路!") sys.exit()步骤5依据本人的需要批改下脚本外面的代码 和 文件门路。步骤6把步骤1中的宏heyujia_confusion正文了,而后执行加密脚本,在终端中输出python confusion.py, (1.如果报错,请查看下本人Mac电脑中的python版本,如果是python3就输出python3 confusion.py. (2.如果报Non-ASCII character '\xe8' in file confusion.py on line 2相干的错,请确定脚本的后面3行是#!/usr/bin/env python# encoding=utf8# -*- coding: utf-8 -*-执行完步骤6后的后果此时字符串已被加密,运行程序会发现一切正常加密后汇编界面看不见咱们的字符串内容了,然而咱们用来解密的办法还是裸露在了汇编界面,所以咱们前期还须要对办法名,变量名,类命等做混同。
...