instrs: Support far jumps/calls encoded target
This commit is contained in:
4
decode.c
4
decode.c
@@ -508,6 +508,8 @@ prefix_end:
|
|||||||
imm_size = 1;
|
imm_size = 1;
|
||||||
else if (UNLIKELY(instr->type == FDI_RET || instr->type == FDI_RETF))
|
else if (UNLIKELY(instr->type == FDI_RET || instr->type == FDI_RETF))
|
||||||
imm_size = 2;
|
imm_size = 2;
|
||||||
|
else if (UNLIKELY(desc->type == FDI_JMPF || desc->type == FDI_CALLF))
|
||||||
|
imm_size = op_size + 2;
|
||||||
else if (UNLIKELY(instr->type == FDI_ENTER))
|
else if (UNLIKELY(instr->type == FDI_ENTER))
|
||||||
imm_size = 3;
|
imm_size = 3;
|
||||||
else if (instr->type == FDI_MOVABS)
|
else if (instr->type == FDI_MOVABS)
|
||||||
@@ -526,6 +528,8 @@ prefix_end:
|
|||||||
instr->imm = LOAD_LE_3(&buffer[off]);
|
instr->imm = LOAD_LE_3(&buffer[off]);
|
||||||
else if (imm_size == 4)
|
else if (imm_size == 4)
|
||||||
instr->imm = (int32_t) LOAD_LE_4(&buffer[off]);
|
instr->imm = (int32_t) LOAD_LE_4(&buffer[off]);
|
||||||
|
else if (imm_size == 6)
|
||||||
|
instr->imm = LOAD_LE_4(&buffer[off]) | LOAD_LE_2(&buffer[off+4]) << 32;
|
||||||
else if (imm_size == 8)
|
else if (imm_size == 8)
|
||||||
instr->imm = (int64_t) LOAD_LE_8(&buffer[off]);
|
instr->imm = (int64_t) LOAD_LE_8(&buffer[off]);
|
||||||
off += imm_size;
|
off += imm_size;
|
||||||
|
|||||||
26
format.c
26
format.c
@@ -178,7 +178,7 @@ fd_format_abs(const FdInstr* instr, uint64_t addr, char* buffer, size_t len)
|
|||||||
case 8: mnemonic = "jrcxz"; break;
|
case 8: mnemonic = "jrcxz"; break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FDI_ENTER:
|
case FDI_ENTER: {
|
||||||
buf = fd_strplcpy(buf, mnemonic, end-buf);
|
buf = fd_strplcpy(buf, mnemonic, end-buf);
|
||||||
if (FD_OPSIZE(instr) == 2)
|
if (FD_OPSIZE(instr) == 2)
|
||||||
buf = fd_strplcpy(buf, "w", end-buf);
|
buf = fd_strplcpy(buf, "w", end-buf);
|
||||||
@@ -194,6 +194,28 @@ fd_format_abs(const FdInstr* instr, uint64_t addr, char* buffer, size_t len)
|
|||||||
*--fmt = ',';
|
*--fmt = ',';
|
||||||
buf = fd_strplcpy(buf, fmt, end-buf);
|
buf = fd_strplcpy(buf, fmt, end-buf);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
case FDI_JMPF:
|
||||||
|
case FDI_CALLF:
|
||||||
|
if (FD_OP_TYPE(instr, 0) == FD_OT_IMM) {
|
||||||
|
buf = fd_strplcpy(buf, mnemonic, end-buf);
|
||||||
|
uint32_t tgt = FD_OP_IMM(instr, 0) & 0xffffffff;
|
||||||
|
if (FD_OP_SIZE(instr, 0) == 2)
|
||||||
|
tgt &= 0xffff;
|
||||||
|
unsigned seg = FD_OP_IMM(instr, 0) >> 8*FD_OP_SIZE(instr, 0);
|
||||||
|
char* fmt = fd_format_hex(seg & 0xffff, tmp + 3);
|
||||||
|
*--fmt = 'x';
|
||||||
|
*--fmt = '0';
|
||||||
|
*--fmt = ' ';
|
||||||
|
buf = fd_strplcpy(buf, fmt, end-buf);
|
||||||
|
fmt = fd_format_hex(tgt, tmp + 3);
|
||||||
|
*--fmt = 'x';
|
||||||
|
*--fmt = '0';
|
||||||
|
*--fmt = ':';
|
||||||
|
buf = fd_strplcpy(buf, fmt, end-buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case FDI_PUSH:
|
case FDI_PUSH:
|
||||||
if (FD_OP_SIZE(instr, 0) == 2 && FD_OP_TYPE(instr, 0) == FD_OT_IMM)
|
if (FD_OP_SIZE(instr, 0) == 2 && FD_OP_TYPE(instr, 0) == FD_OT_IMM)
|
||||||
sizesuffix[0] = 'w';
|
sizesuffix[0] = 'w';
|
||||||
@@ -275,7 +297,7 @@ fd_format_abs(const FdInstr* instr, uint64_t addr, char* buffer, size_t len)
|
|||||||
case FDI_LFS:
|
case FDI_LFS:
|
||||||
case FDI_LGS:
|
case FDI_LGS:
|
||||||
case FDI_LSS:
|
case FDI_LSS:
|
||||||
size = 6;
|
size += 2;
|
||||||
break;
|
break;
|
||||||
case FDI_FLD:
|
case FDI_FLD:
|
||||||
case FDI_FSTP:
|
case FDI_FSTP:
|
||||||
|
|||||||
14
instrs.txt
14
instrs.txt
@@ -157,7 +157,8 @@
|
|||||||
90+ OA GP GP - - XCHG_NOP
|
90+ OA GP GP - - XCHG_NOP
|
||||||
98 NP - - - - C_EX INSTR_WIDTH
|
98 NP - - - - C_EX INSTR_WIDTH
|
||||||
99 NP - - - - C_SEP INSTR_WIDTH
|
99 NP - - - - C_SEP INSTR_WIDTH
|
||||||
#9a CALLF TODO
|
# Far jmp/call immediate size adjusted in code
|
||||||
|
9a I IMM - - - CALLF ONLY32
|
||||||
9b NP - - - - FWAIT
|
9b NP - - - - FWAIT
|
||||||
9c NP - - - - PUSHF DEF64 INSTR_WIDTH
|
9c NP - - - - PUSHF DEF64 INSTR_WIDTH
|
||||||
9d NP - - - - POPF DEF64 INSTR_WIDTH
|
9d NP - - - - POPF DEF64 INSTR_WIDTH
|
||||||
@@ -198,8 +199,8 @@ c1/7 MI GP IMM8 - - SAR
|
|||||||
# RET immediate size handled in code
|
# RET immediate size handled in code
|
||||||
c2 I IMM16 - - - RET FORCE64 INSTR_WIDTH
|
c2 I IMM16 - - - RET FORCE64 INSTR_WIDTH
|
||||||
c3 NP - - - - RET FORCE64 INSTR_WIDTH
|
c3 NP - - - - RET FORCE64 INSTR_WIDTH
|
||||||
c4/m RM GP MEMZ - - LES ONLY32
|
c4/m RM GP MEM - - LES ONLY32
|
||||||
c5/m RM GP MEMZ - - LDS ONLY32
|
c5/m RM GP MEM - - LDS ONLY32
|
||||||
c6/0 MI GP IMM - - MOV SIZE_8
|
c6/0 MI GP IMM - - MOV SIZE_8
|
||||||
c6f8 I IMM8 - - - XABORT
|
c6f8 I IMM8 - - - XABORT
|
||||||
c7/0 MI GP IMM - - MOV
|
c7/0 MI GP IMM - - MOV
|
||||||
@@ -258,7 +259,8 @@ e6 IA GP IMM8 - - OUT SIZE_8
|
|||||||
e7 IA GP IMM8 - - OUT
|
e7 IA GP IMM8 - - OUT
|
||||||
e8 D IMM - - - CALL FORCE64
|
e8 D IMM - - - CALL FORCE64
|
||||||
e9 D IMM - - - JMP FORCE64
|
e9 D IMM - - - JMP FORCE64
|
||||||
#ea JMPf TODO, ONLY32
|
# Far jmp/call immediate size adjusted in code
|
||||||
|
ea I IMM - - - JMPF ONLY32
|
||||||
eb D IMM - - - JMP FORCE64 IMM_8
|
eb D IMM - - - JMP FORCE64 IMM_8
|
||||||
ec NP - - - - IN SIZE_8 INSTR_WIDTH
|
ec NP - - - - IN SIZE_8 INSTR_WIDTH
|
||||||
ed NP - - - - IN INSTR_WIDTH
|
ed NP - - - - IN INSTR_WIDTH
|
||||||
@@ -295,9 +297,9 @@ fe/1 M GP - - - DEC SIZE_8 LOCK
|
|||||||
ff/0 M GP - - - INC LOCK
|
ff/0 M GP - - - INC LOCK
|
||||||
ff/1 M GP - - - DEC LOCK
|
ff/1 M GP - - - DEC LOCK
|
||||||
ff/2 M GP - - - CALL FORCE64
|
ff/2 M GP - - - CALL FORCE64
|
||||||
ff/3m M MEMZ - - - CALLF
|
ff/3m M MEM - - - CALLF
|
||||||
ff/4 M GP - - - JMP FORCE64
|
ff/4 M GP - - - JMP FORCE64
|
||||||
ff/5m M MEMZ - - - JMPF
|
ff/5m M MEM - - - JMPF
|
||||||
ff/6 M GP - - - PUSH DEF64
|
ff/6 M GP - - - PUSH DEF64
|
||||||
0f00/0 M GP16 - - - SLDT
|
0f00/0 M GP16 - - - SLDT
|
||||||
0f00/1 M GP16 - - - STR
|
0f00/1 M GP16 - - - STR
|
||||||
|
|||||||
@@ -311,7 +311,7 @@ main(int argc, char** argv)
|
|||||||
TEST32("\xc5\x00", "lds eax, fword ptr [eax]");
|
TEST32("\xc5\x00", "lds eax, fword ptr [eax]");
|
||||||
TEST32("\x0f\xb2\x00", "lss eax, fword ptr [eax]");
|
TEST32("\x0f\xb2\x00", "lss eax, fword ptr [eax]");
|
||||||
TEST64("\x0f\xb2\x00", "lss eax, fword ptr [rax]");
|
TEST64("\x0f\xb2\x00", "lss eax, fword ptr [rax]");
|
||||||
TEST64("\x48\x0f\xb2\x00", "lss rax, fword ptr [rax]");
|
TEST64("\x48\x0f\xb2\x00", "lss rax, tbyte ptr [rax]");
|
||||||
TEST("\xc5\xf2\x2a\xc0", "vcvtsi2ss xmm0, xmm1, eax");
|
TEST("\xc5\xf2\x2a\xc0", "vcvtsi2ss xmm0, xmm1, eax");
|
||||||
TEST("\xf3\xc5\xf2\x2a\xc0", "UD"); // VEX+REP
|
TEST("\xf3\xc5\xf2\x2a\xc0", "UD"); // VEX+REP
|
||||||
TEST("\xf2\xc5\xf2\x2a\xc0", "UD"); // VEX+REPNZ
|
TEST("\xf2\xc5\xf2\x2a\xc0", "UD"); // VEX+REPNZ
|
||||||
@@ -429,6 +429,19 @@ main(int argc, char** argv)
|
|||||||
TEST64("\xe3\xfe", "jrcxz 0x0");
|
TEST64("\xe3\xfe", "jrcxz 0x0");
|
||||||
TEST32("\x67\xe3\xfd", "jcxz 0x0");
|
TEST32("\x67\xe3\xfd", "jcxz 0x0");
|
||||||
TEST64("\x67\xe3\xfd", "jecxz 0x0");
|
TEST64("\x67\xe3\xfd", "jecxz 0x0");
|
||||||
|
TEST32("\x66\x9a\x23\x01\x23\x00", "call far 0x23:0x123");
|
||||||
|
TEST32("\x9a\x67\x45\x23\x01\x23\x00", "call far 0x23:0x1234567");
|
||||||
|
TEST32("\x9a\xff\xff\xff\xff\xff\xff", "call far 0xffff:0xffffffff");
|
||||||
|
TEST32("\x66\xff\x1f", "call far dword ptr [edi]");
|
||||||
|
TEST64("\x66\xff\x1f", "call far dword ptr [rdi]");
|
||||||
|
TEST32("\xff\x1f", "call far fword ptr [edi]");
|
||||||
|
TEST64("\xff\x1f", "call far fword ptr [rdi]");
|
||||||
|
TEST64("\x48\xff\x1f", "call far tbyte ptr [rdi]");
|
||||||
|
TEST32("\x66\x0f\xb4\x07", "lfs ax, dword ptr [edi]");
|
||||||
|
TEST64("\x66\x0f\xb4\x07", "lfs ax, dword ptr [rdi]");
|
||||||
|
TEST32("\x0f\xb4\x07", "lfs eax, fword ptr [edi]");
|
||||||
|
TEST64("\x0f\xb4\x07", "lfs eax, fword ptr [rdi]");
|
||||||
|
TEST64("\x48\x0f\xb4\x07", "lfs rax, tbyte ptr [rdi]");
|
||||||
TEST("\xa5", "movsd");
|
TEST("\xa5", "movsd");
|
||||||
TEST("\x64\xa5", "fs movsd");
|
TEST("\x64\xa5", "fs movsd");
|
||||||
TEST32("\x2e\xa5", "cs movsd");
|
TEST32("\x2e\xa5", "cs movsd");
|
||||||
|
|||||||
Reference in New Issue
Block a user