Decoding some more i386

This commit is contained in:
Pierre Pronchery 2011-04-23 07:46:35 +00:00
parent 41e423407f
commit 8a24516f7f
4 changed files with 129 additions and 11 deletions

View File

@ -119,15 +119,15 @@ typedef struct _ArchOperand
/* AOT_DREGISTER */ /* AOT_DREGISTER */
struct struct
{ {
char * name; char const * name;
int64_t offset; int64_t offset;
} dregister; } dregister;
/* AOT_DREGISTER2 */ /* AOT_DREGISTER2 */
struct struct
{ {
char * name; char const * name;
char * name2; char const * name2;
} dregister2; } dregister2;
/* AOT_IMMEDIATE */ /* AOT_IMMEDIATE */
@ -140,7 +140,7 @@ typedef struct _ArchOperand
/* AOT_REGISTER */ /* AOT_REGISTER */
struct struct
{ {
char * name; char const * name;
} _register; } _register;
/* FIXME complete */ /* FIXME complete */
} value; } value;
@ -181,6 +181,8 @@ typedef struct _ArchPluginHelper
char const * (*get_filename)(Arch * arch); char const * (*get_filename)(Arch * arch);
ArchInstruction * (*get_instruction_by_opcode)(Arch * arch, ArchInstruction * (*get_instruction_by_opcode)(Arch * arch,
uint8_t size, uint32_t opcode); uint8_t size, uint32_t opcode);
ArchRegister * (*get_register_by_id_size)(Arch * arch, uint32_t id,
uint32_t size);
ArchRegister * (*get_register_by_name_size)(Arch * arch, ArchRegister * (*get_register_by_name_size)(Arch * arch,
char const * name, uint32_t size); char const * name, uint32_t size);

View File

@ -386,13 +386,15 @@ ArchRegister * arch_get_register(Arch * arch, size_t index)
} }
/* arch_get_register_by_id */ /* arch_get_register_by_id_size */
ArchRegister * arch_get_register_by_id(Arch * arch, unsigned int id) ArchRegister * arch_get_register_by_id_size(Arch * arch, uint32_t id,
uint32_t size)
{ {
size_t i; size_t i;
for(i = 0; i < arch->registers_cnt; i++) for(i = 0; i < arch->registers_cnt; i++)
if(arch->plugin->registers[i].id == id) if(arch->plugin->registers[i].id == id
&& arch->plugin->registers[i].size == size)
return &arch->plugin->registers[i]; return &arch->plugin->registers[i];
return NULL; return NULL;
} }
@ -449,8 +451,44 @@ int arch_decode(Arch * arch)
static void _decode_print(ArchInstructionCall * call) static void _decode_print(ArchInstructionCall * call)
{ {
/* FIXME really implement */ char const * sep = "\t";
printf("\t%s\n", call->name); size_t i;
ArchOperand * ao;
char const * name;
printf("\t%s", call->name);
for(i = 0; i < call->operands_cnt; i++)
{
ao = &call->operands[i];
switch(AO_GET_TYPE(call->operands[i].type))
{
case AOT_DREGISTER:
name = ao->value.dregister.name;
printf("%s[%%%s + $0x%lx]", sep, name,
ao->value.dregister.offset);
sep = ", ";
break;
case AOT_DREGISTER2:
name = ao->value.dregister2.name;
printf("%s[%%%s + %%%s]", sep, name,
ao->value.dregister2.name2);
sep = ", ";
break;
case AOT_IMMEDIATE:
printf("%s%s$0x%lx", sep,
ao->value.immediate.negative
? "-" : "",
ao->value.immediate.value);
sep = ", ";
break;
case AOT_REGISTER:
name = call->operands[i].value._register.name;
printf("%s%%%s", sep, name);
sep = ", ";
break;
}
}
putchar('\n');
} }
@ -482,6 +520,7 @@ int arch_init(Arch * arch, char const * filename, FILE * fp)
arch->helper.arch = arch; arch->helper.arch = arch;
arch->helper.get_filename = _arch_get_filename; arch->helper.get_filename = _arch_get_filename;
arch->helper.get_instruction_by_opcode = arch_get_instruction_by_opcode; arch->helper.get_instruction_by_opcode = arch_get_instruction_by_opcode;
arch->helper.get_register_by_id_size = arch_get_register_by_id_size;
arch->helper.get_register_by_name_size = arch_get_register_by_name_size; arch->helper.get_register_by_name_size = arch_get_register_by_name_size;
arch->helper.read = NULL; arch->helper.read = NULL;
arch->helper.write = _arch_write; arch->helper.write = _arch_write;
@ -503,6 +542,7 @@ int arch_init_buffer(Arch * arch, char const * buffer, size_t size)
arch->helper.arch = arch; arch->helper.arch = arch;
arch->helper.get_filename = _arch_get_filename; arch->helper.get_filename = _arch_get_filename;
arch->helper.get_instruction_by_opcode = arch_get_instruction_by_opcode; arch->helper.get_instruction_by_opcode = arch_get_instruction_by_opcode;
arch->helper.get_register_by_id_size = arch_get_register_by_id_size;
arch->helper.get_register_by_name_size = arch_get_register_by_name_size; arch->helper.get_register_by_name_size = arch_get_register_by_name_size;
arch->helper.write = NULL; arch->helper.write = NULL;
arch->helper.read = _arch_read_buffer; arch->helper.read = _arch_read_buffer;

View File

@ -43,7 +43,8 @@ ArchInstruction * arch_get_instruction_by_call(Arch * arch,
ArchInstructionCall * call); ArchInstructionCall * call);
ArchRegister * arch_get_register(Arch * arch, size_t index); ArchRegister * arch_get_register(Arch * arch, size_t index);
ArchRegister * arch_get_register_by_id(Arch * arch, unsigned int id); ArchRegister * arch_get_register_by_id_size(Arch * arch, uint32_t id,
uint32_t size);
ArchRegister * arch_get_register_by_name(Arch * arch, char const * name); ArchRegister * arch_get_register_by_name(Arch * arch, char const * name);
ArchRegister * arch_get_register_by_name_size(Arch * arch, char const * name, ArchRegister * arch_get_register_by_name_size(Arch * arch, char const * name,
uint32_t size); uint32_t size);

View File

@ -30,13 +30,21 @@ static int _i386_write(ArchPlugin * plugin, ArchInstruction * instruction,
/* functions */ /* functions */
/* i386_decode */ /* i386_decode */
static int _decode_dregister(ArchPlugin * plugin, ArchInstructionCall * call,
size_t i);
static int _decode_operand(ArchPlugin * plugin, ArchInstructionCall * call,
size_t i);
static int _decode_register(ArchPlugin * plugin, ArchInstructionCall * call,
size_t i);
static int _i386_decode(ArchPlugin * plugin, ArchInstructionCall * call) static int _i386_decode(ArchPlugin * plugin, ArchInstructionCall * call)
{ {
ArchPluginHelper * helper = plugin->helper; ArchPluginHelper * helper = plugin->helper;
ArchInstruction * ai = NULL; ArchInstruction * ai = NULL;
uint8_t opcode; uint8_t opcode;
size_t i;
/* FIXME really implement */ /* FIXME detect end of input */
if(helper->read(helper->arch, &opcode, sizeof(opcode)) if(helper->read(helper->arch, &opcode, sizeof(opcode))
!= sizeof(opcode)) != sizeof(opcode))
return -1; return -1;
@ -53,6 +61,73 @@ static int _i386_decode(ArchPlugin * plugin, ArchInstructionCall * call)
return 0; return 0;
} }
call->name = ai->name; call->name = ai->name;
call->operands[0].type = ai->op1;
call->operands[1].type = ai->op2;
call->operands[2].type = ai->op3;
for(i = 0; AO_GET_TYPE(call->operands[i].type) != 0; i++)
if(_decode_operand(plugin, call, i) != 0)
return -1;
call->operands_cnt = i;
return 0;
}
static int _decode_dregister(ArchPlugin * plugin, ArchInstructionCall * call,
size_t i)
{
ArchPluginHelper * helper = plugin->helper;
ArchOperandDefinition aod = call->operands[i].type;
ArchRegister * ar;
uint8_t id;
/* FIXME check the size */
if(helper->read(helper->arch, &id, sizeof(id)) != sizeof(id))
return -1;
if((ar = helper->get_register_by_id_size(helper->arch, id,
AO_GET_SIZE(aod))) == NULL)
return -1;
call->operands[i].value.dregister.name = ar->name;
call->operands[i].value.dregister.offset = 0;
return 0;
}
static int _decode_operand(ArchPlugin * plugin, ArchInstructionCall * call,
size_t i)
{
switch(AO_GET_TYPE(call->operands[i].type))
{
/* FIXME implement the rest */
case AOT_DREGISTER:
return _decode_dregister(plugin, call, i);
case AOT_REGISTER:
return _decode_register(plugin, call, i);
}
return -error_set_code(1, "%s", strerror(ENOSYS));
}
static int _decode_register(ArchPlugin * plugin, ArchInstructionCall * call,
size_t i)
{
ArchPluginHelper * helper = plugin->helper;
ArchOperandDefinition aod = call->operands[i].type;
ArchRegister * ar;
uint8_t id;
if(AO_GET_FLAGS(aod) & AOF_IMPLICIT)
{
if((ar = helper->get_register_by_id_size(helper->arch,
AO_GET_VALUE(aod),
AO_GET_SIZE(aod))) == NULL)
return -1;
call->operands[i].value._register.name = ar->name;
return 0;
}
/* FIXME check the size */
if(helper->read(helper->arch, &id, sizeof(id)) != sizeof(id))
return -1;
if((ar = helper->get_register_by_id_size(helper->arch, id,
AO_GET_SIZE(aod))) == NULL)
return -1;
call->operands[i].value._register.name = ar->name;
return 0; return 0;
} }