Beginning to get the Mod R/M byte right (not considering the SIB at all)

This commit is contained in:
Pierre Pronchery 2011-04-17 04:02:20 +00:00
parent 0ff490e2a0
commit e853ba8c28
4 changed files with 98 additions and 39 deletions

View File

@ -67,11 +67,10 @@ typedef enum _ArchOperandType
# define AOM_VALUE 0x000000ff
/* flags */
# define AOF_FILTER 0x1
/* for immediate */
# define AOF_SIGNED 0x2
# define AOF_SIGNED 0x1
/* for registers */
# define AOF_IMPLICIT 0x2
# define AOF_IMPLICIT 0x1
/* macros */
# define AO_GET_FLAGS(operand) ((operand & AOM_FLAGS) >> AOD_FLAGS)

View File

@ -118,17 +118,51 @@ static int _i386_write(ArchPlugin * plugin, ArchInstruction * instruction,
static int _write_dregister(ArchPlugin * plugin,
ArchOperandDefinition definition, ArchOperand * operand)
{
/* FIXME really implement */
return _write_register(plugin, definition, operand);
ArchPluginHelper * helper = plugin->helper;
char const * name = operand->value._register.name;
size_t size = AO_GET_SIZE(definition);
ArchRegister * ar;
ArchOperandDefinition idefinition;
ArchOperand ioperand;
if((ar = helper->get_register_by_name_size(helper->arch, name, size))
== NULL)
return -1;
/* write register */
idefinition = AO_IMMEDIATE(0, 0, 8);
memset(&ioperand, 0, sizeof(ioperand));
ioperand.type = AOT_IMMEDIATE;
ioperand.value.immediate.value = ar->id;
if(AO_GET_FLAGS(definition) & AOF_I386_MODRM)
ioperand.value.immediate.value |= (AO_GET_VALUE(definition)
<< 3);
if(operand->value.dregister.offset == 0)
/* there is no offset */
return _write_immediate(plugin, idefinition, &ioperand);
/* declare offset */
switch(AO_GET_OFFSET(definition) >> 3)
{
case sizeof(uint8_t):
ioperand.value.immediate.value |= 0x40;
break;
case W >> 3:
ioperand.value.immediate.value |= 0x80;
break;
default:
return -1; /* FIXME report error */
}
if(_write_immediate(plugin, idefinition, &ioperand) != 0)
return -1;
/* write offset */
idefinition = AO_IMMEDIATE(0, 0, AO_GET_OFFSET(definition));
ioperand.value.immediate.value = operand->value.dregister.offset;
return _write_immediate(plugin, idefinition, &ioperand);
}
static int _write_immediate(ArchPlugin * plugin,
ArchOperandDefinition definition, ArchOperand * operand)
{
size_t size;
size = AO_GET_SIZE(definition) >> 3;
switch(size)
switch(AO_GET_SIZE(definition) >> 3)
{
case 0:
return 0;
@ -231,6 +265,10 @@ static int _write_register(ArchPlugin * plugin,
idefinition = AO_IMMEDIATE(0, 0, 8);
memset(&ioperand, 0, sizeof(ioperand));
ioperand.type = AOT_IMMEDIATE;
ioperand.value.immediate.value = ar->id;
if(AO_GET_FLAGS(definition) & AOF_I386_MODRM)
ioperand.value.immediate.value = 0xc0 | ar->id
| (AO_GET_VALUE(definition) << 3);
else
ioperand.value.immediate.value = ar->id;
return _write_immediate(plugin, idefinition, &ioperand);
}

View File

@ -7,40 +7,55 @@
# define REG_AX_id REG_eax_id
#endif
/* helpers */
/* opcodes */
#define OP1F (8 << AOD_SIZE)
#define OP2F (16 << AOD_SIZE)
/* operands */
/* registers */
#define OP_R8 AO_REGISTER(0, 8, 0)
#define OP_RW AO_REGISTER(0, W, 0)
#define OP_al AO_REGISTER(AOF_IMPLICIT, REG_al_size, REG_al_id)
#define OP_AX AO_REGISTER(AOF_IMPLICIT, W, REG_AX_id)
/* helpers */
#define OP1F (8 << AOD_SIZE)
#define OP2F (16 << AOD_SIZE)
/* mod r/m byte */
#define OP_RM8_D0 AO_DREGISTER(0, 0, 8, 0)
#define OP_RM8_D8 AO_DREGISTER(0, 8, 8, 0)
#define OP_RM8_DW AO_DREGISTER(0, W, 8, 0)
#define OP_RM8_RW AO_REGISTER(0, 8, 0)
#define OP_RMW_D0 AO_DREGISTER(0, 0, W, 0)
#define OP_RMW_D8 AO_DREGISTER(0, 8, W, 0)
#define OP_RMW_DW AO_DREGISTER(0, W, W, 0)
#define OP_RMW_RW AO_REGISTER(0, W, 0)
#define AOF_I386_MODRM 0x2
#define OP_RM8_D0 AO_DREGISTER(AOF_I386_MODRM, 0, W, 0) /* 0x00 */
#define OP_RM8_D8 AO_DREGISTER(AOF_I386_MODRM, 8, W, 0) /* 0x40 */
#define OP_RM8_DW AO_DREGISTER(AOF_I386_MODRM, W, W, 0) /* 0x80 */
#define OP_RM8_R8 AO_REGISTER(AOF_I386_MODRM, 8, 0) /* 0xc0 */
#define OP_RMW_D0 AO_DREGISTER(AOF_I386_MODRM, 0, W, 0) /* 0x00 */
#define OP_RMW_D8 AO_DREGISTER(AOF_I386_MODRM, 8, W, 0) /* 0x40 */
#define OP_RMW_DW AO_DREGISTER(AOF_I386_MODRM, W, W, 0) /* 0x80 */
#define OP_RMW_RW AO_REGISTER(AOF_I386_MODRM, W, 0) /* 0xc0 */
/* immediate values */
#define OP_U8 AO_IMMEDIATE(0, 0, 8)
#define OP_UW AO_IMMEDIATE(0, 0, W)
/* instructions */
{ "aaa", 0x37, OP1F, AOT_NONE, AOT_NONE, AOT_NONE },
{ "aad", 0xd50a, OP2F, AOT_NONE, AOT_NONE, AOT_NONE },
{ "aad", 0xd5, OP1F, OP_U8, AOT_NONE, AOT_NONE },
{ "aam", 0xd40a, OP2F, AOT_NONE, AOT_NONE, AOT_NONE },
{ "aam", 0xd4, OP1F, OP_U8, AOT_NONE, AOT_NONE },
{ "aas", 0x3f, OP1F, AOT_NONE, AOT_NONE, AOT_NONE },
{ "adc", 0x14, OP1F, OP_al, OP_U8, AOT_NONE },
{ "adc", 0x15, OP1F, OP_AX, OP_UW, AOT_NONE },
{ "adc", 0x80, OP1F, OP_RM8_D0,OP_U8, AOT_NONE },
{ "adc", 0x80, OP1F, OP_RM8_D8,OP_U8, AOT_NONE },
{ "adc", 0x80, OP1F, OP_RM8_DW,OP_U8, AOT_NONE },
{ "adc", 0x80, OP1F, OP_RM8_RW,OP_U8, AOT_NONE },
{ "adc", 0x81, OP1F, OP_RMW_D0,OP_UW, AOT_NONE },
{ "adc", 0x81, OP1F, OP_RMW_D8,OP_UW, AOT_NONE },
{ "adc", 0x81, OP1F, OP_RMW_DW,OP_UW, AOT_NONE },
{ "adc", 0x81, OP1F, OP_RMW_RW,OP_UW, AOT_NONE },
{ "nop", 0x90, OP1F, AOT_NONE, AOT_NONE, AOT_NONE },
/* ADC 0x14 ib 1 al imm8 */
{ "adc", 0x14, OP1F, OP_al, OP_U8, AOT_NONE },
/* ADC 0x15 iW 1 AX immW */
{ "adc", 0x15, OP1F, OP_AX, OP_UW, AOT_NONE },
/* ADC 0x80 /2 ib 1 r/m8 imm8 */
{ "adc", 0x80, OP1F, OP_RM8_D0+2,OP_U8, AOT_NONE },
{ "adc", 0x80, OP1F, OP_RM8_D8+2,OP_U8, AOT_NONE },
{ "adc", 0x80, OP1F, OP_RM8_DW+2,OP_U8, AOT_NONE },
{ "adc", 0x80, OP1F, OP_RM8_R8+2,OP_U8, AOT_NONE },
/* ADC 0x81 /2 iW 1 r/m8 imm8 */
{ "adc", 0x81, OP1F, OP_RMW_D0+2,OP_UW, AOT_NONE },
{ "adc", 0x81, OP1F, OP_RMW_D8+2,OP_UW, AOT_NONE },
{ "adc", 0x81, OP1F, OP_RMW_DW+2,OP_UW, AOT_NONE },
{ "adc", 0x81, OP1F, OP_RMW_RW+2,OP_UW, AOT_NONE },
/* NOP */
{ "nop", 0x90, OP1F, AOT_NONE, AOT_NONE, AOT_NONE },

View File

@ -1,3 +1,4 @@
/* $Id$ */
.text
aaa
aad
@ -5,11 +6,17 @@
aam
aam $0x42
aas
adc %al, $0x42
adc %eax, $0x42
adc [%edx], $0x42
adc [%ebx + $0x5], $0x42
adc %ecx, $0x42
adc [%edx], $0x42434445
adc %ebx, $0x42434445
/* ADC */
adc %al, $0x40 /* 14 40 */
adc %eax, $0x41424344 /* 15 41 42 43 44 */
adc [%edx], $0x46 /* 80 12 46 */
adc [%ebx + $0x15], $0x47 /* 80 53 15 47 */
adc [%ebx + $0x16171819], $0x48 /* 80 93 19 18 17 16 48 */
adc %cl, $0x45 /* 80 d1 45 */
adc [%edx], $0x46474849 /* 81 12 46 47 48 49 */
adc [%ebx + $0x14], $0x4748494a /* 81 53 14 47 48 49 4a */
adc [%ebx + $0x16171819], $0x48494a4b
/* 81 93 19 18 17 16 4b */
/* 4a 49 48 */
adc %ecx, $0x45464748 /* 81 d1 45 46 47 48 */
nop