librz/arch: remove unused ESIL remnants from Dalvik (#6024)

Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
This commit is contained in:
NOT XVilka 2026-03-12 03:07:07 +08:00 committed by GitHub
parent 9f85d684a1
commit 6c77211f44
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 3 additions and 199 deletions

View file

@ -10,42 +10,6 @@
#include "dalvik/opcode.h"
#include "../../bin/format/dex/dex.h"
static const char *getCond(ut8 cond) {
switch (cond) {
case 0x32: // if-eq
return "$z";
case 0x33: // if-ne
return "$z,!";
case 0x34: // if-lt
return "63,$c,!";
case 0x35: // if-ge
return "63,$c,$z,|";
case 0x36: // if-gt
return "63,$c";
case 0x37: // if-le
return "63,$c,!,$z,|";
}
return "";
}
static const char *getCondz(ut8 cond) {
switch (cond) {
case 0x38: // if-eqz
return "NOP";
case 0x39: // if-nez
return "!";
case 0x3a: // if-ltz
return "0,==,63,$c,!";
case 0x3b: // if-gez
return "0,==,63,$c,$z,|";
case 0x3c: // if-gtz
return "0,==,63,$c";
case 0x3d: // if-lez
return "0,==,63,$c,!";
}
return "";
}
static RzAnalysisSwitchOp *parse_packed_switch_payload(RzAnalysis *analysis, ut64 addr, ut64 payload_addr) {
ut8 payload_header[8];
if (!analysis->read_at || !analysis->read_at(analysis, payload_addr, payload_header, 8)) {
@ -154,14 +118,6 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
op->nopcode = 1; // Necessary??
op->id = data[0];
ut32 vA = 0;
ut32 vB = 0;
ut32 vC = 0;
if (len > 3) {
vA = data[1];
vB = data[2];
vC = data[3];
}
switch (data[0]) {
case 0xca: // rem-float:
op->family = RZ_ANALYSIS_OP_FAMILY_FPU;
@ -175,7 +131,6 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
case 0x12: // const/4
{
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
ut32 vB = (data[1] & 0x0f);
ut32 vA = (data[1] & 0xf0) >> 4;
ut32 vC = (len > 4) ? rz_read_le32(data + 2) : 0x22;
// op->stackop = RZ_ANALYSIS_STACK_SET;
@ -184,9 +139,6 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
op->val = val;
// op->reg = vB;
op->nopcode = 2;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, "0x%" PFMT64x ",v%d,=", val, vB);
}
} break;
case 0x01: // move
case 0x07: // move-object
@ -196,16 +148,10 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
ut32 vA = (data[1] & 0xf0) >> 4;
if (vA == vB) {
op->type = RZ_ANALYSIS_OP_TYPE_NOP;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, ",");
}
} else {
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
// op->stackop = RZ_ANALYSIS_STACK_SET;
// op->ptr = -vA;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, "v%d,v%d,=", vA, vB);
}
}
} break;
case 0x02: // move/from16
@ -217,11 +163,7 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
case 0x13: // const/16
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
if (len > 2) {
int vA = (int)data[1];
ut32 vB = (data[3] << 8) | data[2];
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, "v%d,v%d,=", vA, vB);
}
op->val = vB;
}
break;
@ -236,23 +178,14 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
case 0x0b: // move-result-wide
// TODO: add MOVRET OP TYPE ??
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
ut32 vA = data[1];
esilprintf(op, "sp,v%d,=[8],8,sp,+=,8", vA);
}
break;
case 0x1a: // const-string
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
op->datatype = RZ_ANALYSIS_DATATYPE_STRING;
if (len > 2) {
ut32 vA = data[1];
ut32 vB = (data[3] << 8) | data[2];
ut64 offset = RZ_ANALYSIS_GET_OFFSET(analysis, 's', vB);
op->ptr = offset;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
// op->refptr = 0;
esilprintf(op, "0x%" PFMT64x ",v%d,=", offset, vA);
}
}
break;
case 0x1c: // const-class
@ -275,34 +208,16 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
case 0x8d: // int-to-byte
case 0x8e: // int-to-char
op->type = RZ_ANALYSIS_OP_TYPE_CAST;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
ut32 vA = (data[1] & 0x0f);
ut32 vB = (data[1] & 0xf0) >> 4;
esilprintf(op, "v%d,0xff,&,v%d,=", vB, vA);
}
break;
case 0x8f: // int-to-short
op->type = RZ_ANALYSIS_OP_TYPE_CAST;
// op->datatype = RZ_ANALYSIS_DATATYPE_INT32 | RZ_ANALYSIS_DATATYPE_INT16;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
ut32 vA = (data[1] & 0x0f);
ut32 vB = (data[1] & 0xf0) >> 4;
esilprintf(op, "v%d,0xffff,&,v%d,=", vB, vA);
}
break;
case 0x84: // long-to-int
op->type = RZ_ANALYSIS_OP_TYPE_CAST;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
ut32 vA = (data[1] & 0x0f);
ut32 vB = (data[1] & 0xf0) >> 4;
esilprintf(op, "v%d,0xffffffff,&,v%d,=", vB, vA);
}
break;
case 0x20: // instance-of
op->type = RZ_ANALYSIS_OP_TYPE_CMP;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, "%d,instanceof,%d,-,!,v%d,=", vC, vB, vA);
}
break;
case 0x21: // array-length
op->type = RZ_ANALYSIS_OP_TYPE_LENGTH;
@ -342,23 +257,10 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
break;
case 0x54: // iget-object
op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
ut32 vA = (data[1] & 0x0f);
ut32 vB = (data[1] & 0xf0) >> 4;
ut32 vC = (data[2] & 0x0f);
esilprintf(op, "%d,v%d,iget,v%d,=", vC, vB, vA);
}
break;
case 0x63: // sget-boolean
op->datatype = RZ_ANALYSIS_DATATYPE_BOOLEAN;
op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
ut32 vA = (data[1] & 0x0f);
ut32 vB = (data[1] & 0xf0) >> 4;
ut32 vC = (data[2] & 0x0f);
const char *vT = "-boolean";
esilprintf(op, "%d,%d,sget%s,v%d,=", vC, vB, vT, vA);
}
break;
case 0x62: // sget-object
{
@ -366,10 +268,6 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
ut32 vC = len > 3 ? (data[3] << 8) | data[2] : 0;
op->ptr = analysis->binb.get_offset(analysis->binb.bin, 'f', vC);
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
ut32 vA = (data[1] & 0x0f);
esilprintf(op, "%" PFMT64d ",v%d,=", op->ptr, vA);
}
} break;
case 0x6b: // sput-byte
case 0x6d: // sput-short
@ -398,23 +296,15 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
case 0x68: // sput-wide
case 0x6a: // sput-boolean
case 0x6c: // sput-wide
case 0xfe: // sput
{
case 0xfe: { // sput
op->type = RZ_ANALYSIS_OP_TYPE_STORE;
ut32 vC = len > 3 ? (data[3] << 8) | data[2] : 0;
op->ptr = analysis->binb.get_offset(analysis->binb.bin, 'f', vC);
}
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
ut32 vA = (data[1] & 0x0f);
esilprintf(op, "%" PFMT64d ",v%d,=", op->ptr, vA);
}
break;
}
case 0xad: // mul-double
op->family = RZ_ANALYSIS_OP_FAMILY_FPU;
op->type = RZ_ANALYSIS_OP_TYPE_MUL;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, "v%d,v%d,*,v%d,=", vC, vB, vA);
}
break;
case 0x9d:
case 0xc8: // mul-float
@ -425,13 +315,6 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
case 0x92:
case 0xb2:
op->type = RZ_ANALYSIS_OP_TYPE_MUL;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
ut32 vA = (data[1] & 0x0f);
ut32 vB = (data[1] & 0xf0) >> 4;
ut32 vC = (data[2] << 8) | data[3];
esilprintf(op, "%d,v%d,*,v%d,=", vC, vB, vA);
op->val = vC;
}
break;
case 0x7c: // not-int
case 0x7e: // not-long
@ -497,23 +380,12 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
case 0xf1: // return-void-barrier
op->type = RZ_ANALYSIS_OP_TYPE_RET;
op->eob = true;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
if (data[0] == 0x0e) { // return-void
esilprintf(op, "sp,[8],ip,=,8,sp,+=");
} else {
ut32 vA = data[1];
esilprintf(op, "sp,[8],ip,=,8,sp,+=,8,sp,-=,v%d,sp,=[8]", vA);
}
}
break;
case 0x28: // goto
if (len > 1) {
st32 rel = (signed char)data[1];
op->jump = addr + (rel * 2);
op->type = RZ_ANALYSIS_OP_TYPE_JMP;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, "0x%" PFMT64x ",ip,=", op->jump);
}
}
break;
case 0x29: // goto/16
@ -521,9 +393,6 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
st32 rel = (short)(data[3] << 8 | data[2]);
op->jump = addr + (rel * 2);
op->type = RZ_ANALYSIS_OP_TYPE_JMP;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, "0x%" PFMT64x ",ip,=", op->jump);
}
}
break;
case 0x2a: // goto/32
@ -531,9 +400,6 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
st32 rel = (st32)(data[2] | (data[3] << 8) | (data[4] << 16) | (data[5] << 24));
op->jump = addr + (rel * 2);
op->type = RZ_ANALYSIS_OP_TYPE_JMP;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, "0x%" PFMT64x ",ip,=", op->jump);
}
}
break;
case 0x2b:
@ -549,9 +415,6 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
op->type = RZ_ANALYSIS_OP_TYPE_ILL;
op->size = 1;
op->eob = true;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, ",");
}
break;
case 0x2d: // cmpl-float
case 0x2e: // cmpg-float
@ -573,12 +436,6 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
int rel = (int)(data[3] << 8 | data[2]);
op->jump = addr + (rel * 2);
op->fail = addr + sz;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
ut32 vA = data[1];
ut32 vB = data[2];
const char *cond = getCond(data[0]);
esilprintf(op, "v%d,v%d,==,%s,?{,%" PFMT64d ",ip,=}", vB, vA, cond, op->jump);
}
}
break;
case 0x38: // if-eqz
@ -592,34 +449,20 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
int rel = (int)(data[3] << 8 | data[2]);
op->jump = addr + (rel * 2);
op->fail = addr + sz;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
ut32 vA = data[1];
const char *cond = getCondz(data[0]);
esilprintf(op, "v%d,%s,?{,%" PFMT64d ",ip,=}", vA, cond, op->jump);
}
}
break;
case 0xec: // breakpoint
op->type = RZ_ANALYSIS_OP_TYPE_TRAP;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, "TRAP");
}
break;
case 0x1d: // monitor-enter
op->type = RZ_ANALYSIS_OP_TYPE_PUSH;
op->stackop = RZ_ANALYSIS_STACK_INC;
op->stackptr = 1;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, ",");
}
break;
case 0x1e: // monitor-exit /// wrong type?
op->type = RZ_ANALYSIS_OP_TYPE_POP;
op->stackop = RZ_ANALYSIS_STACK_INC;
op->stackptr = -1;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, ",");
}
break;
case 0x73: // invalid
break;
@ -642,9 +485,6 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
op->jump = dst;
}
op->fail = addr + sz;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, "8,sp,-=,0x%" PFMT64x ",sp,=[8],0x%" PFMT64x ",ip,=", op->fail, op->jump);
}
}
break;
case 0x78: // invokeinterface/range
@ -664,9 +504,6 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
} else {
op->type = RZ_ANALYSIS_OP_TYPE_CALL;
op->jump = dst;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, "8,sp,-=,0x%" PFMT64x ",sp,=[8],0x%" PFMT64x ",ip,=", op->fail, op->jump);
}
}
} else {
rz_warn_if_reached();
@ -675,10 +512,6 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
case 0x27: // throw
{
op->type = RZ_ANALYSIS_OP_TYPE_TRAP;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
ut32 vA = data[1];
esilprintf(op, "v%d,TRAP", vA);
}
} break;
case 0xee: // execute-inline
case 0xef: // execute-inline/range
@ -694,21 +527,11 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
int vB = (data[3] << 8) | data[2];
ut64 off = RZ_ANALYSIS_GET_OFFSET(analysis, 't', vB);
op->ptr = off;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
int vA = (int)data[1];
esilprintf(op, "%" PFMT64d ",new,v%d,=", off, vA);
}
}
break;
case 0x23: // new-array
op->type = RZ_ANALYSIS_OP_TYPE_NEW;
// 0x1c, 0x1f, 0x22
if (len > 2 && mask & RZ_ANALYSIS_OP_MASK_ESIL) {
ut32 vA = (data[1] & 0x0f);
ut32 vB = (data[1] & 0xf0) >> 4;
ut32 vC = (int)data[2] | (data[3] << 8);
esilprintf(op, "%d,%d,new-array,v%d,=", vC, vB, vA);
}
break;
case 0x24: // filled-new-array
case 0x25: // filled-new-array-range
@ -725,9 +548,6 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
break;
case 0x00: // nop
op->type = RZ_ANALYSIS_OP_TYPE_NOP;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, ",");
}
break;
case 0x90: // add-int
case 0x9b: // add-long
@ -740,11 +560,6 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
case 0xd0: // add-int/lit16
case 0xd8: // add-int/lit8
op->type = RZ_ANALYSIS_OP_TYPE_ADD;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
ut32 vB = (data[1] & 0x0f);
ut32 vA = (data[1] & 0xf0) >> 4;
esilprintf(op, "v%d,v%d,+=", vB, vA);
}
break;
case 0xa7: // sub-float
case 0xcc: // sub-double
@ -757,9 +572,6 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
case 0xd1: // sub-int/2addr
case 0x9c: // sub-long
op->type = RZ_ANALYSIS_OP_TYPE_SUB;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
esilprintf(op, "v%d,v%d,-,v%d,=", vC, vB, vA);
}
break;
case 0x7b: // neg-int
case 0x7d: // neg-long
@ -778,13 +590,6 @@ static int dalvik_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut
case 0xc1: // or-long/2addr
case 0xa1: // or-long
op->type = RZ_ANALYSIS_OP_TYPE_OR;
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
ut32 vA = (data[1] & 0x0f);
ut32 vB = (data[1] & 0xf0) >> 4;
ut32 vC = (data[2] << 8) | data[3];
esilprintf(op, "%d,v%d,|,v%d,=", vC, vB, vA);
op->val = vC;
}
break;
case 0xe0: // lshl
case 0xc3: // lshl
@ -880,7 +685,6 @@ RzAnalysisPlugin rz_analysis_plugin_dalvik = {
.get_reg_profile = &get_reg_profile,
.license = "LGPL3",
.bits = 32,
.esil = false,
.desc = "Dalvik (Android VM) bytecode analysis plugin",
.op = &dalvik_op,
.archinfo = archinfo,

View file

@ -205,7 +205,7 @@ af
pdfj
EOF
EXPECT=<<EOF
{"name":"fcn.00000000","size":2,"addr":0,"ops":[{"offset":0,"esil":"sp,[8],ip,=,8,sp,+=","refptr":false,"fcn_addr":0,"fcn_last":0,"size":2,"opcode":"return-void","disasm":"return-void","bytes":"0e00","family":"cpu","type":"ret","reloc":false,"type_num":5,"type2_num":0,"flags":["fcn.00000000"]}]}
{"name":"fcn.00000000","size":2,"addr":0,"ops":[{"offset":0,"esil":"","refptr":false,"fcn_addr":0,"fcn_last":0,"size":2,"opcode":"return-void","disasm":"return-void","bytes":"0e00","family":"cpu","type":"ret","reloc":false,"type_num":5,"type2_num":0,"flags":["fcn.00000000"]}]}
EOF
RUN