diff --git a/src/arch.c b/src/arch.c index abb2368..8e6fe24 100644 --- a/src/arch.c +++ b/src/arch.c @@ -449,7 +449,8 @@ int arch_decode(Arch * arch) if(arch->plugin->decode == NULL) return -error_set_code(1, "%s: %s", arch->plugin->name, "Disassembly not supported"); - for(offset = 0; arch->plugin->decode(arch->plugin, &call) == 0; + for(offset = arch->buffer_pos; + arch->plugin->decode(arch->plugin, &call) == 0; offset = arch->buffer_pos) _decode_print(offset, &call); return 0; diff --git a/src/arch/dalvik.c b/src/arch/dalvik.c index b60ca84..92e0d46 100644 --- a/src/arch/dalvik.c +++ b/src/arch/dalvik.c @@ -17,11 +17,22 @@ #include #include +#include #include "Asm.h" /* Dalvik */ /* private */ +/* types */ +typedef struct _DalvikDecode +{ + ArchPlugin * plugin; + ArchInstructionCall * call; + + uint8_t u8; +} DalvikDecode; + + /* constants */ /* register sizes */ #define REG(name, size, id) REG_ ## name ## _size = size, @@ -123,20 +134,21 @@ static int _dalvik_write(ArchPlugin * plugin, ArchInstruction * instruction, /* dalvik_decode */ -static int _decode_immediate(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 _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) { + DalvikDecode dd; ArchPluginHelper * helper = plugin->helper; uint8_t u8; ArchInstruction * ai; size_t i; + memset(&dd, 0, sizeof(dd)); + dd.plugin = plugin; + dd.call = call; /* FIXME detect end of input */ if(helper->read(helper->arch, &u8, sizeof(u8)) != sizeof(u8)) return -1; @@ -152,23 +164,25 @@ static int _dalvik_decode(ArchPlugin * plugin, ArchInstructionCall * call) 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) + if(_decode_operand(&dd, i) != 0) return -1; call->operands_cnt = i; return 0; } -static int _decode_immediate(ArchPlugin * plugin, ArchInstructionCall * call, - size_t i) +static int _decode_immediate(DalvikDecode * dd, size_t i) { - ArchPluginHelper * helper = plugin->helper; - ArchOperand * ao = &call->operands[i]; + ArchPluginHelper * helper = dd->plugin->helper; + ArchOperand * ao = &dd->call->operands[i]; uint8_t u8; uint16_t u16; uint32_t u32; - switch(AO_GET_SIZE(call->operands[i].type)) + switch(AO_GET_SIZE(dd->call->operands[i].type)) { + case 4: + ao->value.immediate.value = dd->u8 & 0xf; + break; case 8: if(helper->read(helper->arch, &u8, sizeof(u8)) != sizeof(u8)) @@ -194,36 +208,41 @@ static int _decode_immediate(ArchPlugin * plugin, ArchInstructionCall * call, return 0; } -static int _decode_operand(ArchPlugin * plugin, ArchInstructionCall * call, - size_t i) +static int _decode_operand(DalvikDecode * dd, size_t i) { - switch(AO_GET_TYPE(call->operands[i].type)) + switch(AO_GET_TYPE(dd->call->operands[i].type)) { case AOT_IMMEDIATE: - return _decode_immediate(plugin, call, i); + return _decode_immediate(dd, i); case AOT_REGISTER: - return _decode_register(plugin, call, i); + return _decode_register(dd, i); default: return -1; } return 0; } -static int _decode_register(ArchPlugin * plugin, ArchInstructionCall * call, - size_t i) +static int _decode_register(DalvikDecode * dd, size_t i) { - ArchPluginHelper * helper = plugin->helper; + ArchPluginHelper * helper = dd->plugin->helper; uint32_t id; uint8_t u8; uint16_t u16; ArchRegister * ar; - if(AO_GET_FLAGS(call->operands[i].type) & AOF_IMPLICIT) - id = AO_GET_VALUE(call->operands[i].type); - else if(AO_GET_FLAGS(call->operands[i].type) & AOF_DALVIK_REGSIZE) + if(AO_GET_FLAGS(dd->call->operands[i].type) & AOF_IMPLICIT) + id = AO_GET_VALUE(dd->call->operands[i].type); + else if(AO_GET_FLAGS(dd->call->operands[i].type) & AOF_DALVIK_REGSIZE) { - switch(AO_GET_VALUE(call->operands[i].type)) + switch(AO_GET_VALUE(dd->call->operands[i].type)) { + case 4: + if(helper->read(helper->arch, &u8, sizeof(u8)) + != sizeof(u8)) + return -1; + id = u8 >> 4; + dd->u8 = u8; + break; case 8: if(helper->read(helper->arch, &u8, sizeof(u8)) != sizeof(u8)) @@ -236,8 +255,6 @@ static int _decode_register(ArchPlugin * plugin, ArchInstructionCall * call, return -1; id = _htol16(u16); break; - case 4: - /* FIXME implement */ default: return -1; } @@ -246,6 +263,6 @@ static int _decode_register(ArchPlugin * plugin, ArchInstructionCall * call, return -1; if((ar = helper->get_register_by_id_size(helper->arch, id, 32)) == NULL) return -1; - call->operands[i].value._register.name = ar->name; + dd->call->operands[i].value._register.name = ar->name; return 0; } diff --git a/src/arch/dalvik.ins b/src/arch/dalvik.ins index cb8e66c..f2e65c2 100644 --- a/src/arch/dalvik.ins +++ b/src/arch/dalvik.ins @@ -26,9 +26,11 @@ #define AOF_DALVIK_REGSIZE 0x2 #define OP_v0 AO_REGISTER(AOF_IMPLICIT, 32, REG_v0_id) #define OP_REGISTER AO_REGISTER(0, 32, 0) +#define OP_REG4 AO_REGISTER(AOF_DALVIK_REGSIZE, 32, 4) #define OP_REG8 AO_REGISTER(AOF_DALVIK_REGSIZE, 32, 8) /* immediate values */ +#define OP_U4 AO_IMMEDIATE(0, 0, 4) #define OP_U8 AO_IMMEDIATE(0, 0, 8) #define OP_U16 AO_IMMEDIATE(0, 0, 16) #define OP_U32 AO_IMMEDIATE(0, 0, 32) @@ -83,9 +85,7 @@ { "cmpl-double", 0x2f, OP1F, OP_REGISTER, OP_REGISTER, OP_REGISTER }, { "cmpl-float", 0x2d, OP1F, OP_REGISTER, OP_REGISTER, OP_REGISTER }, { "const", 0x14, OP1F, OP_REGISTER, OP_U32, AOT_NONE }, -#if 1 /* XXX really implement */ -{ "const/4", 0x12, OP1F, OP_v0, OP_U8, AOT_NONE }, -#endif +{ "const/4", 0x12, OP1F, OP_REG4, OP_U4, AOT_NONE }, { "const/16", 0x13, OP1F, OP_REGISTER, OP_U16, AOT_NONE }, { "const/high16", 0x15, OP1F, OP_REGISTER, OP_U16, AOT_NONE }, { "const-class", 0x1c, OP1F, OP_REGISTER, OP_U16, AOT_NONE }, @@ -271,13 +271,13 @@ { "shr-long/2addr", 0xc4, OP1F, OP_v0, OP_REGISTER, AOT_NONE }, { "sparse-switch", 0x2c, OP1F, OP_REGISTER, OP_U32, AOT_NONE }, #endif -{ "sput", 0x67, OP1F, OP_REGISTER, OP_U16, AOT_NONE }, -{ "sput-boolean", 0x6a, OP1F, OP_REGISTER, OP_U16, AOT_NONE }, -{ "sput-byte", 0x6b, OP1F, OP_REGISTER, OP_U16, AOT_NONE }, -{ "sput-char", 0x6c, OP1F, OP_REGISTER, OP_U16, AOT_NONE }, -{ "sput-object", 0x69, OP1F, OP_REGISTER, OP_U16, AOT_NONE }, -{ "sput-short", 0x6d, OP1F, OP_REGISTER, OP_U16, AOT_NONE }, -{ "sput-wide", 0x68, OP1F, OP_REGISTER, OP_U16, AOT_NONE }, +{ "sput", 0x67, OP1F, OP_REG8, OP_U16, AOT_NONE }, +{ "sput-boolean", 0x6a, OP1F, OP_REG8, OP_U16, AOT_NONE }, +{ "sput-byte", 0x6b, OP1F, OP_REG8, OP_U16, AOT_NONE }, +{ "sput-char", 0x6c, OP1F, OP_REG8, OP_U16, AOT_NONE }, +{ "sput-object", 0x69, OP1F, OP_REG8, OP_U16, AOT_NONE }, +{ "sput-short", 0x6d, OP1F, OP_REG8, OP_U16, AOT_NONE }, +{ "sput-wide", 0x68, OP1F, OP_REG8, OP_U16, AOT_NONE }, { "sub-double", 0xac, OP1F, OP_REGISTER, OP_REGISTER, OP_REGISTER }, { "sub-double/2addr", 0xcc, OP1F, OP_v0, OP_REGISTER, AOT_NONE }, { "sub-float", 0xa7, OP1F, OP_REGISTER, OP_REGISTER, OP_REGISTER }, diff --git a/src/code.c b/src/code.c index f198ee3..8c0f025 100644 --- a/src/code.c +++ b/src/code.c @@ -162,7 +162,8 @@ static int _decode_file_callback(void * priv, char const * section, Code * code = priv; if(section != NULL) - printf("%s%s:\n\n", "\nDisassembly of section ", section); + printf("%s%s:\n", "\nDisassembly of section ", section); + putchar('\n'); return arch_decode_at(code->arch, offset, size, base); }