moved files and cleaned a bit of code
This commit is contained in:
parent
59eaf299ad
commit
43ad022669
@ -15,24 +15,6 @@ ks_thumb = Ks(KS_ARCH_ARM, KS_MODE_THUMB)
|
||||
logger = setup_logger("") # get root logger
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
def boot_bct():
|
||||
rcm = TegraRCM()
|
||||
rcm.dev.read_chip_id()
|
||||
file = "/home/eljakim/Source/tegrax1_plus/source/Shofel2_T124_python/ShofEL2-for-T124/boot_bct.bin"
|
||||
rcm.send_payload(file, thumb=1)
|
||||
|
||||
def boot_gardenia():
|
||||
rcm = TegraRCM()
|
||||
rcm.dev.read_chip_id()
|
||||
file = "/tmp/gardenia/build/bootloader"
|
||||
rcm.send_payload(file, thumb=1)
|
||||
r = rcm.dev.read(0x10000)
|
||||
try:
|
||||
r2 =rcm.dev.read(0x10000)
|
||||
except:
|
||||
time.sleep(1)
|
||||
pass
|
||||
|
||||
def device_setup(concrete_device : "ConcreteDevice"):
|
||||
'''
|
||||
This function has to return a device object that handles the communication between the host and the device.
|
||||
@ -287,8 +269,10 @@ def hw_init(cd : "ConcreteDevice"):
|
||||
|
||||
assert cd.read(4) == b"GiAs", "Failed to jump to debugger"
|
||||
# BCT should be loaded at 0x40020000
|
||||
|
||||
# nvbootcoldboot()
|
||||
|
||||
|
||||
nvbootcoldboot()
|
||||
# dump_emmc()
|
||||
boot_to = 0x0
|
||||
if cd.arch_dbg.state.R0 == 0:
|
||||
# 0x40020000 should point to 0x4000e000
|
||||
@ -297,7 +281,7 @@ def hw_init(cd : "ConcreteDevice"):
|
||||
else:
|
||||
# BCT not loaded, fix this
|
||||
boot_to = 0x4000e000
|
||||
imem = open("/tmp/imem3_bct", 'rb').read()
|
||||
imem = open("bin/imem_bct", 'rb').read()
|
||||
cd.memwrite_region(0x40000000, imem)
|
||||
|
||||
# Setup sdram?
|
||||
@ -317,6 +301,8 @@ def hw_init(cd : "ConcreteDevice"):
|
||||
# cd.restore_stack_and_jump(0x00104822 | 1)
|
||||
# pass
|
||||
|
||||
|
||||
|
||||
# Apply patches
|
||||
# patch validation of secure os
|
||||
stub = f"""
|
||||
@ -333,6 +319,14 @@ def hw_init(cd : "ConcreteDevice"):
|
||||
"""
|
||||
jump_stub = ks_arm.asm(jump_stub, as_bytes=True)[0]
|
||||
|
||||
NVBOOTSDMMCREADPAGE = 0x4001d1dc
|
||||
emmc_dump_patch = cd.memdump_region(NVBOOTSDMMCREADPAGE, 0x20)
|
||||
def dump_emmc_patches():
|
||||
cd.memwrite_region(NVBOOTSDMMCREADPAGE, jump_stub)
|
||||
|
||||
# Add this to enable emmc hooks
|
||||
# dump_emmc_patches()
|
||||
|
||||
# Setup code for log hook
|
||||
cd.memwrite_region(0x4001cadc, jump_stub)
|
||||
|
||||
@ -342,7 +336,29 @@ def hw_init(cd : "ConcreteDevice"):
|
||||
while True:
|
||||
try:
|
||||
r = cd.read(0x100)
|
||||
if cd.arch_dbg.state.R0 == 0x77:
|
||||
if cd.arch_dbg.state.LR == NVBOOTSDMMCREADPAGE:
|
||||
# Try dumping the emmc
|
||||
cd.memwrite_region(NVBOOTSDMMCREADPAGE, emmc_dump_patch)
|
||||
print(f"block={cd.arch_dbg.state.R0} page={cd.arch_dbg.state.R1} buffer={hex(cd.arch_dbg.state.R2)}")
|
||||
|
||||
def dirty_emmc_read(block, page, target_buffer):
|
||||
cd.arch_dbg.state.LR = cd.ga_debugger_location | 1
|
||||
cd.arch_dbg.state.R0 = block
|
||||
cd.arch_dbg.state.R1 = page
|
||||
cd.arch_dbg.state.R2 = target_buffer
|
||||
cd.arch_dbg.state.R3 = cd.ga_debugger_location | 1
|
||||
cd.restore_stack_and_jump(NVBOOTSDMMCREADPAGE | 1)
|
||||
resp = cd.read(0x200)
|
||||
pass
|
||||
|
||||
def dump_emmc():
|
||||
out_buf = 0x40020000
|
||||
dirty_emmc_read(0, 0, out_buf)
|
||||
dat = cd.memdump_region(out_buf, 512)
|
||||
pass
|
||||
dump_emmc()
|
||||
pass
|
||||
elif cd.arch_dbg.state.R0 == 0x77:
|
||||
# In nvtloadbinary
|
||||
dat = open("/tmp/bootloader.bin", 'rb').read()
|
||||
cd.memwrite_region(0x83d88000, dat[:0x90000])
|
||||
@ -468,16 +484,14 @@ def device_main(cd : "ConcreteDevice", args):
|
||||
Main function that will do execution for the device.
|
||||
'''
|
||||
cd.test_connection()
|
||||
partial_emu = True
|
||||
partial_emu = False
|
||||
if partial_emu:
|
||||
relocate_debugger(cd)
|
||||
do_partial_emu(cd)
|
||||
|
||||
sys.exit(0)
|
||||
hw_in_the_loop()
|
||||
hw_init(cd)
|
||||
attempt_boot_bct(cd)
|
||||
test_arm_asm(cd)
|
||||
else:
|
||||
hw_init(cd)
|
||||
attempt_boot_bct(cd)
|
||||
test_arm_asm(cd)
|
||||
pass
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
BIN
ShofEL2-for-T124/intermezzo.bin
Executable file
BIN
ShofEL2-for-T124/intermezzo.bin
Executable file
Binary file not shown.
Binary file not shown.
BIN
bin/bootloader.bin
Normal file
BIN
bin/bootloader.bin
Normal file
Binary file not shown.
BIN
bin/bootrom_t124.bin
Normal file
BIN
bin/bootrom_t124.bin
Normal file
Binary file not shown.
BIN
bin/dumped.bin
Normal file
BIN
bin/dumped.bin
Normal file
Binary file not shown.
BIN
bin/dumped_ref0.bin
Normal file
BIN
bin/dumped_ref0.bin
Normal file
Binary file not shown.
BIN
bin/imem_good.bin
Normal file
BIN
bin/imem_good.bin
Normal file
Binary file not shown.
BIN
bin/imem_ref0_t124.bin
Normal file
BIN
bin/imem_ref0_t124.bin
Normal file
Binary file not shown.
BIN
bin/t124_brom_hwio.pickle
Normal file
BIN
bin/t124_brom_hwio.pickle
Normal file
Binary file not shown.
@ -30,7 +30,7 @@ This will connect the device as a sdcard and allows you to reflash the bootloade
|
||||
But this is no fun at all and I can't introduce my debugger, so let's continue our software only approach.
|
||||
|
||||
## Debugger
|
||||
The first goal is to build my debugger for this target. When connecting the device to a Linux based PCB I see the following message in dmesg:
|
||||
The first goal is to build my debugger for this target. When connecting the device to a Linux based computer I see the following message in dmesg:
|
||||
|
||||
```bash
|
||||
[323058.201469] usb 1-5.3.1: new high-speed USB device number 91 using xhci_hcd
|
||||
|
99
inspect_hwio.py
Normal file
99
inspect_hwio.py
Normal file
@ -0,0 +1,99 @@
|
||||
import argparse, pickle
|
||||
|
||||
'''
|
||||
sdmmc1: sdhci@700b0000 {
|
||||
compatible = "nvidia,tegra210-sdhci", "nvidia,tegra132-sdhci";
|
||||
reg = <0x0 0x700b0000 0x0 0x200>;
|
||||
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&tegra_car TEGRA210_CLK_SDMMC1>;
|
||||
resets = <&tegra_car 14>;
|
||||
reset-names = "sdhci";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pinmux: pinmux@700008d4 {
|
||||
compatible = "nvidia,tegra210-pinmux";
|
||||
reg = <0x0 0x700008d4 0x0 0x299 /* Pad control registers */
|
||||
0x0 0x70003000 0x0 0x290>; /* Mux registers */
|
||||
#gpio-range-cells = <3>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tegra_car: clock@60006000 {
|
||||
compatible = "nvidia,tegra210-car", "syscon";
|
||||
reg = <0x0 0x60006000 0x0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
rtc: rtc@7000e000 {
|
||||
compatible = "nvidia,tegra-rtc";
|
||||
reg = <0x0 0x7000e000 0x0 0x100>;
|
||||
interrupts = <0 2 0x04>;
|
||||
status = "disabled";
|
||||
};
|
||||
tegra_timer: timer@60005000 {
|
||||
compatible = "nvidia,tegra210-timer";
|
||||
reg = <0x0 0x60005000 0x0 0x400>;
|
||||
interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&tegra_car TEGRA210_CLK_TIMER>;
|
||||
};
|
||||
rtc: rtc@7000e000 {
|
||||
compatible = "nvidia,tegra-rtc";
|
||||
reg = <0x0 0x7000e000 0x0 0x100>;
|
||||
interrupts = <0 2 0x04>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
'''
|
||||
|
||||
t124_mem_map = {
|
||||
0x60006000 :
|
||||
{
|
||||
"name" : "tegra_car",
|
||||
"size" : 0x1000,
|
||||
},
|
||||
0x60005000 : {
|
||||
"name" : "tegra_timer",
|
||||
"size" : 0x400,
|
||||
},
|
||||
0x70019000 :
|
||||
{
|
||||
"name" : "memory_controller",
|
||||
"size" : 0x1000,
|
||||
},
|
||||
0x700b0000 : {
|
||||
"name" : "sdhci1",
|
||||
"size" : 0x200,
|
||||
},
|
||||
0x70003000 : {
|
||||
"name" : "pinmux",
|
||||
"size" : 0x290,
|
||||
},
|
||||
0x7000e000 : {
|
||||
"name" : "rtc",
|
||||
"size" : 0x100,
|
||||
}
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Inspect HWIO")
|
||||
parser.add_argument("hwio", help="Path to HWIO file")
|
||||
args = parser.parse_args()
|
||||
|
||||
hwio = pickle.load(open(args.hwio, "rb"))
|
||||
|
||||
devices = {}
|
||||
for address in hwio:
|
||||
t_dev = address - (address % 0x1000)
|
||||
if t_dev not in devices:
|
||||
devices[t_dev] = []
|
||||
|
||||
devices[t_dev].append(address)
|
||||
|
||||
for d in devices:
|
||||
print(f"Device at 0x{d:04x} {t124_mem_map[d]['name'] if d in t124_mem_map else ''}")
|
||||
pass
|
@ -1,8 +1,13 @@
|
||||
import typing, pathlib, struct, argparse
|
||||
import typing, pathlib, struct, argparse, pickle, hashlib, time
|
||||
from ghidra_assistant.utils.archs.arm.arm_emulator import *
|
||||
from ghidra_assistant.ghidra_assistant import GhidraAssistant
|
||||
from ghidra_assistant.concrete_device import ConcreteDevice
|
||||
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.primitives.asymmetric import padding, rsa
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.exceptions import InvalidSignature
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from GA_debugger import *
|
||||
|
||||
@ -34,12 +39,17 @@ class TegraDevice():
|
||||
self.fuses_visible = 0
|
||||
|
||||
def read(self, address, size):
|
||||
if len(self.emulator.saved_hwio[address]) > 0:
|
||||
val = self.emulator.saved_hwio[address].pop(0)
|
||||
self.emulator.write_ptr(address, val)
|
||||
return True
|
||||
if address == TegraDevice.CLK_RST_CONTROLLER_MISC_CLK_ENB_0:
|
||||
self.emulator.write_ptr(TegraDevice.CLK_RST_CONTROLLER_MISC_CLK_ENB_0, self.fuses_visible)
|
||||
return True
|
||||
raise NotImplemented
|
||||
|
||||
def write(self, address, data):
|
||||
return True
|
||||
if address == TegraDevice.CLK_RST_CONTROLLER_MISC_CLK_ENB_0:
|
||||
self.fuses_visible = data
|
||||
return True
|
||||
@ -110,19 +120,130 @@ class EmmcDevice(TegraDevice):
|
||||
def __init__(self, emulator: "TegraEmulator") -> None:
|
||||
super().__init__(emulator)
|
||||
|
||||
def read(self, address, size):
|
||||
pass
|
||||
|
||||
def write(self, address, value):
|
||||
pass
|
||||
|
||||
class CryptoDevice(TegraDevice):
|
||||
BASE = 0x70012000
|
||||
SIZE = 0x1000
|
||||
NAME = "Crypto"
|
||||
KEY_SLOT_SELECT = BASE + 0x31c
|
||||
KEY_SLOT_START = BASE + 0x320
|
||||
KEY_SLOT_END = BASE + 0x330
|
||||
SE_CONFIG_0 = BASE + 0x14
|
||||
SE_BUSY = BASE + 0x800
|
||||
SE_START = BASE + 0x8
|
||||
SE_SHA_CONFIG_0 = BASE + 0x200
|
||||
SE_SHA_MSG_LENGTH_0 = BASE + 0x204
|
||||
SE_SHA_MSG_LENGTH_2 = BASE + 0x208
|
||||
SE_SHA_MSG_LENGTH_2 = BASE + 0x20c
|
||||
SE_IN_LL_ADDR_0 = BASE + 0x18
|
||||
SE_OUT_LL_ADDR_0 = BASE + 0x24
|
||||
SE_SHA_MSG_LEFT_0 = BASE + 0x214
|
||||
SE_RSA_EXP_SIZE_0 = BASE + 0x408
|
||||
SE_RSA_KEY_SIZE_0 = BASE + 0x404
|
||||
SE_RSA_KEYTABLE_ADDR_0 = BASE + 0x420
|
||||
|
||||
SE_RSA_KEY_SIZE_0_VAL_WIDTH_2048 = 3
|
||||
|
||||
def __init__(self, emulator: "TegraEmulator") -> None:
|
||||
super().__init__(emulator)
|
||||
self.keys = {}
|
||||
self.current_key = b"\x00" * 16
|
||||
self.key_slot_config = 0
|
||||
self.key_slot = 0
|
||||
self.config = 0
|
||||
|
||||
def read(self, address, size):
|
||||
if address == CryptoDevice.SE_CONFIG_0:
|
||||
self.emulator.write_ptr(CryptoDevice.SE_CONFIG_0, self.config)
|
||||
elif address == CryptoDevice.SE_BUSY:
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
def write(self, address, value):
|
||||
if address == CryptoDevice.KEY_SLOT_SELECT:
|
||||
# Commit key to key slot
|
||||
self.key_slot_config = value
|
||||
self.key_slot = p32(value)[0] # First byte is keyslot
|
||||
self.keys[self.key_slot] = self.current_key
|
||||
elif address >= CryptoDevice.KEY_SLOT_START and address <= CryptoDevice.KEY_SLOT_END:
|
||||
if self.key_slot not in self.keys:
|
||||
self.keys[self.key_slot] = b"\x00" * 16
|
||||
# Keys are 16 bytes
|
||||
offset = address - CryptoDevice.KEY_SLOT_START
|
||||
self.current_key = self.current_key[:offset] + struct.pack("<I", value) + self.current_key[offset + 4:]
|
||||
elif address == CryptoDevice.SE_CONFIG_0:
|
||||
self.config = value
|
||||
elif address == CryptoDevice.SE_SHA_MSG_LENGTH_0:
|
||||
self.msg_length = value
|
||||
elif address == CryptoDevice.SE_SHA_CONFIG_0:
|
||||
self.sha_config_0 = value
|
||||
elif address == CryptoDevice.SE_IN_LL_ADDR_0:
|
||||
self.in_ll_address = value
|
||||
elif address == CryptoDevice.SE_OUT_LL_ADDR_0:
|
||||
self.out_ll_address = value
|
||||
elif address == CryptoDevice.SE_SHA_MSG_LEFT_0:
|
||||
self.sha_msg_left = value
|
||||
elif address == CryptoDevice.SE_START:
|
||||
self.emulator.write_ptr(CryptoDevice.SE_BUSY, 1) # Busy
|
||||
# Parse SE linked list
|
||||
last_block = self.emulator.read_ptr(self.in_ll_address)
|
||||
# Read block
|
||||
def hash_block():
|
||||
block_address = self.emulator.read_ptr(self.in_ll_address + 4)
|
||||
size = self.emulator.read_ptr(self.in_ll_address + 8)
|
||||
block = self.emulator.uc.mem_read(block_address, size)
|
||||
self.in_ll_address += 12 # Move to next block
|
||||
|
||||
out_address = self.emulator.read_ptr(self.out_ll_address + 4)
|
||||
out_size = self.emulator.read_ptr(self.out_ll_address + 8)
|
||||
|
||||
digest = hashlib.sha256(block).digest()
|
||||
self.emulator.uc.mem_write(out_address, digest[:out_size])
|
||||
while last_block != 0:
|
||||
hash_block()
|
||||
# Last block
|
||||
hash_block()
|
||||
self.emulator.write_ptr(CryptoDevice.SE_BUSY, 0) # Set CE to not busy
|
||||
pass
|
||||
# elif address == CryptoDevice.SE_SHA_MSG_LENGTH_2:
|
||||
# self.msg_length_2 = value
|
||||
elif address == CryptoDevice.SE_RSA_EXP_SIZE_0:
|
||||
self.rsa_exp_size = value
|
||||
elif address == CryptoDevice.SE_RSA_KEY_SIZE_0:
|
||||
assert value == CryptoDevice.SE_RSA_KEY_SIZE_0_VAL_WIDTH_2048, "Only 2048 bit keys supported"
|
||||
self.rsa_key_size = 2048
|
||||
elif address == CryptoDevice.SE_RSA_KEYTABLE_ADDR_0:
|
||||
# Copies ll key into CE
|
||||
last_block = self.emulator.read_ptr(self.in_ll_address)
|
||||
assert last_block == 0, "Only one block supported"
|
||||
block_address = self.emulator.read_ptr(self.in_ll_address + 4)
|
||||
size = self.emulator.read_ptr(self.in_ll_address + 8)
|
||||
self.rsa_key = self.emulator.uc.mem_read(block_address, size)
|
||||
else:
|
||||
if value != 0:
|
||||
pass
|
||||
self.emulator.write_ptr(address, value)
|
||||
|
||||
NVBOOTREADONEOBJECT = 0x00104c40
|
||||
NVBOOTSDMMCREADPAGE = 0x0010a5d6
|
||||
NVBOOTSESHAHASH = 0x00102b6c
|
||||
NVBOOTSERSAPSSSIGNATUREVERIFY = 0x00102ed2
|
||||
|
||||
class TegraEmulator(ARM_Emulator):
|
||||
def __init__(self, hw_itm=True, init_uc=True) -> None:
|
||||
def __init__(self, hw_itm=True, saved_hwio="", init_uc=True) -> None:
|
||||
super().__init__(init_uc)
|
||||
self.log_hw_access = True
|
||||
self.save_hwio = True
|
||||
if saved_hwio:
|
||||
self.saved_hwio = pickle.load(open(saved_hwio, "rb"))
|
||||
else:
|
||||
self.saved_hwio = {}
|
||||
self.hw_itm = hw_itm
|
||||
self.saved_blocks = {}
|
||||
try:
|
||||
@ -175,10 +296,13 @@ class TegraEmulator(ARM_Emulator):
|
||||
|
||||
def setup_devices(self):
|
||||
self.devices = {}
|
||||
self.devices['fuse'] = FuseDevice(self)
|
||||
self.devices['timer'] = TimerDevice(self)
|
||||
self.devices['emmc'] = EmmcDevice(self)
|
||||
# self.devices['fuse'] = FuseDevice(self)
|
||||
# self.devices['timer'] = TimerDevice(self)
|
||||
# self.devices['emmc'] = EmmcDevice(self)
|
||||
self.devices['crypto'] = CryptoDevice(self)
|
||||
|
||||
# Setup EMMC data
|
||||
self.emmc_raw_data = open("/home/eljakim/Source/tegrax1_plus/dump/nv-recovery-image-shield-tablet-lte-us-update3_1_1/blob", "rb").read()[0x112dc9f - 528:]
|
||||
self.devices['tegra'] = TegraDevice(self) # For all other devices
|
||||
|
||||
def hook_unmapped(self, uc, access, address, size, value, user_data):
|
||||
@ -190,8 +314,6 @@ class TegraEmulator(ARM_Emulator):
|
||||
# if self.log_hw_access:
|
||||
# p_info(f"{hex(self.pc)} HW access at 0x{address:x} with size {size}, value={hex(value)} and access {acces_str[access]}")
|
||||
|
||||
# Try and keep memory in sync with target device
|
||||
|
||||
if access == UC_MEM_WRITE:
|
||||
self.debugger.memwrite_region(address, self.uc.mem_read(address, size))
|
||||
if access == UC_MEM_READ:
|
||||
@ -208,6 +330,14 @@ class TegraEmulator(ARM_Emulator):
|
||||
val = struct.unpack("<I", val)[0]
|
||||
elif len(val) == 1:
|
||||
val = struct.unpack("<B", val)[0]
|
||||
|
||||
# save all access for emulation
|
||||
if self.save_hwio:
|
||||
if address not in self.saved_hwio:
|
||||
self.saved_hwio[address] = [val]
|
||||
else:
|
||||
self.saved_hwio[address].append(val)
|
||||
|
||||
p_info(f"{hex(self.pc)} READ at 0x{address:x} with size {size} value={hex(val)} | {hex(address)} <- {hex(val)}")
|
||||
elif access == UC_MEM_WRITE:
|
||||
p_info(f"{hex(self.pc)} WRITE at 0x{address:x} with size {size} value={hex(value)} | {hex(address)} -> {hex(value)}")
|
||||
@ -255,8 +385,22 @@ class TegraEmulator(ARM_Emulator):
|
||||
elif access == UC_MEM_WRITE:
|
||||
dev.write(address, value)
|
||||
return True
|
||||
|
||||
def sync_imem(self):
|
||||
'''
|
||||
Syncs IMEM regions
|
||||
'''
|
||||
if not hasattr(self, "debugger"):
|
||||
pass
|
||||
|
||||
imem = self.uc.mem_read(0x40000000, 0x40000)
|
||||
imem_debugger = self.debugger.memdump_region(0x40000000, 0x40000)
|
||||
pass
|
||||
|
||||
def hook_hw_access(self, uc, access, address, size, value, user_data):
|
||||
# if address == 0x70012800:
|
||||
# self.sync_imem()
|
||||
# pass
|
||||
if self.hw_itm:
|
||||
return self.hw_itm_handle(access, address, size, value)
|
||||
|
||||
@ -284,6 +428,8 @@ class TegraEmulator(ARM_Emulator):
|
||||
self.setup_warmboot_hook()
|
||||
self.setup_hook_blocks()
|
||||
self.setup_rcm_hooks()
|
||||
self.setup_sdmmc_hooks()
|
||||
self.setup_rsa_verify_hook()
|
||||
else:
|
||||
self.setup_log_hook()
|
||||
self.setup_hook_blocks()
|
||||
@ -310,23 +456,55 @@ class TegraEmulator(ARM_Emulator):
|
||||
return True
|
||||
self.uc.hook_add(UC_HOOK_CODE, hook_warmboot, begin=0x00101f3a, end=0x00101f3a + 1)
|
||||
|
||||
def setup_rsa_verify_hook(self):
|
||||
def hook_rsa_signature_verify(uc, address, size, user_data): # TODO not working
|
||||
print(f"RSA signature verify keyslot={self.R0} keysize={self.R1} input={self.R2} message_hash={self.R3} input_size={self.R4} signature={self.R5} algo={self.R6} signature_size={self.R7}")
|
||||
crypto = self.devices['crypto']
|
||||
crypto_key = crypto.rsa_key[:crypto.rsa_key_size // 8]
|
||||
signature = self.uc.mem_read(self.R7, 0x100)
|
||||
|
||||
modulus = int.from_bytes(crypto_key, byteorder='big')
|
||||
public_numbers = rsa.RSAPublicNumbers(e=65537, n=modulus)
|
||||
public_key = public_numbers.public_key(default_backend())
|
||||
|
||||
try:
|
||||
public_key.verify(
|
||||
signature,
|
||||
b"",
|
||||
padding.PSS(
|
||||
mgf=padding.MGF1(hashes.SHA256()),
|
||||
salt_length=padding.PSS.MAX_LENGTH
|
||||
),
|
||||
hashes.SHA256()
|
||||
)
|
||||
print("Signature is valid.")
|
||||
except InvalidSignature:
|
||||
print("Signature is invalid.")
|
||||
|
||||
# Verify signature
|
||||
|
||||
self.PC = self.LR
|
||||
self.R0 = 0
|
||||
return True
|
||||
self.uc.hook_add(UC_HOOK_CODE, hook_rsa_signature_verify, begin=0x00102f08, end=0x00102f08 + 1)
|
||||
|
||||
def apply_patches(self):
|
||||
|
||||
# Nop out 400101f0 to 0x40010220, maybe this is restricting access to IMEM and ROM?
|
||||
self.sc.mov_0_r0 = self.ks.asm("mov r0, #0", as_bytes=True)[0]
|
||||
# self.uc.mem_write(0x400101e4, self.sc.mov_0_r0 * ((0x40010220 - 0x400101e4) // 4))
|
||||
|
||||
# Patch EMMCVerifyResponse
|
||||
self.sc.bx_lr = self.ks.asm("bx lr", as_bytes=True)[0]
|
||||
|
||||
bx_lr_thumb = self.ksT.asm("bx lr", as_bytes=True)[0]
|
||||
movs_0_r0_thumb = self.ksT.asm("movs r0, #0", as_bytes=True)[0]
|
||||
|
||||
# self.uc.mem_write(0x4001dfb0, self.sc.mov_0_r0 + self.sc.bx_lr)
|
||||
if self.target == "bootrom":
|
||||
#NvBootClocksIsPllStable, ret
|
||||
# self.uc.mem_write(0x00101730, bx_lr_thumb)
|
||||
# # NvBootClocksStartPll
|
||||
self.uc.mem_write(0x00101866, bx_lr_thumb)
|
||||
|
||||
# NvBootClocksPllDivRstCtrl
|
||||
self.uc.mem_write(0x001016ce, bx_lr_thumb)
|
||||
|
||||
@ -395,6 +573,24 @@ class TegraEmulator(ARM_Emulator):
|
||||
|
||||
# And patch function to just return
|
||||
self.uc.mem_write(UART_LOG_HOOK, self.ks.asm("bx lr", as_bytes=True)[0])
|
||||
|
||||
def setup_sdmmc_hooks(self):
|
||||
def hook_sdmmc(uc, address, size, user_data):
|
||||
block = self.R0
|
||||
page = self.R1
|
||||
destbuf = self.R2
|
||||
offset = page * 0x200
|
||||
dat = self.emmc_raw_data[offset:offset + 0x200]
|
||||
self.uc.mem_write(destbuf, dat)
|
||||
self.PC = self.LR
|
||||
return True
|
||||
self.uc.hook_add(UC_HOOK_CODE, hook_sdmmc, begin=NVBOOTSDMMCREADPAGE, end=NVBOOTSDMMCREADPAGE + 1)
|
||||
|
||||
def setup_se_sha_hash_hook(self):
|
||||
def hook_se_sha(uc, address, size, user_data):
|
||||
self.saved_se_sha[self.pc] = self.get_registers()
|
||||
return True
|
||||
self.uc.hook_add(UC_HOOK_CODE, hook_se_sha, begin=NVBOOTSESHAHASH, end=NVBOOTSESHAHASH + 1)
|
||||
|
||||
def setup_hook_blocks(self, only_blocks=False):
|
||||
if only_blocks:
|
||||
@ -405,7 +601,24 @@ class TegraEmulator(ARM_Emulator):
|
||||
self.uc.hook_add(UC_HOOK_BLOCK, hook_block)
|
||||
else:
|
||||
def hook_all(uc, address, size, user_data):
|
||||
if self.pc == NVBOOTREADONEOBJECT:
|
||||
info(f"NvBootReadOneObject context={self.R0:04x} dest={self.R1:04x} bct_obj_dst={self.R2:04x} num_copies={self.R3}")
|
||||
if self.pc == 0x00104558:
|
||||
# Sync 0x40000100, length 0x2000
|
||||
info(f"NvBootReadOneObject done dest={self.read_ptr(self.R1)}")
|
||||
# if self.pc == NVBOOTSDMMCREADPAGE:
|
||||
# # At this point we can read our on pages if requested.
|
||||
# info(f"SdmmcReadPage block={self.R0} page={self.R1} destbuf={self.R2:04x}")
|
||||
# print(f"Block at {hex(self.LR)}")
|
||||
if self.pc == 0x00102ee8:
|
||||
pass
|
||||
if self.pc == 0x00102f1e:
|
||||
pass
|
||||
elif self.pc == 0x00104418:
|
||||
pass #Validatebct
|
||||
elif self.pc == 0x00104452:
|
||||
pass #validate done
|
||||
|
||||
self.saved_blocks[self.pc] = self.get_registers()
|
||||
return True
|
||||
self.uc.hook_add(UC_HOOK_CODE, hook_all, self)
|
||||
@ -431,7 +644,7 @@ def do_partial_emu(debugger : ConcreteDevice, real_hw=True):
|
||||
emu = TegraEmulator()
|
||||
emu.install_debugger(debugger)
|
||||
else:
|
||||
emu = TegraEmulator(hw_itm=False)
|
||||
emu = TegraEmulator(hw_itm=False, saved_hwio="bin/t124_brom_hwio.pickle")
|
||||
emu.setup(target="bootrom")
|
||||
emu.run()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user