Imlemented basic command handler and added memdump functionality
This commit is contained in:
parent
cad7c3fe99
commit
2205e2c752
@ -17,20 +17,43 @@ int mystrlen(char *data) {
|
|||||||
return i-1;
|
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")))
|
__attribute__((section(".init")))
|
||||||
void payload_main() {
|
void payload_main() {
|
||||||
uint32_t error_code;
|
uint32_t error_code;
|
||||||
uint32_t data = 0xdeadbeef;
|
uint32_t mem_off;
|
||||||
u32 num_xfer;
|
uint32_t mem_sz;
|
||||||
u32 to_send;
|
uint32_t blk_sz;
|
||||||
|
char data[12];
|
||||||
u8 *buffer = (u8*)0x40020000;
|
u8 *buffer = (u8*)0x40020000;
|
||||||
uint32_t test = 1;
|
|
||||||
|
|
||||||
|
usb_log("cmd_handler", &error_code);
|
||||||
while(1){
|
while(1){
|
||||||
usb_write(&test, sizeof(test), &num_xfer );
|
usb_read(&data, 4, &error_code);
|
||||||
test += 1;
|
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
BIN
dumped.bin
Normal file
Binary file not shown.
53
exploit.py
53
exploit.py
@ -10,6 +10,7 @@ import time
|
|||||||
import fcntl
|
import fcntl
|
||||||
import platform
|
import platform
|
||||||
import os
|
import os
|
||||||
|
from patches import *
|
||||||
|
|
||||||
IS_OSX = platform.system() == "Darwin"
|
IS_OSX = platform.system() == "Darwin"
|
||||||
USBDEVFS_URB_TYPE_CONTROL = 2
|
USBDEVFS_URB_TYPE_CONTROL = 2
|
||||||
@ -205,9 +206,60 @@ class TegraRCM():
|
|||||||
if(status == 0):
|
if(status == 0):
|
||||||
error("wrong status returned!")
|
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
|
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()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("payload", help="Payload to send to the tablet")
|
parser.add_argument("payload", help="Payload to send to the tablet")
|
||||||
@ -216,3 +268,4 @@ if __name__ == "__main__":
|
|||||||
rcm = TegraRCM()
|
rcm = TegraRCM()
|
||||||
rcm.dev.read_chip_id()
|
rcm.dev.read_chip_id()
|
||||||
rcm.send_payload(args.payload)
|
rcm.send_payload(args.payload)
|
||||||
|
rcm.cmd_handler()
|
13
patches.py
Normal file
13
patches.py
Normal 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"))
|
Loading…
Reference in New Issue
Block a user