-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathuboot_img.py
50 lines (39 loc) · 1.35 KB
/
uboot_img.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
import fdt
from hashlib import sha256
SZ = 0x200000
with open('../static/uboot_factory.img', 'rb') as f:
img = f.read()
assert img[SZ:] == img[:SZ] # the uboot image contains the same data two times
def check_hash_and_dump(dump=False):
dt = fdt.parse_dtb(img[:SZ])
print(dt.to_dts())
ub = dt.get_node('images/uboot')
sz = ub.get_property('data-size').value
print(f'sz = 0x{sz:x}')
pos = ub.get_property('data-position').value
print(f'pos = 0x{pos:x}')
h = ub.get_subnode('hash').get_property('value')
hash_hex = ''.join(f'{i:08x}' for i in h)
uboot_bin = img[pos:pos + sz]
assert hash_hex == sha256(uboot_bin).hexdigest()
if dump:
with open('uboot.bin', 'wb') as f:
f.write(uboot_bin)
def patch(): # patch manually instead of using fdt to keep the differences minimal
sz = 0x128288
pos = 0xe00
h = sha256(img[pos:pos + sz]).digest()
hash_offset = img.find(h)
assert hash_offset > 0
with open('uboot_patched.bin', 'rb') as f:
uboot_patched = f.read()
assert len(uboot_patched) == sz
h2 = sha256(uboot_patched).digest()
img2 = bytearray(img[:SZ])
img2[pos:pos + sz] = uboot_patched
img2[hash_offset:hash_offset + len(h)] = h2
with open('uboot_patched.img', 'wb') as f:
f.write(img2)
f.write(img2)
# check_hash_and_dump()
patch()