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,
|
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 */
|
||||||
|
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 */
|
/* 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... */
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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))
|
||||||
|
Loading…
Reference in New Issue
Block a user