Let the arch plug-ins know the current base address when decoding instructions
This commit is contained in:
parent
ca032b4a0c
commit
d43e27eb8d
@ -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 */
|
||||
|
10
src/arch.c
10
src/arch.c
@ -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... */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user