使用Frida辅助逆向

0x00 : 关于使用Frida

Frida是一个跨平台的、多平台的hook框架,使用起来十分方便,而且文档全面,可以很好的辅助逆向工程。在需要使用一些hook的时候,可以很快地完成;如果还是用c/c++的话..写dll,还要想办法dll注入,而且很麻烦不灵活,修改代码很麻烦。

最近的工作中,我做了很多逆向的工作,虽然有部分工作暂时看不到什么收益,算是白折腾浪费了两周,但是这段时间熟悉了pykdwindbg scriptfridaIDA Python的编写…也搞了一些方便日后修改使用的模板,算是有一点点收获吧,不过浪费了时间还是很难过。

0x01 : HOOK需求

我需要去追一些内存分配、有些可能还需要操作一下,方便我的逆向工作顺利进行。

我这里以Adobe Reader 为例子,我hook了reader自己封装的内存分配函数,并且显示分配得到的内存;其他的需求都差不多,直接改模板就行,我是用的官方的模板修改的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from __future__ import print_function
import frida
import sys

def on_message(message, data):
print("[%s] => %s" % (message, data))

def main(target_process):
session = frida.attach(target_process)

script = session.create_script("""

var baseAddr = Module.findBaseAddress('AcroRd32.dll');
console.log('AcroRd32.dll baseAddr: ' + baseAddr);
var CallocFunc = resolveAddress(baseAddr);
var JP2KDecodeFilterObj;
var size = 1;
Interceptor.attach(CallocFunc, {

onEnter: function (args) {
//console.log('[+] Called CallocFunc' + CallocFunc);
size = args[0];
//console.log('[+] ALLOC size : ' + size);
},

onLeave: function (retval) {
console.log('[+] Returned from CallocFunc: ' + retval);
dumpAddr('ret buffer', retval, parseInt(size));
}
});

function replaceMem(addr, size){
if (addr.isNull())
return;
for(var idx = 0; idx < size; idx++){
Memory.writeU8(addr.add(ptr(idx)), 0x41);
}
}

function dumpAddr(info, addr, size) {
if (addr.isNull())
return;
console.log('Data dump ' + info + ' :');
var buf = Memory.readByteArray(addr, size);
console.log(hexdump(buf, { offset: 0, length: size, header: true, ansi: true }));
}

function resolveAddress(addr) {
var offset = ptr(offset_you_get)
var result = baseAddr.add(offset);
console.log('[+] CallocFunc addr=' + result);
return result;
}

""")
script.on('message', on_message)
script.load()
print("[!] Ctrl+D on UNIX, Ctrl+Z on Windows/cmd.exe to detach from instrumented program.\n\n")
sys.stdin.read()
session.detach()

if __name__ == '__main__':
if len(sys.argv) != 2:
print("Usage: %s <process name or PID>" % __file__)
sys.exit(1)

try:
target_process = int(sys.argv[1])
except ValueError:
target_process = sys.argv[1]
main(target_process)

代码还是比较简单的,py脚本,hook部分的代码是js写的,(又被逼着学了一下js,然而我觉得我的js写的有种c的味道…)

如果你仔细看被hook的进程的话,你会发现在hook发生地时候,Frida的dll会注入进去,然后就是传统的那种hook的方式了,只是框架帮你做了太多的事情,所以你只需要写好js就好了。

我截取部分运行时候输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
00000000  00 00 00 00 00 00                                ......
[+] Returned from CallocFunc: 0x348f6fb0
Data dump ret buffer :
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010 00 00 00 ...
[+] Returned from CallocFunc: 0x32d20fd8
Data dump ret buffer :
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
00000000 00 00 00 00 00 00 00 00 00 .........
[+] Returned from CallocFunc: 0x2c3f0f90
Data dump ret buffer :
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00 00 00 00 00 ............
[+] Returned from CallocFunc: 0x1b934fc8
Data dump ret buffer :
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 .............
[+] Returned from CallocFunc: 0x1bd8efb0
Data dump ret buffer :
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010 00 00 00 ...
[+] Returned from CallocFunc: 0x35857f58
Data dump ret buffer :
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00 00 00 ..........
[+] Returned from CallocFunc: 0x35b33fc8
Data dump ret buffer :
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030 00 .
[+] Returned from CallocFunc: 0x1bd66f78
Data dump ret buffer :
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000080 00 00 00 00 00 00 00 00 ........
[+] Returned from CallocFunc: 0x1bd6eff8
...

一些其他的想法,这个其实可以做简单的in memory fuzz了,循环call,然后换内存…当然这个想法很low了,n年前的东西了,而且这种的话cov很难处理。

要说问题,就是Frida读取本地文件的问题,我试了new Filefrida-fs均以失败告终…如果有人知道怎么玩的话,还望不吝赐教 :)

0x02 : 其他

在写这些东西的时候,请教了jmpews师傅很多问题,十分感谢!

jmpews师傅后面向我推荐了 detours + Xenos这种方式来做hook,精力有限,而且上手难度有点高,所以暂时只能放在to do list上了,不过还是很感谢~