From c24149e40f5fe1ab3f7edbd6c73af91c36fd5468 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Thu, 4 Mar 2021 12:18:40 +0100 Subject: Added REX FF opcodes --- src/emu/x64run.c | 72 +++++++++++++++++++++++++++++++++++++++++++++--- src/emu/x64run_private.h | 2 +- 2 files changed, 69 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/emu/x64run.c b/src/emu/x64run.c index d25ba332..c53028b5 100755 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -42,9 +42,6 @@ int Run(x64emu_t *emu, int step) int64_t tmp64s, tmp64s2; double d; float f; - int64_t ll; - sse_regs_t *opex, eax1; - mmx_regs_t *opem, eam1; rex_t rex; int unimp = 0; @@ -250,9 +247,76 @@ x64emurun: if(rex.w) GD->q[0] = (uint64_t)ED; else - GD->dword[0] = (uint32_t)ED; + GD->dword[0] = (uint32_t)(uintptr_t)ED; break; + case 0xFF: /* GRP 5 Ed */ + nextop = F8; + GETED; + switch((nextop>>3)&7) { + case 0: /* INC Ed */ + if(rex.w) + ED->q[0] = inc64(emu, ED->q[0]); + else + ED->dword[0] = inc32(emu, ED->dword[0]); + break; + case 1: /* DEC Ed */ + if(rex.w) + ED->q[0] = dec64(emu, ED->q[0]); + else + ED->dword[0] = dec32(emu, ED->dword[0]); + break; + case 2: /* CALL NEAR Ed */ + tmp64u = (uintptr_t)getAlternate((void*)ED->q[0]); + Push(emu, R_RIP); + R_RIP = tmp64u; + STEP + break; + case 3: /* CALL FAR Ed */ + if(nextop>0xC0) { + R_RIP = emu->old_ip; + printf_log(LOG_NONE, "Illegal Opcode %p: %02X %02X %02X %02X\n", (void*)R_RIP, opcode, nextop, PK(2), PK(3)); + emu->quit=1; + emu->error |= ERR_ILLEGAL; + goto fini; + } else { + Push16(emu, R_CS); + Push(emu, R_RIP); + R_RIP = ED->dword[0]; + R_CS = (ED+1)->word[0]; + goto fini; // exit loop to recompute new CS... + } + break; + case 4: /* JMP NEAR Ed */ + R_RIP = (uintptr_t)getAlternate((void*)ED->q[0]); + STEP + break; + case 5: /* JMP FAR Ed */ + if(nextop>0xc0) { + R_RIP = emu->old_ip; + printf_log(LOG_NONE, "Illegal Opcode %p: 0x%02X 0x%02X %02X %02X\n", (void*)R_RIP, opcode, nextop, PK(2), PK(3)); + emu->quit=1; + emu->error |= ERR_ILLEGAL; + goto fini; + } else { + R_RIP = ED->q[0]; + R_CS = (ED+1)->word[0]; + STEP + goto fini; // exit loop to recompute CS... + } + break; + case 6: /* Push Ed */ + tmp64u = ED->q[0]; // rex.w ignored + Push(emu, tmp64u); // avoid potential issue with push [esp+...] + break; + default: + R_RIP = emu->old_ip; + printf_log(LOG_NONE, "Illegal Opcode %p: %02X %02X %02X %02X %02X %02X\n",(void*)R_RIP, opcode, nextop, PK(2), PK(3), PK(4), PK(5)); + emu->quit=1; + emu->error |= ERR_ILLEGAL; + goto fini; + } + break; default: unimp = 1; goto fini; diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h index 57a100bd..3700147d 100755 --- a/src/emu/x64run_private.h +++ b/src/emu/x64run_private.h @@ -82,7 +82,7 @@ static inline reg64_t* GetECommon(x64emu_t* emu, rex_t rex, uint8_t m) base += (emu->sbiidx[((sib>>3)&7)+(rex.x<<3)]->sq[0] << (sib>>6)); return (reg64_t*)base; } else if (m==0x5) { //disp32 - uintptr_t base = Fetch32(emu); + int32_t base = Fetch32s(emu); return (reg64_t*)(base+R_RIP); } return (reg64_t*)(emu->regs[m].q[0]+(rex.b<<3)); -- cgit 1.4.1