diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-06-17 12:08:43 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-06-17 12:08:43 +0200 |
| commit | 1b47fd952caa889c252223b1996a06444d10e2fc (patch) | |
| tree | 5b45ad0b419a8106088ac9a5ca96590350ff6a3a /src | |
| parent | bf9e5b8e6e3b42768a787f1a3d3c1f423d1fb38f (diff) | |
| download | box64-1b47fd952caa889c252223b1996a06444d10e2fc.tar.gz box64-1b47fd952caa889c252223b1996a06444d10e2fc.zip | |
Added ability to trace and dump 32bits code
Diffstat (limited to 'src')
| -rwxr-xr-x | src/box64context.c | 2 | ||||
| -rwxr-xr-x | src/emu/x64emu.c | 63 | ||||
| -rwxr-xr-x | src/emu/x64run.c | 2 | ||||
| -rwxr-xr-x | src/emu/x64run_private.c | 8 | ||||
| -rwxr-xr-x | src/emu/x64run_private.h | 2 | ||||
| -rwxr-xr-x | src/emu/x64trace.c | 19 | ||||
| -rwxr-xr-x | src/include/box64context.h | 1 | ||||
| -rwxr-xr-x | src/include/x64emu.h | 4 | ||||
| -rwxr-xr-x | src/include/x64trace.h | 3 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibc.c | 2 |
10 files changed, 81 insertions, 25 deletions
diff --git a/src/box64context.c b/src/box64context.c index ff65391c..5c85f3fa 100755 --- a/src/box64context.c +++ b/src/box64context.c @@ -293,6 +293,8 @@ void FreeBox64Context(box64context_t** context) // stop trace now if(ctx->dec) DeleteX64TraceDecoder(&ctx->dec); + if(ctx->dec32) + DeleteX86TraceDecoder(&ctx->dec32); if(ctx->zydis) DeleteX64Trace(ctx); diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c index 05ec337f..3aada0c2 100755 --- a/src/emu/x64emu.c +++ b/src/emu/x64emu.c @@ -395,7 +395,7 @@ void ResetFlags(x64emu_t *emu) emu->df = d_none; } -const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip) +const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip, int is32bits) { static char buff[1000]; static const char* regname[] = {"RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", @@ -413,7 +413,7 @@ const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip) } if(trace_xmm) { // do xmm reg if needed - for(int i=0; i<16; ++i) { + for(int i=0; i<(is32bits?8:16); ++i) { if (trace_regsdiff && (emu->old_xmm[i].q[0] != emu->xmm[i].q[0] || emu->old_xmm[i].q[1] != emu->xmm[i].q[1])) { sprintf(tmp, "\e[1;35m%02d:%016lx-%016lx\e[m", i, emu->xmm[i].q[1], emu->xmm[i].q[0]); emu->old_xmm[i].q[0] = emu->xmm[i].q[0]; @@ -438,21 +438,21 @@ const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip) } strcat(buff, "\n"); } - for (int i=_AX; i<=_R15; ++i) { + if(is32bits) + for (int i=_AX; i<=_RDI; ++i) { #ifdef HAVE_TRACE - if (trace_regsdiff && (emu->regs[i].q[0] != emu->oldregs[i].q[0])) { - sprintf(tmp, "\e[1;35m%s=%016lx\e[m ", regname[i], emu->regs[i].q[0]); - emu->oldregs[i].q[0] = emu->regs[i].q[0]; - } else { - sprintf(tmp, "%s=%016lx ", regname[i], emu->regs[i].q[0]); - } + if (trace_regsdiff && (emu->regs[i].dword[0] != emu->oldregs[i].q[0])) { + sprintf(tmp, "\e[1;35m%s=%08x\e[m ", regname[i], emu->regs[i].dword[0]); + emu->oldregs[i].q[0] = emu->regs[i].dword[0]; + } else { + sprintf(tmp, "%s=%08x ", regname[i], emu->regs[i].dword[0]); + } #else - sprintf(tmp, "%s=%016lx ", regname[i], emu->regs[i].q[0]); + sprintf(tmp, "%s=%08x ", regname[i], emu->regs[i].dword[0]); #endif - strcat(buff, tmp); + strcat(buff, tmp); - if (i%5==4) { - if(i==4) { + if(i==_RDI) { if(emu->df) { #define FLAG_CHAR(f) (ACCESS_FLAG(F_##f##F)) ? #f : "?" sprintf(tmp, "flags=%s%s%s%s%s%s%s\n", FLAG_CHAR(O), FLAG_CHAR(D), FLAG_CHAR(S), FLAG_CHAR(Z), FLAG_CHAR(A), FLAG_CHAR(P), FLAG_CHAR(C)); @@ -467,19 +467,50 @@ const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip) } else { strcat(buff, "\n"); } - } + } + else + for (int i=_AX; i<=_R15; ++i) { +#ifdef HAVE_TRACE + if (trace_regsdiff && (emu->regs[i].q[0] != emu->oldregs[i].q[0])) { + sprintf(tmp, "\e[1;35m%s=%016lx\e[m ", regname[i], emu->regs[i].q[0]); + emu->oldregs[i].q[0] = emu->regs[i].q[0]; + } else { + sprintf(tmp, "%s=%016lx ", regname[i], emu->regs[i].q[0]); + } +#else + sprintf(tmp, "%s=%016lx ", regname[i], emu->regs[i].q[0]); +#endif + strcat(buff, tmp); + + if (i%5==4) { + if(i==4) { + if(emu->df) { +#define FLAG_CHAR(f) (ACCESS_FLAG(F_##f##F)) ? #f : "?" + sprintf(tmp, "flags=%s%s%s%s%s%s%s\n", FLAG_CHAR(O), FLAG_CHAR(D), FLAG_CHAR(S), FLAG_CHAR(Z), FLAG_CHAR(A), FLAG_CHAR(P), FLAG_CHAR(C)); + strcat(buff, tmp); +#undef FLAG_CHAR + } else { +#define FLAG_CHAR(f) (ACCESS_FLAG(F_##f##F)) ? #f : "-" + sprintf(tmp, "FLAGS=%s%s%s%s%s%s%s\n", FLAG_CHAR(O), FLAG_CHAR(D), FLAG_CHAR(S), FLAG_CHAR(Z), FLAG_CHAR(A), FLAG_CHAR(P), FLAG_CHAR(C)); + strcat(buff, tmp); +#undef FLAG_CHAR + } + } else { + strcat(buff, "\n"); + } + } } sprintf(tmp, "RIP=%016lx ", ip); strcat(buff, tmp); return buff; } -void StopEmu(x64emu_t* emu, const char* reason) +void StopEmu(x64emu_t* emu, const char* reason, int is32bits) { emu->quit = 1; printf_log(LOG_NONE, "%s", reason); // dump stuff... - printf_log(LOG_NONE, "==== CPU Registers ====\n%s\n", DumpCPURegs(emu, R_RIP)); + printf_log(LOG_NONE, "==== CPU Registers ====\n%s\n", DumpCPURegs(emu, R_RIP, is32bits)); printf_log(LOG_NONE, "======== Stack ========\nStack is from %lX to %lX\n", R_RBP, R_RSP); if (R_RBP == R_RSP) { printf_log(LOG_NONE, "RBP = RSP: leaf function detected; next 128 bytes should be either data or random.\n"); diff --git a/src/emu/x64run.c b/src/emu/x64run.c index 016e4922..6d66ad1e 100755 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -81,7 +81,7 @@ x64emurun: if(my_context->dec && ( (trace_end == 0) || ((addr >= trace_start) && (addr < trace_end))) ) - PrintTrace(emu, addr, 0); + PrintTrace(emu, addr, 0, is32bits); #endif emu->old_ip = addr; diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c index dfd9a40b..57ff7c44 100755 --- a/src/emu/x64run_private.c +++ b/src/emu/x64run_private.c @@ -1030,7 +1030,7 @@ extern uint64_t start_cnt; #define PK32(a) (*(int32_t*)((uint8_t*)(ip+a))) #define PK64(a) (*(int64_t*)((uint8_t*)(ip+a))) -void PrintTrace(x64emu_t* emu, uintptr_t ip, int dynarec) +void PrintTrace(x64emu_t* emu, uintptr_t ip, int dynarec, int is32bits) { if(start_cnt) --start_cnt; if(!start_cnt && my_context->dec && ( @@ -1051,7 +1051,7 @@ void PrintTrace(x64emu_t* emu, uintptr_t ip, int dynarec) my_context->trace_tid = tid; } #endif - printf_log(LOG_NONE, "%s", DumpCPURegs(emu, ip)); + printf_log(LOG_NONE, "%s", DumpCPURegs(emu, ip, is32bits)); if(R_RIP==0) { printf_log(LOG_NONE, "Running at NULL address\n"); mutex_unlock(&my_context->mutex_trace); @@ -1065,10 +1065,10 @@ void PrintTrace(x64emu_t* emu, uintptr_t ip, int dynarec) printf_log(LOG_NONE, "%p: Native call to %p => %s\n", (void*)ip, (void*)a, GetNativeName(*(void**)(ip+11))); } } else { - printf_log(LOG_NONE, "%s", DecodeX64Trace(my_context->dec, ip)); + printf_log(LOG_NONE, "%s", DecodeX64Trace(is32bits?my_context->dec32:my_context->dec, ip)); uint8_t peek = PK(0); rex_t rex = {0}; - if(peek>=0x40 && peek<=0x4f) { + if(!is32bits && peek>=0x40 && peek<=0x4f) { rex.rex = peek; ip++; peek = PK(0); diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h index 37947164..accf3a6e 100755 --- a/src/emu/x64run_private.h +++ b/src/emu/x64run_private.h @@ -158,7 +158,7 @@ uintptr_t GetSegmentBaseEmu(x64emu_t* emu, int seg); const char* GetNativeName(void* p); #ifdef HAVE_TRACE -void PrintTrace(x64emu_t* emu, uintptr_t ip, int dynarec); +void PrintTrace(x64emu_t* emu, uintptr_t ip, int dynarec, int is32bits); #endif #endif //__X86RUN_PRIVATE_H_ diff --git a/src/emu/x64trace.c b/src/emu/x64trace.c index b5ddb5b7..ac655040 100755 --- a/src/emu/x64trace.c +++ b/src/emu/x64trace.c @@ -59,6 +59,7 @@ int InitX64Trace(box64context_t *context) #undef GO context->dec = InitX64TraceDecoder(context); + context->dec32 = InitX86TraceDecoder(context); return 0; } @@ -73,6 +74,24 @@ void DeleteX64Trace(box64context_t *context) context->zydis = NULL; } +zydis_dec_t* InitX86TraceDecoder(box64context_t *context) +{ + if(!context->zydis) + return NULL; + zydis_dec_t *dec = (zydis_dec_t*)box_calloc(1, sizeof(zydis_dec_t)); + dec->ZydisDecoderDecodeBuffer = context->zydis->ZydisDecoderDecodeBuffer; + dec->ZydisFormatterFormatInstruction = context->zydis->ZydisFormatterFormatInstruction; + context->zydis->ZydisDecoderInit(&dec->decoder, ZYDIS_MACHINE_MODE_LEGACY_32, ZYDIS_ADDRESS_WIDTH_32); + context->zydis->ZydisFormatterInit(&dec->formatter, ZYDIS_FORMATTER_STYLE_INTEL); + + return dec; +} +void DeleteX86TraceDecoder(zydis_dec_t **dec) +{ + box_free(*dec); + *dec = NULL; +} + zydis_dec_t* InitX64TraceDecoder(box64context_t *context) { if(!context->zydis) diff --git a/src/include/box64context.h b/src/include/box64context.h index 2f82e010..954d93cb 100755 --- a/src/include/box64context.h +++ b/src/include/box64context.h @@ -185,6 +185,7 @@ typedef struct box64context_s { int clean_cap; zydis_dec_t *dec; // trace + zydis_dec_t *dec32; // trace int forked; // how many forks... cleanup only when < 0 diff --git a/src/include/x64emu.h b/src/include/x64emu.h index a1e03f6e..dd324add 100755 --- a/src/include/x64emu.h +++ b/src/include/x64emu.h @@ -41,9 +41,9 @@ uint64_t GetRSP(x64emu_t *emu); uint64_t GetRBP(x64emu_t *emu); void ResetFlags(x64emu_t *emu); void ResetSegmentsCache(x64emu_t *emu); -const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip); +const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip, int is32bits); -void StopEmu(x64emu_t* emu, const char* reason); +void StopEmu(x64emu_t* emu, const char* reason, int is32bits); void EmuCall(x64emu_t* emu, uintptr_t addr); void AddCleanup(x64emu_t *emu, void *p, void* dso_handle); void AddCleanup1Arg(x64emu_t *emu, void *p, void* a, void* dso_handle); diff --git a/src/include/x64trace.h b/src/include/x64trace.h index 662f2740..9ecbb9d5 100755 --- a/src/include/x64trace.h +++ b/src/include/x64trace.h @@ -8,8 +8,11 @@ typedef struct zydis_dec_s zydis_dec_t; int InitX64Trace(box64context_t *context); void DeleteX64Trace(box64context_t *context); +zydis_dec_t* InitX86TraceDecoder(box64context_t *context); +void DeleteX86TraceDecoder(zydis_dec_t **dec); zydis_dec_t* InitX64TraceDecoder(box64context_t *context); void DeleteX64TraceDecoder(zydis_dec_t **dec); + const char* DecodeX64Trace(zydis_dec_t *dec, uintptr_t p); #define ZYDIS_RUNTIME_ADDRESS_NONE (uint64_t)(-1) diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index af756f79..cac42fd0 100755 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -437,7 +437,7 @@ void EXPORT my___stack_chk_fail(x64emu_t* emu) if(cycle_log) { print_cycle_log(LOG_INFO); } - StopEmu(emu, buff); + StopEmu(emu, buff, emu->segs[_CS]==0x23); } void EXPORT my___gmon_start__(x64emu_t *emu) { |