最近结合前辈大佬们的反混淆思路,写了一个基于麒麟模拟来做的ollvm fla反混淆
https://github.com/pcy190/deobfuscator
首先是对fla后的块识别。因为对于不同的情况,例如原始逻辑中就有switch case等等,单纯通过块的入度出度数量,或是深搜真实块,可能还是会漏掉一些真实块,鉴于fla后,IDA仍然能F5,还是可以看到真实逻辑的块的,我们可以手动比对真实块是否遗漏,来加上真实块用于后续分析。麒麟的IDA插件具有手动标注真实块的功能,但其要求IDA7.4以上和python3,(但现在流出的demo版本没有ida python),暂时不太可用。
后续会加入一个python2的ida plugin来手动标注真实块,而后将数据保存起来,供反混淆插件使用(主要是常用的泄露ida全是python2)
在https://github.com/GeT1t/deollvm64 的脚本中,是用unicorn来做路径搜索的,但其要手动map内存数据来适配不同二进制环境。用麒麟来做加载能方便适配上不同的环境。
而后修改了patch策略,加入了跳板的策略。即当一个块没有足够长度来存放合适的jmp指令的时候(一般是条件跳转),先jmp跳转到一个跳板地址,再在跳板地址上布置条件判断的指令。
xxx
B.LE loc_12A60
B loc_12D20
->
xxx
B trampoline
trampoline:
B.LE XXX
B XXX
其中适合做trampoline的地址有很多,例如在fake blocks (分发块等等)中,eh_frame 段里面等等。
另外是在arm64,对csel的patch改进。相对之前只能固定patch 特定位置的csel指令,现在能搜索整个块中任意位置的csel指令,然后将块内csel之后的指令往前搬移,以替换csel指令,再在最后空出来的指令位置布置跳转指令来跳转到真实块。
在路径搜索上使用了麒麟ida plugin和deollvm64的两种方式,分别为广搜和深搜。前者的好处是能够全面的搜索所有已知的真实块,后者能够更准确的识别出真实块中的原始条件判断跳转情况。
一个测试效果
原始
patch后
|