-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathmy_patch.py
89 lines (79 loc) · 2.59 KB
/
my_patch.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import keystone
import capstone
import ida_bytes
import idc
from module.utils import MAGIC
KS = keystone.Ks(keystone.KS_ARCH_ARM64, keystone.KS_MODE_LITTLE_ENDIAN)
CS = capstone.Cs(capstone.CS_ARCH_ARM, capstone.CS_MODE_THUMB)
NOP_BYTES = b'\x1f\x20\x03\xd5'
def handle_txt(path):
addr_dict = {}
f = open(path)
line = f.readline().replace("\n", "")
while line:
info = line.split(",")
if len(info) == 2:
patch_addr = info[0]
b_addr = info[1]
if patch_addr not in addr_dict.keys():
addr_dict[patch_addr] = [b_addr]
else:
addr_list = addr_dict[patch_addr]
if b_addr not in addr_list:
addr_dict[patch_addr].append(b_addr)
elif len(info) == 3:
patch_addr = info[0]
b_addr1 = info[1]
b_addr2 = info[2]
if patch_addr not in addr_dict.keys():
addr_dict[patch_addr] = [b_addr1, b_addr2]
else:
addr_list = addr_dict[patch_addr]
if b_addr1 not in addr_list:
addr_dict[patch_addr].append(b_addr1)
if b_addr2 not in addr_list:
addr_dict[patch_addr].append(b_addr1)
else:
raise Exception("check your code")
line = f.readline().replace("\n", "")
f.close()
return addr_dict
def get_b_const_bytes(ea, const):
'''
返回例如 ea: b 0x12334的指令
:param ea:
:param const:
:return:
'''
ea = int(ea, 16)
CODE = f"b {const[0]}"
encoding, count = KS.asm(CODE, ea)
return ea, bytes(encoding)
def find_magic(ea):
for i in range(10):
asm = idc.GetDisasm(ea)
if asm.startswith(MAGIC):
info = asm.split(",")
cond = info[-1].replace(" ","").lower()
return ea, cond
ea = idc.prev_head(ea)
raise Exception("check your code:" + hex(ea))
def get_bxx_const_bytes(ea, const_list):
ea = int(ea, 16)
patch_ea, cond = find_magic(ea)
code = f"b{cond} {const_list[0]}"
encoding, count = KS.asm(code, patch_ea)
ret = bytes(encoding)
code = f"b {const_list[1]}"
encoding, count = KS.asm(code, patch_ea + 4)
ret += bytes(encoding)
return patch_ea, ret
addr_dict = handle_txt("./addr.txt")
for key in addr_dict.keys():
value = addr_dict[key]
if len(value) == 1:
ea, patch_bytes = get_b_const_bytes(key, value)
ida_bytes.patch_bytes(ea, patch_bytes)
else:
ea, patch_bytes = get_bxx_const_bytes(key, value)
ida_bytes.patch_bytes(ea, patch_bytes)