顶象iOS加固保护是顶象基于虚机源码保护技术,针对iOS平台推出的下一代加固产品。可以对iOS APP中的可执行文件进行深度混淆、加固,并使用顶象独创的虚拟机技术对代码进行加密保护,使用任何工具都无法直接进行逆向、破解。对APP进行完整性保护,防止应用程序中的代码及资源文件被恶意篡改
目前iOS加固主要包含逻辑混淆、字符串加密、代码虚拟化保护这三大类功能。通过对下面的代码片段进行保护来展示各个功能的效果:
将代码编译后拖入IDA Pro中进行分析,可以得到这样的控制流图,只有6个代码块,且跳转逻辑简单,可以很容易地判断出if-else以及while的特征:
将其反编译为伪代码,代码逻辑及源代码中使用的字符串均清晰可见,与源代码结构基本一致,效果如下
通过将原始代码的控制流进行切分、打乱、隐藏,或在函数中插入花指令来实现对代码的混淆,使代码逻辑复杂化但不影响原始代码逻辑。
对代码进行逻辑混淆保护后,该函数的控制流图会变得十分复杂,且函数中穿插了大量不会被执行到的无用代码块,以及相互间的逻辑跳转,逆向分析的难度大大增强:
若开启防反编译功能,则控制流图会被完全隐藏,只剩下一个代码块,且无法反编译出有效代码(如下图所示),这对于对抗逆向分析工具来说非常有效,包括但不限于(IDA Pro, Hopper Disassembler, Binary Ninja, GHIDRA等)
把所有静态常量字符串(支持C/C++/OC/Swift字符串)进行加密,运行时解密,防止攻击者通过字符串进行静态分析,猜测代码逻辑。
对代码中的字符串进行加密之后,所有的字符串都被替换为加密的引用,任何反编译手段均无法看到明文的字符串。你好,世界!
,Hello, World!
等字符串原本可以被轻易的反编译出来,但保护之后已经看不到了:
将原始代码编译为动态的DX-VM虚拟机指令,运行在DX虚拟机之上,无法被反编译回可读的源代码,任何工具均无法直接反编译虚拟机指令。
采用代码虚拟化保护后,对函数进行反编译将无法看到任何与原代码相似的内容,函数体中只有对虚拟机子系统的调用:
防止通过调试手段分析应用逻辑,开启防调试功能后,App进程可以有效地阻止各类调试器的调试行为:
防止应用程序中的代码及资源文件被恶意篡改,杜绝盗版或植入广告等二次打包行为。
.xcarchive
格式,不支持.ipa
格式.framework
格式,不支持.dylib
格式.framework
及.a
格式Build Setting
中 Enable Bitcode
设置为 YES
Archive
模式编译以确保Bitcode成功启用,否则编译出的文件将只包含bitcode-marker
五、iOS加固辅助工具 -> 5.2 启用 bitcode
2048M
以内在Xcode工程列表中选择要保护的工程,在Targets列表中,选中要保护的Target
点击 Build Settings 标签页,搜索 bitcode ,确保 Enable Bitcode 选项已经设置为 Yes
Xcode 7.0-Xcode 13.4.1中iOS工程默认开启Bitcode;Xcode 14.0后iOS工程默认关闭Bitcode,需要手动开启。
注意:需要确保当前要编译的Target,以及所依赖的所有Target及子工程全部开启 Enable Bitcode
注意:Xcode 14.0及以上版本请在 target -> build settings -> other c flags 中添加 -fno-objc-msgsend-selector-stubs
(可选)在 Build Settings 中添加自定义配置 HIDE_BITCODE_SYMBOLS = NO
将编译目标(Active Scheme)设置为要保护的Target,Device设置为 Any iOS Device
,并点击点击菜单栏 Product
-> Archive
,等待Archive完成
若工程中引入了第三方提供的动、静态库,但没有开启bitcode,则会导致打包失败,此时可以使用顶象iOS加固辅助工具(点此下载)强制开启第三方库的bitcode,具体操作详见
5.2 启用 bitcode
Archive完成后,Xcode自动弹出的 Organizer
窗口,右键点击Archive文件,并选择Show in Finder
然后在Finder中,右键点击xcarchive文件,点击 压缩"xxx.xcarchive"
,得到 .zip 格式的压缩包
注意:该步骤仅适用工程类型为Framework & Library,如果工程类型为Application,请跳过该步骤
根据iOS App待加固文件准备工作的第1-3步开启bitcode后,在 Build Settings 页面中搜索 skip installl ,将其设置为 No
接着根据iOS App待加固文件准备工作的第4步成功Archive出xcarchive文件后,在finder中右键该文件选择 显示包内容
在Product -> Library -> Frameworks下找到生成的 .framework 文件,并压缩为 zip 文件后上传到顶象加固平台;
如果生成的是 .a 文件,可以直接上传到顶象加固平台
本工具用于辅助使用顶象iOS在线加固系统,常规情况下,用户无需使用本工具即可进行加固,但在某些特殊情况下需要使用本工具在用户本地进行一些操作以辅助加固的进行,可以点击此处下载。
本工具包含以下功能,各功能模块相互独立,若需要使用其中一个功能,不代表一定需要使用工具中的其他功能。
此功能模块用于强制开启第三方库的bitcode,由于顶象iOS在线加固工具是基于bitcode进行,打包时必须确保Enable Bitcode = YES,打出的包才可以用于加固。若此时工程中存在未开启bitcode的第三方库,则会导致打包失败,提示类似如下信息:
ld: 'xxxxx' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target.
ld: bitcode bundle could not be generated because 'xxxxx' was built without full bitcode.
此时可以使用本工具将报错提示中的第三方库强制"开启"bitcode。
使用本工具"开启bitcode"后并非真的在库中嵌入了bitcode,而是欺骗xcode令其认为这些库已经开启了bitcode,进而可以正常地进行编译、打包,真实的bitcode必须由源码生成。
使用辅助工具开启bitcode后,再用Xcode打出xcarchive文件并压缩上传加固
Enable Bitcode
设置为 YES
即可,不需要使用本工具进行处理启用bitcode
选项卡Invalid Bundle
的提示,必须先经过顶象加固处理后方可提交。(静态库以及Object文件不受此影响)加固后开启bitcode
设置为 否
此功能模块用于完成xcarchive的压缩以及加固文件的替换。顶象iOS在线加固对上传的文件大小有一定限制,若app体积过大,则xcarchive压缩后可能会超出此限制,此时可以使用此工具提取加固必须的文件进行压缩,减小压缩包体积。待完成加固后,再将下载下来的加固包替换回原始包中。
在 xcarchive文件
输入框处选择待加固的xcarchive文件,可以直接xcarchive文件拖拽至输入框中,或者点击输入框并在弹出的窗口中选择
输出路径
默认在选择的xcarchive同一目录下,点击 输出路径
输入框,可在弹出的窗口中选择其他路径以进行修改
点击 提取
按钮,工具将提取加固必须的文件进行压缩,保存为上一步中指定的文件
访问顶象控制台,使用上一步提取出的文件进行加固
完成加固后,将加固包下载至本地,拖拽至 加固文件路径
输入框,并点击 替换
按钮,加固后的二进制文件将自动替换进原始xcarchive中
xcarchive文件
处选择之前提取的xcarchive即可为什么要开启Bitcode?不开启Bitcode是否可以加固?
A: Bitcode是一种源代码被编译为二进制机器码过程中的中间表示,它既不是源代码,也不是机器码。开启Bitcode之后,Xcode编译出的二进制文件中会嵌入Bitcode。Apple在Xcode7中引入了Bitcode机制,并默认将其开启,通过提交包含Bitcode的ipa,Apple可以在新产品或者新技术发布后,无需开发者参与,即可通过Bitcode对程序进行优化、或者编译出适用于新产品的应用程序。
顶象的加固技术正是基于Bitcode进行处理,因此需要开启Bitcode进行打包,不开启Bitcode无法进行加固。
可以通过以下命令验证xcarchive包中的的二进制文件是否包含Bitcode,若出现 segname __LLVM
的输出信息说明存在Bitcode,否则说明没有Bitcode。
$ otool -arch arm64 -l path_to/xxx.xcarchive/Products/Applications/xxx.app/xxx | grep LLVM
若提示xxx does not contain bitcode
或者 xxx was built without full bitcode
A: 原因是项目中依赖的库文件没有开启bitcode
五、iOS加固辅助工具 -> 5.2 启用 bitcode
。xxx was built without full bitcode
,说明该第三方库配置了 Enable Bitcode = YES
,但并不是以Archive方式打包的,而是本地编译的Development版本,由于本地编译、测试过程中并不需要bitcode,因此Xcode在此种场景下只会在二进制文件中添加一个字节的bitcode marker以加快编译速度。解决方案:联系该第三方库的提供方使用Archive方式编译。也可以使用顶象iOS加固辅助工具强制开启,详见五、iOS加固辅助工具 -> 5.2 启用 bitcode
。若提示 -weak_library and -bitcode_bundle (Xcode setting ENABLE_BITCODE=YES) cannot be used together
A: 在 Other Linker Flags
中找到类似 -weak_library /usr/lib/libxxx.dylib
的配置,改为 -weak-lxxx
的形式,如将 -weak_library /usr/lib/libstdc++.dylib
改为 -weak-lstdc++
A: 在 target -> build settings -> other c flags 中添加 -fembed-bitcode=all
后重新archive,并按照6.1节中方法确认打出的xcarchive包中是否包含bitcode。
A: 不同的加固参数会带来不同的体积变化,并且相同的加固配置对于不同的代码所产生的影响也是不确定的,这取决于代码自身的复杂程度。以下为基于历史样本的统计值,统计对象为APP内主程序(不含bitcode),文件路径为:
path_to_archive.xcarchive/Products/Applications/AppName.app/AppName
,该结果仅供参考。
计算方法:加固后主程序大小 / 加固前主程序大小(不含bitcode)
类型 | 体积增长倍率 |
---|---|
基础版(限制30%) | 1.1~1.5 |
标准版(简单混淆) | 1.3~1.7 |
标准版(普通混淆) | 1.3~2.0 |
标准版(强力混淆) | 1.5~2.4 |
旗舰版(开启全部功能) | 1.4~2.6 |
加固后主程序内代码段的大小有可能会超出AppStore限制,具体限制请参阅App Store Connect官方文档,请根据实际情况合理设置加固参数。
注:从二进制文件整体的角度来看,加固后体积可能会变小,因为加固前二进制文件中同时包含未加固的机器码和比机器码大数倍的bitcode,若未勾选加固后开启bitcode
,加固后的二进制文件中将只包含机器码,bitcode会从二进制中被移除。
A: 这是由于苹果的安全机制导致,Mac OSX默认只允许AppStore中下载软件
sudo spctl --master-disable
后,重试提示请确保使用官方Xcode编译器进行编译
A: 此提示说明项目中包含非官方Xcode编译的代码,第三方编译器生成的Bitcode无法被Apple识别,如果在开启bitcode的情况下提交AppStore会直接被拒,提示 Invalid Bundle
,但若不开启bitcode提交并不会有任何影响。顶象加固是基于bitcode进行,仅对Xcode内置的Apple LLVM编译器进行了适配,同样无法识别第三方编译器产出的未知格式的bitcode。这里存在两种情况
假如有两个第三方SDK存在此种问题,名字分别为 libSDK.a
和 SDK.framework
,均存放在桌面下,路径为~/Desktop
$ xcrun bitcode_strip -r ~/Desktop/libSDK.a -o ~/Desktop/libSDK.a
$ xcrun bitcode_strip -r ~/Desktop/SDK.framework/SDK -o ~/Desktop/SDK.framework/SDK
若存在其他不希望保护的静态库类型的SDK,同样可以参照此流程进行处理。
当有以下报错信息时,请确认您用的包中是否包含腾讯直播SDK。如TXLiteAVSDK
此时请您使用6.5的方案来兼容腾讯直播SDK
请将ipaGuardPlaceHolder.xcframework.zip
解压后添加到您的ipa工程中
ipaGuardPlaceHolder.h
中,并在合适的地方调用link_ipaguard_placeholder
将编译目标(Active Scheme)设置为要保护的Target,Device设置为 Any iOS Device
,并点击点击菜单栏 Product
-> Archive
,等待Archive完成
Archive完成后,Xcode自动弹出的 Organizer
窗口,右键点击Archive文件,并选择Show in Finder
然后在Finder中,右键点击xcarchive文件,点击 压缩"xxx.xcarchive"
,得到 .zip 格式的压缩包
3.待上传完成点击确认即可
文档版本: 3e5bf23e