Add support for refptr analysis in ARM (gnu + capstone)

This commit is contained in:
pancake 2014-11-07 01:24:14 +01:00
parent 1256b77747
commit 9f9ac0cb16
2 changed files with 36 additions and 33 deletions

View File

@ -7,8 +7,10 @@
#include "esil.h"
#define REG(x) cs_reg_name (*handle, insn->detail->arm.operands[x].reg)
#define REGID(x) insn->detail->arm.operands[x].reg
#define IMM(x) insn->detail->arm.operands[x].imm
#define MEMBASE(x) cs_reg_name(*handle, insn->detail->arm.operands[x].mem.base)
#define REGBASE(x) insn->detail->arm.operands[x].mem.base
#define MEMINDEX(x) insn->detail->arm.operands[x].mem.index
#define MEMDISP(x) insn->detail->arm.operands[x].mem.disp
// TODO scale and disp
@ -121,11 +123,20 @@ static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len
break;
case ARM_INS_LDR:
if (MEMDISP(1)<0) {
r_strbuf_appendf (&op->esil, "%s,%d,-,[4],%s,=",
MEMBASE(1), -MEMDISP(1), REG(0));
r_strbuf_appendf (&op->esil, "%s,%d,-,[4],%s,=",
MEMBASE(1), -MEMDISP(1), REG(0));
if (REGBASE(1) == ARM_REG_PC) {
op->ptr = addr + 8 - MEMDISP(1);
op->refptr = 4;
}
} else {
r_strbuf_appendf (&op->esil, "%s,%d,+,[4],%s,=",
MEMBASE(1), MEMDISP(1), REG(0));
r_strbuf_appendf (&op->esil, "%s,%d,+,[4],%s,=",
MEMBASE(1), MEMDISP(1), REG(0));
if (REGBASE(1) == ARM_REG_PC) {
op->ptr = addr + 8 + MEMDISP(1);
op->refptr = 4;
}
op->refptr = 4;
}
break;
case ARM_INS_LDRB:
@ -149,8 +160,9 @@ static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
op->type = R_ANAL_OP_TYPE_NULL;
op->size = (a->bits==16)? 2: 4;
op->delay = 0;
op->jump = UT64_MAX;
op->fail = UT64_MAX;
op->jump = op->fail = -1;
op->ptr = op->val = -1;
op->refptr = 0;
r_strbuf_init (&op->esil);
if (ret == CS_ERR_OK) {
n = cs_disasm (handle, (ut8*)buf, len, addr, 1, &insn);
@ -162,7 +174,6 @@ static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
case ARM_INS_POP:
case ARM_INS_LDM:
op->type = R_ANAL_OP_TYPE_POP;
for (i = 0; i < insn->detail->arm.op_count; i++) {
if (insn->detail->arm.operands[i].type == ARM_OP_REG &&
insn->detail->arm.operands[i].reg == ARM_REG_PC) {

View File

@ -41,6 +41,8 @@ static int op_thumb(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
arm_set_thumb (arminsn, R_TRUE);
arm_set_input_buffer (arminsn, data);
arm_set_pc (arminsn, addr);
op->jump = op->fail = -1;
op->ptr = op->val = -1;
op->delay = 0;
op->size = arm_disasm_one_insn (arminsn);
op->jump = arminsn->jmp;
@ -168,6 +170,8 @@ static int arm_op32(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
arm_set_thumb (arminsn, R_FALSE);
arm_set_input_buffer (arminsn, data);
arm_set_pc (arminsn, addr);
op->jump = op->fail = -1;
op->ptr = op->val = -1;
op->addr = addr;
op->type = R_ANAL_OP_TYPE_UNK;
@ -249,37 +253,31 @@ static int arm_op32(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
//op->ptr = 4+addr+b[0]; // sure? :)
//op->ptrptr = R_TRUE;
}
} else
//eprintf("0x%08x\n", code[i] & ARM_DTX_LOAD);
// 0x0001B4D8, 1eff2fe1 bx lr
if (b[3]==0xe2 && b[2]==0x8d && b[1]==0xd0) {
//eprintf("0x%08x\n", code[i] & ARM_DTX_LOAD);
// 0x0001B4D8, 1eff2fe1 bx lr
} else if (b[3]==0xe2 && b[2]==0x8d && b[1]==0xd0) {
// ADD SP, SP, ...
op->type = R_ANAL_OP_TYPE_ADD;
op->stackop = R_ANAL_STACK_INC;
op->val = -b[0];
} else
if (b[3]==0xe2 && b[2]==0x4d && b[1]==0xd0) {
} else if (b[3]==0xe2 && b[2]==0x4d && b[1]==0xd0) {
// SUB SP, SP, ..
op->type = R_ANAL_OP_TYPE_SUB;
op->stackop = R_ANAL_STACK_INC;
op->val = b[0];
} else
if (b[3]==0xe2 && b[2]==0x4c && b[1]==0xb0) {
} else if (b[3]==0xe2 && b[2]==0x4c && b[1]==0xb0) {
// SUB SP, FP, ..
op->type = R_ANAL_OP_TYPE_SUB;
op->stackop = R_ANAL_STACK_INC;
op->val = -b[0];
} else
if (b[3]==0xe2 && b[2]==0x4b && b[1]==0xd0) {
} else if (b[3]==0xe2 && b[2]==0x4b && b[1]==0xd0) {
// SUB SP, IP, ..
op->type = R_ANAL_OP_TYPE_SUB;
op->stackop = R_ANAL_STACK_INC;
op->val = -b[0];
} else
if ( (code[i] == 0x1eff2fe1) ||(code[i] == 0xe12fff1e)) { // bx lr
} else if ( (code[i] == 0x1eff2fe1) ||(code[i] == 0xe12fff1e)) { // bx lr
op->type = R_ANAL_OP_TYPE_RET;
} else
if ((code[i] & ARM_DTX_LOAD)) { //IS_LOAD(code[i])) {
} else if ((code[i] & ARM_DTX_LOAD)) { //IS_LOAD(code[i])) {
ut32 ptr = 0;
op->type = R_ANAL_OP_TYPE_MOV;
if (b[2]==0x1b) {
@ -301,23 +299,17 @@ static int arm_op32(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
if (IS_LOAD (code[i])) {
op->type = R_ANAL_OP_TYPE_LOAD;
op->refptr = 4;
}
if (
(( ((code[i]&0xff)>=0x10 && (code[i]&0xff)<0x20)
) && ((code[i]&0xffffff00) == 0xe12fff00))
||
IS_EXITPOINT (code[i])) {
if ( (( ((code[i]&0xff)>=0x10 && (code[i]&0xff)<0x20)) && ((code[i]&0xffffff00) == 0xe12fff00)) || IS_EXITPOINT (code[i])) {
//if (IS_EXITPOINT (code[i])) {
b=data;
branch_dst_addr = disarm_branch_offset (addr, b[0] | (b[1]<<8) | (b[2]<<16)); //code[i]&0x00FFFFFF);
op->ptr = 0;
if (
( ((code[i]&0xff)>=0x10 && (code[i]&0xff)<0x20)
) && ((code[i]&0xffffff00) == 0xe12fff00)
) {
op->type = R_ANAL_OP_TYPE_UJMP;
} else
if (IS_BRANCHL (code[i])) {
if ((((code[i]&0xff)>=0x10 && (code[i]&0xff)<0x20))
&& ((code[i]&0xffffff00) == 0xe12fff00)) {
op->type = R_ANAL_OP_TYPE_UJMP;
} else if (IS_BRANCHL (code[i])) {
if (IS_BRANCH (code[i])) {
op->type = R_ANAL_OP_TYPE_CALL;
op->jump = branch_dst_addr;