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/emu | |
| parent | bf9e5b8e6e3b42768a787f1a3d3c1f423d1fb38f (diff) | |
| download | box64-1b47fd952caa889c252223b1996a06444d10e2fc.tar.gz box64-1b47fd952caa889c252223b1996a06444d10e2fc.zip | |
Added ability to trace and dump 32bits code
Diffstat (limited to 'src/emu')
| -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 |
5 files changed, 72 insertions, 22 deletions
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) |