最近拿到一个某版本的某视频app的so,这个版本跟之前反ollvm混淆版本所有不同,于是拿JNI_OnLoad分析并记录一下
将样本放到IDA中看看JNI_OnLoad,如下
一眼看上去,貌似就是普通的ollvm混淆,但是我们先看看这个函数的结尾。
这很明显不是一个函数的结尾,跟进去sub_525A看看
这个也不像是一个函数,而且结尾用的是MOV PC,R1跳转,IDA根本不知道目的地是哪里。既然这样,模拟执行trace一下看看(具体方法见之前的的帖子),trace部分内容如下
( libcms2.so[0xCBBCB000])[8F 46 ]0x00005264: MOV PC, R1 ;(R1=0xCBBD0270 ) ( libcms2.so[0xCBBCB000])[02 BC ]0x00005270: POP {R1} ;(SP=0x100FFF54 ) ( libcms2.so[0xCBBCB000])[11 E0 ]0x00005272: B #0XCBBD0298
可以见到MOV PC,R1指令实际上跳转到了0x00005270中,经过观察trace文件,发现该样本的所有类似BX xxx,MOV PC,xxx,实际上都仅仅是一个跳转,BX并没有起到X转换模式的作用,仅仅相当于一个B xxxx,所以我们可以通过分析trace文件,找到这类指令,统一patch成B 目标地址就行了,这样子IDA就能正常分析下去。
先手动patch完之后再次打开IDA,
发现IDA无法分析JNI_Onload,是patch出了什么问题吗,我们在JNI_Onload按一下P,MakeFunction试试,发现报错如下
.text:0000505A: The function has undefined instruction/data at the specified address.
双击看看报错的地方
我们看到0000505A根本不是一条指令,为何会出现这种代码?往上看地址00005046,发现这里搞了个CBZ R1,loc_5058+2,故意跳到了一条指令的中间,这样子IDA肯定无法分析的,实际上如果这条指令条件是成立的话,原程序肯定也会崩溃,所以我们断定这条指令肯定不成立,处理的话直接NOP掉即可。其实这种手法在这个样本很多地方都有,后面通过脚本直接处理掉。
基本原理就是使用恒成立或者恒不成立的条件指令作为跳转,然后在另外一个不会执行的分支加入一些错误的指令让静态分析器出错,因为静态分析器遇到条件跳转指令会认为有两个分支,进入不执行的错误分支解析时候发现有不正常的指令,所以解析无法继续,这类混淆依然可以直接改成b xxxx直接去掉错误的分支,让IDA分析正常
来看看另外一个类似的混淆
我们看看loc_24A8,这个loc的代码是arm的,但是看上去非常奇怪,实际上loc_24A8是thumb的代码,造成loc_24A8被IDA识别arm的原因是loc_249E最后一条BX R1指令,R1为偶数,因此目的地被识别成arm模式,其实loc_249E根本不执行,只是用作欺骗IDA让目的块loc_24A8识别成arm。将loc_24A8改成thumb模式,代码是这样的
这里还看到一条SVC 0指令,说不定这么做是为了隐藏某个敏感的系统调用。
其实总结一下这些混淆不外乎几点
上述几点都可以通过trace修复,下面是修复脚本脚本链接
脚本的原理很简单
下面是经过脚本处理后的JNI_Onload
真正的函数结尾
再经过ollvm反混淆后
2020安全开发者峰会(2020 SDC)议题征集 中国.北京 7月!
最后于 11小时前 被my1988编辑 ,原因: