添加机型支持
第 0 部分:通过覆写栈来执行 FDL1/SPL(无需验证)

本项目已经完成了这一步。你可以浏览 该文件夹 了解当前支持的 SOC,也可以查看每个文件夹下的 stack-info.csv 或 BootROM 了解这些 ROP chain 文件的工作原理。

SOC 代号SOC 公开名称RAMFDL1 地址FDL2 地址ROM
sc9820esc9820e / sl8521eLPDDR2/30x50000x9efffe00eMMC
sc9832esc9832e / sl8541eLPDDR2/30x50000x9efffe00eMMC
sc9863asc9863a / A8581LPDDR3/4/4X0x50000x9efffe00eMMC
ud710T710 / T740 / T7510LPDDR4/4X/4Y0x55000x9efffe00eMMC/UFS
udx710V510LPDDR4/4X0x280070000x9efffe00Nand
ums312T310LPDDR3/4/4X0x55000x9efffe00eMMC
ums512T610 / T618 / T700 / A7862LPDDR3/4/4X0x55000x9efffe00eMMC
ums9230T606 / T612 / T616
T72xx
LPDDR4X0x650008000x9efffe00eMMC/UFS
ums9620T760 / T770 / T820 / S8000 / A7870
T8100/T9100
LPDDR4X0x650008000xb4fffe00eMMC/UFS
ums9621T750 / T765
T8200
LPDDR4X0x650008000xbefffe00eMMC/UFS
ums9360T7300LPDDR4X0x650080000xbdfffe00eMMC/UFS
ums9632T8300 / T9300LPDDR4X0x650080000xbdfffe00eMMC/UFS

sc9820e / sc9832e 共用同一个 BootROM。

ums9621:参见 exec_addr_v2

修改镜像

SPL 方式:patch do_cboot(),将 trustos 组件从设备 emmc/ufs 加载到设备内存

FDL1 方式:patch do_cboot(),将 trustos 组件从 PC 发送到设备内存

SPL 或 FDL1 方式的选择
  1. 尝试在官方包(update.zip、tfupdate.bin、sprd.pac 等)中寻找镜像;如果 FDL1、FDL2(arm64 上就是 uboot)、splloader 都齐全,优先按 SPL 方法,SPL 失败再用 FDL1。
  2. 用 spd_dump 的 read_part 从同 SOC(最好同厂商)的其他设备读取 splloader 和 uboot,配合 FDL1、FDL2,然后按 SPL 方法。(大多数 ud710 可以使用任意 ud710 设备的 FDL 来读取分区)
  3. (修改 chipram 源码并编译)在下载模式下读取分区需要一个可用的 fdl1,但官方包通常不提供 FDL1。可参考 此 gist 的更简便做法。拿到可用的 FDL1 后,FDL1 方式与 SPL 方式差别不大。
IDA 加载

sc9820e / sc9832e / sc9863a:在 spl/fdl1 中使用 64bit,在 uboot/lk/trustos/sml 中尝试 32bit 或 64bit。

其他 SOC 的所有二进制文件均选择 64bit 模式。

FDL1/2 地址已在上面的表格中;splloader 地址与 FDL1 相同;trustos/sml/teecfg 的加载地址可以在 splloader 中找到。

IDA 脚本(用于 uboot/lk,不适用于 spl/fdl1)
IDA 7/8

arm32 uboot 0x9efffe00

import idaapi
import idautils
import ida_funcs
import ida_offset
import ida_segment
import idc

segments = idautils.Segments()
if segments:
    seg_ea = next(segments)
    seg_start = idaapi.getseg(seg_ea).start_ea
    seg_end = idaapi.getseg(seg_ea).end_ea
    ea1 = seg_start
    ea3 = seg_end

    ea2 = seg_end
    print("ea1 0x{:X}".format(ea1))
    print("ea2 0x{:X}".format(ea2))
    print("ea3 0x{:X}".format(ea3))

    while ea1 < ea3:
        ea1 = idaapi.find_binary(ea1 + 4, ea3, "? ? ? 9f",16, idaapi.SEARCH_DOWN)
        if ea1 != idaapi.BADADDR:
            offset_start = ida_offset.op_plain_offset(ea1, 0, 0)
    ida_funcs.add_func(seg_start+0x200)

arm64 uboot 0x9efffe00

import idaapi
import idautils
import ida_funcs
import ida_offset
import ida_segment
import idc

segments = idautils.Segments()
if segments:
    seg_ea = next(segments)
    seg_start = idaapi.getseg(seg_ea).start_ea
    seg_end = idaapi.getseg(seg_ea).end_ea
    ea1 = seg_start
    ea3 = seg_end

    ea2 = idaapi.find_binary(seg_start, seg_end, "C0 03 5F D6",16, idaapi.SEARCH_UP) + 4
    print("ea1 0x{:X}".format(ea1))
    print("ea2 0x{:X}".format(ea2))
    print("ea3 0x{:X}".format(ea3))
    ida_segment.add_segm(0, ea2, ea3, ".data", "DATA")
    s = ida_segment.get_segm_by_name(".data")
    s.bitness  = 2
    ida_segment.update_segm(s)

    while ea1 < ea3:
        ea1 = idaapi.find_binary(ea1 + 8, ea3, "? ? ? 9f 00 00 00 00",16, idaapi.SEARCH_DOWN)
        if ea1 != idaapi.BADADDR:
            val = idc.get_qword(ea1)
            if val < ea2:
                func_start = ida_funcs.add_func(val)
            offset_start = ida_offset.op_plain_offset(ea1, 0, 0)
    ida_funcs.add_func(seg_start+0x200)

arm64 uboot 0xb4fffe00

import idaapi
import idautils
import ida_funcs
import ida_offset
import ida_segment
import idc

segments = idautils.Segments()
if segments:
    seg_ea = next(segments)
    seg_start = idaapi.getseg(seg_ea).start_ea
    seg_end = idaapi.getseg(seg_ea).end_ea
    ea1 = seg_start
    ea3 = seg_end

    ea2 = idaapi.find_binary(seg_start, seg_end, "C0 03 5F D6",16, idaapi.SEARCH_UP) + 4
    print("ea1 0x{:X}".format(ea1))
    print("ea2 0x{:X}".format(ea2))
    print("ea3 0x{:X}".format(ea3))
    ida_segment.add_segm(0, ea2, ea3, ".data", "DATA")
    s = ida_segment.get_segm_by_name(".data")
    s.bitness  = 2
    ida_segment.update_segm(s)

    while ea1 < ea3:
        ea1 = idaapi.find_binary(ea1 + 8, ea3, "? ? ? b5 00 00 00 00",16, idaapi.SEARCH_DOWN)
        if ea1 != idaapi.BADADDR:
            val = idc.get_qword(ea1)
            if val < ea2:
                func_start = ida_funcs.add_func(val)
            offset_start = ida_offset.op_plain_offset(ea1, 0, 0)
    ida_funcs.add_func(seg_start+0x200)
IDA 9

arm32 uboot 0x9efffe00

import idaapi
import idautils
import ida_bytes
import ida_funcs
import ida_offset
import ida_segment
import idc

patterns1 = ida_bytes.compiled_binpat_vec_t()
segments = idautils.Segments()
if segments:
    seg_ea = next(segments)
    seg_start = idaapi.getseg(seg_ea).start_ea
    seg_end = idaapi.getseg(seg_ea).end_ea
    ea1 = seg_start
    ea3 = seg_end

    ea2 = seg_end
    print("ea1 0x{:X}".format(ea1))
    print("ea2 0x{:X}".format(ea2))
    print("ea3 0x{:X}".format(ea3))
    ida_bytes.parse_binpat_str(patterns1, 0, "?? ?? ?? 9f", 16)
    while ea1 < ea3:
        ea1 = ida_bytes.bin_search(ea1 + 4, ea3, patterns1, ida_bytes.BIN_SEARCH_FORWARD)[0]
        if ea1 != idaapi.BADADDR:
            offset_start = ida_offset.op_plain_offset(ea1, 0, 0)
    ida_funcs.add_func(seg_start + 0x200)

arm64 uboot 0x9efffe00

import idaapi
import idautils
import ida_bytes
import ida_funcs
import ida_offset
import ida_segment
import idc

patterns1 = ida_bytes.compiled_binpat_vec_t()
patterns2 = ida_bytes.compiled_binpat_vec_t()
segments = idautils.Segments()
if segments:
    seg_ea = next(segments)
    seg_start = idaapi.getseg(seg_ea).start_ea
    seg_end = idaapi.getseg(seg_ea).end_ea
    ea1 = seg_start
    ea3 = seg_end
    ida_bytes.parse_binpat_str(patterns1, 0, "C0 03 5F D6", 16)
    ea2 = ida_bytes.bin_search(seg_start, seg_end, patterns1, ida_bytes.BIN_SEARCH_BACKWARD)[0] + 4

    print("ea1 0x{:X}".format(ea1))
    print("ea2 0x{:X}".format(ea2))
    print("ea3 0x{:X}".format(ea3))
    ida_segment.add_segm(0, ea2, ea3, ".data", "DATA")
    s = ida_segment.get_segm_by_name(".data")
    s.bitness  = 2
    ida_segment.update_segm(s)
    ida_bytes.parse_binpat_str(patterns2, 0, "?? ?? ?? 9f 00 00 00 00", 16)
    while ea1 < ea3:
        ea1 = ida_bytes.bin_search(ea1 + 8, ea3, patterns2, ida_bytes.BIN_SEARCH_FORWARD)[0]
        if ea1 != idaapi.BADADDR:
            val = idc.get_qword(ea1)
            if val < ea2:
                func_start = ida_funcs.add_func(val)
            offset_start = ida_offset.op_plain_offset(ea1, 0, 0)
    ida_funcs.add_func(seg_start + 0x200)

arm64 uboot 0xb4fffe00

import idaapi
import idautils
import ida_bytes
import ida_funcs
import ida_offset
import ida_segment
import idc

patterns1 = ida_bytes.compiled_binpat_vec_t()
patterns2 = ida_bytes.compiled_binpat_vec_t()
segments = idautils.Segments()
if segments:
    seg_ea = next(segments)
    seg_start = idaapi.getseg(seg_ea).start_ea
    seg_end = idaapi.getseg(seg_ea).end_ea
    ea1 = seg_start
    ea3 = seg_end
    ida_bytes.parse_binpat_str(patterns1, 0, "C0 03 5F D6", 16)
    ea2 = ida_bytes.bin_search(seg_start, seg_end, patterns1, ida_bytes.BIN_SEARCH_BACKWARD)[0] + 4

    print("ea1 0x{:X}".format(ea1))
    print("ea2 0x{:X}".format(ea2))
    print("ea3 0x{:X}".format(ea3))
    ida_segment.add_segm(0, ea2, ea3, ".data", "DATA")
    s = ida_segment.get_segm_by_name(".data")
    s.bitness  = 2
    ida_segment.update_segm(s)
    ida_bytes.parse_binpat_str(patterns2, 0, "?? ?? ?? b5 00 00 00 00", 16)
    while ea1 < ea3:
        ea1 = ida_bytes.bin_search(ea1 + 8, ea3, patterns2, ida_bytes.BIN_SEARCH_FORWARD)[0]
        if ea1 != idaapi.BADADDR:
            val = idc.get_qword(ea1)
            if val < ea2:
                func_start = ida_funcs.add_func(val)
            offset_start = ida_offset.op_plain_offset(ea1, 0, 0)
    ida_funcs.add_func(seg_start + 0x200)
友链