started device implementation
This commit is contained in:
parent
a1ab8650bc
commit
59eaf299ad
8
.vscode/launch.json
vendored
8
.vscode/launch.json
vendored
@ -35,6 +35,14 @@
|
|||||||
"program": "GA_debugger.py",
|
"program": "GA_debugger.py",
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
"justMyCode": false
|
"justMyCode": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Emulate BootROM",
|
||||||
|
"type": "python",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "partial_emulation.py",
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"justMyCode": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
Binary file not shown.
@ -1,4 +1,4 @@
|
|||||||
import typing, pathlib, struct
|
import typing, pathlib, struct, argparse
|
||||||
from ghidra_assistant.utils.archs.arm.arm_emulator import *
|
from ghidra_assistant.utils.archs.arm.arm_emulator import *
|
||||||
from ghidra_assistant.ghidra_assistant import GhidraAssistant
|
from ghidra_assistant.ghidra_assistant import GhidraAssistant
|
||||||
from ghidra_assistant.concrete_device import ConcreteDevice
|
from ghidra_assistant.concrete_device import ConcreteDevice
|
||||||
@ -21,20 +21,121 @@ acces_str = {
|
|||||||
|
|
||||||
def p8(value):
|
def p8(value):
|
||||||
return struct.pack("<B", value)
|
return struct.pack("<B", value)
|
||||||
|
|
||||||
|
class TegraDevice():
|
||||||
|
BASE = 0x0
|
||||||
|
SIZE = 0x1000
|
||||||
|
NAME = "Generic Tegra Device"
|
||||||
|
NV_ADDRESS_MAP_CLK_RST_BASE = 0x60006000
|
||||||
|
CLK_RST_CONTROLLER_MISC_CLK_ENB_0 = NV_ADDRESS_MAP_CLK_RST_BASE + 0x48
|
||||||
|
|
||||||
class PartialEmu(ARM_Emulator):
|
def __init__(self, emulator : "TegraEmulator") -> None:
|
||||||
def __init__(self, init_uc=True) -> None:
|
self.emulator = emulator
|
||||||
|
self.fuses_visible = 0
|
||||||
|
|
||||||
|
def read(self, address, size):
|
||||||
|
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):
|
||||||
|
if address == TegraDevice.CLK_RST_CONTROLLER_MISC_CLK_ENB_0:
|
||||||
|
self.fuses_visible = data
|
||||||
|
return True
|
||||||
|
raise NotImplemented
|
||||||
|
|
||||||
|
class FuseDevice(TegraDevice):
|
||||||
|
BASE = 0x7000F000
|
||||||
|
SIZE = 0x1000
|
||||||
|
NAME = "Fuse"
|
||||||
|
FUSE_ODM_INFO_0 = BASE + 0x99c
|
||||||
|
FUSE_FUSEADDR_0 = BASE + 0x804
|
||||||
|
FUSE_FUSECTRL_0 = BASE + 0x800
|
||||||
|
CMD_READ = 1
|
||||||
|
CMD_IDLE = 0
|
||||||
|
FUSE_DAT = BytesIO()
|
||||||
|
def __init__(self, emulator: "TegraEmulator") -> None:
|
||||||
|
super().__init__(emulator)
|
||||||
|
self.fuse_ctr_cmd = 0xc0040000
|
||||||
|
self.fuse_addr = 0x0
|
||||||
|
|
||||||
|
def read(self, address, size):
|
||||||
|
if address == FuseDevice.FUSE_ODM_INFO_0:
|
||||||
|
self.emulator.write_ptr(FuseDevice.FUSE_ODM_INFO_0, 2)
|
||||||
|
elif address == FuseDevice.FUSE_FUSECTRL_0:
|
||||||
|
# get last int from fuse_ctr_cmd
|
||||||
|
cmd = self.fuse_ctr_cmd & 0xffffffff
|
||||||
|
if cmd == FuseDevice.CMD_READ:
|
||||||
|
# Handle read
|
||||||
|
|
||||||
|
# Set idle, set last byte of cmd to 0
|
||||||
|
self.fuse_ctr_cmd = cmd & 0xffffff00
|
||||||
|
self.emulator.write_ptr(FuseDevice.FUSE_FUSECTRL_0, self.fuse_ctr_cmd)
|
||||||
|
|
||||||
|
self.emulator.write_ptr(FuseDevice.FUSE_FUSECTRL_0, self.fuse_ctr_cmd)
|
||||||
|
else:
|
||||||
|
raise NotImplemented
|
||||||
|
return True
|
||||||
|
|
||||||
|
def write(self, address, value):
|
||||||
|
if address == FuseDevice.FUSE_FUSEADDR_0:
|
||||||
|
self.fuse_addr = value
|
||||||
|
elif address == FuseDevice.FUSE_FUSECTRL_0:
|
||||||
|
self.emulator.write_ptr(FuseDevice.FUSE_FUSECTRL_0, value)
|
||||||
|
self.fuse_ctr_cmd = value
|
||||||
|
else:
|
||||||
|
raise NotImplemented
|
||||||
|
return True
|
||||||
|
pass
|
||||||
|
|
||||||
|
class TimerDevice(TegraDevice):
|
||||||
|
BASE = 0x60005000
|
||||||
|
SIZE = 0x1000
|
||||||
|
NAME = "Timer"
|
||||||
|
READ_TIME_OFFSET = BASE + 0x10
|
||||||
|
def __init__(self, emulator: "TegraEmulator") -> None:
|
||||||
|
super().__init__(emulator)
|
||||||
|
|
||||||
|
def read(self, address, size):
|
||||||
|
if address == TimerDevice.READ_TIME_OFFSET:
|
||||||
|
val = int(time.clock_gettime_ns(0)/1000) & 0xffffffff
|
||||||
|
self.emulator.write_ptr(TimerDevice.READ_TIME_OFFSET, val)
|
||||||
|
return True
|
||||||
|
|
||||||
|
class EmmcDevice(TegraDevice):
|
||||||
|
BASE = 0x700b0000
|
||||||
|
SIZE = 0x1000
|
||||||
|
NAME = "Emmc"
|
||||||
|
def __init__(self, emulator: "TegraEmulator") -> None:
|
||||||
|
super().__init__(emulator)
|
||||||
|
|
||||||
|
class CryptoDevice(TegraDevice):
|
||||||
|
BASE = 0x70012000
|
||||||
|
SIZE = 0x1000
|
||||||
|
NAME = "Crypto"
|
||||||
|
def __init__(self, emulator: "TegraEmulator") -> None:
|
||||||
|
super().__init__(emulator)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TegraEmulator(ARM_Emulator):
|
||||||
|
def __init__(self, hw_itm=True, init_uc=True) -> None:
|
||||||
super().__init__(init_uc)
|
super().__init__(init_uc)
|
||||||
self.log_hw_access = True
|
self.log_hw_access = True
|
||||||
|
self.hw_itm = hw_itm
|
||||||
self.saved_blocks = {}
|
self.saved_blocks = {}
|
||||||
try:
|
try:
|
||||||
self.ghidra = GhidraAssistant()
|
self.ghidra = GhidraAssistant()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def setup(self):
|
def setup(self, target="bootrom"):
|
||||||
|
self.target = target
|
||||||
self.setup_memory()
|
self.setup_memory()
|
||||||
self.setup_registers()
|
self.setup_registers()
|
||||||
|
if not self.hw_itm:
|
||||||
|
self.setup_devices()
|
||||||
self.setup_hooks()
|
self.setup_hooks()
|
||||||
self.apply_patches()
|
self.apply_patches()
|
||||||
|
|
||||||
@ -49,77 +150,199 @@ class PartialEmu(ARM_Emulator):
|
|||||||
self.uc.mem_write(0x100000, self.bootrom)
|
self.uc.mem_write(0x100000, self.bootrom)
|
||||||
|
|
||||||
# map IMEM
|
# map IMEM
|
||||||
self.imem_path = pathlib.Path("imem3_bct")
|
|
||||||
self.imem = self.imem_path.read_bytes()
|
|
||||||
self.uc.mem_map(0x40000000, 0x40000, UC_PROT_EXEC | UC_PROT_READ | UC_PROT_WRITE)
|
self.uc.mem_map(0x40000000, 0x40000, UC_PROT_EXEC | UC_PROT_READ | UC_PROT_WRITE)
|
||||||
self.uc.mem_write(0x40000000, self.imem)
|
if self.target == "bootrom":
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self.imem_path = pathlib.Path("imem3_bct")
|
||||||
|
self.imem = self.imem_path.read_bytes()
|
||||||
|
self.uc.mem_write(0x40000000, self.imem)
|
||||||
|
|
||||||
# DRAM
|
# DRAM
|
||||||
DRAM_BASE = 0x80000000
|
DRAM_BASE = 0x80000000
|
||||||
DRAM_SIZE = 2 * GB
|
DRAM_SIZE = 2 * GB
|
||||||
self.uc.mem_map(DRAM_BASE, DRAM_SIZE, UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC)
|
self.uc.mem_map(DRAM_BASE, DRAM_SIZE, UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC)
|
||||||
|
|
||||||
def setup_registers(self):
|
def setup_registers(self, target="bootrom"):
|
||||||
self.sp = 0x4000d000
|
if self.target == "bootrom":
|
||||||
self.pc = 0x4000e000
|
self.pc = 0x100000 | 1
|
||||||
self.is_thumb = False
|
self.sp = 0x4000d000
|
||||||
|
self.is_thumb = True
|
||||||
|
else:
|
||||||
|
self.sp = 0x4000d000
|
||||||
|
self.pc = 0x4000e000
|
||||||
|
self.is_thumb = False
|
||||||
|
|
||||||
|
def setup_devices(self):
|
||||||
|
self.devices = {}
|
||||||
|
self.devices['fuse'] = FuseDevice(self)
|
||||||
|
self.devices['timer'] = TimerDevice(self)
|
||||||
|
self.devices['emmc'] = EmmcDevice(self)
|
||||||
|
self.devices['crypto'] = CryptoDevice(self)
|
||||||
|
self.devices['tegra'] = TegraDevice(self) # For all other devices
|
||||||
|
|
||||||
def hook_unmapped(self, uc, access, address, size, value, user_data):
|
def hook_unmapped(self, uc, access, address, size, value, user_data):
|
||||||
print(f"Unmapped memory access at 0x{address:x} with size {size} and access {acces_str[access]}")
|
print(f"Unmapped memory access at 0x{address:x} with size {size} and access {acces_str[access]}")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def hook_mem_access(self, uc, access, address, size, value, user_data):
|
||||||
|
# Hook all memory accesses
|
||||||
|
# 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]}")
|
||||||
|
|
||||||
def hook_hw_access(self, uc, access, address, size, value, user_data):
|
# Try and keep memory in sync with target device
|
||||||
if self.log_hw_access:
|
|
||||||
p_info(f"{hex(self.pc)} HW access at 0x{address:x} with size {size} and access {acces_str[access]}")
|
if access == UC_MEM_WRITE:
|
||||||
|
self.debugger.memwrite_region(address, self.uc.mem_read(address, size))
|
||||||
|
if access == UC_MEM_READ:
|
||||||
|
self.uc.mem_write(address, self.debugger.memdump_region(address, size))
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
def hw_itm_handle(self, access, address, size, value):
|
||||||
# All unmapped memory is send to the debugger
|
# All unmapped memory is send to the debugger
|
||||||
|
if self.log_hw_access:
|
||||||
|
if access == UC_MEM_READ:
|
||||||
|
val = self.debugger.memdump_region(address, size)
|
||||||
|
if len(val) == 4:
|
||||||
|
val = struct.unpack("<I", val)[0]
|
||||||
|
elif len(val) == 1:
|
||||||
|
val = struct.unpack("<B", val)[0]
|
||||||
|
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)}")
|
||||||
try:
|
try:
|
||||||
|
if address == 0x70012800:
|
||||||
|
# self.ghidra.ghidra.set_background_color(self.saved_blocks)
|
||||||
|
sys.exit(0)
|
||||||
|
pass
|
||||||
if access == UC_MEM_WRITE:
|
if access == UC_MEM_WRITE:
|
||||||
if size == 4:
|
if size == 4:
|
||||||
self.debugger.memwrite_region(address, p32(value))
|
self.debugger.memwrite_region(address, p32(value))
|
||||||
self.uc.mem_write(address, p32(value))
|
# self.uc.mem_write(address, p32(value))
|
||||||
# self.uc.mem_write(address, self.debugger.memdump_region(address, size))
|
# self.uc.mem_write(address, self.debugger.memdump_region(address, size))
|
||||||
elif size == 1:
|
elif size == 1:
|
||||||
self.debugger.memwrite_region(address, p8(value))
|
self.debugger.memwrite_io(address, p8(value))
|
||||||
self.uc.mem_write(address, p8(value))
|
# self.uc.mem_write(address, p8(value))
|
||||||
# self.uc.mem_write(address, self.debugger.memdump_region(address, size))
|
# self.uc.mem_write(address, self.debugger.memdump_region(address, size))
|
||||||
else:
|
else:
|
||||||
raise Exception("Unhandled write!")
|
raise Exception("Unhandled write!")
|
||||||
elif access == UC_MEM_READ:
|
elif access == UC_MEM_READ:
|
||||||
uc.mem_write(address, self.debugger.memdump_region(address, size))
|
if size == 1:
|
||||||
|
pass
|
||||||
|
self.uc.mem_write(address, self.debugger.memdump_region(address, size))
|
||||||
else:
|
else:
|
||||||
raise Exception("Not handled!")
|
raise Exception("Not handled!")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
sys.exit(0)
|
||||||
pass
|
pass
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def get_device_at(self, address):
|
||||||
|
for devname in self.devices:
|
||||||
|
dev = self.devices[devname]
|
||||||
|
if address >= dev.BASE and address < dev.BASE + dev.SIZE:
|
||||||
|
return dev
|
||||||
|
return self.devices['tegra']
|
||||||
|
# raise Exception(f"No device found at address {hex(address)} pc={hex(sef.pc)}")
|
||||||
|
|
||||||
|
def hw_emulation_handle(self, access, address, size, value):
|
||||||
|
dev = self.get_device_at(address)
|
||||||
|
print(f"Device={dev.NAME} pc={hex(self.pc)} target=0x{address:x} size={size} access={acces_str[access]}")
|
||||||
|
if access == UC_MEM_READ:
|
||||||
|
dev.read(address, size)
|
||||||
|
elif access == UC_MEM_WRITE:
|
||||||
|
dev.write(address, value)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def hook_hw_access(self, uc, access, address, size, value, user_data):
|
||||||
|
if self.hw_itm:
|
||||||
|
return self.hw_itm_handle(access, address, size, value)
|
||||||
|
|
||||||
|
return self.hw_emulation_handle(access, address, size, value)
|
||||||
|
|
||||||
def setup_hooks(self):
|
def setup_hooks(self):
|
||||||
# hook unmapped
|
# hook unmapped
|
||||||
self.uc.hook_add(UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_FETCH_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_UNMAPPED, self.hook_unmapped)
|
self.uc.hook_add(UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_FETCH_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_UNMAPPED, self.hook_unmapped)
|
||||||
|
|
||||||
# 0x6000f000
|
# 0x6000f000
|
||||||
self.uc.mem_map(0x60000000, 0x10000, UC_PROT_READ | UC_PROT_WRITE)
|
self.uc.mem_map(0x60000000, 0x20000, UC_PROT_READ | UC_PROT_WRITE)
|
||||||
self.uc.hook_add(UC_HOOK_MEM_READ | UC_HOOK_MEM_WRITE, self.hook_hw_access, begin=0x60000000, end=0x60000000 + 0x10000)
|
self.uc.hook_add(UC_HOOK_MEM_READ | UC_HOOK_MEM_WRITE, self.hook_hw_access, begin=0x60000000, end=0x60000000 + 0x10000)
|
||||||
|
|
||||||
self.uc.mem_map(0x70000000, 0x100000, UC_PROT_READ | UC_PROT_WRITE)
|
self.uc.mem_map(0x70000000, 0x100000, UC_PROT_READ | UC_PROT_WRITE)
|
||||||
self.uc.hook_add(UC_HOOK_MEM_READ | UC_HOOK_MEM_WRITE, self.hook_hw_access, begin=0x70000000, end=0x70000000 + 0x100000)
|
self.uc.hook_add(UC_HOOK_MEM_READ | UC_HOOK_MEM_WRITE, self.hook_hw_access, begin=0x70000000, end=0x70000000 + 0x100000)
|
||||||
|
|
||||||
self.setup_log_hook()
|
|
||||||
self.setup_hook_blocks()
|
#ROM
|
||||||
|
# self.uc.hook_add(UC_HOOK_MEM_READ | UC_HOOK_MEM_WRITE, self.hook_mem_access, self, 0x100000, 0x100000 + len(self.bootrom))
|
||||||
|
#IMEM access
|
||||||
|
# self.uc.hook_add(UC_HOOK_MEM_READ | UC_HOOK_MEM_WRITE, self.hook_mem_access, self, 0x40000000, 0x40000000 + 0x40000)
|
||||||
|
# DRAM
|
||||||
|
# self.uc.hook_add(UC_HOOK_MEM_READ | UC_HOOK_MEM_WRITE, self.hook_mem_access, self, 0x80000000, 0x80000000 + 2 * GB)
|
||||||
|
if self.target == "bootrom":
|
||||||
|
self.setup_warmboot_hook()
|
||||||
|
self.setup_hook_blocks()
|
||||||
|
self.setup_rcm_hooks()
|
||||||
|
else:
|
||||||
|
self.setup_log_hook()
|
||||||
|
self.setup_hook_blocks()
|
||||||
# self.setup_hook_EmmcValidateResponse()
|
# self.setup_hook_EmmcValidateResponse()
|
||||||
|
|
||||||
|
def setup_coldboot_hook(self):
|
||||||
|
def hook_coldboot(uc, address, size, user_data):
|
||||||
|
logging.info(f"Reached coldboot target.")
|
||||||
|
self.print_ctx()
|
||||||
|
return True
|
||||||
|
self.uc.hook_add(UC_HOOK_CODE, hook_coldboot, begin=0x0010145e, end=0x0010145e + 1)
|
||||||
|
|
||||||
|
def setup_rcm_hooks(self):
|
||||||
|
def hook_rcm(uc, address, size, user_data):
|
||||||
|
self.R0 = 0
|
||||||
|
self.R1 = 0
|
||||||
|
return True
|
||||||
|
self.uc.hook_add(UC_HOOK_CODE, hook_rcm, begin=0x00101414, end=0x00101414 + 1)
|
||||||
|
|
||||||
|
def setup_warmboot_hook(self):
|
||||||
|
def hook_warmboot(uc, address, size, user_data):
|
||||||
|
logging.info(f"Hooking warmboot, forcing coldboot.")
|
||||||
|
self.R0 = 0
|
||||||
|
return True
|
||||||
|
self.uc.hook_add(UC_HOOK_CODE, hook_warmboot, begin=0x00101f3a, end=0x00101f3a + 1)
|
||||||
|
|
||||||
def apply_patches(self):
|
def apply_patches(self):
|
||||||
|
|
||||||
# Nop out 400101f0 to 0x40010220, maybe this is restricting access to IMEM and ROM?
|
# 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.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))
|
# self.uc.mem_write(0x400101e4, self.sc.mov_0_r0 * ((0x40010220 - 0x400101e4) // 4))
|
||||||
|
|
||||||
# Patch EMMCVerifyResponse
|
# Patch EMMCVerifyResponse
|
||||||
self.sc.bx_lr = self.ks.asm("bx lr", as_bytes=True)[0]
|
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)
|
# 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)
|
||||||
|
|
||||||
|
#usb init?
|
||||||
|
self.uc.mem_write(0x00103bf4, bx_lr_thumb)
|
||||||
|
|
||||||
|
#SE engine always ready
|
||||||
|
# self.uc.mem_write(0x00102b24, movs_0_r0_thumb)
|
||||||
|
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
try:
|
try:
|
||||||
self.uc.emu_start(self.pc, 0)
|
self.uc.emu_start(self.pc, 0)
|
||||||
|
pass
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(str(e))
|
print(str(e))
|
||||||
self.print_ctx(print)
|
self.print_ctx(print)
|
||||||
@ -173,12 +396,19 @@ class PartialEmu(ARM_Emulator):
|
|||||||
# And patch function to just return
|
# And patch function to just return
|
||||||
self.uc.mem_write(UART_LOG_HOOK, self.ks.asm("bx lr", as_bytes=True)[0])
|
self.uc.mem_write(UART_LOG_HOOK, self.ks.asm("bx lr", as_bytes=True)[0])
|
||||||
|
|
||||||
def setup_hook_blocks(self):
|
def setup_hook_blocks(self, only_blocks=False):
|
||||||
def hook_block(uc, address, size, user_data):
|
if only_blocks:
|
||||||
# print(f"Block at {hex(self.LR)}")
|
def hook_block(uc, address, size, user_data):
|
||||||
self.saved_blocks[self.LR] = self.get_registers()
|
# print(f"Block at {hex(self.LR)}")
|
||||||
return True
|
self.saved_blocks[self.LR] = self.get_registers()
|
||||||
self.uc.hook_add(UC_HOOK_BLOCK, hook_block)
|
return True
|
||||||
|
self.uc.hook_add(UC_HOOK_BLOCK, hook_block)
|
||||||
|
else:
|
||||||
|
def hook_all(uc, address, size, user_data):
|
||||||
|
# print(f"Block at {hex(self.LR)}")
|
||||||
|
self.saved_blocks[self.pc] = self.get_registers()
|
||||||
|
return True
|
||||||
|
self.uc.hook_add(UC_HOOK_CODE, hook_all, self)
|
||||||
|
|
||||||
def setup_interrupt_hook(self):
|
def setup_interrupt_hook(self):
|
||||||
RAISE_INTERRUPT = 0x4001cab8
|
RAISE_INTERRUPT = 0x4001cab8
|
||||||
@ -196,8 +426,14 @@ class PartialEmu(ARM_Emulator):
|
|||||||
|
|
||||||
self.uc.hook_add(UC_HOOK_CODE, hook_emmc, begin=0x4001dfb0, end=0x4001e160)
|
self.uc.hook_add(UC_HOOK_CODE, hook_emmc, begin=0x4001dfb0, end=0x4001e160)
|
||||||
|
|
||||||
def do_partial_emu(debugger : ConcreteDevice):
|
def do_partial_emu(debugger : ConcreteDevice, real_hw=True):
|
||||||
emu = PartialEmu()
|
if real_hw:
|
||||||
emu.install_debugger(debugger)
|
emu = TegraEmulator()
|
||||||
emu.setup()
|
emu.install_debugger(debugger)
|
||||||
emu.run()
|
else:
|
||||||
|
emu = TegraEmulator(hw_itm=False)
|
||||||
|
emu.setup(target="bootrom")
|
||||||
|
emu.run()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
do_partial_emu(None, real_hw=False)
|
@ -9,8 +9,8 @@ ghidra_assistant/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
|
|||||||
ghidra_assistant/__pycache__/__init__.cpython-310.pyc,,
|
ghidra_assistant/__pycache__/__init__.cpython-310.pyc,,
|
||||||
ghidra_assistant/__pycache__/concrete_device.cpython-310.pyc,,
|
ghidra_assistant/__pycache__/concrete_device.cpython-310.pyc,,
|
||||||
ghidra_assistant/__pycache__/ghidra_assistant.cpython-310.pyc,,
|
ghidra_assistant/__pycache__/ghidra_assistant.cpython-310.pyc,,
|
||||||
ghidra_assistant/concrete_device.py,sha256=llVfmejKwBl8lohEhcpTeKvepguJ0dhUKGlZQL2wV0Y,8228
|
ghidra_assistant/concrete_device.py,sha256=MF6X-DZpPN9UhZzmrXUyM_GbGdJKQVziNAJ9RjOzyLI,8418
|
||||||
ghidra_assistant/ghidra_assistant.py,sha256=CYJw9zTDB6QdXes0oebg2HRjIDdEc_SwqVdBY7iJQpY,497
|
ghidra_assistant/ghidra_assistant.py,sha256=tlpbxh9-V29IVN_tBiE6hOc7nuWa9zZt-z1AwGZpRD8,728
|
||||||
ghidra_assistant/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
ghidra_assistant/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||||
ghidra_assistant/utils/__pycache__/__init__.cpython-310.pyc,,
|
ghidra_assistant/utils/__pycache__/__init__.cpython-310.pyc,,
|
||||||
ghidra_assistant/utils/__pycache__/bit_helper.cpython-310.pyc,,
|
ghidra_assistant/utils/__pycache__/bit_helper.cpython-310.pyc,,
|
||||||
@ -22,12 +22,12 @@ ghidra_assistant/utils/archs/__pycache__/asm_utils.cpython-310.pyc,,
|
|||||||
ghidra_assistant/utils/archs/arm/__pycache__/armT_processor_state.cpython-310.pyc,,
|
ghidra_assistant/utils/archs/arm/__pycache__/armT_processor_state.cpython-310.pyc,,
|
||||||
ghidra_assistant/utils/archs/arm/__pycache__/arm_emulator.cpython-310.pyc,,
|
ghidra_assistant/utils/archs/arm/__pycache__/arm_emulator.cpython-310.pyc,,
|
||||||
ghidra_assistant/utils/archs/arm/armT_processor_state.py,sha256=ZdsI6Q9mLv-YZEmJSEwKUmsh7903--nfa-dlhfi8QtQ,9466
|
ghidra_assistant/utils/archs/arm/armT_processor_state.py,sha256=ZdsI6Q9mLv-YZEmJSEwKUmsh7903--nfa-dlhfi8QtQ,9466
|
||||||
ghidra_assistant/utils/archs/arm/arm_emulator.py,sha256=Wq7Tyiph3KYmvmMnRG8dl4TFKJEeNP8dtDrm_XpBLew,7798
|
ghidra_assistant/utils/archs/arm/arm_emulator.py,sha256=dL86jwUMYON5Ry_OcDPDjvEYp4LYCZcadW3yiiG26fk,7841
|
||||||
ghidra_assistant/utils/archs/arm64/__pycache__/arm64_emulator.cpython-310.pyc,,
|
ghidra_assistant/utils/archs/arm64/__pycache__/arm64_emulator.cpython-310.pyc,,
|
||||||
ghidra_assistant/utils/archs/arm64/__pycache__/arm64_processor_state.cpython-310.pyc,,
|
ghidra_assistant/utils/archs/arm64/__pycache__/arm64_processor_state.cpython-310.pyc,,
|
||||||
ghidra_assistant/utils/archs/arm64/__pycache__/asm_arm64.cpython-310.pyc,,
|
ghidra_assistant/utils/archs/arm64/__pycache__/asm_arm64.cpython-310.pyc,,
|
||||||
ghidra_assistant/utils/archs/arm64/__pycache__/uc_emulator.cpython-310.pyc,,
|
ghidra_assistant/utils/archs/arm64/__pycache__/uc_emulator.cpython-310.pyc,,
|
||||||
ghidra_assistant/utils/archs/arm64/arm64_emulator.py,sha256=MtAM0DjxagGJZfN5SQuzKJ2tf7kqcYs4r_9a07pZg9o,17044
|
ghidra_assistant/utils/archs/arm64/arm64_emulator.py,sha256=h19lNQvT9RSHeN4MrUagqq7coo0tbTHzlofsNtAFcmI,16964
|
||||||
ghidra_assistant/utils/archs/arm64/arm64_processor_state.py,sha256=GqKoqwbCDhznJEbIgefvlsTcn6ensMD-q70bQMWsgvo,17633
|
ghidra_assistant/utils/archs/arm64/arm64_processor_state.py,sha256=GqKoqwbCDhznJEbIgefvlsTcn6ensMD-q70bQMWsgvo,17633
|
||||||
ghidra_assistant/utils/archs/arm64/asm_arm64.py,sha256=k96Xp7hEhQWD6lbbmT2bAKuwJCz5VDRF6gx2koMuDW8,2562
|
ghidra_assistant/utils/archs/arm64/asm_arm64.py,sha256=k96Xp7hEhQWD6lbbmT2bAKuwJCz5VDRF6gx2koMuDW8,2562
|
||||||
ghidra_assistant/utils/archs/arm64/misc/MMU/__pycache__/arm64_mmu.cpython-310.pyc,,
|
ghidra_assistant/utils/archs/arm64/misc/MMU/__pycache__/arm64_mmu.cpython-310.pyc,,
|
||||||
@ -60,13 +60,13 @@ ghidra_assistant/utils/debugger/debugger_archs/__pycache__/ga_arm_thumb.cpython-
|
|||||||
ghidra_assistant/utils/debugger/debugger_archs/base_arch.py,sha256=uzyYUm_xEekk3j8uHx8blaKDbK8VR_gMU-Br8RY0tCs,1244
|
ghidra_assistant/utils/debugger/debugger_archs/base_arch.py,sha256=uzyYUm_xEekk3j8uHx8blaKDbK8VR_gMU-Br8RY0tCs,1244
|
||||||
ghidra_assistant/utils/debugger/debugger_archs/ga_arm.py,sha256=lPecV5UyTBErJgIkfrAa1d3kiH3PN_gaD5zhA4uzU4A,2745
|
ghidra_assistant/utils/debugger/debugger_archs/ga_arm.py,sha256=lPecV5UyTBErJgIkfrAa1d3kiH3PN_gaD5zhA4uzU4A,2745
|
||||||
ghidra_assistant/utils/debugger/debugger_archs/ga_arm64.py,sha256=_195wxctqIBidDfHjSn-bicrsAbOtnhQGta4LgfiOog,9363
|
ghidra_assistant/utils/debugger/debugger_archs/ga_arm64.py,sha256=_195wxctqIBidDfHjSn-bicrsAbOtnhQGta4LgfiOog,9363
|
||||||
ghidra_assistant/utils/debugger/debugger_archs/ga_arm_thumb.py,sha256=tZsQk6hnduZBy6n7g6x7tBhutpTmDk4W1wrNSbSaSsE,4946
|
ghidra_assistant/utils/debugger/debugger_archs/ga_arm_thumb.py,sha256=v8qwn7DsI2Hl38bzzybpfmwhYi82o5i_-8Pva5gtFDw,5339
|
||||||
ghidra_assistant/utils/definitions.py,sha256=tsk4MkEz510JN9-T1ZZExq61uZ32MVPc-0JljHQSde0,3511
|
ghidra_assistant/utils/definitions.py,sha256=tsk4MkEz510JN9-T1ZZExq61uZ32MVPc-0JljHQSde0,3511
|
||||||
ghidra_assistant/utils/ga_client.py,sha256=dQeJdxL8z48WOw0cHf7sNtqlCVS3ZJ9FSTiB5om-ojM,2065
|
ghidra_assistant/utils/ga_client.py,sha256=dQeJdxL8z48WOw0cHf7sNtqlCVS3ZJ9FSTiB5om-ojM,2065
|
||||||
ghidra_assistant/utils/ga_server.py,sha256=gchzEPmEtT8kigVB3Jnnv35nsB2k3_dSrQ5_BD8UgUA,5067
|
ghidra_assistant/utils/ga_server.py,sha256=gchzEPmEtT8kigVB3Jnnv35nsB2k3_dSrQ5_BD8UgUA,5067
|
||||||
ghidra_assistant/utils/ghidra/__pycache__/ghidra_connect.cpython-310.pyc,,
|
ghidra_assistant/utils/ghidra/__pycache__/ghidra_connect.cpython-310.pyc,,
|
||||||
ghidra_assistant/utils/ghidra/__pycache__/pyhidra.cpython-310.pyc,,
|
ghidra_assistant/utils/ghidra/__pycache__/pyhidra.cpython-310.pyc,,
|
||||||
ghidra_assistant/utils/ghidra/ghidra_connect.py,sha256=UUBAzRq4WraqBewi-gH-bXyoAkydBUpVvuVYthNjoUU,13856
|
ghidra_assistant/utils/ghidra/ghidra_connect.py,sha256=69JunNjWcNc4uBLw5u3S0KAzBY9yeF_QQjvnTdI2Fwg,15506
|
||||||
ghidra_assistant/utils/ghidra/pyhidra.py,sha256=amdhJcj4Fw3INuAqtIl7DfXNTtTwzPmj2FnyM0sNOFY,412
|
ghidra_assistant/utils/ghidra/pyhidra.py,sha256=amdhJcj4Fw3INuAqtIl7DfXNTtTwzPmj2FnyM0sNOFY,412
|
||||||
ghidra_assistant/utils/utils.py,sha256=Ij9FiQsuCWAA8iIWt_3aO46E5K4e5zqaA7DCeqB7sk0,7372
|
ghidra_assistant/utils/utils.py,sha256=Ij9FiQsuCWAA8iIWt_3aO46E5K4e5zqaA7DCeqB7sk0,7372
|
||||||
ghidra_assistant/venv/bin/__pycache__/rst2html.cpython-310.pyc,,
|
ghidra_assistant/venv/bin/__pycache__/rst2html.cpython-310.pyc,,
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -111,6 +111,12 @@ class ConcreteDevice():
|
|||||||
Sync processor state from memory region to registers on device.
|
Sync processor state from memory region to registers on device.
|
||||||
'''
|
'''
|
||||||
raise NotImplemented
|
raise NotImplemented
|
||||||
|
|
||||||
|
def memwrite_io(self, address, data):
|
||||||
|
'''
|
||||||
|
Write some data byte by byte
|
||||||
|
'''
|
||||||
|
raise NotImplemented
|
||||||
|
|
||||||
def memdump_region(self, offset, size):
|
def memdump_region(self, offset, size):
|
||||||
'''
|
'''
|
||||||
@ -194,6 +200,7 @@ class ConcreteDevice():
|
|||||||
self.read = self.arch_dbg.read
|
self.read = self.arch_dbg.read
|
||||||
self.write = self.arch_dbg.write
|
self.write = self.arch_dbg.write
|
||||||
self.memdump_region = self.arch_dbg.memdump_region
|
self.memdump_region = self.arch_dbg.memdump_region
|
||||||
|
self.memwrite_io = self.arch_dbg.memwrite_io
|
||||||
# self.memdump_region_small = self.arch_dbg.memdump_region_small
|
# self.memdump_region_small = self.arch_dbg.memdump_region_small
|
||||||
self.memwrite_region = self.arch_dbg.memwrite_region
|
self.memwrite_region = self.arch_dbg.memwrite_region
|
||||||
self.get_debugger_location = self.arch_dbg.get_debugger_location
|
self.get_debugger_location = self.arch_dbg.get_debugger_location
|
||||||
|
@ -17,6 +17,12 @@ def main():
|
|||||||
'''
|
'''
|
||||||
info("Running tests")
|
info("Running tests")
|
||||||
ga = GhidraAssistant()
|
ga = GhidraAssistant()
|
||||||
|
|
||||||
|
# Test colouring lines
|
||||||
|
# Generate a list of fake PC values from 0x4001ed94 to 0x4001ed94 + 0x1000
|
||||||
|
pc_values = [0x4001ed94 + i for i in range(0, 0x1000, 4)]
|
||||||
|
ga.ghidra.set_background_color(pc_values, "red")
|
||||||
|
|
||||||
dat = ga.ghidra.get_ghidra_memory_maps()
|
dat = ga.ghidra.get_ghidra_memory_maps()
|
||||||
|
|
||||||
# Test concrete device
|
# Test concrete device
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -8,6 +8,7 @@ from ...utils import *
|
|||||||
class ARM_Emulator:
|
class ARM_Emulator:
|
||||||
'''
|
'''
|
||||||
Class that will interact with the unicorn engine for emulating ARM code.
|
Class that will interact with the unicorn engine for emulating ARM code.
|
||||||
|
Supports both ARM and Thumb modes.
|
||||||
'''
|
'''
|
||||||
def __init__(self, init_uc = True):
|
def __init__(self, init_uc = True):
|
||||||
if init_uc:
|
if init_uc:
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -22,7 +22,7 @@ class ARM64UC_Emulator():
|
|||||||
|
|
||||||
def setup_shellcode(self):
|
def setup_shellcode(self):
|
||||||
self.sc = ShellcodeCrafter(self.ks, self.cs)
|
self.sc = ShellcodeCrafter(self.ks, self.cs)
|
||||||
|
|
||||||
def get_mapping(self, address):
|
def get_mapping(self, address):
|
||||||
for mem in self.uc.mem_regions():
|
for mem in self.uc.mem_regions():
|
||||||
if address >= mem[0] and address < mem[1]:
|
if address >= mem[0] and address < mem[1]:
|
||||||
@ -33,7 +33,7 @@ class ARM64UC_Emulator():
|
|||||||
if self.get_mapping(address) != None:
|
if self.get_mapping(address) != None:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def read_string(self, at):
|
def read_string(self, at):
|
||||||
if at == 0:
|
if at == 0:
|
||||||
return b''
|
return b''
|
||||||
@ -45,13 +45,13 @@ class ARM64UC_Emulator():
|
|||||||
return s
|
return s
|
||||||
s += b
|
s += b
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def write_ptr(self, at, ptr):
|
def write_ptr(self, at, ptr):
|
||||||
return self.uc.mem_write(at, p32(ptr))
|
return self.uc.mem_write(at, p32(ptr))
|
||||||
|
|
||||||
def read_ptr(self, at):
|
def read_ptr(self, at):
|
||||||
return u32(self.uc.mem_read(at, 4))
|
return u32(self.uc.mem_read(at, 4))
|
||||||
|
|
||||||
def add_breakpoint(self, at, target_fun):
|
def add_breakpoint(self, at, target_fun):
|
||||||
self.uc.hook_add(UC_HOOK_CODE, target_fun, None, at, at + 1)
|
self.uc.hook_add(UC_HOOK_CODE, target_fun, None, at, at + 1)
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ class ARM64UC_Emulator():
|
|||||||
@sp.setter
|
@sp.setter
|
||||||
def sp(self, value):
|
def sp(self, value):
|
||||||
self.uc.reg_write(UC_ARM64_REG_SP, value)
|
self.uc.reg_write(UC_ARM64_REG_SP, value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def lr(self):
|
def lr(self):
|
||||||
return self.uc.reg_read(UC_ARM64_REG_LR)
|
return self.uc.reg_read(UC_ARM64_REG_LR)
|
||||||
@ -114,7 +114,7 @@ class ARM64UC_Emulator():
|
|||||||
@lr.setter
|
@lr.setter
|
||||||
def lr(self, value):
|
def lr(self, value):
|
||||||
self.uc.reg_write(UC_ARM64_REG_LR, value)
|
self.uc.reg_write(UC_ARM64_REG_LR, value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def vbar_el1(self):
|
def vbar_el1(self):
|
||||||
return self.uc.reg_read(UC_ARM64_REG_VBAR_EL1)
|
return self.uc.reg_read(UC_ARM64_REG_VBAR_EL1)
|
||||||
@ -122,7 +122,7 @@ class ARM64UC_Emulator():
|
|||||||
@vbar_el1.setter
|
@vbar_el1.setter
|
||||||
def vbar_el1(self, value):
|
def vbar_el1(self, value):
|
||||||
self.uc.reg_write(UC_ARM64_REG_VBAR_EL1, value)
|
self.uc.reg_write(UC_ARM64_REG_VBAR_EL1, value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def vbar_el2(self):
|
def vbar_el2(self):
|
||||||
return self.uc.reg_read(UC_ARM64_REG_VBAR_EL2)
|
return self.uc.reg_read(UC_ARM64_REG_VBAR_EL2)
|
||||||
@ -130,7 +130,7 @@ class ARM64UC_Emulator():
|
|||||||
@vbar_el2.setter
|
@vbar_el2.setter
|
||||||
def vbar_el2(self, value):
|
def vbar_el2(self, value):
|
||||||
self.uc.reg_write(UC_ARM64_REG_VBAR_EL2, value)
|
self.uc.reg_write(UC_ARM64_REG_VBAR_EL2, value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def vbar_el3(self):
|
def vbar_el3(self):
|
||||||
return self.uc.reg_read(UC_ARM64_REG_VBAR_EL3)
|
return self.uc.reg_read(UC_ARM64_REG_VBAR_EL3)
|
||||||
@ -138,7 +138,7 @@ class ARM64UC_Emulator():
|
|||||||
@vbar_el3.setter
|
@vbar_el3.setter
|
||||||
def vbar_el3(self, value):
|
def vbar_el3(self, value):
|
||||||
self.uc.reg_write(UC_ARM64_REG_VBAR_EL3, value)
|
self.uc.reg_write(UC_ARM64_REG_VBAR_EL3, value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def elr_el0(self):
|
def elr_el0(self):
|
||||||
return self.uc.reg_read(UC_ARM64_REG_ELR_EL0)
|
return self.uc.reg_read(UC_ARM64_REG_ELR_EL0)
|
||||||
@ -146,7 +146,7 @@ class ARM64UC_Emulator():
|
|||||||
@elr_el0.setter
|
@elr_el0.setter
|
||||||
def elr_el0(self, value):
|
def elr_el0(self, value):
|
||||||
self.uc.reg_write(UC_ARM64_REG_ELR_EL0, value)
|
self.uc.reg_write(UC_ARM64_REG_ELR_EL0, value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def elr_el1(self):
|
def elr_el1(self):
|
||||||
return self.uc.reg_read(UC_ARM64_REG_ELR_EL1)
|
return self.uc.reg_read(UC_ARM64_REG_ELR_EL1)
|
||||||
@ -154,7 +154,7 @@ class ARM64UC_Emulator():
|
|||||||
@elr_el1.setter
|
@elr_el1.setter
|
||||||
def elr_el1(self, value):
|
def elr_el1(self, value):
|
||||||
self.uc.reg_write(UC_ARM64_REG_ELR_EL1, value)
|
self.uc.reg_write(UC_ARM64_REG_ELR_EL1, value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def elr_el2(self):
|
def elr_el2(self):
|
||||||
return self.uc.reg_read(UC_ARM64_REG_ELR_EL2)
|
return self.uc.reg_read(UC_ARM64_REG_ELR_EL2)
|
||||||
@ -162,7 +162,7 @@ class ARM64UC_Emulator():
|
|||||||
@elr_el2.setter
|
@elr_el2.setter
|
||||||
def elr_el2(self, value):
|
def elr_el2(self, value):
|
||||||
self.uc.reg_write(UC_ARM64_REG_ELR_EL2, value)
|
self.uc.reg_write(UC_ARM64_REG_ELR_EL2, value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def elr_el3(self):
|
def elr_el3(self):
|
||||||
return self.uc.reg_read(UC_ARM64_REG_ELR_EL3)
|
return self.uc.reg_read(UC_ARM64_REG_ELR_EL3)
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -10,6 +10,15 @@ class GA_arm_thumb_debugger(BaseArch_debugger):
|
|||||||
self.ks = Ks(KS_MODE_ARM, KS_MODE_THUMB)
|
self.ks = Ks(KS_MODE_ARM, KS_MODE_THUMB)
|
||||||
self.sc = ShellcodeCrafterARMThumb(self.ks, self.cs)
|
self.sc = ShellcodeCrafterARMThumb(self.ks, self.cs)
|
||||||
self.state = ARMThumb_Concrete_State(storage_addr, self)
|
self.state = ARMThumb_Concrete_State(storage_addr, self)
|
||||||
|
|
||||||
|
def memwrite_io(self, address, data):
|
||||||
|
assert len(data) < (0x20 - 12), "Data length is too long for IO write"
|
||||||
|
self.write("HWIO")
|
||||||
|
packet = struct.pack('<III', address, 0, len(data)) + data
|
||||||
|
# fill the block up to 0x20 bytes
|
||||||
|
packet += b"\x00" * (0x20 - len(packet))
|
||||||
|
self.write(packet)
|
||||||
|
self.read(DEBUGGER_BLOCKSIZE_TRANSMISSION)
|
||||||
|
|
||||||
def memdump_region(self, offset, size):
|
def memdump_region(self, offset, size):
|
||||||
'''
|
'''
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -109,14 +109,25 @@ class Ghidra:
|
|||||||
def _jaddr(self, addr):
|
def _jaddr(self, addr):
|
||||||
# The string that's fed to getAddress NEEDS to be hex for some godawful reason
|
# The string that's fed to getAddress NEEDS to be hex for some godawful reason
|
||||||
return self.address_factory.getAddress(hex(addr))
|
return self.address_factory.getAddress(hex(addr))
|
||||||
|
|
||||||
|
def _jbytes(self, dat):
|
||||||
|
return bytes(dat)
|
||||||
|
|
||||||
|
def startTransaction(self, name):
|
||||||
|
self.stopTransaction()
|
||||||
|
self.transaction = currentProgram.startTransaction(f"Coloring lines")
|
||||||
|
|
||||||
|
def stopTransaction(self):
|
||||||
|
if hasattr(self, "transaction"):
|
||||||
|
currentProgram.endTransaction(self.transaction, True)
|
||||||
|
|
||||||
def set_background_color(self, addresses):
|
def set_background_color(self, addresses, color="java.awt.Color.YELLOW"):
|
||||||
'''
|
'''
|
||||||
Highlight a list of addresses
|
Highlight a list of addresses
|
||||||
'''
|
'''
|
||||||
tr = currentProgram.startTransaction(f"Coloring lines")
|
tr = currentProgram.startTransaction(f"Coloring lines")
|
||||||
d = self.bridge.remote_eval("[currentProgram.getAddressFactory().getAddress(addr) for addr in addresses]", addresses=[hex(addr) for addr in addresses])
|
d = self.bridge.remote_eval("[currentProgram.getAddressFactory().getAddress(addr) for addr in addresses]", addresses=[hex(addr) for addr in addresses])
|
||||||
self.bridge.remote_eval("[setBackgroundColor(addr, java.awt.Color.YELLOW) for addr in d]", d=d)
|
self.bridge.remote_eval(f"[setBackgroundColor(addr, {color}) for addr in d]", d=d)
|
||||||
currentProgram.endTransaction(tr, True)
|
currentProgram.endTransaction(tr, True)
|
||||||
|
|
||||||
def clear_background_color(self):
|
def clear_background_color(self):
|
||||||
@ -264,6 +275,36 @@ class Ghidra:
|
|||||||
#name: unicode, start: ghidra.program.model.address.Address, fileBytes: ghidra.program.database.mem.FileBytes, offset: long, size: long, overlay: bool) -> ghidra.program.model.mem.MemoryBlock:
|
#name: unicode, start: ghidra.program.model.address.Address, fileBytes: ghidra.program.database.mem.FileBytes, offset: long, size: long, overlay: bool) -> ghidra.program.model.mem.MemoryBlock:
|
||||||
self.memory.setBytes(toAddr(start), bytes(data))
|
self.memory.setBytes(toAddr(start), bytes(data))
|
||||||
currentProgram.endTransaction(tr, True)
|
currentProgram.endTransaction(tr, True)
|
||||||
|
|
||||||
|
def mmap_region(self, addr, name, size, read=True, write=True, execute=False):
|
||||||
|
tr = currentProgram.startTransaction(f"Mapping memory region {name} at {hex(addr)}")
|
||||||
|
self.memory.createInitializedBlock(name, toAddr(addr), size, 0, monitor, False)
|
||||||
|
block = self.memory.getBlock(toAddr(hex(addr)))
|
||||||
|
block.setPermissions(read, write, execute)
|
||||||
|
currentProgram.endTransaction(tr, True)
|
||||||
|
|
||||||
|
def write_mem(self, addr, data):
|
||||||
|
'''
|
||||||
|
write data to memory, if region is available
|
||||||
|
'''
|
||||||
|
# check if address is in a block
|
||||||
|
block = self.get_memory_block(addr)
|
||||||
|
if block is None:
|
||||||
|
warn(f"Address {hex(addr)} is not in a block")
|
||||||
|
return
|
||||||
|
# check if len(data) is too big
|
||||||
|
if len(data) > block.getSize():
|
||||||
|
warn(f"Data is too big for block {block.name}")
|
||||||
|
return
|
||||||
|
tr = currentProgram.startTransaction(f"Writing memory at {hex(addr)}")
|
||||||
|
self.memory.setBytes(toAddr(addr), bytes(data))
|
||||||
|
currentProgram.endTransaction(tr, True)
|
||||||
|
|
||||||
|
def get_memory_block(self, addr):
|
||||||
|
for block in self.memory.getBlocks():
|
||||||
|
if block.contains(toAddr(hex(addr))):
|
||||||
|
return block
|
||||||
|
return None
|
||||||
|
|
||||||
def get_function_decompiled_code(self, func):
|
def get_function_decompiled_code(self, func):
|
||||||
# decompile the function and print the pseudo C
|
# decompile the function and print the pseudo C
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user