iOS开发系列--代码混淆

由于iOS系统的封闭性,相对于安卓来说,iOS开发过程中代码混淆可能就显得并不是得非有不可了。但是在安全性(可通过class-dump反编译暴露出类的方法名)和特殊需求上(例如马甲包的混淆过审)还是有一定需求的!
此脚本借鉴于kaich/codeobscure。在使用原作者脚本的过程中,发现了一些BUG和不足,比如正则表达式的判断不准确,生成过多无用的替换宏,需要花费过多时间去人工排错...
由于本人对python并不是很熟,所以只是在原作者的基础上作了一些完善修改。

优化内容:

  • 修改正则表达式,更精准地找出关键词。
  • 替换规则更改:随机字符串==>随机生成2个单词拼接。防止苹果审核过程被误认加入混淆乱码。
  • 增加-k选项,通过ignoreKey.txt文件添加需要过滤的关键词,可避免每次生成都要手动删除部分关键词的麻烦。
  • 增加property关键词、懒加载方法名过滤,减少无用宏的生成。
  • 增加IBAction方法关键词的二次过滤(原脚本存在自定义方法跟IBAction方法重名,无法排除的情况)。

以下内容大部分来源于kaich/codeobscure

实现原理

其实插件的实现方式十分简单,提取用户编写的文件中的方法名,使用宏定义将其更换为任意的无规则字符串。但这种方式有一些需要注意的点:

  1. 对于系统库产生的方法名,不可替换;对于系统使用到的关键字,也不可以替换;否则会报错;
  2. Swift混编的项目,Swift中的代码不可替换;同时Swift调用Objective-C的特定方法名也不可以轻易替换;
  3. 第三方库暴露的头文件的方法名,不可替换;

根据上面的规则(可能有遗漏),该脚本采用了相对简单的方法来避免:

  1. 只扫描.h和.m文件,只扫描方法名。(对于属性名,尝试过扫描,但由于属性的访问方式多样,并不建议做混淆,会产生额外的工作量);
  2. 对于系统库,让用户手动指定,这个是可以提取的,直接拿到系统库的头文件即可,脚本会自动扫描到所有的系统关键字,直接做排除处理。(以iOS11的SDK为例,系统关键字约6万个);
  3. 对于Swift代码,可以直接排除在扫描目录外;
  4. 对于第三方库,用户可以手动指定目录,脚本会自动扫描提取关键字,在混淆时避免这些关键字。

依据上述原理,基本可以避免多数情况下产生的混淆错误;当然,由于各种项目的复杂性,有一些复杂的混淆错误无法避免,需要后续手动调整代码。

使用方式

  1. clone本仓库;
  2. 你需要安装python3的运行环境,这个可以使用brew进行安装,这里不再赘述。
  3. 你首先需要确定以下几项:
  • 提取一份你当前项目编译环境的SDK库头文件目录;(Demo中提取了iOS11的SDK头文件目录)
  • 你需要混淆的代码的目录;
  • 你不需要混淆的代码的目录;
  • 你需要提取关键字做排除混淆的目录;(例如Pod仓库、第三方头文件)
  • Swift代码目录;(理论上不会扫描替换,可以用于排除桥接文件)
  • 输出文件目录;脚本运行后会产生多个log文件,以及最终需要使用到的混淆头文件;

注:建议目录使用绝对路径,相对路径容易出问题。

  1. 确定以上几项后,找到仓库根目录的Confuse.py文件,使用以下命令行模板运行:
python3 Confuse.py \
-i 你需要混淆的代码的目录,可以是多个目录,以`,`分隔 \
-s 当前项目编译环境的SDK库头文件目录,可以是多个目录,以`,`分隔 \
-e 你不需要混淆的代码的目录,Swift代码目录,可以是多个目录,以`,`分隔 \
-c 你需要提取关键字做排除混淆的目录,可以是多个目录,以`,`分隔 \
-k 可选,用于存放需要过滤的key(增加内容)
-o 输出文件目录

注:各参数的意义如下:

  • -i(input_dirs):必须,项目需要处理的主要文件所在的目录
  • -s(system_dirs):可选,配置系统Framework文件的目录,一般用于做排除字典,避免替换系统关键字
  • -e(exclusive_dirs):可选,用于存放不扫描处理的文件的目录,比如Swift文件目录
  • -c(clean_dirs):可选,用于存放排除关键字的文件的目录,例如Pods下的目录,或者静态库(头文件修改后会出错)
  • -k(ignore_key_dir):可选,用于存放需要过滤的key(增加内容)
  • -o(output_dir):必须,输出文件的目录,用于输出关键字、日志以及最后生成的混淆头文件的目录
  1. 运行后会在你指定的输出目录下产生一份Confuse.h文件,内容一般如下:
#ifndef NEED_CONFUSE_h
#define NEED_CONFUSE_h
// 生成时间: 2018-04-03 17:20:51
#define Function1 linotypistStonecrop
#define function1 exactingnessMimologist
#define function2 sheepmanSupersublimated
#define functionWithTitle kensititeCratinean
#define subTitle icelandicUntell
#endif

这份文件包含了一堆的宏定义,将需要替换的方法名都替换为了一些随机的字符串,因为宏定义是全局替换,我们只需要将该文件引入到自己的项目中,并在PCH文件中进行引入即可。

引入该文件后,Command+B测试编译,如果无法避免而产生编译错误则需要手动调整;由于将所有的替换归集到了头文件中了,所以遇到有错误的地方尝试删除对应宏定义替换信息重新编辑即可。

另外附上一个系统系统库路径:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks


图文教程

了解完原理,接下来用图文来详细介绍使用方法:
首先去我的Github上获取下源代码资源文件。

注:关键文件如下:

  • Confuse.h最终生成的替换文件就是这个了,该文件里记录了所有需要混淆的方法名和与之对应的替换字符串
  • Confuse.py该文件是脚本内容所在,所有实现方法都在这。
  • ignoreKey.txt该文件下记录需要过滤的特殊key,每个key换行读取
  • start.sh开始执行脚本 ,在此脚本内更改路径

现在开始集成:

首先需要一个pch文件,至于pch的用法自行百度吧.。

#ifndef TMPrefixHeader_pch
#define TMPrefixHeader_pch
//代码混淆关键导入文件头,注释后不混淆
#import "Confuse.h"
#endif /* TMPrefixHeader_pch */

根据自行需求添加特殊keyignoreKey.txt文件内

通过start.sh脚本快速执行


终端执行内容大概如下:

生成的混淆文件:

编译结果:对无参数、无返回值、多参数等方法名完成识别替换。


接下来我们用class-dump来反编译一下:

class-dump -H /Users/wuaming/Library/Developer/Xcode/DerivedData/TMConfuse-becmpkjuhzbzfldtqwaiznqcmmxq/Build/Products/Debug-iphonesimulator/TMConfuse.app -o /Users/wuaming/Desktop/heads

对比结果:


附上个人Github:https://github.com/TMWu/TMConfuse

思否:https://segmentfault.com/a/1190000014167401

最后还是要感谢下几位大佬!
相关链接:
Objective-C Class-dump 安装和使用方法(原创)
iOS安全攻防(二十三):Objective-C代码混淆
感谢原作者的Github

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容

  • 技 术 文 章 / 超 人 对于IOS来说,由于系统是封闭的,APP上架需要通过App Store,安全性来说相当...
    树下敲代码的超人阅读 10,548评论 47 77
  • 前言 什么!我们的代码拿去安全扫描啦?什么!还扫描出来问题啦?什么!源码都别看到啦? 居于上一篇文章iOS简单逆向...
    甘邦阅读 17,964评论 24 40
  • app风靡的时代,总有一些奇葩的需求。为了刷量,刷排名,制作壳包,为了通过苹果爸爸审核,想到代码混淆,垃圾代码等策...
    二斤寂寞阅读 22,638评论 11 52
  • 最近在自己的成长历程,一段段经历浮现出来。上班路上,一个声音说:“你们不是以我引以为豪吗?我要让你们失望。”止不住...
    在云端01阅读 164评论 2 2