-
Notifications
You must be signed in to change notification settings - Fork 8
/
rom-dump.py
executable file
·140 lines (128 loc) · 4.28 KB
/
rom-dump.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
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
# This code is to dump a section of firmware, assuming we already have security
# access. It's "good enough" code, I'm sure I could have refined it, but there
# wasn't any need. Re-running it until I happened to get clean "uploads" was
# good enough.
from __future__ import print_function
import sys
import can
import time
Bus0 = can.interface.Bus(bustype='socketcan', channel='can0', bitrate=49500)
def getReply(aid, pid):
t = 0
dataLen = 0
data = []
storedMsg = None
while (t<50):
msg = Bus0.recv(0)
if (msg==None):
t += 1
time.sleep(0.1)
continue
if (msg.arbitration_id != RecvAID):
continue
elif (msg.data[0]&0xf0==0 and msg.data[1] == 0x7f and msg.data[2] == pid):
return msg
elif (msg.data[0]&0xf0==0 and msg.data[1] == pid+0x40):
return msg
elif (msg.data[0]&0xf0==0x10 and msg.data[2] == pid+0x40):
storedMsg = msg
dataLen = msg.data[1]-6
data = msg.data[1:]
elif (msg.data[0]&0xf0==0x20):
pl = min(8, dataLen+1)
data += msg.data[1:pl]
dataLen -= (pl-1)
if (dataLen <= 0):
msg.data = data
return msg
if (storedMsg != None and dataLen != 0):
storedMsg.data = data
return storedMsg
else:
print("Oops:",dataLen,len(data))
return None
def doubleScan():
request = can.message(arbitration_id=sendaid,
data=[0x10, 0x0b, 0x35, 0x00, 0x44, 0x00, 0x00, offset*16],
extended_id=false)
print(request)
bus0.send(request)
request = can.message(arbitration_id=sendaid,
data=[0x21, 0x00, 0x00, 0x00, 0x00, 0x01, 0,0],
extended_id=false)
print(request)
bus0.send(request)
def scanRam():
# Note: hit with f1bc -> f287
print("Forcing Time!")
modifier = 0
errorCount = 0
for offset in range(0,256):
request = can.Message(arbitration_id=SendAID,
data=[0x07, 0x35, 0x00, 0x22, offset,0,0,4],
extended_id=False)
print(request)
Bus0.send(request)
msg = getReply(RecvAID, 0x35)
if (msg == None):
print("no reply")
elif (msg.data[1] == 0x7f and msg.data[3]==0x31):
errorCount += 1
else:
print(msg)
if (errorCount > 0):
print("Errors:",errorCount)
def dumpRam(address, length, filename):
request = can.Message(arbitration_id=SendAID,
data=[0x07, 0x35, 0x00, 0x22, address/256,address%256, length/256,length%256],
extended_id=False)
print(request)
Bus0.send(request)
reply = getReply(RecvAID, 0x35)
print(reply)
if (reply == None):
print("no reply")
return False
elif (reply.data[1] == 0x7f):
print("error")
return False
blocks = (length+reply.data[3]-1) / reply.data[3]
dump = open(filename, "w")
try:
for block in range(0,blocks):
getBlock = can.Message(arbitration_id=SendAID,
data=[0x02, 0x36, (block+1)%256, 0,0,0,0,0],
extended_id=False)
Bus0.send(getBlock)
repBlock = getReply(RecvAID, 0x36)
print(repBlock)
if (repBlock == None):
print("no reply")
return False
elif (reply.data[1] == 0x7f):
print("error")
return False
dump.write(repBlock.data[3:]) # first three bytes are length/$PID/block
finally:
request = can.Message(arbitration_id=SendAID,
data=[0x01, 0x37, 0,0,0,0,0,0],
extended_id=False)
print(request)
Bus0.send(request)
reply = getReply(RecvAID, 0x37)
print(reply)
dump.close
if __name__ == "__main__":
if (len(sys.argv) < 2):
print("Usage:",sys.argv[0],"<AID>")
exit(1)
else:
SendAID = int(sys.argv[1],0)
RecvAID = SendAID+8
print("using aid:",hex(SendAID))
#scanRam();
print("WARNING: there is a BUG in this code.")
print("you may have to re-run multiple times to get good dumps.")
width = 0x800
for addr in range(0,0x10000,width):
dumpRam(addr, width, "mem-dump-%03x-%04x.raw"%(SendAID,addr))