ios h5马甲包项目过包 实践

h5马甲包从需求到提审需要四步骤

H5项目的出包任务分为四步:1.新建工程和基础代码 2.将美术资源和出包需求导入工程项目 3.(最重要的部分)进行代码混淆 4.打包成ipa(分为debug包和release包)

前面的1、2步就不在这里赘述。主要是针对第三步和第四步。

第三步代码混淆是最重要的步骤,主要是因为h5的马甲包因为核心内容就是一个url的链接部分,其他工具等代码部分高度相似,项目与项目之间又没什么差别,所以如果不在这一步做好很容易被4.3打回。所以代码混淆算是h5或是整个马甲包工作的重心。

常用的代码混淆方法无外是修改工程名、修改类名、方法名等等。还有一些info文件或者资源文件的更换(或者用winhex改变二进制代码达到修改md5的目的)。在调查之后听说苹果审核机制中会对代码细节做要求,可能以上简单的混淆方法就不那么实用。结合Stanford的moss算法(代码查重的算法,与数据流方向和语法树有关),在想是否能有一种方法可以在编译的时候改变程序的语法树或者数据流方向。

抱着这种疑问,我去调查了目前市面上一些商用的“代码加固”的产品。其实“代码加固”和“代码混淆”从目的来看是属于同一个概念。市面上的代码加固产品核心算法都是ollvm的变体等等,可以很好的达到混淆的目的。那么我们是否可以使用这种算法来混淆呢?

 

简介
OLLVM(Obfuscator-LLVM)是瑞士西北应用科技大学安全实验室于2010年6月份发起的一个项目,该项目旨在提供一套开源的针对LLVM的代码混淆工具,以增加对逆向工程的难度。github上地址是https://github.com/obfuscator-llvm/obfuscator,只不过仅更新到llvm的4.0,2017年开始就没在更新。

个人整理

个人移植好的版本地址https://github.com/heroims/obfuscator.git

 

获得ollvm(从此往下 代码可能并不能直接使用,需要根据注释和实际情况调整)

1 $ git clone https://https://github.com/heroims/obfuscator.git
2 $ mkdir build  
---------------------------------------------注意git的地址和build的地址非常重要 3 $ cd build
---------------------------------------------下面这行代码输入后 需要经过很长的编译安装时间 4 $ cmake -DCMAKE_BUILD_TYPE=Release ../obfuscator/ 5 $ make -j7

xcode集成

XCode里集成需要看版本,XCode10之前和之后是一个分水岭,XCode9之前和之后有一个小配置不同。(因为10版本之后 xcode添加的toolschain打包的ipa不能发布,所以只能采用Xcode9版本,之后会遇到问题)

 

修改Info.plist

$ cd /Applications/Xcode.app/Contents/PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins/
$ sudo cp -r Clang\ LLVM\ 1.0.xcplugin/ Obfuscator.xcplugin
$ cd Obfuscator.xcplugin/Contents/
$ sudo plutil -convert xml1 Info.plist
$ sudo vim Info.plist

用vim操作(操作指令 a 是insert  :wq 是保存退出 )

修改下面几项

<string>com.apple.compilers.clang</string> -> <string>com.apple.compilers.obfuscator</string>
<string>Clang LLVM 1.0 Compiler Xcode Plug-in</string> -> <string>Obfuscator Xcode Plug-in</string>

 

修改Obfuscator.xcspec

$ sudo plutil -convert binary1 Info.plist
$ cd Resources/
$ sudo mv Clang\ LLVM\ 1.0.xcspec Obfuscator.xcspec
$ sudo vim Obfuscator.xcspec
Apple LLVM 8.0 不一定是 8.0
Obfuscator 4.0 不一定是 4.0
具体看你下载的版本和电脑安装的版本

Identifier = "com.apple.compilers.llvm.clang.1_0"; -> Identifier = "com.apple.compilers.llvm.obfuscator.4_0";  
Name = "Apple LLVM 8.0"; -> Name = "Obfuscator 4.0";  
Description = "Apple LLVM 8.0 compiler"; -> Description = "Obfuscator 4.0";  
Vendor = Apple; -> Vendor = HEIG-VD;  
Version = "7.0"; -> Version = "4.0";  
修改ExecPath的地址为当前build/bin的地址(!重点) 刚刚编译出来的bulid 文件夹下的bin目录路径 例如 /Users/你的用户名/xxx/bulid/bin/clang
ExecPath = "clang"; -> ExecPath = "/path/to/obfuscator_bin/clang";

最后一步

 Apple\ LLVM\ 8.0.strings 不一定是 8.0
Obfuscator 4.0.strings 不一定是4.0


$ cd English.lproj/  
$ sudo mv Apple\ LLVM\ 8.0.strings "Obfuscator 4.0.strings"  
$ sudo plutil -convert xml1 Obfuscator\ 4.0.strings  
$ sudo vim Obfuscator\ 4.0.strings

"Description" = "Apple LLVM 8.0 Compiler"; -> "Description" = "Obfuscator 4.0";  
"Name" = "Apple LLVM 8.0"; -> "Name" = "Obfuscator 4.0";  
"Vendor" = "Apple"; -> "Vendor" = "HEIG-VD";  
"Version" = "8.0"; -> "Version" = "4.0";

以上 算是安装成功

 

接下来 需要打开 xcode 进行设置

Enable Bitcode      Enable Index-While-Building Functionality 都选NO

Enable Testablity 选 YES

然后编译器选择刚刚添加的 Obfuscator X.0 就好了

在编译前进行参数设置 (在other c flags )

控制流扁平化
这个模式主要是把一些if-else语句,嵌套成do-while语句

-mllvm -fla:激活控制流扁平化
-mllvm -split:激活基本块分割。在一起使用时改善展平。
-mllvm -split_num=3:如果激活了传递,则在每个基本块上应用3次。默认值:1

指令替换
这个模式主要用功能上等效但更复杂的指令序列替换标准二元运算符(+ , – , & , | 和 ^)

-mllvm -sub:激活指令替换
-mllvm -sub_loop=3:如果激活了传递,则在函数上应用3次。默认值:1

虚假控制流程
这个模式主要嵌套几层判断逻辑,一个简单的运算都会在外面包几层if-else,所以这个模式加上编译速度会慢很多因为要做几层假的逻辑包裹真正有用的代码。

另外说一下这个模式编译的时候要浪费相当长时间包哪几层不是闹得!

-mllvm -bcf:激活虚假控制流程
-mllvm -bcf_loop=3:如果激活了传递,则在函数上应用3次。默认值:1
-mllvm -bcf_prob=40:如果激活了传递,基本块将以40%的概率进行模糊处理。默认值:30

 

以上安装设置完就可以编译和出包了

在出包之后可能会遇到无法上架appstore的情况,解决方式如下

报错代码-90725  

解决方法:

(1)下载一个xcode 10 ,直接用xcode 10 打包

(2)下载xcode 10,显示包内容  通过以下路径去找ios ‘高版本‘的sdk 

Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.2.sdk(高版本sdk) 将最后这个文件拷贝到xcode 9 下面的相同路径下,把原有的 低版本的sdk 删除掉重新编译打包就可以上传成功了

在观察的是否混淆成功和混淆结果的时候可以使用 hopperdisassembler 网上有破解版

 

ios h5马甲包项目过包 实践

上一篇:原生的js实现jsonp的跨域封装


下一篇:Spring MVC源码——Servlet WebApplicationContext