about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-06-17 12:08:43 +0200
committerptitSeb <sebastien.chev@gmail.com>2023-06-17 12:08:43 +0200
commit1b47fd952caa889c252223b1996a06444d10e2fc (patch)
tree5b45ad0b419a8106088ac9a5ca96590350ff6a3a /src
parentbf9e5b8e6e3b42768a787f1a3d3c1f423d1fb38f (diff)
downloadbox64-1b47fd952caa889c252223b1996a06444d10e2fc.tar.gz
box64-1b47fd952caa889c252223b1996a06444d10e2fc.zip
Added ability to trace and dump 32bits code
Diffstat (limited to 'src')
-rwxr-xr-xsrc/box64context.c2
-rwxr-xr-xsrc/emu/x64emu.c63
-rwxr-xr-xsrc/emu/x64run.c2
-rwxr-xr-xsrc/emu/x64run_private.c8
-rwxr-xr-xsrc/emu/x64run_private.h2
-rwxr-xr-xsrc/emu/x64trace.c19
-rwxr-xr-xsrc/include/box64context.h1
-rwxr-xr-xsrc/include/x64emu.h4
-rwxr-xr-xsrc/include/x64trace.h3
-rwxr-xr-xsrc/wrapped/wrappedlibc.c2
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)
 {