Let the arch plug-ins know the current base address when decoding instructions

This commit is contained in:
Pierre Pronchery 2011-08-31 16:19:07 +00:00
parent ca032b4a0c
commit d43e27eb8d
8 changed files with 42 additions and 20 deletions

View File

@ -221,7 +221,8 @@ struct _ArchPlugin
int (*write)(ArchPlugin * arch, ArchInstruction * instruction,
ArchInstructionCall * call);
int (*decode)(ArchPlugin * arch, ArchInstructionCall * call);
int (*decode)(ArchPlugin * arch, ArchInstructionCall * call,
off_t base);
};
#endif /* !DEVEL_ASM_ARCH_H */

View File

@ -436,12 +436,13 @@ ArchRegister * arch_get_register_by_name_size(Arch * arch, char const * name,
/* useful */
/* arch_decode */
int arch_decode(Arch * arch, Code * code, ArchInstructionCall ** calls,
size_t * calls_cnt)
size_t * calls_cnt, off_t base)
{
int ret = 0;
ArchInstructionCall * c = NULL;
size_t c_cnt = 0;
ArchInstructionCall * p;
size_t offset = 0;
if(arch->plugin->decode == NULL)
return -error_set_code(1, "%s: %s", arch->plugin->name,
@ -458,11 +459,12 @@ int arch_decode(Arch * arch, Code * code, ArchInstructionCall ** calls,
c = p;
p = &c[c_cnt];
memset(p, 0, sizeof(*p));
p->base = arch->base;
p->base = base + offset;
p->offset = arch->buffer_pos;
if(arch->plugin->decode(arch->plugin, p) != 0)
if(arch->plugin->decode(arch->plugin, p, base) != 0)
break;
p->size = arch->buffer_pos - p->offset;
offset += p->size;
c_cnt++;
}
if(ret == 0)
@ -491,7 +493,7 @@ int arch_decode_at(Arch * arch, Code * code, ArchInstructionCall ** calls,
arch->code = code;
arch->buffer_pos = offset;
arch->buffer_cnt = offset + size;
if((ret = arch_decode(arch, code, calls, calls_cnt)) == 0
if((ret = arch_decode(arch, code, calls, calls_cnt, base)) == 0
&& fseek(arch->fp, offset + size, SEEK_SET) != 0)
{
free(*calls); /* XXX the pointer was updated anyway... */

View File

@ -61,7 +61,7 @@ int arch_write(Arch * arch, ArchInstruction * instruction,
/* disassembly */
int arch_decode(Arch * arch, Code * code, ArchInstructionCall ** calls,
size_t * calls_cnt);
size_t * calls_cnt, off_t base);
int arch_decode_at(Arch * arch, Code * code, ArchInstructionCall ** calls,
size_t * calls_cnt, off_t offset, size_t size, off_t base);
ssize_t arch_read(Arch * arch, void * buf, size_t cnt);

View File

@ -79,7 +79,8 @@ static ArchInstruction _dalvik_instructions[] =
/* plug-in */
static int _dalvik_write(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call);
static int _dalvik_decode(ArchPlugin * plugin, ArchInstructionCall * call);
static int _dalvik_decode(ArchPlugin * plugin, ArchInstructionCall * call,
off_t base);
/* public */
@ -138,7 +139,8 @@ static int _decode_immediate(DalvikDecode * dd, size_t i);
static int _decode_operand(DalvikDecode * dd, size_t i);
static int _decode_register(DalvikDecode * dd, size_t i);
static int _dalvik_decode(ArchPlugin * plugin, ArchInstructionCall * call)
static int _dalvik_decode(ArchPlugin * plugin, ArchInstructionCall * call,
off_t base)
{
DalvikDecode dd;
ArchPluginHelper * helper = plugin->helper;

View File

@ -23,7 +23,8 @@
/* i386 */
/* private */
/* prototypes */
static int _i386_decode(ArchPlugin * plugin, ArchInstructionCall * call);
static int _i386_decode(ArchPlugin * plugin, ArchInstructionCall * call,
off_t base);
static int _i386_write(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call);
@ -45,18 +46,22 @@ static int _decode_operand(ArchPlugin * plugin, ArchInstructionCall * call,
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,
off_t base)
{
ArchPluginHelper * helper = plugin->helper;
ArchInstruction * ai = NULL;
unsigned int opcode;
uint8_t u8;
uint16_t u16;
size_t i;
off_t offset;
/* FIXME detect end of input */
if(helper->read(helper->arch, &u8, sizeof(u8)) != sizeof(u8))
return -1;
if((ai = helper->get_instruction_by_opcode(helper->arch, 8, u8))
opcode = u8;
if((ai = helper->get_instruction_by_opcode(helper->arch, 8, opcode))
== NULL)
{
u16 = u8;
@ -70,9 +75,9 @@ static int _i386_decode(ArchPlugin * plugin, ArchInstructionCall * call)
call->operands_cnt = 1;
return 0;
}
u16 = (u16 << 8) | u8;
opcode = (u16 << 8) | u8;
if((ai = helper->get_instruction_by_opcode(helper->arch, 16,
u16)) == NULL)
opcode)) == NULL)
{
call->name = "dw";
call->operands[0].definition = AO_IMMEDIATE(0, 16, 0);
@ -92,6 +97,14 @@ static int _i386_decode(ArchPlugin * plugin, ArchInstructionCall * call)
if(_decode_operand(plugin, call, &i) != 0)
return -1;
call->operands_cnt = i;
/* additional adjustments */
switch(opcode)
{
case 0xe8: /* call */
call->operands[0].value.immediate.value += call->base
+ 5;
break;
}
return 0;
}

View File

@ -250,7 +250,8 @@ static ArchInstruction _java_instructions[] =
/* plug-in */
static int _java_write(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call);
static int _java_decode(ArchPlugin * plugin, ArchInstructionCall * call);
static int _java_decode(ArchPlugin * plugin, ArchInstructionCall * call,
off_t base);
/* public */
@ -317,7 +318,8 @@ static int _java_write(ArchPlugin * plugin, ArchInstruction * instruction,
/* java_decode */
static int _java_decode(ArchPlugin * plugin, ArchInstructionCall * call)
static int _java_decode(ArchPlugin * plugin, ArchInstructionCall * call,
off_t base)
{
ArchPluginHelper * helper = plugin->helper;
uint8_t u8;

View File

@ -22,7 +22,8 @@
/* private */
/* prototypes */
/* plug-in */
static int _sparc_decode(ArchPlugin * plugin, ArchInstructionCall * call);
static int _sparc_decode(ArchPlugin * plugin, ArchInstructionCall * call,
off_t base);
static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call);
@ -30,7 +31,8 @@ static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
/* functions */
/* plug-in */
/* sparc_decode */
static int _sparc_decode(ArchPlugin * plugin, ArchInstructionCall * call)
static int _sparc_decode(ArchPlugin * plugin, ArchInstructionCall * call,
off_t base)
{
ArchPluginHelper * helper = plugin->helper;
uint32_t u32;

View File

@ -338,7 +338,7 @@ int code_decode_at(Code * code, char const * section, off_t offset,
base) != 0)
return -1;
if(size != 0)
printf("\n%08lx:\n", (long)offset + (long)base);
printf("\n%08lx:\n", (long)base);
for(i = 0; i < calls_cnt; i++)
code_print(code, &calls[i]);
free(calls);
@ -357,7 +357,7 @@ int code_decode_buffer(Code * code, char const * buffer, size_t size)
size_t i;
arch_init_buffer(code->arch, buffer, size);
if((ret = arch_decode(code->arch, code, &calls, &calls_cnt)) == 0)
if((ret = arch_decode(code->arch, code, &calls, &calls_cnt, 0)) == 0)
{
for(i = 0; i < calls_cnt; i++)
code_print(code, &calls[i]);
@ -429,7 +429,7 @@ int code_print(Code * code, ArchInstructionCall * call)
if(arch_seek(code->arch, call->offset, SEEK_SET) < 0)
return -1;
printf("%8lx:", (long)call->base + (long)call->offset);
printf("%8lx:", (long)call->base);
for(i = 0; i < call->size; i++)
{
if(arch_read(code->arch, &u8, sizeof(u8)) != sizeof(u8))