saimaa: sblmain stack-pc override prop; sbl analysis tools
This commit is contained in:
@@ -100,6 +100,7 @@ struct SaimaaMachineState {
|
||||
MachineState parent_obj;
|
||||
char *sbl1;
|
||||
char *emmc;
|
||||
char *sblmain; /* hex: popped-PC override for PBL trampoline */
|
||||
};
|
||||
typedef struct SaimaaMachineState SaimaaMachineState;
|
||||
|
||||
@@ -181,6 +182,14 @@ static void saimaa_machine_init(MachineState *machine)
|
||||
}
|
||||
ARM_CPU(first_cpu)->env.regs[13] = 0x085FFF00;
|
||||
ARM_CPU(first_cpu)->env.regs[0] = 0x00220000; /* fake pbl_shared */
|
||||
if (sms->sblmain) {
|
||||
/* PBL trampoline pops pc from stack top; override it */
|
||||
uint32_t tgt = strtoul(sms->sblmain, NULL, 0);
|
||||
uint32_t zero = 0;
|
||||
cpu_physical_memory_write(0x085FFF00, &zero, 4);
|
||||
cpu_physical_memory_write(0x085FFF00 + 12 * 4, &tgt, 4);
|
||||
printf("saimaa: stack-pc override -> 0x%x\n", tgt);
|
||||
}
|
||||
printf("saimaa: SBL1 %s loaded (%zd bytes), entry 0x%lx\n",
|
||||
sms->sbl1, sz, (unsigned long)entry);
|
||||
}
|
||||
@@ -204,12 +213,27 @@ static void saimaa_set_sbl1(Object *obj, const char *value, Error **errp)
|
||||
sms->sbl1 = g_strdup(value);
|
||||
}
|
||||
|
||||
static char *saimaa_get_sblmain(Object *obj, Error **errp)
|
||||
{
|
||||
return g_strdup(SAIMAA_MACHINE(obj)->sblmain);
|
||||
}
|
||||
|
||||
static void saimaa_set_sblmain(Object *obj, const char *value, Error **errp)
|
||||
{
|
||||
SaimaaMachineState *sms = SAIMAA_MACHINE(obj);
|
||||
g_free(sms->sblmain);
|
||||
sms->sblmain = g_strdup(value);
|
||||
}
|
||||
|
||||
static void saimaa_machine_instance_init(Object *obj)
|
||||
{
|
||||
SaimaaMachineState *sms = SAIMAA_MACHINE(obj);
|
||||
sms->sbl1 = NULL;
|
||||
sms->emmc = NULL;
|
||||
sms->sblmain = NULL;
|
||||
object_property_add_str(obj, "sbl1", saimaa_get_sbl1, saimaa_set_sbl1);
|
||||
object_property_add_str(obj, "sblmain", saimaa_get_sblmain,
|
||||
saimaa_set_sblmain);
|
||||
}
|
||||
|
||||
static void saimaa_machine_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
"""sbl_adr.py — поиск ADR (ADD/SUB pc) ссылок на интересные строки SBL1.
|
||||
Использование: ./tools/sbl_adr.py fw/sbl/img0.elf
|
||||
"""
|
||||
import struct
|
||||
import sys
|
||||
|
||||
d = open(sys.argv[1], "rb").read()
|
||||
STRINGS = [b"SBL1, Start", b"SBL1, End", b"SBL1, Delta",
|
||||
b"Sahara: Hello pkt sent", b"bl_power_on", b"sbl1_main"]
|
||||
svas = {}
|
||||
for s in STRINGS:
|
||||
i = d.find(s)
|
||||
if i < 0:
|
||||
continue
|
||||
# find which segment contains it
|
||||
phoff = struct.unpack("<I", d[28:32])[0]
|
||||
phnum = struct.unpack("<H", d[44:46])[0]
|
||||
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 off <= i < off + fsz:
|
||||
svas[s] = v + (i - off)
|
||||
for s, va in svas.items():
|
||||
print(s.decode(), "VA:", hex(va))
|
||||
|
||||
phoff = struct.unpack("<I", d[28:32])[0]
|
||||
phnum = struct.unpack("<H", d[44:46])[0]
|
||||
segs = []
|
||||
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 and (fl & 1 or True):
|
||||
segs.append((off, v, fsz))
|
||||
for s, va in svas.items():
|
||||
print("--- refs to", s.decode(), hex(va))
|
||||
n = 0
|
||||
for off, v, sz in segs:
|
||||
code = d[off:off + sz]
|
||||
for j in range(0, len(code) - 4, 4):
|
||||
x = struct.unpack("<I", code[j:j + 4])[0]
|
||||
# ADD Rd,pc,#imm12 rotated; SUB Rd,pc,#imm
|
||||
if (x & 0x0FFF0000) in (0x028F0000, 0x024F0000):
|
||||
imm = x & 0xFFF
|
||||
rot = (x & 0xF00) >> 7
|
||||
imm = ((imm >> rot) | (imm << (32 - rot))) & 0xFFFFFFFF if rot else imm
|
||||
tgt = (v + j + 8 + (imm if (x & 0x400000) else -imm)) & 0xFFFFFFFF
|
||||
if abs(tgt - va) < 0x100:
|
||||
print(" ", hex(v + j), "->", hex(tgt))
|
||||
n += 1
|
||||
if n > 6:
|
||||
break
|
||||
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python3
|
||||
"""sbl_mains.py — кандидаты в sbl_main: плотность BL + близость строк boot-лога.
|
||||
Использование: ./tools/sbl_mains.py fw/sbl/img0.elf
|
||||
"""
|
||||
import struct
|
||||
import sys
|
||||
|
||||
d = open(sys.argv[1], "rb").read()
|
||||
phoff = struct.unpack("<I", d[28:32])[0]
|
||||
phnum = struct.unpack("<H", d[44:46])[0]
|
||||
segs = []
|
||||
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:
|
||||
segs.append((off, v, fsz))
|
||||
|
||||
# prologues: STMDB sp!,{...,lr} (bit11 set)
|
||||
cands = []
|
||||
for off, v, sz in segs:
|
||||
code = d[off:off + sz]
|
||||
for j in range(0, len(code) - 4, 4):
|
||||
x = struct.unpack("<I", code[j:j + 4])[0]
|
||||
if (x & 0xFFFF0800) == 0xE92D0800: # push ... r11?/lr frame
|
||||
# count BLs in next 2KB
|
||||
bls = 0
|
||||
for q in range(j, min(j + 2048, len(code) - 4), 4):
|
||||
y = struct.unpack("<I", code[q:q + 4])[0]
|
||||
if (y >> 25) == 0b101 and (y & 0x01000000):
|
||||
bls += 1
|
||||
if bls >= 8:
|
||||
cands.append((bls, v + j))
|
||||
cands.sort(reverse=True)
|
||||
print("top candidates (bl-count, addr):")
|
||||
for bls, a in cands[:15]:
|
||||
print(f" {bls:3d} {a:#x}")
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/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))
|
||||
Reference in New Issue
Block a user