mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-23 21:29:49 +00:00
* Initial import of Dalvik (Android VM) disassemble plugin
* Change opcode buffer size to 3218 (need refactor)
This commit is contained in:
parent
74ff5af871
commit
0283c92f6e
302
libr/asm/arch/dalvik/opcode.h
Normal file
302
libr/asm/arch/dalvik/opcode.h
Normal file
@ -0,0 +1,302 @@
|
||||
/* radare - GPL3 - Copyright 2009-2010 */
|
||||
|
||||
enum fmt_inst {
|
||||
fmt00 = 0, // None
|
||||
fmtop, // op
|
||||
fmtopvAvB, // op vA, vB
|
||||
fmtopvAcB, // op vA, #+B
|
||||
fmtopvAA, // op vAA
|
||||
fmtoppAA, // op +AA
|
||||
fmtopAAtBBBB, // op AA, thing@BBBB
|
||||
fmtoppAAAA, // op +AAAA
|
||||
fmtopvAAvBBBB, // op vAA, vBBBB
|
||||
fmtopvAApBBBB, // op vAA, +BBBB
|
||||
fmtopvAAcBBBB, // op vAA, #+BBBB
|
||||
fmtopvAAcBBBB0000, // op vAA, #+BBBB00000[00000000]
|
||||
fmtopvAAtBBBB, // op vAA, thing@BBBB
|
||||
fmtopvAAvBBvCC, // op vAA, vBB, vCC
|
||||
fmtopvAAvBBcCC, // op vAA, vBB, #+CC
|
||||
fmtopvAvBpCCCC, // op vA, vB, +CCCC
|
||||
fmtopvAvBcCCCC, // op vA, vB, #+CCCC
|
||||
fmtopvAvBtCCCC, // op vA, vB, thing@CCCC
|
||||
fmtoptopvAvBoCCCC, // [opt] op vA, vB, field offset CCCC
|
||||
fmtopvAAAAvBBBB, // op vAAAA, vBBBB
|
||||
fmtoppAAAAAAAA, // op +AAAAAAAA
|
||||
fmtopvAApBBBBBBBB, // op vAA, +BBBBBBBB
|
||||
fmtopvAAcBBBBBBBB, // op vAA, #+BBBBBBBB
|
||||
fmtopvAAtBBBBBBBB, // op vAA, thing@BBBBBBBB
|
||||
fmtopvXtBBBB, // op {vC, vD, vE, vF, vG}, thing@BBBB (B: count, A: vG)
|
||||
fmtoptinvokeVS, // [opt] invoke-virtual+super
|
||||
fmtoptinvokeI, // [opt] invoke-interface
|
||||
fmtopvCCCCmBBBB, // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
|
||||
fmtoptinvokeVSR, // [opt] invoke-virtual+super/range
|
||||
fmtoptinvokeIR, // [opt] invoke-interface/range
|
||||
fmtoptinlineI, // [opt] inline invoke
|
||||
fmtoptinlineIR, // [opt] inline invoke/range
|
||||
fmtopvAAcBBBBBBBBBBBBBBBB, // op vAA, #+BBBBBBBBBBBBBBBB
|
||||
};
|
||||
|
||||
struct dalvik_opcodes_t {
|
||||
char *name;
|
||||
int len;
|
||||
int fmt;
|
||||
};
|
||||
|
||||
const struct dalvik_opcodes_t opcodes[256] = {
|
||||
{"nop", 2, fmtop}, /* 0x00 */
|
||||
{"move", 2, fmtopvAvB},
|
||||
{"move/from16", 4, fmtopvAAvBBBB},
|
||||
{"move/16", 6, fmtopvAAAAvBBBB},
|
||||
{"move-wide", 2, fmtopvAvB},
|
||||
{"move-wide/from16", 4, fmtopvAAvBBBB},
|
||||
{"move-wide/16", 6, fmtopvAAAAvBBBB},
|
||||
{"move-object", 2, fmtopvAvB},
|
||||
{"move-object/from16", 4, fmtopvAAvBBBB},
|
||||
{"move-object/16", 6, fmtopvAAAAvBBBB},
|
||||
{"move-result", 2, fmtopvAA},
|
||||
{"move-result-wide", 2, fmtopvAA},
|
||||
{"move-result-object", 2, fmtopvAA},
|
||||
{"move-exception", 2, fmtopvAA},
|
||||
{"return-void", 2, fmtop},
|
||||
{"return", 2, fmtopvAA},
|
||||
{"return-wide", 2, fmtopvAA}, /* 0x10 */
|
||||
{"return-object", 2, fmtopvAA},
|
||||
{"const/4", 2, fmtopvAcB},
|
||||
{"const/16", 4, fmtopvAAcBBBB},
|
||||
{"const", 6, fmtopvAAcBBBBBBBB},
|
||||
{"const/high16", 4, fmtopvAAcBBBB0000},
|
||||
{"const-wide/16", 4, fmtopvAAcBBBB},
|
||||
{"const-wide/32", 6, fmtopvAAcBBBBBBBB},
|
||||
{"const-wide", 10, fmtopvAAcBBBBBBBBBBBBBBBB},
|
||||
{"const-wide/high16", 4, fmtopvAAcBBBB0000},
|
||||
{"const-string", 4, fmtopvAAtBBBB},
|
||||
{"const-string/jumbo", 6, fmtopvAAtBBBBBBBB},
|
||||
{"const-class", 4, fmtopvAAtBBBB},
|
||||
{"monitor-enter", 2, fmtopvAA},
|
||||
{"monitor-exit", 2, fmtopvAA},
|
||||
{"check-cast", 4, fmtopvAAtBBBB},
|
||||
{"instance-of", 4, fmtopvAvBtCCCC}, /* 0x20 */
|
||||
{"array-length", 2, fmtopvAvB},
|
||||
{"new-instance", 4, fmtopvAAtBBBB},
|
||||
{"new-array", 4, fmtopvAvBtCCCC},
|
||||
{"filled-new-array", 6, fmtopvXtBBBB},
|
||||
{"filled-new-array/range", 6, fmtopvCCCCmBBBB},
|
||||
{"fill-array-data", 6, fmtopvAApBBBBBBBB},
|
||||
{"throw", 2, fmtopvAA},
|
||||
{"goto", 2, fmtoppAA},
|
||||
{"goto/16", 4, fmtoppAAAA},
|
||||
{"goto/32", 6, fmtoppAAAAAAAA},
|
||||
{"packed-switch", 6, fmtopvAApBBBBBBBB},
|
||||
{"sparse-switch", 6, fmtopvAApBBBBBBBB},
|
||||
{"cmpl-float", 4, fmtopvAAvBBvCC},
|
||||
{"cmpg-float", 4, fmtopvAAvBBvCC},
|
||||
{"cmpl-double", 4, fmtopvAAvBBvCC},
|
||||
{"cmpg-double", 4, fmtopvAAvBBvCC}, /* 0x30 */
|
||||
{"cmp-long", 4, fmtopvAAvBBvCC},
|
||||
{"if-eq", 4, fmtopvAvBpCCCC},
|
||||
{"if-ne", 4, fmtopvAvBpCCCC},
|
||||
{"if-lt", 4, fmtopvAvBpCCCC},
|
||||
{"if-ge", 4, fmtopvAvBpCCCC},
|
||||
{"if-gt", 4, fmtopvAvBpCCCC},
|
||||
{"if-le", 4, fmtopvAvBpCCCC},
|
||||
{"if-eqz", 4, fmtopvAApBBBB},
|
||||
{"if-nez", 4, fmtopvAApBBBB},
|
||||
{"if-ltz", 4, fmtopvAApBBBB},
|
||||
{"if-gez", 4, fmtopvAApBBBB},
|
||||
{"if-gtz", 4, fmtopvAApBBBB},
|
||||
{"if-lez", 4, fmtopvAApBBBB},
|
||||
{"UNUSED", 0, fmt00},
|
||||
{"UNUSED", 0, fmt00},
|
||||
{"UNUSED", 0, fmt00}, /* 0x40 */
|
||||
{"UNUSED", 0, fmt00},
|
||||
{"UNUSED", 0, fmt00},
|
||||
{"UNUSED", 0, fmt00},
|
||||
{"aget", 4, fmtopvAAvBBvCC},
|
||||
{"aget-wide", 4, fmtopvAAvBBvCC},
|
||||
{"aget-object", 4, fmtopvAAvBBvCC},
|
||||
{"aget-boolean", 4, fmtopvAAvBBvCC},
|
||||
{"aget-byte", 4, fmtopvAAvBBvCC},
|
||||
{"aget-char", 4, fmtopvAAvBBvCC},
|
||||
{"aget-short", 4, fmtopvAAvBBvCC},
|
||||
{"aput", 4, fmtopvAAvBBvCC},
|
||||
{"aput-wide", 4, fmtopvAAvBBvCC},
|
||||
{"aput-object", 4, fmtopvAAvBBvCC},
|
||||
{"aput-boolean", 4, fmtopvAAvBBvCC},
|
||||
{"aput-byte", 4, fmtopvAAvBBvCC},
|
||||
{"aput-char", 4, fmtopvAAvBBvCC}, /* 0x50 */
|
||||
{"aput-short", 4, fmtopvAAvBBvCC},
|
||||
{"iget", 4, fmtopvAvBtCCCC},
|
||||
{"iget-wide", 4, fmtopvAvBtCCCC},
|
||||
{"iget-object", 4, fmtopvAvBtCCCC},
|
||||
{"iget-boolean", 4, fmtopvAvBtCCCC},
|
||||
{"iget-byte", 4, fmtopvAvBtCCCC},
|
||||
{"iget-char", 4, fmtopvAvBtCCCC},
|
||||
{"iget-short", 4, fmtopvAvBtCCCC},
|
||||
{"iput", 4, fmtopvAvBtCCCC},
|
||||
{"iput-wide", 4, fmtopvAvBtCCCC},
|
||||
{"iput-object", 4, fmtopvAvBtCCCC},
|
||||
{"iput-boolean", 4, fmtopvAvBtCCCC},
|
||||
{"iput-byte", 4, fmtopvAvBtCCCC},
|
||||
{"iput-char", 4, fmtopvAvBtCCCC},
|
||||
{"iput-short", 4, fmtopvAvBtCCCC},
|
||||
{"sget", 4, fmtopvAAtBBBB}, /* 0x60 */
|
||||
{"sget-wide", 4, fmtopvAAtBBBB},
|
||||
{"sget-object", 4, fmtopvAAtBBBB},
|
||||
{"sget-boolean", 4, fmtopvAAtBBBB},
|
||||
{"sget-byte", 4, fmtopvAAtBBBB},
|
||||
{"sget-char", 4, fmtopvAAtBBBB},
|
||||
{"sget-short", 4, fmtopvAAtBBBB},
|
||||
{"sput", 4, fmtopvAAtBBBB},
|
||||
{"sput-wide", 4, fmtopvAAtBBBB},
|
||||
{"sput-object", 4, fmtopvAAtBBBB},
|
||||
{"sput-boolean", 4, fmtopvAAtBBBB},
|
||||
{"sput-byte", 4, fmtopvAAtBBBB},
|
||||
{"sput-char", 4, fmtopvAAtBBBB},
|
||||
{"sput-short", 4, fmtopvAAtBBBB},
|
||||
{"invoke-virtual", 6, fmtopvXtBBBB},
|
||||
{"invoke-super", 6, fmtopvXtBBBB},
|
||||
{"invoke-direct", 6, fmtopvXtBBBB}, /* 0x70 */
|
||||
{"invoke-static", 6, fmtopvXtBBBB},
|
||||
{"invoke-interface", 6, fmtopvXtBBBB}, //XXX: Maybe use opt invoke-interface ??
|
||||
{"UNUSED", 0, fmt00},
|
||||
{"invoke-virtual/range", 6, fmtopvCCCCmBBBB},
|
||||
{"invoke-super/range", 6, fmtopvCCCCmBBBB},
|
||||
{"invoke-direct/range", 6, fmtopvCCCCmBBBB},
|
||||
{"invoke-static/range", 6, fmtopvCCCCmBBBB},
|
||||
{"invoke-interface/range", 6, fmtopvCCCCmBBBB},
|
||||
{"UNUSED", 0, fmt00},
|
||||
{"UNUSED", 0, fmt00},
|
||||
{"neg-int", 2, fmtopvAvB},
|
||||
{"not-int", 2, fmtopvAvB},
|
||||
{"neg-long", 2, fmtopvAvB},
|
||||
{"not-long", 2, fmtopvAvB},
|
||||
{"neg-float", 2, fmtopvAvB},
|
||||
{"neg-double", 2, fmtopvAvB}, /* 0x80 */
|
||||
{"int-to-long", 2, fmtopvAvB},
|
||||
{"int-to-float", 2, fmtopvAvB},
|
||||
{"int-to-double", 2, fmtopvAvB},
|
||||
{"long-to-int", 2, fmtopvAvB},
|
||||
{"long-to-float", 2, fmtopvAvB},
|
||||
{"long-to-double", 2, fmtopvAvB},
|
||||
{"float-to-int", 2, fmtopvAvB},
|
||||
{"float-to-long", 2, fmtopvAvB},
|
||||
{"float-to-double", 2, fmtopvAvB},
|
||||
{"double-to-int", 2, fmtopvAvB},
|
||||
{"double-to-long", 2, fmtopvAvB},
|
||||
{"double-to-float", 2, fmtopvAvB},
|
||||
{"int-to-byte", 2, fmtopvAvB},
|
||||
{"int-to-char", 2, fmtopvAvB},
|
||||
{"int-to-short", 2, fmtopvAvB},
|
||||
{"add-int", 4, fmtopvAAvBBvCC}, /* 0x90 */
|
||||
{"sub-int", 4, fmtopvAAvBBvCC},
|
||||
{"mul-int", 4, fmtopvAAvBBvCC},
|
||||
{"div-int", 4, fmtopvAAvBBvCC},
|
||||
{"rem-int", 4, fmtopvAAvBBvCC},
|
||||
{"and-int", 4, fmtopvAAvBBvCC},
|
||||
{"or-int", 4, fmtopvAAvBBvCC},
|
||||
{"xor-int", 4, fmtopvAAvBBvCC},
|
||||
{"shl-int", 4, fmtopvAAvBBvCC},
|
||||
{"shr-int", 4, fmtopvAAvBBvCC},
|
||||
{"ushr-int", 4, fmtopvAAvBBvCC},
|
||||
{"add-long", 4, fmtopvAAvBBvCC},
|
||||
{"sub-long", 4, fmtopvAAvBBvCC},
|
||||
{"mul-long", 4, fmtopvAAvBBvCC},
|
||||
{"div-long", 4, fmtopvAAvBBvCC},
|
||||
{"rem-long", 4, fmtopvAAvBBvCC},
|
||||
{"and-long", 4, fmtopvAAvBBvCC}, /* 0xa0 */
|
||||
{"or-long", 4, fmtopvAAvBBvCC},
|
||||
{"xor-long", 4, fmtopvAAvBBvCC},
|
||||
{"shl-long", 4, fmtopvAAvBBvCC},
|
||||
{"shr-long", 4, fmtopvAAvBBvCC},
|
||||
{"ushr-long", 4, fmtopvAAvBBvCC},
|
||||
{"add-float", 4, fmtopvAAvBBvCC},
|
||||
{"sub-float", 4, fmtopvAAvBBvCC},
|
||||
{"mul-float", 4, fmtopvAAvBBvCC},
|
||||
{"div-float", 4, fmtopvAAvBBvCC},
|
||||
{"rem-float", 4, fmtopvAAvBBvCC},
|
||||
{"sub-double", 4, fmtopvAAvBBvCC},
|
||||
{"add-double", 4, fmtopvAAvBBvCC},
|
||||
{"mul-double", 4, fmtopvAAvBBvCC},
|
||||
{"div-double", 4, fmtopvAAvBBvCC},
|
||||
{"rem-double", 4, fmtopvAAvBBvCC},
|
||||
{"add-int/2addr", 2, fmtopvAvB}, /* 0xb0 */
|
||||
{"sub-int/2addr", 2, fmtopvAvB},
|
||||
{"mul-int/2addr", 2, fmtopvAvB},
|
||||
{"div-int/2addr", 2, fmtopvAvB},
|
||||
{"rem-int/2addr", 2, fmtopvAvB},
|
||||
{"and-int/2addr", 2, fmtopvAvB},
|
||||
{"or-int/2addr", 2, fmtopvAvB},
|
||||
{"xor-int/2addr", 2, fmtopvAvB},
|
||||
{"shl-int/2addr", 2, fmtopvAvB},
|
||||
{"shr-int/2addr", 2, fmtopvAvB},
|
||||
{"ushr-int/2addr", 2, fmtopvAvB},
|
||||
{"add-long/2addr", 2, fmtopvAvB},
|
||||
{"sub-long/2addr", 2, fmtopvAvB},
|
||||
{"mul-long/2addr", 2, fmtopvAvB},
|
||||
{"div-long/2addr", 2, fmtopvAvB},
|
||||
{"rem-long/2addr", 2, fmtopvAvB},
|
||||
{"and-long/2addr", 2, fmtopvAvB}, /* 0xc0 */
|
||||
{"or-long/2addr", 2, fmtopvAvB},
|
||||
{"xor-long/2addr", 2, fmtopvAvB},
|
||||
{"shl-long/2addr", 2, fmtopvAvB},
|
||||
{"shr-long/2addr", 2, fmtopvAvB},
|
||||
{"ushr-long/2addr", 2, fmtopvAvB},
|
||||
{"add-float/2addr", 2, fmtopvAvB},
|
||||
{"sub-float/2addr", 2, fmtopvAvB},
|
||||
{"mul-float/2addr", 2, fmtopvAvB},
|
||||
{"div-float/2addr", 2, fmtopvAvB},
|
||||
{"rem-float/2addr", 2, fmtopvAvB},
|
||||
{"add-double/2addr", 2, fmtopvAvB},
|
||||
{"sub-double/2addr", 2, fmtopvAvB},
|
||||
{"mul-double/2addr", 2, fmtopvAvB},
|
||||
{"div-double/2addr", 2, fmtopvAvB},
|
||||
{"rem-double/2addr", 2, fmtopvAvB},
|
||||
{"add-int/lit16", 4, fmtopvAvBcCCCC}, /* 0xd0 */
|
||||
{"rsub-int", 4, fmtopvAvBcCCCC},
|
||||
{"mul-int/lit16", 4, fmtopvAvBcCCCC},
|
||||
{"div-int/lit16", 4, fmtopvAvBcCCCC},
|
||||
{"rem-int/lit16", 4, fmtopvAvBcCCCC},
|
||||
{"and-int/lit16", 4, fmtopvAvBcCCCC},
|
||||
{"or-int/lit16", 4, fmtopvAvBcCCCC},
|
||||
{"xor-int/lit16", 4, fmtopvAvBcCCCC},
|
||||
{"add-int/lit8", 4, fmtopvAAvBBcCC},
|
||||
{"rsub-int/lit8", 4, fmtopvAAvBBcCC},
|
||||
{"mul-int/lit8", 4, fmtopvAAvBBcCC},
|
||||
{"div-int/lit8", 4, fmtopvAAvBBcCC},
|
||||
{"rem-int/lit8", 4, fmtopvAAvBBcCC},
|
||||
{"and-int/lit8", 4, fmtopvAAvBBcCC},
|
||||
{"or-int/lit8", 4, fmtopvAAvBBcCC},
|
||||
{"xor-int/lit8", 4, fmtopvAAvBBcCC},
|
||||
{"shl-int/lit8", 4, fmtopvAAvBBcCC}, /* 0xe0 */
|
||||
{"shr-int/lit8", 4, fmtopvAAvBBcCC},
|
||||
{"ushr-int/lit8", 4, fmtopvAAvBBcCC},
|
||||
{"+iget-volatile", 4, fmtopvAvBtCCCC},
|
||||
{"+iput-volatile", 4, fmtopvAvBtCCCC},
|
||||
{"+sget-volatile", 4, fmtopvAvBtCCCC},
|
||||
{"+sput-volatile", 4, fmtopvAvBtCCCC},
|
||||
{"+iget-object-volatile", 4, fmtopvAvBtCCCC},
|
||||
{"+iget-wide-volatile", 4, fmtopvAvBtCCCC},
|
||||
{"+iput-wide-volatile", 4, fmtopvAvBtCCCC},
|
||||
{"+sget-wide-volatile", 4, fmtopvAvBtCCCC},
|
||||
{"+sput-wide-volatile", 4, fmtopvAvBtCCCC},
|
||||
{"^breakpoint", 4, fmtopvAvBtCCCC},
|
||||
{"^throw-verification-error", 4, fmtopAAtBBBB},
|
||||
{"+execute-inline", 6, fmtoptinlineI},
|
||||
{"+execute-inline/range", 6, fmtoptinlineIR},
|
||||
{"+invoke-direct-empty", 6, fmtopvXtBBBB}, /* 0xf0 */
|
||||
{"UNUSED", 0, fmt00},
|
||||
{"+iget-quick", 4, fmtoptopvAvBoCCCC},
|
||||
{"+iget-wide-quick", 4, fmtoptopvAvBoCCCC},
|
||||
{"+iget-object-quick", 4, fmtoptopvAvBoCCCC},
|
||||
{"+iput-quick", 4, fmtoptopvAvBoCCCC},
|
||||
{"+iput-wide-quick", 4, fmtoptopvAvBoCCCC},
|
||||
{"+iput-object-quick", 4, fmtoptopvAvBoCCCC},
|
||||
{"+invoke-virtual-quick", 6, fmtoptinvokeVS},
|
||||
{"+invoke-virtual-quick/range", 6, fmtoptinvokeVSR},
|
||||
{"+invoke-super-quick", 6, fmtoptinvokeVS},
|
||||
{"+invoke-super-quick/range", 6, fmtoptinvokeVSR},
|
||||
{"+iput-object-volatile", 4, fmtopvAvBtCCCC},
|
||||
{"+sget-object-volatile", 4, fmtopvAAtBBBB},
|
||||
{"+sput-object-volatile", 4, fmtopvAAtBBBB},
|
||||
{"UNUSED", 0, fmt00}
|
||||
};
|
344
libr/asm/p/asm_dalvik.c
Normal file
344
libr/asm/p/asm_dalvik.c
Normal file
@ -0,0 +1,344 @@
|
||||
/* radare - GPL3 - Copyright 2009-2010 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_asm.h>
|
||||
|
||||
#include <dalvik/opcode.h>
|
||||
|
||||
static int pc;
|
||||
|
||||
static int disassemble(RAsm *a, RAsmAop *aop, ut8 *buf, ut64 len) {
|
||||
int i = (int) buf[0];
|
||||
int size = 0;
|
||||
int vA, vB, vC;
|
||||
char str[1024];
|
||||
|
||||
if (opcodes[i].len <= len) {
|
||||
strcpy (aop->buf_asm, opcodes[i].name);
|
||||
size = opcodes[i].len;
|
||||
switch (opcodes[i].fmt) {
|
||||
case fmtop: break;
|
||||
case fmtopvAvB:
|
||||
vA = buf[1] & 0x0f;
|
||||
vB = (buf[1] & 0xf0)>>4;
|
||||
sprintf (str, " v%i, v%i", vA, vB);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAAvBBBB:
|
||||
vA = (int) buf[1];
|
||||
vB = (buf[3]<<8) | buf[2];
|
||||
sprintf (str, " v%i, v%i", vA, vB);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAAAAvBBBB: // buf[1] seems useless :/
|
||||
vA = (buf[3]<<8) | buf[2];
|
||||
vB = (buf[5]<<8) | buf[4];
|
||||
sprintf (str, " v%i, v%i", vA, vB);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAA:
|
||||
vA = (int) buf[1];
|
||||
sprintf (str, " v%i", vA);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAcB:
|
||||
vA = buf[1] & 0x0f;
|
||||
vB = (buf[1] & 0xf0)>>4;
|
||||
sprintf (str, " v%i, %#x", vA, vB);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAAcBBBB:
|
||||
vA = (int) buf[1];
|
||||
short sB = (buf[3]<<8) | buf[2];
|
||||
sprintf (str, " v%i, %#04hx", vA, sB);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAAcBBBBBBBB:
|
||||
vA = (int) buf[1];
|
||||
vB = buf[5]|(buf[4]<<8)|(buf[3]<<16)|(buf[2]<<24);
|
||||
sprintf (str, " v%i, %#08x", vA, vB);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAAcBBBB0000:
|
||||
vA = (int) buf[1];
|
||||
vB = 0|(buf[3]<<16)|(buf[2]<<24);
|
||||
sprintf (str, " v%i, %#08x", vA, vB);
|
||||
if (buf[0] == 19) strcat (str, "00000000"); // const-wide/high16
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAAcBBBBBBBBBBBBBBBB:
|
||||
vA = (int) buf[1];
|
||||
long long int lB = buf[9]|(buf[8]<<8)|(buf[7]<<16)|(buf[6]<<24)|
|
||||
((long long int)buf[5]<<32)|((long long int)buf[4]<<40)|
|
||||
((long long int)buf[3]<<48)|((long long int)buf[2]<<56);
|
||||
sprintf (str, " v%i, 0x%llx", vA, lB);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAAvBBvCC:
|
||||
vA = (int) buf[1];
|
||||
vB = (int) buf[2];
|
||||
vC = (int) buf[3];
|
||||
sprintf (str, " v%i, v%i, v%i", vA, vB, vC);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAAvBBcCC:
|
||||
vA = (int) buf[1];
|
||||
vB = (int) buf[2];
|
||||
vC = (int) buf[3];
|
||||
sprintf (str, " v%i, v%i, %#x", vA, vB, vC);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAvBcCCCC:
|
||||
vA = buf[1] & 0x0f;
|
||||
vB = (buf[1] & 0xf0)>>4;
|
||||
vC = (buf[3]<<8) | buf[2];
|
||||
sprintf (str, " v%i, v%i, %#x", vA, vB, vC);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtoppAA:
|
||||
vA = pc + (int) buf[1];
|
||||
sprintf (str, " %i", vA);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtoppAAAA:
|
||||
vA = pc + (int) (buf[3] <<8 | buf[2]);
|
||||
sprintf (str, " %i", vA);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAApBBBB:
|
||||
vA = pc + (int) buf[1];
|
||||
vB = pc + (int) (buf[3] <<8 | buf[2]);
|
||||
sprintf (str, " v%i, %i", vA, vB);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtoppAAAAAAAA: //FIXME: Remove pc use
|
||||
vA = pc + (int) (buf[5]|(buf[4]<<8)|(buf[3]<<16)|(buf[2]<<24));
|
||||
sprintf (str, " %#08x", vA);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAvBpCCCC:
|
||||
vA = buf[1] & 0x0f;
|
||||
vB = (buf[1] & 0xf0)>>4;
|
||||
vC = pc + (int) (buf[3] <<8 | buf[2]);
|
||||
sprintf (str, " v%i, v%i, %i", vA, vB, vC);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAApBBBBBBBB:
|
||||
vA = (int) buf[1];
|
||||
vB = (int) (buf[5]|(buf[4]<<8)|(buf[3]<<16)|(buf[2]<<24));
|
||||
sprintf (str, " v%i, %i", vA, vB);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtoptinlineI:
|
||||
vA = (int) (buf[1] & 0x0f);
|
||||
vB = (buf[3]<<8) | buf[2];
|
||||
switch (vA) {
|
||||
case 1:
|
||||
sprintf (str, " {v%i}", buf[4] & 0x0f);
|
||||
break;
|
||||
case 2:
|
||||
sprintf (str, " {v%i, v%i}", buf[4]&0x0f, (buf[4]&0xf0)>>4);
|
||||
break;
|
||||
case 3:
|
||||
sprintf (str, " {v%i, v%i, v%i}", buf[4]&0x0f,
|
||||
(buf[4]&0xf0)>>4, buf[5]&0x0f);
|
||||
break;
|
||||
case 4:
|
||||
sprintf (str, " {v%i, v%i, v%i, v%i}", buf[4]&0x0f,
|
||||
(buf[4]&0xf0)>>4, buf[5]&0x0f, (buf[5]&0xf0)>>4);
|
||||
break;
|
||||
default:
|
||||
sprintf (str, " {}");
|
||||
}
|
||||
strcat (aop->buf_asm, str);
|
||||
sprintf (str, ", [%04x]", vB);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtoptinlineIR:
|
||||
case fmtoptinvokeVSR:
|
||||
vA = (int) buf[1];
|
||||
vB = (buf[3]<<8) | buf[2];
|
||||
vC = (buf[5]<<8) | buf[4];
|
||||
strcat (aop->buf_asm, " {");
|
||||
while (vA) {
|
||||
sprintf (str, "v%i, ", vC);
|
||||
strcat (aop->buf_asm, str);
|
||||
vA--;
|
||||
vC++;
|
||||
}
|
||||
aop->buf_asm[strlen (aop->buf_asm)-2] = 0;
|
||||
sprintf (str, "}, [%04x]", vB);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtoptinvokeVS:
|
||||
vA = (int) (buf[1] & 0xf0)>>4;
|
||||
vB = (buf[3]<<8) | buf[2];
|
||||
switch (vA) {
|
||||
case 1:
|
||||
sprintf (str, " {v%i}", buf[4] & 0x0f);
|
||||
break;
|
||||
case 2:
|
||||
sprintf (str, " {v%i, v%i}", buf[4]&0x0f, (buf[4]&0xf0)>>4);
|
||||
break;
|
||||
case 3:
|
||||
sprintf (str, " {v%i, v%i, v%i}", buf[4]&0x0f,
|
||||
(buf[4]&0xf0)>>4, buf[5]&0x0f);
|
||||
break;
|
||||
case 4:
|
||||
sprintf (str, " {v%i, v%i, v%i, v%i}", buf[4]&0x0f,
|
||||
(buf[4]&0xf0)>>4, buf[5]&0x0f, (buf[5]&0xf0)>>4);
|
||||
break;
|
||||
default:
|
||||
sprintf (str, " {}");
|
||||
}
|
||||
strcat (aop->buf_asm, str);
|
||||
sprintf (str, ", [%04x]", vB);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAAtBBBB:
|
||||
//FIXME: strings & class & fieldmust be a dex(r_bin) section
|
||||
vA = (int) buf[1];
|
||||
vB = (buf[3]<<8) | buf[2];
|
||||
if (buf[0] == 0x1a)
|
||||
sprintf (str, " v%i, strings+%i", vA, vB);
|
||||
else if (buf[0] == 0x1c || buf[0] == 0x1f || buf[0] == 0x22)
|
||||
sprintf (str, " v%i, class+%i", vA, vB);
|
||||
else
|
||||
sprintf (str, " v%i, field+%i", vA, vB);
|
||||
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtoptopvAvBoCCCC: //FIXME: obj must be a dex(r_bin) section
|
||||
vA = (buf[1] & 0x0f);
|
||||
vB = (buf[1] & 0xf0)>>4;
|
||||
vC = (buf[3]<<8) | buf[2];
|
||||
sprintf (str, " v%i, v%i, [obj+%04x]", vA, vB, vC);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopAAtBBBB: //FIXME: thing must be a dex(r_bin) section
|
||||
vA = (int) buf[1];
|
||||
vB = (buf[3]<<8) | buf[2];
|
||||
sprintf (str, " v%i, thing+%i", vA, vB);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAvBtCCCC: //FIXME: class & field must be a dex section
|
||||
vA = (buf[1] & 0x0f);
|
||||
vB = (buf[1] & 0xf0)>>4;
|
||||
vC = (buf[3]<<8) | buf[2];
|
||||
if (buf[0] == 0x20 || buf[0] == 0x23) //instance-of & new-array
|
||||
sprintf (str, " v%i, v%i, class+%i", vA, vB, vC);
|
||||
else
|
||||
sprintf (str, " v%i, v%i, field+%i", vA, vB, vC);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvAAtBBBBBBBB: //FIXME: string must be a dex(r_bin) section
|
||||
vA = (int) buf[1];
|
||||
vB = (int) (buf[5]|(buf[4]<<8)|(buf[3]<<16)|(buf[2]<<24));
|
||||
sprintf (str, " v%i, string+%i", vA, vB);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvCCCCmBBBB: //FIXME: class must be a dex(r_bin) section
|
||||
vA = (int) buf[1];
|
||||
vB = (buf[3]<<8) | buf[2];
|
||||
vC = (buf[5]<<8) | buf[4];
|
||||
strcat (aop->buf_asm, " {");
|
||||
while (vA) {
|
||||
sprintf (str, "v%i, ", vC);
|
||||
strcat (aop->buf_asm, str);
|
||||
vA--;
|
||||
vC++;
|
||||
}
|
||||
aop->buf_asm[strlen (aop->buf_asm)-2] = 0;
|
||||
if (buf[0] == 0x25) // filled-new-array/range
|
||||
sprintf (str, "}, class+%i", vB);
|
||||
else
|
||||
sprintf (str, "}, method+%i", vB);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtopvXtBBBB: //FIXME: class & method must be a dex(r_bin) section
|
||||
vA = (int) (buf[1] & 0xf0)>>4;
|
||||
vB = (buf[3]<<8) | buf[2];
|
||||
switch (vA) {
|
||||
case 1:
|
||||
sprintf (str, " {v%i}", buf[4] & 0x0f);
|
||||
break;
|
||||
case 2:
|
||||
sprintf (str, " {v%i, v%i}", buf[4]&0x0f, (buf[4]&0xf0)>>4);
|
||||
break;
|
||||
case 3:
|
||||
sprintf (str, " {v%i, v%i, v%i}", buf[4]&0x0f,
|
||||
(buf[4]&0xf0)>>4, buf[5]&0x0f);
|
||||
break;
|
||||
case 4:
|
||||
sprintf (str, " {v%i, v%i, v%i, v%i}", buf[4]&0x0f,
|
||||
(buf[4]&0xf0)>>4, buf[5]&0x0f, (buf[5]&0xf0)>>4);
|
||||
break;
|
||||
default:
|
||||
sprintf (str, " {}");
|
||||
}
|
||||
strcat (aop->buf_asm, str);
|
||||
if (buf[0] == 0x24) // filled-new-array
|
||||
sprintf (str, ", class+%i", vB);
|
||||
else
|
||||
sprintf (str, ", method+%i", vB);
|
||||
strcat (aop->buf_asm, str);
|
||||
break;
|
||||
case fmtoptinvokeI: // Any opcode has this formats
|
||||
case fmtoptinvokeIR:
|
||||
case fmt00:
|
||||
default: break;
|
||||
}
|
||||
|
||||
aop->inst_len = size;
|
||||
} else {
|
||||
strcpy (aop->buf_asm, "invalid ");
|
||||
aop->inst_len = len;
|
||||
size = len;
|
||||
}
|
||||
if (size) pc++;
|
||||
return size;
|
||||
}
|
||||
|
||||
//TODO
|
||||
static int assemble(RAsm *a, RAsmAop *aop, const char *buf) {
|
||||
int i;
|
||||
char *p;
|
||||
|
||||
p = strchr (buf,' ');
|
||||
if (p) *p = 0;
|
||||
for (i=0; i<256; i++) {
|
||||
if (!strcmp (opcodes[i].name, buf)) {
|
||||
r_mem_copyendian (aop->buf, (void*)&i, 4, a->big_endian);
|
||||
aop->inst_len = opcodes[i].len;
|
||||
return aop->inst_len;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init (void *user) {
|
||||
pc = 0;
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
RAsmPlugin r_asm_plugin_dalvik = {
|
||||
.name = "dalvik",
|
||||
.arch = "dalvik",
|
||||
.desc = "Dalvik (Android VM) disassembly plugin",
|
||||
.bits = (int[]){ 32, 64, 0 },
|
||||
.init = &init,
|
||||
.fini = NULL,
|
||||
.disassemble = &disassemble,
|
||||
.assemble = &assemble
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_ASM,
|
||||
.data = &r_asm_plugin_dalvik
|
||||
};
|
||||
#endif
|
9
libr/asm/p/dalvik.mk
Normal file
9
libr/asm/p/dalvik.mk
Normal file
@ -0,0 +1,9 @@
|
||||
OBJ_DALVIK=asm_dalvik.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_DALVIK}
|
||||
TARGET_DALVIK=asm_dalvik.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_DALVIK}
|
||||
|
||||
${TARGET_DALVIK}: ${OBJ_DALVIK}
|
||||
${CC} ${LDFLAGS} -I../arch/dalvik ${CFLAGS} -o asm_dalvik.${EXT_SO} ${OBJ_DALVIK}
|
@ -7,7 +7,7 @@
|
||||
#include <list.h>
|
||||
#include <r_util.h>
|
||||
|
||||
#define R_ASM_BUFSIZE 1024
|
||||
#define R_ASM_BUFSIZE 3128
|
||||
#define R_ASM_FASTCALL_ARGS 6
|
||||
|
||||
enum {
|
||||
@ -137,6 +137,7 @@ extern RAsmPlugin r_asm_plugin_ppc;
|
||||
extern RAsmPlugin r_asm_plugin_sparc;
|
||||
extern RAsmPlugin r_asm_plugin_psosvm;
|
||||
extern RAsmPlugin r_asm_plugin_avr;
|
||||
extern RAsmPlugin r_asm_plugin_dalvik;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -8,6 +8,7 @@ asm.arm
|
||||
asm.armthumb
|
||||
asm.csr
|
||||
asm.avr
|
||||
asm.dalvik
|
||||
asm.mips
|
||||
asm.ppc
|
||||
asm.x86
|
||||
|
Loading…
Reference in New Issue
Block a user