论两个生死冤家的前世今生
从PE时代流传下来的神器IDA,新生代的混淆神器OLLVM,他们之间的碰撞让逆向人员如何是好
ollvm混淆IDA无法精准识别函数末尾
当各位把各种CarckME分析的透透的时候,信心满满的准备进军大厂APK的时候,打开IDA拖入SO,定位JniOnload函数,F5,嗯????F5,F5,F5,F5
除非您的功力可以达到只看那令人头大的汇编代码,就能脑补翻译成C伪代码的地步,否则这种情况对逆向人员的打击不可谓不大.
但是碰到那种被OLLVM强混淆并且本身函数就超长的那种(笔者见过最多的一个被混淆的函数指令有26000+行)我相信就算您是神人也无法脑补!!!
其实,这就是OLLVM这个小坏蛋欺骗IDA的一个办法.
如果你对x86指令集或者arm指令集的函数构成有所了解的话,你一定知道在未经特殊处理的编译器生成的函数汇编中,函数开头会保存现场,保存返回点,分配函数栈空间,而函数结尾会恢复函数栈空间,恢复现场,回到返回点.
而当前IDA分析出来竟然在0x4F64E就是返回点.这当然不可能啦!
如何查找函数尾部,并且修复,给IDA指定函数尾部
所以我们需要定位真正的函数返回值然后告诉笨笨的IDA,首先我们放出一个正常的未经过混淆的函数在IDA中的样子
经过观察发现真正的函数结尾是在恢复现场,那我们就有理由说那个被欺骗的Jni_Onload的函数结尾应该是 POP {R4-R7,PC}
IDApy的妙用
如果说我们要手动找一个离自己最近的POP {R4-R7,PC}指令的话,那么请先看一张图
这里面全部都是IDA无法识别的指令,需要我们手动alt+g设置为1然后再强行解释为code才能正常识别,然后还要翻过大篇的指令寻找我们要的指令
对于懒懒的我来说,我们必须找到一种能让不知疲倦的电脑帮我们干活的方法.
于是笔者找到了IDAPython
以及在线版的KeyStore将汇编指令转换为Hex机器码的工具
在网站中输入我们的汇编指令,得到当前指令THUMB的opcode为F0BD ,为啥是THUMB呢 ,有基础的小伙伴应该知道ARM32有两种运行模式(ARM/THUMB),因为我们发现JniOnload中存在2字节的opcode以及经验来说,它一定用的THUMB指令集.
在ARM32下如何确定一个函数是ARM指令还是THUMB指令呢,最简单的就是把opcode翻译成arm指令,看哪一个更像真正的函数结构. 这种东西一眼就能看出来,所以不在赘述.
上脚本!!!
设置起点以及分析长度开跑.然后你就能在IDA的输出窗口看到一大串函数地址
正常来说第一个就是 我们直接双击进入0x50310
发现它一定是JniOnload的返回值,因为它的条件完全符合JniOnload保存现场,创建栈空间的大小.
(函数结尾)0x50312 - (函数开始)0x4f620 = 3314
这么多指令我们要手动查找的话,着实得费一番功夫,现在我们知道了函数结尾的地方.
那我们现在P一下,嗯哼? 还是不行,根据IDA输出窗口的地方我们找到了
重点看04FB0E这个地方 CBZ竟然跳到了一条指令中间???
他真是太坏了,正常这种指令是永远也不会走到的分支,但是它的存在就是为了欺骗IDA,像这种存在,我这个样本中还有很多处,时间关系大家要慢慢挖掘.我这里只是给一个思路,学习还要靠大家自己.ollvm其实并不可怕,大家加油
既然遇见了,我们就patch一下 给他nop暂时.
然后P一下就好啦,虽然还是有OLLVM的流程平坦化,指令替换,以及控制流伪造,但是至少我们能F5了不是.
有空我们再把去混淆脚本升级一下,让IDA更智能,更能让我们随心所用!!!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2021-8-27 12:05
被至尊小仙侠编辑
,原因: