From a595e1f3e9ec47bdc0c9a8a0d7c764516e29e00b Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Fri, 24 Sep 2021 10:35:10 +0200 Subject: emul - added command line options for verbose output, tracing, ... --- ecomp-c/emul.c | 125 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 92 insertions(+), 33 deletions(-) diff --git a/ecomp-c/emul.c b/ecomp-c/emul.c index e4234f9..f97e787 100644 --- a/ecomp-c/emul.c +++ b/ecomp-c/emul.c @@ -9,6 +9,7 @@ #include #include #include +#include #define PAGE_SIZE 4 * 1024 * 1024 #define CODE_START 0x1000000 @@ -119,6 +120,40 @@ int main( int argc, char *argv[] ) cs_insn *instrs; uint64_t data_start = 0; size_t data_size = 0; + int opt; + bool verbose = false; + bool dump = false; + bool trace = false; + + while( ( opt = getopt( argc, argv, "vdth" ) ) != -1 ) { + switch( opt ) { + case 'v': + verbose = true; + break; + case 'd': + dump = true; + break; + case 't': + trace = true; + break; + case 'h': + printf( "Usage: %s [-v] [file.bin]\n\n", argv[0] ); + printf( "Options:\n" ); + printf( " -h show help\n" ); + printf( " -v verbose output\n" ); + printf( " -d dump code and data read\n" ); + printf( " -t trace and print single stepts during emulation\n" ); + exit( EXIT_SUCCESS ); + default: + fprintf( stderr, "Usage: %s [-v] [file.bin]\n", argv[0] ); + exit( EXIT_FAILURE ); + } + } + + if( optind >= argc ) { + fprintf( stderr, "Expected a binary file to interpret\n" ); + exit( EXIT_FAILURE ); + } uerr = uc_open( UC_ARCH_X86, UC_MODE_32, &uc ); if( uerr != UC_ERR_OK ) { @@ -146,8 +181,8 @@ int main( int argc, char *argv[] ) uc_close( uc ); exit( EXIT_FAILURE ); } - - f = fopen( argv[1], "r" ); + + f = fopen( argv[optind], "r" ); if( f == NULL ) { fprintf( stderr, "ERROR: unable to read file '%s': %s\n", argv[1], strerror( errno ) ); uc_close( uc ); @@ -189,7 +224,9 @@ int main( int argc, char *argv[] ) uc_close( uc ); exit( EXIT_FAILURE ); } - printf( "Read %zu bytes of code and static data..\n", code_size ); + if( verbose ) { + printf( "Read %zu bytes of code and static data..\n", code_size ); + } fclose( f ); @@ -202,20 +239,26 @@ int main( int argc, char *argv[] ) exit( EXIT_FAILURE ); } + if( verbose ) { + printf( "Executing code..\n" ); + } + // print all the disassembled code for( int i = 0; i < nof_instrs; i++ ) { - printf( "%04X: ", (uint32_t)instrs[i].address ); - for( int j = 0; j < instrs[i].size; j++ ) { - printf( "%02X", instrs[i].bytes[j] ); - } - for( int j = ( 16 - instrs[i].size ) * 2; j > 0; j-- ) { - printf( " " ); - } - - if( data_start == 0 ) { - printf( "%s %s\n", instrs[i].mnemonic, instrs[i].op_str ); - } else { - printf( "data\n" ); + if( dump ) { + printf( "%04X: ", (uint32_t)instrs[i].address ); + for( int j = 0; j < instrs[i].size; j++ ) { + printf( "%02X", instrs[i].bytes[j] ); + } + for( int j = ( 16 - instrs[i].size ) * 2; j > 0; j-- ) { + printf( " " ); + } + + if( data_start == 0 ) { + printf( "%s %s\n", instrs[i].mnemonic, instrs[i].op_str ); + } else { + printf( "data\n" ); + } } /* code and data segment are separated by a 'hlt' instruction, @@ -295,22 +338,29 @@ int main( int argc, char *argv[] ) uc_reg_write( uc, UC_X86_REG_EBP, &esp ); data_size = file_size - ( data_start - CODE_START ); - dump_memory( uc, data_start, data_start + data_size ); - printf( "core start %x\n", (unsigned int)CODE_START ); - printf( "data start %x\n", (unsigned int)data_start ); - printf( "data size %x\n", (unsigned int)data_size ); - printf( "stack start %x\n", (unsigned int)esp ); + if( dump ) { + dump_memory( uc, data_start, data_start + data_size ); + printf( "core start %x\n", (unsigned int)CODE_START ); + printf( "data start %x\n", (unsigned int)data_start ); + printf( "data size %x\n", (unsigned int)data_size ); + printf( "stack start %x\n", (unsigned int)esp ); + } uint64_t address = CODE_START; bool terminate = false; bool notfound = false; int iteration = 1; - printf( "Single step execution:\n" ); + if( trace ) { + printf( "Single step execution:\n" ); + } + while( !terminate ) { - printf( "-- iteration %d\n", iteration ); + if( trace ) { + printf( "-- iteration %d\n", iteration ); + } iteration++; int n = mul_hash( address, p ) * 2; @@ -330,17 +380,20 @@ int main( int argc, char *argv[] ) } n = instrs_map[n]; - printf( "%04X: ", (unsigned int)address ); + if( trace ) { + printf( "%04X: ", (unsigned int)address ); - for( int i = 0; i < instrs[n].size; i++ ) { - printf( "%02X", instrs[n].bytes[i] ); - } - for( int i = ( 16 - instrs[n].size ) * 2; i > 0; i-- ) { - printf( " " ); + for( int i = 0; i < instrs[n].size; i++ ) { + printf( "%02X", instrs[n].bytes[i] ); + } + + for( int i = ( 16 - instrs[n].size ) * 2; i > 0; i-- ) { + printf( " " ); + } + + printf( "%s %s\n", instrs[n].mnemonic, instrs[n].op_str ); } - printf( "%s %s\n", instrs[n].mnemonic, instrs[n].op_str ); - uerr = uc_emu_start( uc, addr, CODE_START + code_size, 0, 1 ); if( uerr != UC_ERR_OK ) { fprintf( stderr, "ERROR: failed to call uc_emu_start( ): %s\n", uc_strerror( uerr ) ); @@ -354,15 +407,21 @@ int main( int argc, char *argv[] ) addr = eip; address = eip; - dump_regs( uc ); - dump_stack( uc ); - dump_memory( uc, data_start, data_start + data_size ); + if( trace ) { + dump_regs( uc ); + dump_stack( uc ); + dump_memory( uc, data_start, data_start + data_size ); + } if( strcmp( instrs[n].mnemonic, "hlt" ) == 0 ) { terminate = true; } } + if( verbose ) { + printf( "Done, executed %d instructions.\n", iteration ); + } + free( instrs_map ); cs_free( instrs, nof_instrs ); cs_close( &cs ); -- cgit v1.2.3-54-g00ecf