-
Notifications
You must be signed in to change notification settings - Fork 16
/
patcher.py
47 lines (36 loc) · 1.38 KB
/
patcher.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
# Powered by HAPPY
class Patcher:
binary: bytes
patched_filename: str
filename: str
def __init__(self, filename: str, suffix: str = ".patched"):
self.filename = filename
with open(filename, 'rb') as f:
self.binary = f.read()
self.patched_filename = filename + suffix
def patch(self, address, size, value):
assert len(self.binary) >= address + size
value = self._force_bytes(value)
assert len(value) == size
assert type(value) == bytes
self.binary = self.binary[:address] + value + self.binary[address + size:]
def copy_to_patch(self, to_address, from_address, size):
"""
copy binary bytes
"""
assert len(self.binary) >= from_address + size
self.patch(to_address, size, self.binary[from_address:from_address + size])
@staticmethod
def _force_bytes(data):
if isinstance(data, bytes):
return data
if isinstance(data, str):
# return data.encode(encoding)
return data.encode("iso-8859-15") # same as latin1
if isinstance(data, list):
# keystone assemble only
return bytes(data)
return data
def write_patch_to_file(self):
with open(self.patched_filename, 'wb') as f:
f.write(self.binary)