-
Notifications
You must be signed in to change notification settings - Fork 2
/
resolve_indirect_calls.py
67 lines (52 loc) · 1.64 KB
/
resolve_indirect_calls.py
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
from pyda import *
import sys
import subprocess
p = process()
BASE = p.maps[p.exe_path].base
def u64(data):
return int.from_bytes(data, "little")
def get_calls(proc):
p = subprocess.run(f"objdump -M intel -d {proc.exe_path} | grep call", shell=True, capture_output=True)
output = p.stdout.decode()
call_locs = {}
ind_call_locs = {}
for l in output.split("\n"):
if len(l) <= 1:
continue
if "QWORD PTR" in l and l.endswith("]"):
addr = int(l.split(":")[0].strip(), 16)
lol = "".join(l.split(":")[1].split("[")[1].split("]")[0])
if '+' in lol:
reg, off = lol.split("+", 1)
else:
reg, off = lol, "0"
try:
off = int(off, 0)
except:
continue
ind_call_locs[addr] = (reg, off)
elif l.split()[-2] == "call":
call_locs[int(l.split(":")[0].strip(), 16)] = l.split()[-1]
return call_locs, ind_call_locs
call_locs, ind_call_locs = get_calls(p)
def call_reg(p):
reg = call_locs[p.regs.rip - BASE]
rax = p.regs[reg]
print(f"call {hex(p.regs.rip - BASE)} -> {hex(rax - BASE)}")
def ind_call_print(p):
addr = p.regs.rip - BASE
reg, off = ind_call_locs[addr]
reg_val = p.regs[reg]
mem_target = reg_val + off
try:
mem = p.read(mem_target, 8)
print(f"indcall {hex(addr)} -> {hex(u64(mem) - BASE)}")
except Exception as e:
print(e)
pass
if BASE != 0:
for c in call_locs:
p.hook(BASE + c, call_reg)
for c in ind_call_locs:
p.hook(BASE + c, ind_call_print)
p.run()