Imlemented basic command handler and added memdump functionality

This commit is contained in:
Eljakim Herrewijnen 2021-11-22 23:22:01 +01:00
parent cad7c3fe99
commit 2205e2c752
4 changed files with 101 additions and 12 deletions

View File

@ -17,20 +17,43 @@ int mystrlen(char *data) {
return i-1;
}
#define usb_log(msg, error) usb_write(msg, mystrlen(msg), error);
void usb_log(char * msg, uint32_t * error){
usb_write(msg, mystrlen(msg), error);
}
// #define usb_log(msg, error) usb_write(msg, mystrlen(msg), error);
__attribute__((section(".init")))
void payload_main() {
uint32_t error_code;
uint32_t data = 0xdeadbeef;
u32 num_xfer;
u32 to_send;
uint32_t mem_off;
uint32_t mem_sz;
uint32_t blk_sz;
char data[12];
u8 *buffer = (u8*)0x40020000;
uint32_t test = 1;
while (1) {
usb_write(&test, sizeof(test), &num_xfer );
test += 1;
usb_log("cmd_handler", &error_code);
while(1){
usb_read(&data, 4, &error_code);
if(data[0] == 'M' && data[1] == 'E' && data[2] == 'M' && data[3] == 'D') {
usb_write(&data, 4, &error_code);
usb_read(&data, 8,&error_code); // Receive uint64_t size and and uint32_t offset
mem_off = *(uint32_t *)data;
mem_sz = *(uint32_t *)(data+4);
for(unsigned int i=0;i<mem_sz;i+=0x200) {
if((mem_sz - i) < 0x200) {
blk_sz = mem_sz - i;
} else {
blk_sz = 0x200;
}
usb_write((void *)(mem_off+i), blk_sz, &error_code);
usb_read(&data, 4, &error_code);
if(!(data[0] == 'A' && data[1] == 'C' && data[2] == 'K')) {
break;
}
}
}
usb_log("done", &error_code);
}
}

BIN
dumped.bin Normal file

Binary file not shown.

View File

@ -10,6 +10,7 @@ import time
import fcntl
import platform
import os
from patches import *
IS_OSX = platform.system() == "Darwin"
USBDEVFS_URB_TYPE_CONTROL = 2
@ -205,8 +206,59 @@ class TegraRCM():
if(status == 0):
error("wrong status returned!")
def send_verify_cmd(self, cmd):
self.dev.write(cmd)
r = self.dev.read(0x200)
if(r != cmd):
error(f"Error on sending command! {r}")
return False
return True
def handle_done(self):
r = self.dev.read(0x200)
if(r != b"done"):
error("Error on writing vbar!")
def memdump_region(self, offset, size):
if(not self.send_verify_cmd(b"MEMD")):
return
mem_param = struct.pack('<LL', offset, size)
self.dev.write(mem_param)
received = b''
blk_sz = 0x200
while len(received) < size:
if (remaining := size - len(received)) < 0x200:
blk_sz = remaining
d = self.dev.read(blk_sz)
if len(d) == blk_sz:
self.dev.write(b"ACK\x00")
received += d
self.handle_done()
return received
def search_bootrom(self):
dumped = BytesIO()
for i in range(0, 0x1000000, 0x10000):
d = self.memdump_region(i, 0x10000)
dumped.write(d)
if(cpsr_to_r0_ins in d or r1_to_cpsr in d):
info(f"Found cpsr instruction at {hex(i)}")
print(".", end="")
info(f"dumped {hex(len(dumped))} data")
def dump_bootrom(self):
d = self.memdump_region(0x100000, 0x1000)
if(True):
pass
def cmd_handler(self):
while True:
cmd = self.dev.read(0x200)
if(cmd == b"cmd_handler"):
self.search_bootrom()
#dump memory
self.dump_bootrom()
pass
if __name__ == "__main__":
parser = argparse.ArgumentParser()
@ -216,3 +268,4 @@ if __name__ == "__main__":
rcm = TegraRCM()
rcm.dev.read_chip_id()
rcm.send_payload(args.payload)
rcm.cmd_handler()

13
patches.py Normal file
View File

@ -0,0 +1,13 @@
from keystone import *
from capstone import *
from utils import *
import io
cs = Cs(CS_ARCH_ARM, CS_MODE_THUMB)
ks = Ks(KS_ARCH_ARM, KS_MODE_THUMB)
def ks_to_bytes(ks_code):
return b"".join([int.to_bytes(x, 1, "little") for x in ks_code[0]])
cpsr_to_r0_ins = ks_to_bytes(ks.asm("mrs r0, cpsr"))
r1_to_cpsr = ks_to_bytes(ks.asm("msr cpsr_c, r1"))