Fix handling of 66h prefix on jumps
It turns out that in x86-64 mode, address and operand size overrides are ignored by the processor. (Tested that on a real machine.) Even libopcodes gets this wrong...
This commit is contained in:
11
decode.c
11
decode.c
@@ -570,6 +570,8 @@ decode(const uint8_t* buffer, int len, DecodeMode mode, uintptr_t address,
|
|||||||
}
|
}
|
||||||
else if (UNLIKELY(imm_control != 0))
|
else if (UNLIKELY(imm_control != 0))
|
||||||
{
|
{
|
||||||
|
struct Operand* operand = &instr->operands[DESC_IMM_IDX(desc)];
|
||||||
|
|
||||||
uint8_t imm_size;
|
uint8_t imm_size;
|
||||||
if (DESC_IMM_BYTE(desc))
|
if (DESC_IMM_BYTE(desc))
|
||||||
{
|
{
|
||||||
@@ -583,6 +585,14 @@ decode(const uint8_t* buffer, int len, DecodeMode mode, uintptr_t address,
|
|||||||
{
|
{
|
||||||
imm_size = 3;
|
imm_size = 3;
|
||||||
}
|
}
|
||||||
|
#if defined(ARCH_X86_64)
|
||||||
|
else if (mode == DECODE_64 && UNLIKELY(imm_control == 4))
|
||||||
|
{
|
||||||
|
// Jumps are always 8 or 32 bit on x86-64.
|
||||||
|
imm_size = 4;
|
||||||
|
operand->size = 8;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else if (prefixes & PREFIX_OPSZ)
|
else if (prefixes & PREFIX_OPSZ)
|
||||||
{
|
{
|
||||||
imm_size = 2;
|
imm_size = 2;
|
||||||
@@ -634,7 +644,6 @@ decode(const uint8_t* buffer, int len, DecodeMode mode, uintptr_t address,
|
|||||||
instr->immediate += instr->address + off;
|
instr->immediate += instr->address + off;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Operand* operand = &instr->operands[DESC_IMM_IDX(desc)];
|
|
||||||
if (UNLIKELY(imm_control == 5))
|
if (UNLIKELY(imm_control == 5))
|
||||||
{
|
{
|
||||||
operand->type = OT_REG;
|
operand->type = OT_REG;
|
||||||
|
|||||||
4
tests/decode-jmp.txt
Normal file
4
tests/decode-jmp.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
decode32 e900000000 [JMP imm4:0x1234005]
|
||||||
|
decode32 66e90100 [JMP imm2:0x4005]
|
||||||
|
decode64 e900000000 [JMP imm8:0x1234005]
|
||||||
|
decode64 66e900000000 [JMP imm8:0x1234006]
|
||||||
@@ -19,6 +19,7 @@ testcases = [
|
|||||||
['enter', 'decode-enter.sh'],
|
['enter', 'decode-enter.sh'],
|
||||||
['imul', 'decode-imul.sh'],
|
['imul', 'decode-imul.sh'],
|
||||||
['inc', 'decode-inc.sh'],
|
['inc', 'decode-inc.sh'],
|
||||||
|
['jmp', 'decode-jmp.txt'],
|
||||||
['movsx', 'decode-movsx.sh'],
|
['movsx', 'decode-movsx.sh'],
|
||||||
['ret', 'decode-ret.sh'],
|
['ret', 'decode-ret.sh'],
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user