Skip to content

Instantly share code, notes, and snippets.

@trdenton
Created September 12, 2016 03:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trdenton/91349ca423229dde7d66981fb139f0b0 to your computer and use it in GitHub Desktop.
Save trdenton/91349ca423229dde7d66981fb139f0b0 to your computer and use it in GitHub Desktop.
read a saleae file, analyze its memory activity, reconstruct a binary image
#!/usr/bin/python
import sys
from enum import Enum
f = open(sys.argv[1])
lines = f.readlines()
class Directions:
READ='Read'
WRITE='Write'
class States:
(START, ADDR2, READ) = range(3)
state = States.START
curr_address= 0
PSKeys = {
0x00:'SYS_CONFIG_ID_NULL',
0xff:'SYS_CONFIG_ID_PAD',
0x01:'SYS_CONFIG_ID_RESET',
0x02:'SYS_CONFIG_ID_PATCH',
0x03:'SYS_CONFIG_ID_COMMAND',
0x04:'SYS_CONFIG_ID_WAIT',
0x05:'SYS_CONFIG_ID_REGISTER',
0x06:'SYS_CONFIG_ID_MEMORY',
0x11:'SYS_CONFIG_ID_BD_ADDR',
0x12:'SYS_CONFIG_ID_UNIT_KEY',
0x13:'SYS_CONFIG_ID_DEVICE_CLASS',
0x14:'SYS_CONFIG_ID_RAND_SEED',
0x15:'SYS_CONFIG_ID_SYS_CONFIG',
0x16:'SYS_CONFIG_ID_LOCALNAME',
0x17:'SYS_CONFIG_ID_PCM_CONFIG',
0x18:'SYS_CONFIG_ID_CLK_CALIB',
0x21:'SYS_CONFIG_ID_SLEEP',
0x22:'SYS_CONFIG_ID_SNIFF',
0x23:'SYS_CONFIG_ID_RF_CALIB',
0x24:'SYS_CONFIG_ID_RADIO_CONFIG',
0x25:'SYS_CONFIG_ID_RSSI',
0x26:'SYS_CONFIG_ID_RF_REGISTER',
0x40:'SYS_CONFIG_ID_HOST_MEM',
0x41:'SYS_CONFIG_ID_LED_CONFIG',
0x42:'SYS_CONFIG_ID_PMU_CONFIG',
0x43:'SYS_CONFIG_ID_HEADSET_TIMER',
0x44:'SYS_CONFIG_ID_HEADSET_VOLUME',
0x45:'SYS_CONFIG_ID_HID_CONFIG',
0x46:'SYS_CONFIG_ID_WII_CONFIG',
0x47:'SYS_CONFIG_ID_UPDATE_TIMINGS',
0x48:'SYS_CONFIG_ID_PMU_BYTE_WRITE'
}
dat = [0]*(64*1024)
for l in lines:
#skip the first header line
if 'Time [s]' in l:
continue
(timestamp,packet_id,address,data,direction,ack)=l.split(',')
data = int(data)
# print state
# print ack
# print curr_address
if 'ACK' not in ack:
continue
if state==States.START:
if direction==Directions.READ:
continue
elif direction==Directions.WRITE:
if address == '160':
curr_address = data
state=States.READ
elif state == States.ADDR2:
if direction==Directions.READ:
#this shouldnt happen but perform the read anyway
if address=='161':
dat[curr_address]=data
curr_address += 1
state=States.READ
elif direction==Directions.WRITE:
if address=='160':
curr_address += (data<<8)
state=States.READ
elif state == States.READ:
if direction==Directions.READ:
if address=='161':
dat[curr_address]=data
curr_address +=1
elif direction==Directions.WRITE:
if address== '160':
curr_address = data
state = States.ADDR2
print "Parsing info header..."
with open (sys.argv[2],"wb") as compdata:
bytes = bytearray(dat)
compdata.write(bytes)
def read16(d,a):
return read8(d,a) | (read8(d,a+1)<<8)
def read8(d,a):
return d[a]
def parse_PSKey(d,a):
key_id = read8(d,a)
a+=1
length = read8(d,a)
a+=1
data = [0]*length
for i in range(length):
data[i] = read8(d,a+i)
if key_id in PSKeys:
print "PSKey: %s"%PSKeys[key_id]
else:
print "PSKey: unknown"
print "Length: %d"%length
print "Data: {%s}"% ",".join(map(str,data))
#32-bit align address
while (a & 0x3) != 0:
a+=1
return a
chip_id = read16(dat,0)
main_version = read8(dat,2)
sub_version = read8(dat,3)
pskey_length = read16(dat,4)
data_length = read16(dat,6)
print "**************"
print "Chip ID: %s"%hex(chip_id)
print "Version: %d.%d"%(main_version,sub_version)
print "PSKey Length: %d"%pskey_length
print "Data Length: %d"%data_length
max_pskey_addr = 0x88 + pskey_length
parse_addr = 0x88
while(parse_addr < max_pskey_addr):
parse_addr = parse_PSKey(dat,parse_addr)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment