From 728d58d5cbea121faf26699bca726db2530ae71a Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Fri, 24 Sep 2021 19:07:11 +0000 Subject: emul: added INT 0x80 hook for syscall 4 (write) for printint --- ecomp-c/emul.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/ecomp-c/emul.c b/ecomp-c/emul.c index f97e787..c1d819f 100644 --- a/ecomp-c/emul.c +++ b/ecomp-c/emul.c @@ -105,6 +105,58 @@ static int compute_p( int size ) return p; } +static void handle_interrupts( uc_engine *uc, uint32_t interrupt, void *user_data ) +{ + uint32_t eax, ebx, ecx, edx; + bool trace = *((bool *)user_data); + + if( trace ) { + printf( "INT %x\n", interrupt ); + dump_regs( uc ); + } + + if( interrupt != 0x80 ) { + return; + } + + uc_reg_read( uc, UC_X86_REG_EAX, &eax ); + switch( eax ) { + case 4: // SYSCALL_WRITE + { + unsigned char buffer[256]; + size_t size; + uc_err uerr; + + uc_reg_read( uc, UC_X86_REG_EBX, &ebx ); + if( ebx != 1 ) { + fprintf( stderr, "ERROR: failed to call SYSCALL_WRITE on non-stdout (not implemented)\n" ); + return; + } + + uc_reg_read( uc, UC_X86_REG_ECX, &ecx ); + uc_reg_read( uc, UC_X86_REG_EDX, &edx ); + size = sizeof( buffer ) - 1; + if( edx < sizeof( buffer ) - 1 ) { + size = edx; + } + + uerr = uc_mem_read( uc, ecx, buffer, size ); + buffer[size] = '\0'; + if( uerr != UC_ERR_OK ) { + fprintf( stderr, "ERROR: failed to call uc_mem_read( ) in int x080 syscall 4 (SYSCALL_WRITE): %s\n", uc_strerror( uerr ) ); + dump_regs( uc ); + exit( EXIT_FAILURE ); + } + + printf( "%*s", size, buffer ); + } + break; + + default: + fprintf( stderr, "WARN: unknown syscall %0x, EAX: %d\n", interrupt, eax ); + } +} + int main( int argc, char *argv[] ) { uc_engine *uc; @@ -355,6 +407,16 @@ int main( int argc, char *argv[] ) if( trace ) { printf( "Single step execution:\n" ); } + + // hook for emulating syscalls (int 0x80 on the host) + uc_hook hook; + uerr = uc_hook_add( uc, &hook, UC_HOOK_INTR, handle_interrupts, (void *)&trace, 1, 0 ); + if( uerr != UC_ERR_OK ) { + fprintf( stderr, "ERROR: failed to call uc_hook_add( handle_interrupts ): %s\n", uc_strerror( uerr ) ); + cs_close( &cs ); + uc_close( uc ); + exit( EXIT_FAILURE ); + } while( !terminate ) { @@ -393,7 +455,7 @@ int main( int argc, char *argv[] ) 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 ) ); -- cgit v1.2.3-54-g00ecf