mirror of
https://github.com/radareorg/radare2.git
synced 2025-03-03 03:35:37 +00:00
Support another type of jmptbl for x86-64 ##anal
This commit is contained in:
parent
fa0b39896c
commit
a404c77063
@ -439,9 +439,11 @@ static int walkthrough_arm_jmptbl_style(RAnal *anal, RAnalFunction *fcn, int dep
|
||||
anal->cmdtail = r_str_appendf (anal->cmdtail,
|
||||
"f switch.0x%08"PFMT64x" 1 @ 0x%08"PFMT64x"\n",
|
||||
ip, ip);
|
||||
anal->cmdtail = r_str_appendf (anal->cmdtail,
|
||||
"f case.default.0x%"PFMT64x " 1 @ 0x%08"PFMT64x "\n",
|
||||
default_case, default_case);
|
||||
if (default_case != 0 && default_case != UT64_MAX) {
|
||||
anal->cmdtail = r_str_appendf (anal->cmdtail,
|
||||
"f case.default.0x%"PFMT64x " 1 @ 0x%08"PFMT64x "\n",
|
||||
default_case, default_case);
|
||||
}
|
||||
|
||||
}
|
||||
return ret;
|
||||
@ -499,7 +501,7 @@ static int try_walkthrough_jmptbl(RAnal *anal, RAnalFunction *fcn, int depth, ut
|
||||
break;
|
||||
}
|
||||
}
|
||||
queue_case (anal, ip, jmpptr, offs/sz, jmptbl_loc + offs);
|
||||
queue_case (anal, ip, jmpptr, offs / sz, jmptbl_loc + offs);
|
||||
recurseAt (jmpptr);
|
||||
}
|
||||
|
||||
@ -511,10 +513,11 @@ static int try_walkthrough_jmptbl(RAnal *anal, RAnalFunction *fcn, int depth, ut
|
||||
anal->cmdtail = r_str_appendf (anal->cmdtail,
|
||||
"f switch.0x%08"PFMT64x" 1 @ 0x%08"PFMT64x"\n",
|
||||
ip, ip);
|
||||
|
||||
anal->cmdtail = r_str_appendf (anal->cmdtail,
|
||||
"f case.default.0x%"PFMT64x " 1 @ 0x%08"PFMT64x "\n",
|
||||
default_case, default_case);
|
||||
if (default_case != 0 && default_case != UT64_MAX) {
|
||||
anal->cmdtail = r_str_appendf (anal->cmdtail,
|
||||
"f case.default.0x%"PFMT64x " 1 @ 0x%08"PFMT64x "\n",
|
||||
default_case, default_case);
|
||||
}
|
||||
}
|
||||
|
||||
free (jmptbl);
|
||||
@ -873,8 +876,8 @@ static bool purity_checked(HtUP *ht, RAnalFunction *fcn)
|
||||
/*
|
||||
* Checks whether a given function is pure and sets its 'is_pure' field.
|
||||
* This function marks fcn 'not pure' if fcn, or any function called by fcn, accesses data
|
||||
* from outside, even if it only READS it.
|
||||
* Probably worth changing it in the future, so that it marks fcn 'impure' only when it
|
||||
* from outside, even if it only READS it.
|
||||
* Probably worth changing it in the future, so that it marks fcn 'impure' only when it
|
||||
* (or any function called by fcn) MODIFIES external data.
|
||||
*/
|
||||
static void check_purity(HtUP *ht, RAnal *anal, RAnalFunction *fcn) {
|
||||
@ -971,6 +974,7 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut6
|
||||
|
||||
VERBOSE_ANAL eprintf ("Append bb at 0x%08"PFMT64x" (fcn 0x%08"PFMT64x ")\n", addr, fcn->addr);
|
||||
|
||||
ut64 leaddr = UT64_MAX;
|
||||
bool last_is_push = false;
|
||||
bool last_is_mov_lr_pc = false;
|
||||
ut64 last_push_addr = UT64_MAX;
|
||||
@ -1126,7 +1130,7 @@ repeat:
|
||||
last_is_mov_lr_pc = true;
|
||||
}
|
||||
}
|
||||
// skip mov reg,reg
|
||||
// skip mov reg, reg
|
||||
if (anal->opt.jmptbl) {
|
||||
if (op.scale && op.ireg) {
|
||||
movptr = op.ptr;
|
||||
@ -1144,6 +1148,14 @@ repeat:
|
||||
}
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_LEA:
|
||||
// if first byte in op.ptr is 0xff, then set leaddr assuming its a jumptable
|
||||
{
|
||||
ut8 buf[4];
|
||||
anal->iob.read_at (anal->iob.io, op.ptr, &buf, sizeof (buf));
|
||||
if (buf[2] == 0xff && buf[3] == 0xff) {
|
||||
leaddr = op.ptr; // XXX movptr is dupped but seems to be trashed sometimes, better track leaddr separately
|
||||
}
|
||||
}
|
||||
// skip lea reg,[reg]
|
||||
if (anal->opt.hpskip && regs_exist (op.src[0], op.dst)
|
||||
&& !strcmp (op.src[0]->reg->name, op.dst->reg->name)) {
|
||||
@ -1182,7 +1194,7 @@ repeat:
|
||||
op.type = R_ANAL_OP_TYPE_RET;
|
||||
gotoBeach (R_ANAL_RET_END);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_ILL:
|
||||
if (anal->opt.nopskip && len > 3 && !memcmp (buf, "\x00\x00\x00\x00", 4)) {
|
||||
@ -1298,8 +1310,16 @@ repeat:
|
||||
gotoBeachRet ();
|
||||
#endif
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_SUB:
|
||||
if (op.val != UT64_MAX && op.val > 0) {
|
||||
// if register is not stack
|
||||
cmpval = op.val;
|
||||
}
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_CMP:
|
||||
cmpval = op.ptr;
|
||||
if (op.ptr) {
|
||||
cmpval = op.ptr;
|
||||
}
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_CJMP:
|
||||
case R_ANAL_OP_TYPE_MCJMP:
|
||||
@ -1448,6 +1468,10 @@ repeat:
|
||||
if (try_get_jmptbl_info (anal, fcn, op.addr, bb, &table_size, &default_case)) {
|
||||
ret = try_walkthrough_jmptbl (anal, fcn, depth, op.addr, op.ptr, op.ptr, anal->bits >> 3, table_size, default_case, ret);
|
||||
}
|
||||
} else if (movptr == 0) {
|
||||
ut64 jmptbl_base = leaddr;
|
||||
ut64 table_size = cmpval + 1;
|
||||
ret = try_walkthrough_jmptbl (anal, fcn, depth, op.addr, jmptbl_base, jmptbl_base, 4, table_size, -1, ret);
|
||||
} else if (movptr != UT64_MAX) {
|
||||
ut64 table_size, default_case;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user