diff options
Diffstat (limited to 'src/emu/x64emu.c')
| -rw-r--r-- | src/emu/x64emu.c | 112 |
1 files changed, 75 insertions, 37 deletions
diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c index de4dd50e..9de4cb18 100644 --- a/src/emu/x64emu.c +++ b/src/emu/x64emu.c @@ -58,17 +58,6 @@ uint32_t* GetParityTab() return x86emu_parity_tab; } -void PushExit(x64emu_t* emu) -{ - uintptr_t endMarker = AddCheckBridge(my_context->system, NULL, NULL, 0, "ExitEmulation"); - Push(emu, endMarker); -} - -void* GetExit() -{ - return (void*)AddCheckBridge(my_context->system, NULL, NULL, 0, "ExitEmulation"); -} - static void internalX64Setup(x64emu_t* emu, box64context_t *context, uintptr_t start, uintptr_t stack, int stacksize, int ownstack) { emu->context = context; @@ -86,9 +75,9 @@ static void internalX64Setup(x64emu_t* emu, box64context_t *context, uintptr_t s R_RIP = start; R_RSP = (stack + stacksize) & ~7; // align stack start, always // fake init of segments... - emu->segs[_CS] = 0x73; - emu->segs[_DS] = emu->segs[_ES] = emu->segs[_SS] = 0x7b; - emu->segs[_FS] = 0x33; + emu->segs[_CS] = 0x33; + emu->segs[_DS] = emu->segs[_ES] = emu->segs[_SS] = 0x2b; + emu->segs[_FS] = 0x43; emu->segs[_GS] = default_gs; // setup fpu regs reset_fpu(emu); @@ -117,10 +106,18 @@ x64emu_t *NewX64EmuFromStack(x64emu_t* emu, box64context_t *context, uintptr_t s } EXPORTDYN -void SetupX64Emu(x64emu_t *emu) +void SetupX64Emu(x64emu_t *emu, x64emu_t *ref) { printf_log(LOG_DEBUG, "Setup X86_64 Emu\n"); - (void)emu; // Not doing much here... + if(ref) { + // save RIP and RSP + uintptr_t old_rip = R_RIP; + uintptr_t old_rsp = R_RSP; + CloneEmu(emu, ref); + // restore RIP and RSP + R_RIP = old_rip; + R_RSP = old_rsp; + } } #ifdef HAVE_TRACE @@ -398,11 +395,13 @@ 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", " R8", " R9", "R10", "R11", "R12", "R13", "R14", "R15"}; + static const char* regname32[]={"EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI"}; + static const char* segname[] = {"ES", "CS", "SS", "DS", "FS", "GS"}; char tmp[160]; buff[0] = '\0'; #ifdef HAVE_TRACE @@ -416,7 +415,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]; @@ -441,21 +440,28 @@ const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip) } strcat(buff, "\n"); } - for (int i=_AX; i<=_R15; ++i) { + for (int i=0; i<6; ++i) { + sprintf(tmp, "%s=0x%04x", segname[i], emu->segs[i]); + strcat(buff, tmp); + if(i!=_GS) + strcat(buff, " "); + } + strcat(buff, "\n"); + 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 ", regname32[i], emu->regs[i].dword[0]); + emu->oldregs[i].q[0] = emu->regs[i].dword[0]; + } else { + sprintf(tmp, "%s=%08x ", regname32[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==_RBX) { 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,22 +473,54 @@ const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip) strcat(buff, tmp); #undef FLAG_CHAR } + } + } + 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 { - strcat(buff, "\n"); + 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); + if(is32bits) + sprintf(tmp, "EIP=%08lx ", ip); + else + 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"); @@ -497,13 +535,13 @@ void StopEmu(x64emu_t* emu, const char* reason) #endif } -void UnimpOpcode(x64emu_t* emu) +void UnimpOpcode(x64emu_t* emu, int is32bits) { R_RIP = emu->old_ip; int tid = syscall(SYS_gettid); - printf_log(LOG_NONE, "%04d|%p: Unimplemented Opcode (%02X %02X %02X %02X) %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", - tid, (void*)emu->old_ip, + printf_log(LOG_NONE, "%04d|%p: Unimplemented %sOpcode (%02X %02X %02X %02X) %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + tid, (void*)emu->old_ip, is32bits?"32bits ":"", Peek(emu, -4), Peek(emu, -3), Peek(emu, -2), Peek(emu, -1), Peek(emu, 0), Peek(emu, 1), Peek(emu, 2), Peek(emu, 3), Peek(emu, 4), Peek(emu, 5), Peek(emu, 6), Peek(emu, 7), |