基于IDA Python的OLLVM反混淆(四) 实战拼某某混淆
## 前言最后一次炒冷饭,这次以拼某某为例分析arm指令下的ollvm去混淆
拼某某版本(3.66.0)
## 实验环境
1.Android真机(Android5.1)
2.ida7.5
3.win10
## 过程
与x86的反混淆类型,思路还是找出所有控制块,对真实块下断点,记录断点执行顺序,之后连接真实块.
以JNI_OnLoad为例.
### 找出所有控制块
控制块的特征比较明显,就是对内存基本上没有操作.
1.
2.
3.
4.
5.
6.
........
### ida python脚本
这里对部分进行说明
```
def dbg_process_attach(self, pid, tid, ea, name, base, size):
print("Process attach pid=%d tid=%d ea=0x%x name=%s base=%x size=%x" % (pid, tid, ea, name, base, size))
self.pre_block=None
self.related_dict=dict()
self.block_addr_dict=dict()
so_base=idaapi.get_imagebase()
self.f_blocks = idaapi.FlowChart(idaapi.get_func(so_base+fun_offset), flags=idaapi.FC_PREDS)
for block in self.f_blocks:
start=block.start_ea
end=idc.prev_head(block.end_ea)
# 排除所有的控制块
if(end==start) or\
(idc.print_insn_mnem(start)=='LDR' and idc.print_insn_mnem(idc.next_head(start)).startswith('B')) or \
(idc.print_insn_mnem(start)=='LDR' and idc.print_insn_mnem(idc.next_head(start))=='CMP' and idc.print_insn_mnem(idc.next_head(idc.next_head(start)))=='MOV' and idc.print_insn_mnem(idc.next_head(idc.next_head(idc.next_head(start)))).startswith('B')) or\
(idc.print_insn_mnem(start)=='CMP' and idc.print_insn_mnem(idc.next_head(start))=='MOV' and idc.print_insn_mnem(idc.next_head(idc.next_head(start))).startswith('B')) or \
(idc.print_insn_mnem(start)=='MOV' and idc.print_insn_mnem(idc.next_head(start))=='CMP' and idc.print_insn_mnem(idc.next_head(idc.next_head(start))).startswith('B')) or \
(idc.print_insn_mnem(start)=='LDR' and idc.print_insn_mnem(idc.next_head(start))=='CMP' and idc.print_insn_mnem(idc.next_head(idc.next_head(start))).startswith('B')) or \
(idc.print_insn_mnem(start)=='CMP' and idc.print_insn_mnem(idc.next_head(start)).startswith('B')) or \
(idc.print_insn_mnem(start)=='LDR' and idc.print_insn_mnem(idc.next_head(start))=='CMP' and idc.print_insn_mnem(idc.next_head(idc.next_head(start)))=='MOV'\
and idc.print_insn_mnem(idc.next_head(idc.next_head(idc.next_head(start)))).startswith('LDR')\
and idc.print_insn_mnem(idc.next_head(idc.next_head(idc.next_head(idc.next_head(start))))).startswith('B')
) or\
(idc.print_insn_mnem(start)=='LDR' and idc.print_insn_mnem(idc.next_head(start))=='CMP' and idc.print_insn_mnem(idc.next_head(idc.next_head(start)))=='LDR'\
and idc.print_insn_mnem(idc.next_head(idc.next_head(idc.next_head(start)))).startswith('B')
):
continue
add_bpt(end,0,BPT_SOFT)
while start<block.end_ea: #对POP下断点 相当于x86的retn
if idc.print_insn_mnem(start).startswith('POP'):
add_bpt(start,0,BPT_SOFT)
break
start=idc.next_head(start)
```
这段代码是ida附加进程执行的代码,排除所有控制块代码,对真实块下断点
```
def dbg_process_exit(self, pid, tid, ea, code):#调试退出时执行
print("Process exited pid=%d tid=%d ea=0x%x code=%d" % (pid, tid, ea, code))
for ea in self.related_dict:
if len(self.related_dict)==1:
if idc.print_insn_mnem(ea).startswith('B'):
disasm='B'+' '+hex(self.related_dict.pop())
patcher.patch_code(ea,disasm,patcher.syntax,True,False)
else:
disasm='B'+' '+hex(self.related_dict.pop())
patcher.patch_code(idc.next_head(ea),disasm,patcher.syntax,True,False)
else:
print(ea,self.related_dict)#该真实块有两个后继真实块,要手动patch
```
这段代码是退出调试执行,连接所有真实块,**对于有两个后继真实块的块需要自行手动修改.**
### 动态调试
1.将ida文件夹dbgsrv的android_server传入手机端,改变文件权限
```
adb push android_server /data/local/tmp/android_server
adb shell
su
chmod 777 /data/local/tmp/android_server
/data/local/tmp/android_server
```
2.adb端口转发
```
adb forward tcp:23946 tcp:23946
```
3.打开ddms
4.ida载入python脚本,附加进程,,ddms运行
```
jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8700
```
5.运行直到retn块后,结束调试
## 去混淆结果
F5后结果
## 写在最后
基于ida的ollvm有一定的局限性,比如要处理反调试,还需要可调试的真机.
较好的方案可以使用unidbg(动态调试)代替
github地址:
https://github.com/PShocker/de-ollvm-arm Shocker 发表于 2021-9-12 13:22
对,这个方法有一定的局限性.但相比其他大神的反混淆脚本,这个应该是最通俗易懂的.
目前我是用angr实现了armv7的fla还原,但是bcf还没有怎么研究,楼主对bcf了解吗,我想把这两个弄在一个脚本里还原 huhuf6 发表于 2021-9-12 13:13
楼主看了一下你都样本,是纯arm32不带thumb指令的,如果带thumb指令的话应该还有蛮多坑的,如果是在动态调 ...
对,这个方法有一定的局限性.但相比其他大神的反混淆脚本,这个应该是最通俗易懂的.{:1_918:} 谢谢楼主分享 感谢楼主分享 楼主看了一下你都样本,是纯arm32不带thumb指令的,如果带thumb指令的话应该还有蛮多坑的,如果是在动态调试的时候执行patch的话,是不是就原本没有执行的块就被nop掉了? 谢谢楼主分享:lol
谢谢楼主分享 请问楼楼idpython有没有什么好的教程?官方的api文档比较难查阅啊 Forgo7ten2020 发表于 2021-9-13 10:15
请问楼楼idpython有没有什么好的教程?官方的api文档比较难查阅啊
你可以看看这篇文章
基于python3.x IDAPython第二讲 段 函数 汇编指令等操作
页:
[1]
2