39 lines
1.4 KiB
Python
39 lines
1.4 KiB
Python
#!/usr/bin/env python3
|
|
"""sbl_refs.py — поиск кодовых ссылок на строку в SBL1 (img0.elf, seg 0x8005800).
|
|
Использование: ./tools/sbl_refs.py fw/sbl/img0.elf 'SBL1, Start'
|
|
"""
|
|
import struct
|
|
import sys
|
|
|
|
path, needle = sys.argv[1], sys.argv[2].encode()
|
|
d = open(path, "rb").read()
|
|
i = d.find(needle)
|
|
print("str fileoff:", hex(i))
|
|
SEG_OFF, SEG_VA, SEG_SZ = 0x3000, 0x8005800, 0x33A54
|
|
va = SEG_VA + (i - SEG_OFF)
|
|
print("str VA:", hex(va))
|
|
# search ALL segments for pc-relative loads to it
|
|
import re
|
|
|
|
def segs(d):
|
|
phoff = struct.unpack("<I", d[28:32])[0]
|
|
phnum = struct.unpack("<H", d[44:46])[0]
|
|
out = []
|
|
for k in range(phnum):
|
|
p = d[phoff + k * 32:phoff + (k + 1) * 32]
|
|
t, off, v, pa, fsz, msz, fl, al = struct.unpack("<IIIIIIII", p)
|
|
if t == 1 and fsz:
|
|
out.append((off, v, fsz))
|
|
return out
|
|
|
|
for soff, v, sz in segs(d):
|
|
code = d[soff:soff + sz]
|
|
for j in range(0, len(code) - 4, 4):
|
|
x = struct.unpack("<I", code[j:j + 4])[0]
|
|
# LDR Rd,[pc,#imm] (0x059Fxxxx) or LDR Rd,[pc,#-imm] (0x051Fxxxx)
|
|
if (x & 0x0FF00000) in (0x05900000, 0x05100000) and (x & 0xF0000) == 0xF0000:
|
|
o = x & 0xFFF
|
|
tgt = v + j + 8 + (-o if x & 0x800000 == 0 else o)
|
|
if abs(tgt - va) < 0x200:
|
|
print(hex(v + j), "LDR r%d" % ((x >> 12) & 15), "->", hex(tgt))
|