From 5f14a0eac53d7020dba35f54c33b5393f0740f63 Mon Sep 17 00:00:00 2001 From: SashegDev Date: Mon, 7 Sep 2026 09:28:02 +0000 Subject: [PATCH] saimaa: sblmain stack-pc override prop; sbl analysis tools --- qemu/saimaa.c | 24 +++++++++++++++++++++ tools/sbl_adr.py | 52 ++++++++++++++++++++++++++++++++++++++++++++++ tools/sbl_mains.py | 36 ++++++++++++++++++++++++++++++++ tools/sbl_refs.py | 38 +++++++++++++++++++++++++++++++++ 4 files changed, 150 insertions(+) create mode 100644 tools/sbl_adr.py create mode 100644 tools/sbl_mains.py create mode 100644 tools/sbl_refs.py diff --git a/qemu/saimaa.c b/qemu/saimaa.c index ffd9ed3..2845bd6 100644 --- a/qemu/saimaa.c +++ b/qemu/saimaa.c @@ -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) diff --git a/tools/sbl_adr.py b/tools/sbl_adr.py new file mode 100644 index 0000000..b9fc817 --- /dev/null +++ b/tools/sbl_adr.py @@ -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("> 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 diff --git a/tools/sbl_mains.py b/tools/sbl_mains.py new file mode 100644 index 0000000..aa64533 --- /dev/null +++ b/tools/sbl_mains.py @@ -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("> 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}") diff --git a/tools/sbl_refs.py b/tools/sbl_refs.py new file mode 100644 index 0000000..3d215e8 --- /dev/null +++ b/tools/sbl_refs.py @@ -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("> 12) & 15), "->", hex(tgt))