-
Notifications
You must be signed in to change notification settings - Fork 15
/
script.py
111 lines (80 loc) · 2.71 KB
/
script.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
from operator import le
import re
file = open('PLAY.mal_', 'rb')
buffer = file.read()
file.close()
# main case
regex = b'\x06\x81\xC4....\x83\xC4.\xE8....'
count = 0
def patchedBytes(buffer, changes):
for change in changes:
offset = change[0]
length = change[1]
value = change[2]
if len(value) != length:
return
buffer = [each for each in buffer]
value = [each for each in value]
for i in range(length):
buffer[i + offset] = value[i]
result = b''
for each in buffer:
result += int.to_bytes(each, 1, 'little')
return result
def toIDAAddress(address):
return address - 0x400 + 0x401000
def toBufferAddress(address):
return address + 0x400 - 0x401000
fix_dict = {}
changes = []
for match in re.finditer(regex, buffer):
count += 1
new_esp = match.start() + 15
match_bytes = match.group()
call_address = int.from_bytes(
match_bytes[match_bytes.find(b'\xE8') + 1:], "little") + new_esp
addition_val = int(buffer[call_address + 3])
jump_address = new_esp + addition_val
patch_address = new_esp - 5
changes.append([patch_address, 5, b'\xE9' +
int.to_bytes(addition_val, 1, 'little') + b'\x00\x00\x00'])
buffer = patchedBytes(buffer, changes)
# edge_case 1
regex = b'\x83\xC4.\x83\xC4.\xE8....'
count = 0
match = re.findall(regex, buffer)
for match in re.finditer(regex, buffer):
count += 1
new_esp = match.start() + 11
match_bytes = match.group()
call_address = int.from_bytes(
match_bytes[match_bytes.find(b'\xE8') + 1:], "little") + new_esp
print(hex(new_esp), hex(call_address), hex(toIDAAddress(match.start())))
addition_val = int(buffer[call_address + 3])
jump_address = new_esp + addition_val
patch_address = new_esp - 5
changes.append([patch_address, 5, b'\xE9' +
int.to_bytes(addition_val, 1, 'little') + b'\x00\x00\x00'])
buffer = patchedBytes(buffer, changes)
# edge_case 2
regex = b'\x83\xC4.\xE8'
count = 0
match = re.findall(regex, buffer)
for match in re.finditer(regex, buffer):
count += 1
if toIDAAddress(match.start()) <= 0x410000:
continue
new_esp = match.start() + 8
match_bytes = match.group()
call_address = int.from_bytes(
buffer[match.start() + 4:match.start() + 8], "little") + new_esp
addition_val = int(buffer[call_address + 3])
jump_address = new_esp + addition_val
patch_address = new_esp - 5
changes.append([patch_address, 5, b'\xE9' +
int.to_bytes(addition_val, 1, 'little') + b'\x00\x00\x00'])
# write changes
buffer = patchedBytes(buffer, changes)
file = open('patched_PLAY.mal_', 'wb')
file.write(buffer)
file.close()