添加机型支持
第 0 部分:通过覆写栈来执行 FDL1/SPL(无需验证)
本项目已经完成了这一步。你可以浏览 该文件夹 了解当前支持的 SOC,也可以查看每个文件夹下的 stack-info.csv 或 BootROM 了解这些 ROP chain 文件的工作原理。
| SOC 代号 | SOC 公开名称 | RAM | FDL1 地址 | FDL2 地址 | ROM |
|---|---|---|---|---|---|
| sc9820e | sc9820e / sl8521e | LPDDR2/3 | 0x5000 | 0x9efffe00 | eMMC |
| sc9832e | sc9832e / sl8541e | LPDDR2/3 | 0x5000 | 0x9efffe00 | eMMC |
| sc9863a | sc9863a / A8581 | LPDDR3/4/4X | 0x5000 | 0x9efffe00 | eMMC |
| ud710 | T710 / T740 / T7510 | LPDDR4/4X/4Y | 0x5500 | 0x9efffe00 | eMMC/UFS |
| udx710 | V510 | LPDDR4/4X | 0x28007000 | 0x9efffe00 | Nand |
| ums312 | T310 | LPDDR3/4/4X | 0x5500 | 0x9efffe00 | eMMC |
| ums512 | T610 / T618 / T700 / A7862 | LPDDR3/4/4X | 0x5500 | 0x9efffe00 | eMMC |
| ums9230 | T606 / T612 / T616 T72xx | LPDDR4X | 0x65000800 | 0x9efffe00 | eMMC/UFS |
| ums9620 | T760 / T770 / T820 / S8000 / A7870 T8100/T9100 | LPDDR4X | 0x65000800 | 0xb4fffe00 | eMMC/UFS |
| ums9621 | T750 / T765 T8200 | LPDDR4X | 0x65000800 | 0xbefffe00 | eMMC/UFS |
| ums9360 | T7300 | LPDDR4X | 0x65008000 | 0xbdfffe00 | eMMC/UFS |
| ums9632 | T8300 / T9300 | LPDDR4X | 0x65008000 | 0xbdfffe00 | eMMC/UFS |
sc9820e / sc9832e 共用同一个 BootROM。
ums9621:参见 exec_addr_v2
修改镜像
SPL 方式:patch do_cboot(),将 trustos 组件从设备 emmc/ufs 加载到设备内存
FDL1 方式:patch do_cboot(),将 trustos 组件从 PC 发送到设备内存
SPL 或 FDL1 方式的选择
- 尝试在官方包(update.zip、tfupdate.bin、sprd.pac 等)中寻找镜像;如果 FDL1、FDL2(arm64 上就是 uboot)、splloader 都齐全,优先按 SPL 方法,SPL 失败再用 FDL1。
- 用
spd_dump的read_part从同 SOC(最好同厂商)的其他设备读取 splloader 和 uboot,配合 FDL1、FDL2,然后按 SPL 方法。(大多数 ud710 可以使用任意 ud710 设备的 FDL 来读取分区) - (修改 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)