Decoding some more i386
This commit is contained in:
parent
41e423407f
commit
8a24516f7f
@ -119,15 +119,15 @@ typedef struct _ArchOperand
|
||||
/* AOT_DREGISTER */
|
||||
struct
|
||||
{
|
||||
char * name;
|
||||
char const * name;
|
||||
int64_t offset;
|
||||
} dregister;
|
||||
|
||||
/* AOT_DREGISTER2 */
|
||||
struct
|
||||
{
|
||||
char * name;
|
||||
char * name2;
|
||||
char const * name;
|
||||
char const * name2;
|
||||
} dregister2;
|
||||
|
||||
/* AOT_IMMEDIATE */
|
||||
@ -140,7 +140,7 @@ typedef struct _ArchOperand
|
||||
/* AOT_REGISTER */
|
||||
struct
|
||||
{
|
||||
char * name;
|
||||
char const * name;
|
||||
} _register;
|
||||
/* FIXME complete */
|
||||
} value;
|
||||
@ -181,6 +181,8 @@ typedef struct _ArchPluginHelper
|
||||
char const * (*get_filename)(Arch * arch);
|
||||
ArchInstruction * (*get_instruction_by_opcode)(Arch * arch,
|
||||
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,
|
||||
char const * name, uint32_t size);
|
||||
|
||||
|
50
src/arch.c
50
src/arch.c
@ -386,13 +386,15 @@ ArchRegister * arch_get_register(Arch * arch, size_t index)
|
||||
}
|
||||
|
||||
|
||||
/* arch_get_register_by_id */
|
||||
ArchRegister * arch_get_register_by_id(Arch * arch, unsigned int id)
|
||||
/* arch_get_register_by_id_size */
|
||||
ArchRegister * arch_get_register_by_id_size(Arch * arch, uint32_t id,
|
||||
uint32_t size)
|
||||
{
|
||||
size_t 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 NULL;
|
||||
}
|
||||
@ -449,8 +451,44 @@ int arch_decode(Arch * arch)
|
||||
|
||||
static void _decode_print(ArchInstructionCall * call)
|
||||
{
|
||||
/* FIXME really implement */
|
||||
printf("\t%s\n", call->name);
|
||||
char const * sep = "\t";
|
||||
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.get_filename = _arch_get_filename;
|
||||
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.read = NULL;
|
||||
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.get_filename = _arch_get_filename;
|
||||
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.write = NULL;
|
||||
arch->helper.read = _arch_read_buffer;
|
||||
|
@ -43,7 +43,8 @@ ArchInstruction * arch_get_instruction_by_call(Arch * arch,
|
||||
ArchInstructionCall * call);
|
||||
|
||||
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_size(Arch * arch, char const * name,
|
||||
uint32_t size);
|
||||
|
@ -30,13 +30,21 @@ static int _i386_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||
|
||||
/* functions */
|
||||
/* 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)
|
||||
{
|
||||
ArchPluginHelper * helper = plugin->helper;
|
||||
ArchInstruction * ai = NULL;
|
||||
uint8_t opcode;
|
||||
size_t i;
|
||||
|
||||
/* FIXME really implement */
|
||||
/* FIXME detect end of input */
|
||||
if(helper->read(helper->arch, &opcode, sizeof(opcode))
|
||||
!= sizeof(opcode))
|
||||
return -1;
|
||||
@ -53,6 +61,73 @@ static int _i386_decode(ArchPlugin * plugin, ArchInstructionCall * call)
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user