巩义网站推广,怎么为网站做外链,wordpress自动推送,厦门网站建设官网对于iOS来说#xff0c;由于系统是封闭的#xff0c;APP上架需要通过App Store#xff0c;安全性来说相当高。但是对于大厂和知名APP而言#xff0c;别人给的安全保障永远没有自己做的来得踏实。所以对于大厂、少部分企业级和金融支付类应用来说加固是相当重要的。下面是目…对于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 首先需要在工程代码中进行修改把下面的宏和decryptConfusionCSdecryptConstString函数放入代码中用宏包含每个需要转换的字符串。/* 字符串混淆解密函数将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#endifinterface ViewController ()endimplementation 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# encodingutf8# -*- 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 ../daimahunxiaoif __name__ __main__: print(本脚本用于对源代码中被标记的字符串进行加密) if len(srcPath) 0: openSrcFile(srcPath) else: print(请输入正确的源代码路径) sys.exit()步骤4 把下面的解密代码放入decrypt.py解密脚本中#!/usr/bin/env python# encodingutf8# -*- 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 ../daimahunxiaoif __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# encodingutf8# -*- coding: utf-8 -*-执行完步骤6后的结果此时字符串已被加密运行程序会发现一切正常加密后汇编界面看不见我们的字符串内容了但是我们用来解密的方法还是暴露在了汇编界面所以我们后期还需要对方法名变量名类命等做混淆。步骤7 把步骤1中的宏heyujia_confusion取消注释然后执行解密脚本在终端中输入 python decrypt.py解密后文本又变回了原样。这里只是基本的异或转换加密让代码中的字符串变成看不懂的char []实际操作中远远不止这么简单 例如首先我们先用加密工具例如AES.Base64等把需要转换的字符串先加密变成加密字符串然后在用异或转换加密的脚本把加密字符串进行转换(包括解密用的钥匙串)在使用的时候先异或解密字符串然后根据解密钥匙串把字符串在转为可用的字符串ps.还有一种保护字符串的方法就是使用NSLocalizedString字符串本地化。虽然跟着我的步骤你确实加密成功了但是你却无法实际验证。所以要验证最终的混淆结果是否达到效果你还需要学习如何破壳解密IPA如何动态静态逆向编程分析工程源码大家可以先看看我 这篇文章 。先掌握逆向分析后再来做代码混淆就能验证混淆结果是否有效变量、方法名类名混淆对于混淆这一块网上真的是千篇一律基本都是copy的念大婶的内容没有一点自己的创新和思考。网上的方法我也用过但是有缺陷只能混淆方法名或者说自己固定的内容去替换。第一不自动对于大项目而言每个方法名自己添加太麻烦。第二变量混淆有问题因为只是单纯的字符串替换用宏代替。当遇到使用_ 下划线访问变量时就会出现错误。对于变量、方法名类名的混淆其实跟字符串混淆差不多都是加密混淆然后解密混淆。不同的是变量、方法名类名的混淆目的是为了让别人反编译的时候不知道你的变量、方法类是具体用来干什么的不会像明文那样一目了然。增加逆向难度。混淆的内容不需要像字符串一样最后程序运行时还要转成中文正常使用。由于本人对shell脚本语言也不是非常熟悉想要按照自己的思路写一套完整的混淆脚本还不行。所以这部分也是在网上找的算是目前最实用最完善的混淆首先 打开终端cd到需要混淆的工程目录下输入touch obConfusion.sh (加密混淆脚本文件)touch obDecrypt.sh (解密混淆脚本文件)生成2个脚本文件然后在工程目录以外创建一个文件夹用于保存加密时生成的加密文本内容该内容会在解密时用到最后是在 obConfusion.sh 和 obDecrypt.sh 文件中加入脚本内容下面是加密混淆脚本内容#!/bin/sh################################### (该脚本是在https://github.com/heqingliang/CodeObfus 上找到的)# 代码混淆脚本 heyujia 2018.03.15####################################识别含有多字节编码字符时遇到的解析冲突问题export LC_CTYPECexport LANGC#配置项#项目路径,会混淆该路径下的文件ProjectPath/Users/xieyujia/Desktop/ios/学习项目/daimahunxiao#这个路径是混淆成功后原文本和替换文本解密对应的文件存放路径(该路径不能在项目目录或其子目录)混淆成功后会在该路径下生成一个解密时需要的文件根据该文件的文本内容把混淆后的内容更换为原文本内容该文件名的组成由$(date %Y%m%d)_$(date %H%M)及日期_小时组成每分钟会不一样。所以解密的时候需要每次更换文件路径SecretFile/Users/xieyujia/Desktop/ios/学习项目/tihuan$(date %Y%m%d)_$(date %H%M)#第一个参数为项目路径if [[ $1 ]]thenif [[ $1 ! _ ]]; thenProjectPath$1fifi#第二个参数指定密钥文件路径及文件名if [[ $2 ]]thenif [[ $2 ! _ ]]; thenSecretFile$2fifi###############################################################################查找文本中所有要求混淆的属性方法类只会替换文本中ob_开头和_fus结尾的字符串(区分大小写例如oB_就不会做混淆)如果注释内容有该类型的字符串也会进行替换。对于使用 _下划线访问的变量属性不会有影响一样会替换成对应_的混淆内容。resultfilesgrep ob_[A-Za-z0-9_]*_fus -rl $ProjectPath#查找结果为空则退出if [[ -z $resultfiles ]]thenecho 项目没有需要混淆的代码exitelseecho 开始混淆代码...echo $SecretFilefix$(awk BEGIN{srand();k0;}#随机数生成函数function random_int(min, max) {return int( rand()*(max-min1) ) min;}#随机字符串生成函数function random_string(len) {resultUCSk;alpbetnumsplit(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z, alpbet, ,);for (i0; i 0) {tempstrsubstr(x, RSTART, RLENGTH);#判断是否有之前已经找过的重复字符串for ( i 0; i k; i ){if (strarr[i] tempstr){break;}}if(i $SecretFilerecordnum1while [[ 1 1 ]]; dorecordecho $x|cut -d | -f$recordnumif [[ -z $record ]]thenbreakfirecord1echo $record|cut -d : -f1echo 原项:$record1record2echo $record|cut -d : -f2echo 加密项:$record2#替换文件夹中所有文件的内容(支持正则)#单引号不能扩展sed -i s/${record1}/${record2}/g grep $record1 -rl $ProjectPathecho 第$recordnum项混淆代码处理完毕let recordnum $recordnum 1done#查找需要混淆的文件名并替换filerecordnum1while [[ 1 1 ]]; dofilerecordecho $x|cut -d | -f$filerecordnumif [[ -z $filerecord ]]thenbreakfifilerecord1echo $filerecord|cut -d : -f1#echo 原项:$filerecord1filerecord2echo $filerecord|cut -d : -f2#echo 加密项:$filerecord2#改文件名find $ProjectPath -name $filerecord1*| awk BEGIN{frecord1$filerecord1;frecord2$filerecord2;finish1}{filestr$0;gsub(frecord1,frecord2,filestr);print mv $0 filestr;echo 第finish个混淆文件处理完毕;finish;}|bashlet filerecordnum $filerecordnum 1done下面是解密混淆脚本的内容#!/bin/sh######################################## 代码还原脚本 RyoHo 2018.03.15########################################识别含有多字节编码字符时遇到的解析冲突问题export LC_CTYPECexport LANGC#配置项#已经混淆的项目路径ProjectPath/Users/xieyujia/Desktop/ios/学习项目/daimahunxiao#这个是文件路径而不是目录是混淆的时候生成的文本文件路径每次不一样。所以每次加密后解密时需要更换路径SecretFile/Users/xieyujia/Desktop/ios/学习项目/tihuan20180315_1456#第一个参数为项目路径if [[ $1 ]]thenif [[ $1 ! _ ]]; thenProjectPath$1fifi#第二个参数指定密钥文件路径及文件名if [[ $2 ]]thenif [[ $2 ! _ ]]; thenSecretFile$2fifi###############################################################################内容还原xcat $SecretFilerecordnum1while [[ 1 1 ]]; dorecordecho $x|cut -d | -f$recordnumif [[ -z $record ]]thenbreakfirecord1echo $record|cut -d : -f1echo 原项:$record1record2echo $record|cut -d : -f2echo 加密项:$record2#若项目中加密项与密钥文件的加密项不符合则退出程序searchresultgrep $record2 -rl $ProjectPathif [[ -z $searchresult ]]; thenecho 指定的密钥文件不能还原exitfi#替换文件夹中所有文件的内容(支持正则)#单引号不能扩展sed -i s/${record2}/${record1}/g $searchresultecho 第$recordnum项混淆代码还原完毕let recordnum $recordnum 1done#文件还原filerecordnum1while [[ 1 1 ]]; dofilerecordecho $x|cut -d | -f$filerecordnumif [[ -z $filerecord ]]thenbreakfifilerecord1echo $filerecord|cut -d : -f1#echo 原项:$filerecord1filerecord2echo $filerecord|cut -d : -f2#echo 加密项:$filerecord2#改文件名find $ProjectPath -name $filerecord2*| awk BEGIN{frecord1$filerecord1;frecord2$filerecord2;finish1;}{filestr$0;gsub(frecord2,frecord1,filestr);print mv $0 filestr ;echo 第finish个混淆文件还原完毕finish;}|bashlet filerecordnum $filerecordnum 1done应大家需要把脚本源码:https://github.com/xkftkffz/DMHXDemo 地址 放出来建议大家看看脚本内容有利于学习理解。该脚本是有针对性的混淆内容可以自己修改脚本中的正则表达式来确定混淆的内容。脚本中只会替换文本中ob_开头和_fus结尾的字符串(区分大小写例如oB_就不会做混淆)如果注释内容有该类型的字符串也会进行替换。对于使用 _下划线访问的变量属性不会有影响一样会替换成对应_的混淆内容。