Tenloy's Blog

iOS制作马甲总结

Word count: 7.5kReading time: 28 min
2020/06/13 Share

前言:内容大幅度参考了网上一些博客 + 亲自实践。若文末忘记注明出处,请见谅,留言修改。

一、为什么制作马甲?

  • 防止app因为违规被苹果下架后”一无所有”。付费视频类,彩票类的app多少都会违反苹果的一些规范有被下架的风险,马甲包可以在app被下架的时候顶上去,那什么情况下会被下架呢?

    • 之前审核的时候用到开关,审核过了之后APP的内容和审核时的内容差异较大,苹果复查的时候发现被下架
    • 用户举报,被下架
    • 竞品方举报,被下架
  • 为主app导入流量,因为马甲包一般和主app用的是同一套后台,用户数据上是互通的,可以通过在马甲包里添加跳转链接等方式引导用户去下载使用主app,往主app里导入流量

  • 广撒网,增加收入。

之前做过付费视频APP,其实那个时候付费视频的黄金期已经快过了,上架的第一个APP通过做aso优化,一天的用户充值可以达到15000左右,但是再想提高充值就很难了(针对我们当时APP的情况)。但是再上架一个功能一样马甲包,通过aso优化很轻松就能做到日充值10000左右,可以脑洞大开一下如果上架100个马甲包会是一种怎样的体验。其实一般的小公司能做上架七八个就很够用了,日流水近10万,很可观了

其实苹果2018年5月份之前对马甲包的审核力度还不是很大,但是七月份之后苹果对马甲包的审核处理力度增大了很多。是因为在这期间世界杯的到来,很多博彩类的app马甲包上架,这种情况也被央视报道,说苹果审核不够严谨,应用市场上充斥着大量的马甲包,导致应用市场混乱,引起了苹果的重视,大量下架了这类app,理所应当马甲包的上架审核也严格了很多。

在这之后马甲包上架就更加困难了,苹果对代码层面的审核也严格了很多,所以马甲包的代码混淆就要比之前力度更大,包括资源文件,费代码,混淆都要尽量多的添加和修改。马甲包的功能也要尽可能的完善丰富起来(功能单一容易被2.1大礼包),而且这些功能不能太大众化,同类产品也很用可能用类似的马甲。

二、解决两个问题

  • 2.1 : 说是违反了一个或多个应用市场规则,一旦跟马甲包、棋牌、彩票等扯上关系(比如关键词含有赌博、竞彩等),都将会上标记,进入机审流程,最后以2.1理由批量拒绝。

  • 4.3 : 应用程序提供了与提交给App Store的其他应用程序相同的特性集;它只是内容或语言不同,这被认为是垃圾邮件的一种形式

2.1 脚本混淆

混淆 脚本混淆念茜-OC代码混淆

注意:添加混淆作用的头文件(这个文件名是脚本confuse.sh中定义的)

#import "codeObfuscation.h" 需要自己手动addFileTo…

被拒,苹果新规:不允许使用这种脚本混淆了。违反了2.3.1,说有隐藏功能,base64加密API肯定不能再使用了,苹果都说了,加密特征太过明显。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
### Guideline 2.3.1 - Performance

We discovered that your app contains hidden features. Specifically, it would be appropriate to remove all code obfuscation and selector mangling or to explain in detail the purpose of its inclusion before resubmitting for review.
The next submission of this app may require a longer review time, and this app will not be eligible for an expedited review until this issue is resolved.

**Next Steps**
- Review the Performance section of the [App Store Review Guidelines](https://developer.apple.com/app-store/review/guidelines/).
- Ensure your app is compliant with all sections of the [App Store Review Guidelines](https://developer.apple.com/app-store/review/guidelines/) and the [Terms & Conditions](https://developer.apple.com/terms/) of the Apple Developer Program.
- Once your app is fully compliant, resubmit your app for review.

Submitting apps designed to mislead or harm customers or evade the review process may result in the termination of your Apple Developer Program account. Review the [Terms & Conditions](https://developer.apple.com/terms/) of the Apple Developer Program to learn more about our policies regarding termination.

询问为什么说我们有隐藏功能的苹果回复:
Thank you for the response. Your app includes code obfuscation and selector mangling (ConfuseCode, it would be appropriate to remove all code obfuscation and selector mangling (ConfuseCode) or to explain in detail the purpose of its inclusion before resubmitting for review.

2.2 手动混淆

2.2.1 思路

切断当前马甲包与以往马甲包的所有相似性关联;

包括分项细述:

  • ipa包特征。包括有

    • 代码相似性:
      • 已有代码的混淆
        • 改项目名:参考链接:iOS 最新修改项目名称
        • 改文件、类、函数、宏、全局变量名
        • 新增属性、属性使用,函数以及函数调用
        • 改项目配置、plist文件等
      • 添加一些无用的代码, 切记一定要调用, 这是重点;
      • 删注释是没用的,因为注释是不会被编译进包里
      • 改文件夹或者文件名应该是不太靠谱的,编译的时候会根据路径来引用查找,编译之后应该是根据在包里的相对内存地址来查找类和函数,跟你编译时的文件名称和路径关系应该不大。不过为了方便和代码的统一,更换时可以顺便换了。
    • 资源相似性:
      • 资源改名如图片、音效;
      • 适当添加一些无用的资源
  • 开发者帐号:两个马甲包不要关联到同一个开发者帐号的信息;比如打包时关联。

  • 打包电脑:有条件的最好用不同的MAC来打包(每台MAC上最好打包马甲包不要超过5个)

  • 上传IP:上传马甲包时,IP不要跟其他马甲包的IP相同

  • 材料相似:

    • ituns后台材料如宣传图,icon,版权人不要出现相同;
    • 应用内部UI最好也做调整,规避人工4.3问题。

修改名称时,不要生成随机的md5编码数据格式串的名字,不管是代码还是图片资源,会被苹果认定在刻意隐藏一些功能。

2.2.2 KLGenerateSpamCode

KLGenerateSpamCode 是一个应对苹果对重复应用的审核(Guideline 4.3 Design Spam)的工具,用于避免苹果机审检测概率。

主要功能有:

  • 修改工程名
  • 修改类名前缀
  • 扫描工程中的代码,生成同等数量的 Category 文件,文件中及是同等方法数量的垃圾代码。
  • 修改 xxx.xcassets 文件夹中的 png 资源文件名。
  • 删除代码中的所有注释和空行(这个貌似没什么必要)。

三、审核流程

3.1 机审

  1. APP工程重命名
  2. 文件夹名、文件名重命名:类前缀
  3. API(方法名、属性):方法名前缀
  4. 添加大量的垃圾文件(只添加,不引用好像也不行,可以创建一些view/model 不添加显示
  5. 往之前的代码中添加废代码,进行混淆(记住添加注释是没有用的,)
  6. 资源文件的属性进行修改,就是md5编码与之前的资源文件不同(其实很简单,让ui把素材放入ps中再重新导出就可以了)

由此可见:+类前缀、方法名前缀是有多重要…

3.2 人审

  • UI界面尽量跟之前有大的区别(这里可以做开关)
  • 修改截图,icon,logo,ui,ue,url,界面风格,配色
  • 马甲包功能不能太简单容易被苹果送上2.1大礼包

说起来简单:就是代码尽量多的混淆,跟之前包的代码有大的区别。马甲包内容尽量与众不同,功能尽量完善

做起来难:做一个完美的马甲包其实跟做了一个新的App差不多了

3.3 审核被拒处理

第一种机器审核(主要是App代码上、App相关资料方面)

被拒信息一般都是:

1
2
3
Guideline4.3 - Design - Spam(找技术改代码)

Your app duplicates the content and functionality of apps submitted to the AppStore, which is considered a form of spam.

这种主要是对App进行扫描,就和我们毕业论文查重一样,针对关键性信息进行匹配,当这个匹配度超过一定的比例,苹果就会认为重复应用。

在代码层级上来查,现在苹果应该是已经达到全面扫描二进制文件,从中提取技术特征,有种查杀病毒的赶脚。比较明显的就是现在游戏App如果接入了某宝或者某信的支付SDK,那么这种包体必定会被拒,这就是苹果预先对一些带有第三方支付的sdk采集技术特征,然后机器扫描你是否接入了这个SDK。

如果是资料的话,无非是苹果的两个开发者后台(http://developer.apple.com/和http://itunesconnect.apple.com/)上的信息,这种和代码层上排重差不多,同样是提取特征值。

具体是上面那种原因被拒,根据我上包的经验来看,如果是从提交审核到拒审的时间间隔较短,那么很大可能就是资料上的重复导致。这种情况下,我们需要对我们的资料进行排查了。如果间隔时间较长,那么这种就一定是代码的问题,我们就需要在对代码进行混淆、垃圾代码等操作,反正必须改变特征比例。

第二种人工审核(对APP的内容、功能进行核验,防止APP有bug,防止APP模仿其他应用,内容与其他APP重复)

被拒信息一般都是

1
2
3
Guideline4.3 - Design - Spam (改UI)

Wefound that your app provides the same feature set as other apps submitted to the App Store, which is not appropriate to the App Store.

这种在我看来,就是界面、功能、app名称等,和其他的App太相似了,审核人员一看就觉得是个马甲包;另外一种就是审核人员可能只是怀疑,这种我们就稍微进行假页面的添加、修改下前期的UI界面,如果这种还被审核人员查到了,就需要申诉,说明我们不一样。

第三种 名字等相似度过高

名字相似度太高,很多产品或运营同学经常是这个账号被拒太多次之后,就转移到另一个账号去上,同时又没有将原来账号里的APP作废,这样就导致4.3问题的出现。要记得,如果是要重新在其他账号上架,一定要关注名字、icon以及代码的问题。

关于审核时间**:**

  • 只要出现4.3或2.1 全都出现了审核延迟,大概7-10天左右再会审核的。所以花了这么长时间,而创建了新的应用,就不会延时。基本上当天晚上就会审(周未除外)

关于应用相似度

  • 应用全是做电商类的,原生代码都是封装了第三方的,也都一样,因为是外包公司,底层都一样,一个框架开发出来的。前端UI及JS方面。50%差不多,每款应用都有进行了修改,一般改动的是30%-50%。

其它说明

  • 我们的应用也不属于马甲包吧,外包公司,制定了一套模块或是封装了一些代码,拿来重用,界面部分都是定制的。苹果要死认定是我是重复应用,我这也是百口莫辨,无奈只有不断提交上次,不断尝试。 实在上架不了,技术也要另寻高就了。为了糊口也没有办法。

结论:

旧应用进行更新上架,两次是100%一晚通过, 新应用,只要当前账户有被拒了4.3 再创建了新的,也会被拒4.3。比较危险的情况是:一个开发者账号下,存在过一直因为4.3的原因审核被拒,再在这个账号上提交马甲包,很容易被推迟审核或则再次因为4.3被拒,最好放弃这个账号,采用新账号去提交审核。

四、App配置多个马甲包的环境

在一个工程中,动态配置马甲包的bundle id、appicon、lanuchImage等:iOS app配置多环境变量和制作马甲包

附一篇实操文章

功能已经过时,但思路挺全面的

1. 马甲包

1.1 什么是马甲包?

马甲包是利用 App store 的规则漏洞,通过技术手段,多次上架同一款产品的方法。马甲包和主产品包拥有基本一致的内容和功能,项目代码基本都是完全复用的,除了图标,应用名称,包名等不一致,其他基本一致。

1.2 为什么做马甲包,以及马甲包的好处

  • AB 测试
    可以测试跨度大的新功能,好的功能就在主包上迭代,不好的也无所谓,不影响主包的使用体验,避免用户流失。

  • 导流
    主包和马甲包同属一个平台,用户信息可以共享;通过弹窗,广告,Push等引导用户到App Store下载主App;有一部份App接了网盟相互导流。

  • 增加关键词覆盖
    App Store关键词长度上限是100个字符,据了解人为正常优化的极限是关键词覆盖数在4000左右,那些覆盖数在8000+的都是利用了苹果漏洞。所以,多做一个马甲,也就意味着覆盖的关键词可以更多。

  • 刷榜
    积分墙、真机、机刷等。用马甲包来刷排名,抵抗主包风险。

1.3 马甲包制作注意事项

  • 二进制不同
    应用名称,图标,包名,工程名,打包电脑,代码,静态资源等的修改。

  • 差异化
    整体UI,产品功能,页面布局等的修改

1.4 实践

KLGenerateSpamCode 是一个应对苹果对重复应用的审核(Guideline 4.3 Design Spam)的工具,用于避免苹果机审检测概率。

主要功能有:

  • 修改工程名
  • 修改类名前缀
  • 扫描工程中的代码,生成同等数量的 Category 文件,文件中及是同等方法数量的垃圾代码。
  • 修改 xxx.xcassets 文件夹中的 png 资源文件名。
  • 删除代码中的所有注释和空行。
-w910

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1. 项目名地址,注意不是项目文件夹地址
/Users/vincent/Desktop/code/spamCode/VHLSpamCodeDemo/VHLSpamCodeDemo
# 2. 修改项目名称
-modifyProjectName VHLSpamCodeDemo>VHLSpamCodeDemo1
# 3. 忽略文件夹
-ignoreDirNames Depends
# 4. 修改类名前缀。没有前缀的会加上前缀,有前缀的会修改。注意修改后是否重名
-modifyClassNamePrefix /Users/vincent/Desktop/code/spamCode/VHLSpamCodeDemo/VHLSpamCodeDemo.xcodeproj VHL>VIN
# 5. 生成垃圾代码
-spamCodeOut /Users/vincent/Desktop/code/spamCode/VHLSpamCodeDemo/VHLSpamCodeDemo2/SpamCode VSpam
# 6. 修改 xxx.xcassets 文件夹中的 png 资源文件名
-handleXcassets
# 7. 删除空行和注释
-deleteComments
-w1075

修改工程名后,如果包含 pod,需要到文件夹下重新执行 pod update

1.5 优化图片大小,修改图片 hash 值

  • ImageOptim

    mac 下无损压缩图片工具,将包含图片的文件夹拖入工具,会自动扫描文件夹下的所有文件,自动选择最优算法进行优化。一般第一次优化项目时,会有几M到10几M的优化效果。

  • ImageMagick

    ImageMagick: 是一款创建、编辑、合成,转换图像的命令行工具。

    通过 brew 安装 imagemagick

    1
    brew install imagemagick

    压缩文件夹下所有 png 文件,会修改 hash 值

    1
    find . -iname "*.png" -exec echo {} \; -exec convert {} {} \;

    更多 imagemagick 命令以及使用方法
    图像处理 - ImageMagick 简单介绍与案例

2. 逆向基础,以及为什么要做混淆

当我们用 Xcode 构建一个程序的过程时,编译器会把源文件 (.m 和 .h) 文件转换为一个可执行文件。这个可执行文件中包含的字节码会将被 CPU 执行,虽然不能直接从这些字节码中查看我们的核心代码,但是黑客可以通过一些反汇编的逆向工具来分析我们的程序,找到漏洞进行破解。

可执行文件格式

EXE Windows 下可直接执行的文件扩展名
ELF Linux 下的可执行文件
Mach-O MacOS/iOS 下主要的可执行文件

2.1 Mach 与 Mach-O

Mac 是苹果电脑 Macintosh 的简称,而 Mach 则是一种操作系统内核。Mach 内核被 NeXT 公司的NeXTSTEP 操作系统使用。在Mach上,一种可执行的文件格是就是 Mach-O(Mach Object file format)。1996年,乔布斯将 NeXTSTEP 带回苹果,成为了OS X的内核基础。所以虽然 MacOS X 是 Unix 的“后代”,但所主要支持的可执行文件格式是 Mach-O。

2.2 iOS 可执行文件

通常我们通过 Xcode 打包或者从应用商店下载的 APP 都是 ipa 包(iPhone Application)。这是一个变相的 zip 压缩包,可以通过 unzip 命令进行解压。

解压之后,会有一个 Payload 目录,而 Payload 里则是一个 .app 文件,而这个实际上又是一个目录,或者说是一个完整的 App Bundle。

在这个目录中,里面体积最大的文件通常就是和 ipa 包同名的一个二进制文件。通过 file 命令可以查看该文件的类型

1
2
3
xx: Mach-O universal binary with 2 architectures: [arm_v7:Mach-O executable arm_v7] [arm64]
xx (for architecture armv7): Mach-O executable arm_v7
xx (for architecture arm64): Mach-O 64-bit executable arm64

这里可以看出,这是一个支持 armv7 和 armv7s 两种处理器架构的通用程序包,里面包含的两部分都是 Mach-O 格式。

i386 模拟器32位处理器
x86_64 模拟器64位处理器
armv7,armv7s 真机32位处理器
arm64 真机64位处理器

Mach-O 的文件结构:

从这张图上来看,Mach-O文件的数据主体可分为三大部分,分别是头部(Header)、加载命令(Load commands)、和最终的数据(Data)。

2.3 class-dump

class-dump 是一个利用 Objective-C 语言的 runtime 特性,将存储在 Mach-O 文件结构里 data 部分的类属性和方法等信息提取出来,并生成对应的 .h 文件的工具。注意: 必须是脱壳后的可执行文件。(比如通过越狱手机或者第三方应用下载渠道)

2.4 安装使用

class-dump 官网下载 dmg,将 dmg 里面的 class-dump 拷贝到 /usr/local/bin 文件夹下,然后就可以在终端中使用 class-dump 命令了。

简单使用:

1
class-dump -H [需要被导出的 Mach-O 文件路径] -o [头文件输出目录地址]

也可以可以查看导出后的头文件目录:

-w621

2.5 hopper

Hopper 是一种适用于 OS X 和 Linux 的逆向工程工具,可以用于反汇编、反编译和调试 32位/64位英特尔处理器的 Mac、Linux、Windows 和 iOS 可执行程序。

将 Mach-O 文件拖入 hopper 可以查看。

-w1425

通过以上的方式,别人可以对照应用的功能来分析代码逻辑,从而进行针对性的破解。所以对项目的核心的代码进行混淆就是非常有必要的了。

3. 代码混淆

常规的混淆思路:

  • 花代码花指令,即随意往程序中加入迷惑人的代码指令
  • 易读字符替换

防止被 class-dump 后,被人分析核心代码逻辑。可以对关键,已读的字符串进行替换,比如 ad, vip 等关键词。

3.1 替换字符串混淆

但是我们又不想替换成不想关的字符串后给自己调试带来麻烦,这里我们可以使用 HSKConfuse 的 shell 脚本,通过在Build Phrase 中设定在编译之前进行方法名的字符串替换,从而在不影响自己编写代码的基础上,对编译后的二进制包进行混淆。

首先在项目中新建文件:

1
2
confuse.sh: 存放混淆的脚本
func.list: 需要混淆的方法、变量名

confuse.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/env bash

TABLENAME=symbols
SYMBOL_DB_FILE="symbols"
STRING_SYMBOL_FILE="$PROJECT_DIR/VHLObfuscationDemo/VHLObfuscation/func.list"

CONFUSE_FILE="$PROJECT_DIR/VHLObfuscationDemo"
HEAD_FILE="$PROJECT_DIR/VHLObfuscationDemo/VHLObfuscation/codeObfuscation.h"

export LC_CTYPE=C

# ** 可以不执行下面的方法,替换成自己的规则手动写入到 func.list 中**
# 取以.m或.h结尾的文件以+号或-号开头的行,并以 vhl_ 开头的方法 |去掉所有+号或-号|用空格代替符号|n个空格跟着<号 替换成 <号|开头不能是IBAction|用空格split字串取第二部分|排序|去重复|删除空行|删掉以init开头的行>写进func.list
grep -h -r -I "^[-+]" $CONFUSE_FILE --include '*.[mh]' |sed "s/[+-]//g"|sed "s/[();,: *\^\/\{]/ /g"|sed "s/[ ]*</</"| sed "/^[ ]*IBAction/d"|awk '{split($0,b," "); print b[2]; }'| sort|uniq |sed "/^$/d"|sed -n "/^vhl_/p" >$STRING_SYMBOL_FILE

#维护数据库方便日后作排重,以下代码来自念茜的微博
createTable()
{
echo "create table $TABLENAME(src text, des text);" | sqlite3 $SYMBOL_DB_FILE
}

insertValue()
{
echo "insert into $TABLENAME values('$1' ,'$2');" | sqlite3 $SYMBOL_DB_FILE
}

query()
{
echo "select * from $TABLENAME where src='$1';" | sqlite3 $SYMBOL_DB_FILE
}

ramdomString()
{
openssl rand -base64 64 | tr -cd 'a-zA-Z' |head -c 16

}

rm -f $SYMBOL_DB_FILE
rm -f $HEAD_FILE
createTable

touch $HEAD_FILE
echo '#ifndef Demo_codeObfuscation_h
#define Demo_codeObfuscation_h' >> $HEAD_FILE
echo "//confuse string at `date`" >> $HEAD_FILE
cat "$STRING_SYMBOL_FILE" | while read -ra line; do
if [[ ! -z "$line" ]]; then
ramdom=`ramdomString`
echo $line $ramdom
insertValue $line $ramdom
echo "#define $line $ramdom" >> $HEAD_FILE
fi
done
echo "#endif" >> $HEAD_FILE

sqlite3 $SYMBOL_DB_FILE .dump

以上的 shell 脚本运行后会自动获取 .h, m 文件中以 vhl_ 开头的方法写到到该文件。如果需要自定义的话,可以不执行以上那句命令,然后换成自己的规则写入 func.list 中。例如:

1
2
3
vhl_isVIP
xx_showAD
yy_isAllow

然后在 Build Phases 中,左上角加号添加 run script 填入地址

-w1125

3.2 查看编译结果

-w899

成功编译后,会在指定目录下生成一个 codeObfuscation.h 文件。这里可以看到,在编译过程中会执行 shell 脚本,对相关字符串进行替换

添加 .pch 文件,并在 Build Setttings > Prefix Header 中链接该 .pch 文件,在 .pch 文件中导入 codeObfuscation.h,此时项目中指定的方法都被替换成了codeObfuscation.h 中的宏定义。

-w906

运行成功后将 Products 中的二进制文件拖入到 hopper 中查看

-w1008

此时,方法已经被混淆了。

注意:这个不要大面积的使用,会有被审核拒绝的风险,拒绝原因是说你程序里面可能包含有隐藏功能,因为 apple 无法从这些混淆后的方法获取到有用的信息。

4. 编译混淆

以上我们虽然对关键字符串进行了混淆,但是实际代码的执行逻辑等并没有改变。黑客仍然可以通过分析代码逻辑或者伪代码来寻找程序的漏洞。那有没有可能改变编译后的代码逻辑,从而让别人无法分析我们的程序呢。

4.1 iOS 是如何编译的

Objective C采用 Clang 作为前端,而 Swift 则采用 swift() 作为前端,二者都是用 LLVM(Low level vritual machine) 作为编译器后端。

编译命令地址

1
2
3
4
# Objective-C
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
# Swift
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift

Xcode 编译过程:

-w1132

4.2 编译器

4.2.1 相关名词

  • GCC:(GNU Compiler Collection)缩写,一个编程语言编译器,是GNU(自由软件理事会)的关键部分。也是GNU工具链的一部分。GCC常被认为是跨平台编译器的事实标准,特别是它的C语言编译器。GCC原本只能处理C语言。但是面对Clang的竞争,很快作出了扩展,现在已经可以处理C++,Fortran、Pascal、Object-C、Java、Ada,以及Go语言。许多操作系统,包括许多Unix系统,如Linux及BSD家族都采用GCC作为标准编译器。MacOSX也是采用这个编译器。

  • LLVM:是Low Level Virtual Machine的简称。这个库提供了与编译器相关的支持,能够进行程序语言的编译期优化、链接优化、在线编译优化、代码生成。可以作为多种语言编译器的后台来使用。

  • Clang:Clang 是 LLVM 的子项目,是 C,C++ 和 Objective-C 编译器,目的是提供惊人的快速编译,比 GCC 快3倍,其中的 clang static analyzer 主要是进行语法分析,语义分析和生成中间代码,当然这个过程会对代码进行检查,出错的和需要警告的会标注出来。

  • 前端编译器:编译器前端的任务是进行:语法分析,语义分析,生成中间代码(intermediate representation )。在这个过程中,会进行类型检查,如果发现错误或者警告会标注出来在哪一行。

  • 后端编译器:编译器后端会进行机器无关的代码优化,生成机器语言,并且进行机器相关的代码优化。iOS的编译过程,后端的处理如下

LVVM 优化器会进行 BitCode 的生成,链接期优化等等。

LLVM机器码生成器会针对不同的架构,比如arm64等生成不同的机器码。

2000年,伊利诺伊大学厄巴纳-香槟分校(University of Illinois at Urbana-Champaign 简称UIUC)这所享有世界声望的一流公立研究型大学的 Chris Lattner(他的 twitter @clattner_llvm ) 开发了一个叫作 Low Level Virtual Machine 的编译器开发工具套件,后来涉及范围越来越大,可以用于常规编译器,JIT编译器,汇编器,调试器,静态分析工具等一系列跟编程语言相关的工作,于是就把简称 LLVM 这个简称作为了正式的名字。Chris Lattner 后来又开发了 Clang,使得 LLVM 直接挑战 GCC 的地位。2012年,LLVM 获得美国计算机学会 ACM 的软件系统大奖,和 UNIX,WWW,TCP/IP,Tex,JAVA 等齐名。

Chris Lattner 生于 1978 年,2005年加入苹果,将苹果使用的 GCC 全面转为 LLVM。2010年开始主导开发 Swift 语言。

iOS 开发中 Objective-C 是 Clang / LLVM 来编译的。

4.3 Hikari

Hikari 是一个基于 Obfuscator-LLVM 对 Xcode9的适配。

OLLVM 是瑞士西北应用科技大学安全实验室于2010年6月份发起的一个项目,该项目旨在提供一套开源的针对 LLVM 的代码混淆工具,以增加对逆向工程的难度。目前,OLLVM已经支持LLVM-4.0版本。

4.3.1 安装

下载 github 提供的 pkg 安装文件并双击安装

1
https://github.com/HikariObfuscator/Hikari/releases

然后重启 Xcode 就能看到已经有 Kikari 编译工具

-w640

4.3.2 使用

  1. Xcode -> Toolchains -> Hikari 将混淆工具和项目关联
  2. 将所有与要运行的 target 相关的 target(包括pod进来的库)Enable Index-While-Building 的值改为 NO
  3. Optimization Level 的值设置为 None[-O0]
  4. Build Settings -> Other C Flags 中加入混淆标记
1
2
3
4
5
6
7
8
9
-mllvm -enable-bcfobf 		启用伪控制流  
-mllvm -enable-cffobf 启用控制流平坦化
-mllvm -enable-splitobf 启用基本块分割
-mllvm -enable-subobf 启用指令替换
-mllvm -enable-acdobf 启用反class-dump
-mllvm -enable-indibran 启用基于寄存器的相对跳转,配合其他加固可以彻底破坏IDA/Hopper的伪代码(俗称F5)
-mllvm -enable-strcry 启用字符串加密
-mllvm -enable-funcwra 启用函数封装
-mllvm -enable-allob 依次性启用上述所有标记

重新编译就会使用 Hikari 在编译器后端对项目进行编译了。

将编译后的二进制文件拖入 hopper 中进行对比

-w1194

发现代码已经被混淆过了。

最新的 Xcode10 通过非官方默认的 Toolchains 编译后的的 ipa 是拒绝提交审核的。

总结

以上是对 iOS 下马甲包,代码混淆,编译混淆的一些学习实践,实际使用中需要根据自己的实际需求进行调整尝试。

demo 地址:iOSObfuscator

加密与破解,编译与反编译永远都是在不停攻防的。没有一堵绝对安全的墙,也没有绝对完美的银弹。只有在开发成本与安全成本中找个一个平衡,才是可持续发展的选择。

参考文章

Author:Tenloy

原文链接:https://tenloy.github.io/2020/06/13/ios-vest.html

发表日期:2020.06.13 , 11:30 AM

更新日期:2024.04.07 , 8:02 PM

版权声明:本文采用Crative Commons 4.0 许可协议进行许可

CATALOG
  1. 一、为什么制作马甲?
  2. 二、解决两个问题
    1. 2.1 脚本混淆
    2. 2.2 手动混淆
      1. 2.2.1 思路
      2. 2.2.2 KLGenerateSpamCode
  3. 三、审核流程
    1. 3.1 机审
    2. 3.2 人审
    3. 3.3 审核被拒处理
  4. 四、App配置多个马甲包的环境
  5. 附一篇实操文章
    1. 1. 马甲包
      1. 1.1 什么是马甲包?
      2. 1.2 为什么做马甲包,以及马甲包的好处
      3. 1.3 马甲包制作注意事项
      4. 1.4 实践
      5. 1.5 优化图片大小,修改图片 hash 值
    2. 2. 逆向基础,以及为什么要做混淆
      1. 2.1 Mach 与 Mach-O
      2. 2.2 iOS 可执行文件
      3. 2.3 class-dump
      4. 2.4 安装使用
      5. 2.5 hopper
    3. 3. 代码混淆
      1. 3.1 替换字符串混淆
      2. 3.2 查看编译结果
    4. 4. 编译混淆
      1. 4.1 iOS 是如何编译的
      2. 4.2 编译器
        1. 4.2.1 相关名词
      3. 4.3 Hikari
        1. 4.3.1 安装
        2. 4.3.2 使用
    5. 总结
    6. 参考文章