Disassembling some more Dalvik

This commit is contained in:
Pierre Pronchery 2011-04-23 21:06:48 +00:00
parent a4c030b500
commit 5e227be104
4 changed files with 58 additions and 39 deletions

View File

@ -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;

View File

@ -17,11 +17,22 @@
#include <System.h>
#include <stdio.h>
#include <string.h>
#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;
}

View File

@ -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 },

View File

@ -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);
}