[原创]尝试解下fairplayd(苹果|ios)的混淆(块调度)
块调度只是各个地方叫法不一样,这个就和开源的Hikari,
https://github.com/HikariObfuscator/Hikari/blob/release_60/lib/Transforms/Obfuscation/IndirectBranch.cpp
这部分代码类似,光这个块调度相对较弱,与苹果这个比较。聚安全(顶象)快调度,还有我自己做的也相对要强一些。
第一次接触这种混淆是为了开发一个类似的混淆(2018年6月),处于好奇心去分析,当时能做到函数中的块与块之间跳转的计算。
函数入口第一个块到第二个块之间当时是没有找到方法的,估计是被吓到了,分析过的人都说是和this(r0)指针相关的,没法解,
this(r0) 指针是动态的。这个一直在我心里有悬念,所以有花了两个晚上分析,然后发现都可以解了。
特别强调
这里只分析通过静态的方式计算下一个块的偏移,单纯是解混淆不存在对功能的分析,更不涉及黑灰。
块调度的原理无非就是把跳转指令diy下,由跳转到一个偏移变成跳转到一个寄存器的值。寄存器的值就可以通过算法计算得到呢。
先解函数中间的块,结构如下,

这个相对简单,口算假设下w8和w26的值就能得到x11.
在两种条件下分别得到跳转地址
口算不能解决数量级问题,还是得借助工具算,这里我使用unicorn https://github.com/unicorn-engine/unicorn

带this(r0)指针,或者说是带参数的,比如下图的X19,依赖于sub_100CB3AEC返回值

sub_100CB3AEC的参数往上又依赖于一堆东西,瞬间有点懵逼了。X0->X19->X0->X8->X9->SP一系列的回朔有点晕,
不过神奇的地方就是这是苹果的障眼法。这个函数是一个纯计算函数,也可知道参数是int8_t类型那么直无非就是0-0xff.继续带入计算,
解得w0永远等于0xfffffff0。这样这部分就和函数中间的一样了,同理解得x19等于0x1001594e4
然后毋庸置疑的进入了下一个函数sub_1001594E4
要分析流程解一两个肯定不算,还得继续分析,到这个函数更懵逼的事情发生了。
也是上一次我没解的问题,如下图,要得到X9,往上W20->W9->X25->X0.不一样的X0出现了,

看下X0是怎么来的吧。如下两幅图,来源于X29也就是FP,栈底指针。


这里口算得非常懵逼,直到动了下笔,画了一副图,才恍然大悟。画图如下

画完此图我已经猜到SUB W20,W9,W8这条指令中W20的值是5,但为了保险起见还是带入计算了下,果然是等于5
计算过程
根据绘图可以得知
0000000100159540 29 0B 40 B9 LDR W9, [X25,#8]
000000010095318C A8 03 18 B8 STUR W8, [X29,#var_80]
W9取得的值其实就是W8
0000000100953188 28 15 00 11 ADD W8, W9, #5
W8依赖于W9往上依赖于W23,W10,X29。W23与W10是固定的值,0xe226,0x7218这些固定的值其实也可以看出一些猫腻,
但是没有想明白以前很难联系起来。X29,又依赖于SP,这样SP就是一个变量了,设置任意X29的值,带入后计算得到W20的值就是等于5.证明猜测正确。
技术得到W20的值后,又与函数中的情况一样了,同理可得X9=0x100159564
目前分析遇到的也就这三种情况。
找到跳转关系应该是解这种混淆的第一步(当然这之前还需准确找到函数的头和尾),如果要求没那么高,其实也可以分析了。如果要F5的话,目前能想到的办法就是改指令,苹果这个还没验证。聚安全(顶象)类似的这种混淆我已经拿一个小函数,验证了下,要自动化的话太难了,优化的工作量也很大。效果如下图

基本调用流程已经出来。
代码太乱暂时也无法通用就不贴出来献丑了。
样本ios11.3.1,fairplayd.H2
注意:上传附件及图片大小不得大于30M。
⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。
