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, int (*write)(ArchPlugin * arch, ArchInstruction * instruction,
ArchInstructionCall * call); ArchInstructionCall * call);
int (*decode)(ArchPlugin * arch, ArchInstructionCall * call); int (*decode)(ArchPlugin * arch, ArchInstructionCall * call,
off_t base);
}; };
#endif /* !DEVEL_ASM_ARCH_H */ #endif /* !DEVEL_ASM_ARCH_H */

View File

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

View File

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

View File

@ -79,7 +79,8 @@ static ArchInstruction _dalvik_instructions[] =
/* plug-in */ /* plug-in */
static int _dalvik_write(ArchPlugin * plugin, ArchInstruction * instruction, static int _dalvik_write(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call); ArchInstructionCall * call);
static int _dalvik_decode(ArchPlugin * plugin, ArchInstructionCall * call); static int _dalvik_decode(ArchPlugin * plugin, ArchInstructionCall * call,
off_t base);
/* public */ /* 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_operand(DalvikDecode * dd, size_t i);
static int _decode_register(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; DalvikDecode dd;
ArchPluginHelper * helper = plugin->helper; ArchPluginHelper * helper = plugin->helper;

View File

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

View File

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

View File

@ -22,7 +22,8 @@
/* private */ /* private */
/* prototypes */ /* prototypes */
/* plug-in */ /* 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, static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
ArchInstructionCall * call); ArchInstructionCall * call);
@ -30,7 +31,8 @@ static int _sparc_write(ArchPlugin * plugin, ArchInstruction * instruction,
/* functions */ /* functions */
/* plug-in */ /* plug-in */
/* sparc_decode */ /* 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; ArchPluginHelper * helper = plugin->helper;
uint32_t u32; uint32_t u32;

View File

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