最近一直在看Python,也很喜欢Python的灵活性;今天主要想说的是iOS的代码混淆,为什么想做代码混淆?为了APP的安全,为了防止别人破壳轻易破解我们代码;还有就是做马甲包了,我们知道马甲包的市场需求很大,但是不能花费过多的精力在开发上,毕竟只是个马甲,没必要花费太多的成本!
网上搜了一下,开源免费的混淆都在转载念茜大姐大的sh脚本的混淆方法,或者在念茜的脚本基础上二次开发,大家去看过就知道念茜的这篇博客是在14年写的,那时我刚做iOS没多久?,而且那时候中国区审核还没有那么严格,若果你现在还使用那种方法进行混淆,你肯定会收到苹果的2.3.1 大礼包?,所以我们还是探索别的混淆方法吧,不要再挖坟了!
我这里主要是通过Python写的混淆工具,具体功能有方法混淆、属性混淆、类名混淆、添加垃圾代码、自动创建垃圾类、删除注释、修改资源文件Hash值、加密字符串、翻新资源名、模拟人工混淆、混淆文件名、混淆文件目录、混淆词库、混淆日志、映射列表、敏感词过滤、图片压缩、爬虫服务、修改项目名,具体的如下:
ZFJObsLib混淆工具全面支持OC项目工程、swift项目和u3d项目!!!???
下载地址:
Git地址:https://gitee.com/zfj1128/ZFJObsLib_dmg
使用教学视频:
链接:https://pan.baidu.com/s/1pqUkgU8YxSzjqTzpHlAD6g 密码:9sll
import addRubbishCode as addCode
import cunfusionObjName as conObjN
import confusionFun as conFunc
import cunfusionProperty as conPro
import confusionLog as conLog
import deleteNotes as delNot
import updateSourceHash as updHash
import encryptString as encStr
import sourceName as soName
import modifyProjectName as modProName
import missFolder
from singletonModel import ZFJPersoninfo
def start_fun(file_dir, funMap = {}):
personinfo = ZFJPersoninfo()
personinfo.isMissing = True
if len(file_dir) == 0:
return
if int(funMap['property']) > 0:
# 混淆属性
conLog.tips('*' * 30 + 'Fun:开始混淆属性' + '*' * 30)
conPro.startConfusionPro(file_dir, personinfo.prefixMap['proPreFix'])
if int(funMap['funName']) > 0:
# 混淆方法
conLog.tips('*' * 30 + 'Fun:开始混淆方法' + '*' * 30)
conFunc.startConfusionFun(file_dir, personinfo.prefixMap['funPreFix'])
if int(funMap['objName']) > 0:
# 混淆类名
conLog.tips('*' * 30 + 'Fun:开始混淆类名' + '*' * 30)
conObjN.startObfuscatedObjName(file_dir, personinfo.prefixMap['objPreFix'])
if int(funMap['souHashKey']) > 0:
# 修改资源文件的hash值
conLog.tips('*' * 30 + 'Fun:修改资源HASH值' + '*' * 30)
updHash.startUpdateSourceHash(file_dir)
if int(funMap['upSouName']) > 0:
# 翻新资源文件名
conLog.tips('*' * 30 + 'Fun:翻新资源文件名' + '*' * 30)
soName.startSourceName(file_dir, personinfo.prefixMap['imgPreFix'])
if int(funMap['encryStr']) > 0:
# 加密明文字符串
conLog.tips('*' * 30 + 'Fun:加密明文字符串' + '*' * 30)
encStr.startEncryptStr(file_dir)
if int(funMap['rubbishCode']) > 0:
# 垃圾代码
conLog.tips('*' * 30 + 'Fun:添加垃圾代码' + '*' * 30)
amount = int(funMap['rubbishLine']) # -添加行数
amount = 5 if amount <= 0 else amount
addCode.startAddRubbishCode(file_dir, amount, personinfo.prefixMap['rubPreFix'])
if int(funMap['deleteNotes']) > 0:
# 混淆或者删除注释
conLog.tips('*' * 30 + 'Fun:开始删除注释' + '*' * 30)
delNot.startDeleteNotes(file_dir)
if int(funMap['missFolder']) > 0:
# 混淆文件夹名
conLog.tips('*' * 30 + 'Fun:开始混淆文件夹名' + '*' * 30)
missFolder.startMissFolder(file_dir, personinfo.prefixMap['folderPreFix'])
if int(funMap['misProjectName']) > 0:
# 修改项目名
conLog.tips('*' * 30 + 'Fun:开始修改项目名' + '*' * 30)
modProName.startModifyProjectName(file_dir)
conLog.tips('*' * 30 + 'End:混淆结束' + '*' * 30)
personinfo.isMissing = False
混淆的部分日志,混淆的时候回通过import logging自动生成混淆日志《ZFJ混淆日志.log》,便于开发者修改部分报错:
我们在混淆的时候,没必要全部进行混淆,特别是第三方库,或者Pods管理的第三方库;毕竟混淆的越多问题也就越多,所以我添加了混淆忽略文件?,如下图:
import confusionLog as conLog
ignore_Files = ['/Pods/', '/Vendor/', '/LIB/', '/Util/']
conLog.tips('已忽略的路径 === ' + str(ignore_Files))
# 判断是否是忽略的文件夹
def isIgnoreFiles(tmp_path):
# if '+' in tmp_path:
# return True
for item in ignore_Files:
if item in tmp_path:
return True
return False
1.方法混淆
2.属性混淆
3.类名混淆
4.添加垃圾代码
在.h文件中暴露垃圾代码
垃圾代码的调用与实现
5.创建垃圾类
详细请看:?《Python-ZFJObsLib完美生成iOS垃圾代码》https://zfj1128.blog.csdn.net/article/details/99086206?
6.去除注释
7.敏感词过滤
8.修改Hash值
针对项目中的资源文件,我们可以通过修改Hash的方式来进行混淆,运行如下:
?Tips:已忽略的路径 === ['/Pods/', '/Vendor/', '/LIB/', '/Util/']
?Infor:[UPdHash OK] /Users/zhangfujie/Desktop/Obfuscated/GUEG_MJ/GUEG/GUEG/Assets.xcassets/MainWeb_Back_Icon.imageset/fanhui-4.png
?Infor:[UPdHash Meg] Old:dd03889c2e8647b9377d08775333557ff11425dd<->New:4a72c7b640882ae436b18868aa021331169db3fa
?Infor:[UPdHash OK] /Users/zhangfujie/Desktop/Obfuscated/GUEG_MJ/GUEG/GUEG/Assets.xcassets/AppIcon.appiconset/60.png
?Infor:[UPdHash Meg] Old:2d73347848d7168c09c48efe28a7ac5a9ec7411b<->New:551483123b5cc2c4c5ff2f5bf876db0d075261a1
?Infor:[UPdHash OK] /Users/zhangfujie/Desktop/Obfuscated/GUEG_MJ/GUEG/GUEG/Assets.xcassets/AppIcon.appiconset/58.png
?Infor:[UPdHash Meg] Old:c0c671fe3707bca8c5accdcadd8aa9f4f1f2726c<->New:d022db1c1f99c263b69bc09c09bc52dd1fa97fb5
?Infor:[UPdHash OK] /Users/zhangfujie/Desktop/Obfuscated/GUEG_MJ/GUEG/GUEG/Assets.xcassets/AppIcon.appiconset/120-1.png
?Infor:[UPdHash Meg] Old:5a6a7ec42d7489be18888828c1a9caba0da688ca<->New:8bbddfbbbed9023e4537e9e6caeed79c88ef8955
?Infor:[UPdHash OK] /Users/zhangfujie/Desktop/Obfuscated/GUEG_MJ/GUEG/GUEG/Assets.xcassets/AppIcon.appiconset/120.png
?Infor:[UPdHash Meg] Old:5a6a7ec42d7489be18888828c1a9caba0da688ca<->New:dcc4b47092bca1d6a6bb6d7bd671a0ef7ce2f4da
?Infor:[UPdHash OK] /Users/zhangfujie/Desktop/Obfuscated/GUEG_MJ/GUEG/GUEG/Assets.xcassets/AppIcon.appiconset/180.png
?Infor:[UPdHash Meg] Old:fee9220dbba52040517a0f77ffe8335e9300a64b<->New:d28a9118e1cf4a2ce9fc2805184ad42e20500c95
?Infor:[UPdHash OK] /Users/zhangfujie/Desktop/Obfuscated/GUEG_MJ/GUEG/GUEG/Assets.xcassets/AppIcon.appiconset/GUEG_ICON.png
?Infor:[UPdHash Meg] Old:07ed6c66ec7d5550bfa1e32b4848687417027c90<->New:fb780d87591cc86dd0fd24cdfa41e76a091ad657
?Infor:[UPdHash OK] /Users/zhangfujie/Desktop/Obfuscated/GUEG_MJ/GUEG/GUEG/Assets.xcassets/AppIcon.appiconset/80.png
?Infor:[UPdHash Meg] Old:ca3b3f61fc4c391515fe895d81360d15ec598049<->New:769ebf182fbb3a3fd69c46c3a595c1669c505f63
?Infor:[UPdHash OK] /Users/zhangfujie/Desktop/Obfuscated/GUEG_MJ/GUEG/GUEG/Assets.xcassets/AppIcon.appiconset/40.png
?Infor:[UPdHash Meg] Old:1bb7908a2ba1295fa69ad476a81003f2f413a3a8<->New:10793e67b27cdf5ad1ee4b9d37aecc62074b8ffc
?Infor:[UPdHash OK] /Users/zhangfujie/Desktop/Obfuscated/GUEG_MJ/GUEG/GUEG/Assets.xcassets/AppIcon.appiconset/87.png
......等等......
9.加密字符串
编译前的代码如下:
- (void)uiConfig{
ZFJView *zfjView = [[ZFJView alloc] initWithZFJ:@"ZFJ1128"];
zfjView.backgroundColor = [UIColor yellowColor];
zfjView.frame = CGRectMake(100, 100, 150, 150);
[zfjView setZFJViewTitleLab];
[zfjView setZFJViewTitleLab:@"aaaaaa"];
[zfjView setZFJViewTitleLab:@"aaa" efg:@"dscvdscsd"];
[zfjView setZFJViewTitleLab:@"ddscvsdv" efg:@"cdsvdfbdf" hijk:@"cdvsvbdsbdfgnfdhnhdg"];
[self.view addSubview:zfjView];
[ZFJView svdsvfdsvfdvbzdfb];
}
编译后的代码如下:
- (void)uiConfig{
ZFJView *zfjView = [[ZFJView alloc] initWithZFJ:ZFJ_NSSTRING(((char []) {240, 236, 224, 155, 155, 152, 146, 0}))];
zfjView.backgroundColor = [UIColor yellowColor];
zfjView.frame = CGRectMake(100, 100, 150, 150);
[zfjView setZFJViewTitleLab];
[zfjView setZFJViewTitleLab:ZFJ_NSSTRING(((char []) {203, 203, 203, 203, 203, 203, 0}))];
[zfjView setZFJViewTitleLab:ZFJ_NSSTRING(((char []) {203, 203, 203, 0})) efg:ZFJ_NSSTRING(((char []) {206, 217, 201, 220, 206, 217, 201, 217, 206, 0}))];
[zfjView setZFJViewTitleLab:ZFJ_NSSTRING(((char []) {206, 206, 217, 201, 220, 217, 206, 220, 0})) efg:ZFJ_NSSTRING(((char []) {201, 206, 217, 220, 206, 204, 200, 206, 204, 0})) hijk:ZFJ_NSSTRING(((char []) {201, 206, 220, 217, 220, 200, 206, 217, 200, 206, 204, 205, 196, 204, 206, 194, 196, 194, 206, 205, 0}))];
[self.view addSubview:zfjView];
[ZFJView svdsvfdsvfdvbzdfb];
}
加密混淆反编译前后Hopper对比如下
我们可以看到再通过Hopper看不到硬编码了!???
10.翻新资源名
找到工程中的图片资源并翻新,然后自动替换代码中的引用。
11.混淆工程目录
说明:如果你的项目包含PCH,还有自带的Info.plist,需要你手动到project.pbxproj修改路径;
12.图片压缩工具
ZFJObsLib集成图片压缩工具,支持一键生成iOS开发三套图标,也支持自定义压缩尺寸,还可以移除Alpha通道,转成RGB图片模式;实现逻辑可参考:https://zfj1128.blog.csdn.net/article/details/94625153
具体如下图:
13.爬虫工具
教学视频
资源爬取:链接:https://pan.baidu.com/s/1xa9ruF_hMcN49716BJUx2w 密码:1zpg
节点爬取:链接:https://pan.baidu.com/s/1ebWWYtjoKkiH9mqakR6EMQ 密码:cosa
使用截图
14.设置混淆前缀
15.资源清理工具
在iOS项目开发的过程中,如果版本迭代开发的时间比较长,那么在很多版本开发以后或者说有多人开发参与以后,工程中难免有一些垃圾资源,未被使用却占据着api包的大小!
这里我通过Python脚本来查找项目中未被使用的图片、音频、视频资源,然后删除掉;以达到减小APP包大小的目的!
详细请看:?《Python-一键查找iOS项目中未使用的图片、音频、视频资源》https://zfj1128.blog.csdn.net/article/details/99290441?
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。