Skip to content

AddSupportToModel

TomKing062 edited this page May 24, 2024 · 35 revisions

Part 0: overwrite stack to execute FDL1/SPL without verfication (already done in this project)

You can browse this folder to know currently supported Socs , you can check stack-info.csv in each folder or BootROM to know how these ROP chain files work.

Soc code name Soc public name RAM FDL1 address FDL2 address 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 LPDDR4X 0x65000800 0x9efffe00 eMMC/UFS
ums9620 T760/T770/T820/S8000/A7870 LPDDR4X 0x65000800 0xb4fffe00 eMMC/UFS

sc9820e/sc9832e share same BootROM.

For other Socs affected by CVE-2022-38694, make custom_exec.bin accroding to BootROM.

modify images

SPL way: patch do_cboot(), trustos components loaded from device emmc/ufs to device memory

FDL1 way: patch do_cboot(), trustos components sent from PC to device memory

SPL or FDL1 way

SPL way works on a9-a13, FDL1 way seems only work on a9-a10 (because unisoc changed trustos's load address).

  1. try to find images in official packet(update.zip, tfupdate.bin, sprd.pac etc), if FDL1,FDL2(on arm64 it is just uboot),splloader are all available, then follow SPL method

  2. use spd_dump toread_part splloader and uboot with FDL1 and FDL2 from other device with same Soc(batter from same manufacturer), then follow SPL method.

​ (on most ud710, we can use FDLs of any ud710 devices to read partitions)

  1. (take quite a bit of work) read partition in download mode needs a proper fdl1, but official packet doesn't provide FDL1. Copy parameters from splloader to source code and compile, here are some examples. After get usable FDL1, FDL1 way and SPL way don't differ much, follow for the one that supports your Android version.

ida load

image

image

sc9820e/sc9832e/sc9863a may use 32bit or 64bit

other soc just choose 64bit mode

FDL1/2 address are already in sheet above, splloader address is same as FDL1, trustos/sml/teecfg load address can be find in splloader

ida scripts

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)
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)
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)