Initial support for ARM and ARM64 nopskip with invalid instructions

This commit is contained in:
pancake 2015-01-10 03:21:27 +01:00
parent 743bd0a68a
commit d32c7d8f80
3 changed files with 61 additions and 3 deletions

View File

@ -379,6 +379,24 @@ repeat:
anal->iob.read_at (anal->iob.io, x, bbuf, sizeof (bbuf));\
ret = fcn_recurse (anal, fcn, x, bbuf, sizeof (bbuf), depth-1);
switch (op.type) {
case R_ANAL_OP_TYPE_ILL:
if (anal->nopskip && !memcmp (buf, "\x00\x00\x00\x00", 4)) {
if ((addr + delay.un_idx-oplen) == fcn->addr) {
fcn->addr += oplen;
bb->size -= oplen;
bb->addr += oplen;
idx = delay.un_idx;
goto repeat;
} else {
// sa
bb->size -= oplen;
op.type = R_ANAL_OP_TYPE_RET;
}
}
FITFCNSZ ();
r_anal_op_fini (&op);
gotoBeach (R_ANAL_RET_END);
break;
case R_ANAL_OP_TYPE_TRAP:
if (anal->nopskip && buf[0]==0xcc) {
if ((addr + delay.un_idx-oplen) == fcn->addr) {

View File

@ -194,6 +194,9 @@ static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len
static void anop64 (RAnalOp *op, cs_insn *insn) {
ut64 addr = op->addr;
switch (insn->id) {
case ARM64_INS_NOP:
op->type = R_ANAL_OP_TYPE_NOP;
break;
case ARM64_INS_SUB:
op->type = R_ANAL_OP_TYPE_SUB;
break;
@ -204,21 +207,42 @@ static void anop64 (RAnalOp *op, cs_insn *insn) {
case ARM64_INS_MOVI:
case ARM64_INS_MOVK:
case ARM64_INS_MOVN:
case ARM64_INS_MOVZ:
case ARM64_INS_SMOV:
case ARM64_INS_UMOV:
case ARM64_INS_FMOV:
op->type = R_ANAL_OP_TYPE_MOV;
break;
case ARM64_INS_MOVZ:
op->type = R_ANAL_OP_TYPE_MOV;
op->ptr = 0LL;
op->ptrsize = 8;
break;
case ARM64_INS_UXTB:
op->type = R_ANAL_OP_TYPE_MOV;
op->ptr = 0LL;
op->ptrsize = 4;
break;
case ARM64_INS_UXTH:
op->type = R_ANAL_OP_TYPE_MOV;
op->ptr = 0LL;
op->ptrsize = 2;
break;
case ARM64_INS_CMP:
case ARM64_INS_TST:
op->type = R_ANAL_OP_TYPE_CMP;
break;
case ARM64_INS_ROR:
case ARM64_INS_ORN:
case ARM64_INS_LSL:
case ARM64_INS_LSR:
op->type = R_ANAL_OP_TYPE_OR;
break;
case ARM64_INS_LSL:
op->type = R_ANAL_OP_TYPE_SHL;
break;
case ARM64_INS_ASR:
case ARM64_INS_LSR:
op->type = R_ANAL_OP_TYPE_SHR;
break;
case ARM64_INS_STRB:
case ARM64_INS_STR:
op->type = R_ANAL_OP_TYPE_STORE;
if (REGBASE64(1) == ARM64_REG_X29) {
@ -228,6 +252,7 @@ static void anop64 (RAnalOp *op, cs_insn *insn) {
}
break;
case ARM64_INS_LDR:
case ARM64_INS_LDRB:
op->type = R_ANAL_OP_TYPE_LOAD;
if (REGBASE64(1) == ARM64_REG_X29) {
op->stackop = R_ANAL_STACK_GET;
@ -243,6 +268,12 @@ static void anop64 (RAnalOp *op, cs_insn *insn) {
op->type = R_ANAL_OP_TYPE_CALL;
op->jump = IMM64(0);
break;
case ARM64_INS_CBZ:
case ARM64_INS_CBNZ:
op->type = R_ANAL_OP_TYPE_CJMP;
op->jump = IMM64(1);
op->fail = addr+op->size;
break;
case ARM64_INS_B:
// BX LR == RET
if (insn->detail->arm64.operands[0].reg == ARM64_REG_LR) {
@ -265,6 +296,9 @@ static void anop32 (RAnalOp *op, cs_insn *insn) {
ut64 addr = op->addr;
int i;
switch (insn->id) {
case ARM_INS_NOP:
op->type = R_ANAL_OP_TYPE_NOP;
break;
case ARM_INS_POP:
case ARM_INS_LDM:
op->type = R_ANAL_OP_TYPE_POP;
@ -306,6 +340,9 @@ static void anop32 (RAnalOp *op, cs_insn *insn) {
case ARM_INS_VQMOVN:
op->type = R_ANAL_OP_TYPE_MOV;
break;
case ARM_INS_AND:
op->type = R_ANAL_OP_TYPE_AND;
break;
case ARM_INS_CMP:
case ARM_INS_TST:
op->type = R_ANAL_OP_TYPE_CMP;
@ -317,6 +354,7 @@ static void anop32 (RAnalOp *op, cs_insn *insn) {
break;
//case ARM_INS_POP:
case ARM_INS_PUSH:
case ARM64_INS_STRB:
case ARM_INS_STR:
op->type = R_ANAL_OP_TYPE_STORE;
// 0x00008160 04202de5 str r2, [sp, -4]!
@ -328,6 +366,7 @@ static void anop32 (RAnalOp *op, cs_insn *insn) {
}
break;
case ARM_INS_LDR:
case ARM_INS_LDRB:
// 0x000082a8 28301be5 ldr r3, [fp, -0x28]
if (insn->detail->arm.operands[0].reg == ARM_REG_PC) {
op->type = R_ANAL_OP_TYPE_UJMP;

View File

@ -624,6 +624,7 @@ typedef struct r_anal_op_t {
ut32 selector; /* segment selector */
st64 ptr; /* reference to memory */ /* XXX signed? */
ut64 val; /* reference to value */ /* XXX signed? */
int ptrsize; /* f.ex: zero extends for 8, 16 or 32 bits only */
st64 stackptr; /* stack pointer */
int refptr; /* if (0) ptr = "reference" else ptr = "load memory of refptr bytes" */
RAnalValue *src[3];