项目简介
MixFiles是一款mac os应用,用于自动化对基于oc开发的iOS项目进行项目混淆,方便快速从现有项目中完成马甲包的开发,减少手动混淆工作量
截止目前完成以下功能:
- 1.文件及目录选择,目录支持递归,文件会过滤掉.h、.m文件以外的文件
- 2.Import打乱
- 3.@property属性打乱
- 4.OC方法声明及方法实现打乱
- 5.注释代码删除
- 6.Compile Sources打乱,需要选中打乱的'.xcodeproj'文件
- 7.文件名修改,同时会修改项目目录下的import引用名称
- 8.修改类名
- 9.实现方法插入代码
UI展示
image.png实现过程
本工具是在基于静态代码扫描,通过正则匹配出所有需要处理的代码、文件,实现内容修改覆盖,mac os程序通过NSFileHandle要实现对文件的修改操作,需要在项目中设置:
MixFiles->Targets->MixFiles->Capabilities->AppSandbox->FileAccess->User Selected File 为Read/Write
相关正则表达式
1.属性正则表达式:
static NSString *kRegOfProp = @"@property[\\s\\S]*?;";
2.注释正则表达式:
说明:?<!:表示不包含:,比如http://
static NSString *kRegOfNote = @"[\\t ]*((?<!:)\\/\\/.*|\\/\\*(\\s|.)*?\\*\\/)\\s?";
3.实现方法匹配规则:
实现方法匹配规则,要求方法最后一个括号顶在最前面
static NSString *kRegOfImpMethod = @"[\\-\\+]\\s?\\([\\s\\S]*?\\{[\\s\\S]*?\\n\\}";
4.声明方法正则
static NSString *kRegOfmethod = @"[\\-\\+]\\s?\\([\\s\\S]*?;";
关键代码
-
文件写入
//否则writeHandle获取为空
NSFileHandle *writeHandle = [NSFileHandle fileHandleForWritingAtPath:filepath];
//将文件字节截短至0,相当于将文件清空,可供文件填写
[writeHandle truncateFileAtOffset:0];
NSError *error = nil;
[writeHandle writeData:[fileContext dataUsingEncoding:NSUTF8StringEncoding] error:&error];
if (error) {
NSLog(@"FilePath=%@\nError=%@",filepath,error);
}
[writeHandle closeFile];
-
代码打乱
//打乱属性:将匹配的交换模版字符串随机选两个交换,中间使用了两个占位字符串kTMPREPLACE1,kTMPREPLACE2
while (self.mixPropView.state == NSControlStateValueOn && props.count > 1) {
uint32_t index = arc4random_uniform((uint32_t)(props.count - 1)) + 1;
NSString *firstStr = props[0];
NSString *secondStr = props[index];
tmpcontent = [tmpcontent stringByReplacingOccurrencesOfString:firstStr withString:kTMPREPLACE1];
tmpcontent = [tmpcontent stringByReplacingOccurrencesOfString:secondStr withString:kTMPREPLACE2];
tmpcontent = [tmpcontent stringByReplacingOccurrencesOfString:kTMPREPLACE1 withString:secondStr];
tmpcontent = [tmpcontent stringByReplacingOccurrencesOfString:kTMPREPLACE2 withString:firstStr];
[props removeObjectAtIndex:index];
[props removeObjectAtIndex:0];
}
-
打乱效果
属性、方法、import打乱都是文件内容的修改,如果开启了删除注释功能,首先执行删除注释,如果没有删除注释,对于属性、方法有注释的,在执行代码打乱时,将注释和属性或者方法绑定为一个交换模块
image.png
image.png
project.pbxproj文件解析
-
文件描述
project.pbxproj文件包含项目中所有的配置项,包括文件引用、目录结构、setting设置等等,通常我们都会遇到project.pbxproj的文件冲突,该文件位于xx.xcodeproj->包内容->project.pbxproj
-
pbxproj内容
该文件使用UUID作为交叉引用的索引,每个每个文件、group、framework等都对应唯一UUID,所有的配置对象都放在Objects中,整体内容格式
image.png
-
查看pbxproj
rootObject是project文件根入口,这里我们新建一个project从简单的pbxproj文件开始看,以下我们来新建一个demo项目,来看看项目的project.pbxproj的结构是什么样的
image.png
image.png
-
Objects内容
Objects内容被分割成若干个section,section的数量和种类跟工程有关
每个section区间都会以 /* Begin xxxx section /开始,以/ End xxxx section */ 结束,下面列出主要会涉及到的section(非全部),project.pbxproj查看顺序可以根据下面这个顺序查看
PBXProject ,项目工程配置
PBXNativeTarget ,target配置
PBXSourcesBuildPhase ,Compile Sources配置
PBXBuildFile ,编译文件,包含Copy Bundle Resources资源
PBXFileReference ,文件索引
Compile Sources打乱
-
打乱原理:
查找PBXSourcesBuildPhase这个section,只需要把这里的files内容打乱即可,注意PBXSourcesBuildPhase下会因为多个Target存在多组需要打乱的Resources,正则表达式:
static NSString kRegOfCompileFile = @"[\t ].* \/\* .\.(m|c) in Sources \\/";
static NSString kRegOfPBXSourceBuildPhase = @"\/\ Begin PBXSourcesBuildPhase section \\/[\s\S]?\/\* End PBXSourcesBuildPhase section \*\/";
-
打乱效果
类名修改
类名正则
只需要匹配类名,不包括扩展,分类,这些与类名是强相关的,只需要知道有哪些类名更改了,不符合规则的不管,因为只做类名的修改,没必要全覆盖,这样可以做到只修改自定义类的类名
static NSString kRegOfClass = @"@interface . :";
实现
- 遍历扫描文件,比如文件A,找出A中所有符合替换规则的类名,
- 递归遍历项目根目录、过滤,对文件内容中与类名匹配的字符串进行替换,需要排除的因素:
1:前面有其他字符[a-zA-Z]
2:后面有其他字符或者.h,([a-zA-Z])|(\.h)
效果
image.png扩展
一款优秀工具离开不大家的体验、反馈、各位技术大佬的宝贵意见,希望本工具能在以后的工作中为大家带来一丢丢效率上的改进,作者也会持续优化改进工具体验、性能.
未来还在探索方法名的修改方法,暂时还未找到可靠的实现方案,喜欢的点个赞或Star
项目地址
https://github.com/GeLeis/MixFile_iOS.git
网友评论