mirror of
https://github.com/radareorg/radare2.git
synced 2025-04-01 17:11:51 +00:00
Add jumptable support for main() in bins/elf/ls.odd (#15233) ##anal
This commit is contained in:
parent
f6265e131f
commit
dc59b5e7dc
@ -741,7 +741,8 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 len, int
|
||||
return R_ANAL_RET_ERROR; // MUST BE NOT DUP
|
||||
}
|
||||
|
||||
ut64 leaddr = UT64_MAX;
|
||||
static ut64 leaddr = UT64_MAX;
|
||||
static ut64 lea_jmptbl_ip = UT64_MAX;
|
||||
char *last_reg_mov_lea_name = NULL;
|
||||
ut64 last_reg_mov_lea_val = UT64_MAX;
|
||||
bool last_is_reg_mov_lea = false;
|
||||
@ -997,7 +998,7 @@ repeat:
|
||||
{
|
||||
ut8 buf[4];
|
||||
anal->iob.read_at (anal->iob.io, op.ptr, buf, sizeof (buf));
|
||||
if (buf[2] == 0xff && buf[3] == 0xff) {
|
||||
if ((buf[2] == 0xff || buf[2] == 0xfe) && buf[3] == 0xff) {
|
||||
leaddr = op.ptr; // XXX movdisp is dupped but seems to be trashed sometimes(?), better track leaddr separately
|
||||
}
|
||||
if (op.dst && op.dst->reg && op.dst->reg->name && op.ptr > 0 && op.ptr != UT64_MAX) {
|
||||
@ -1033,6 +1034,9 @@ repeat:
|
||||
if (try_get_jmptbl_info (anal, fcn, jmp_aop.addr, bb, &table_size, &default_case)
|
||||
|| try_get_delta_jmptbl_info (anal, fcn, jmp_aop.addr, op.addr, &table_size, &default_case)) {
|
||||
ret = try_walkthrough_jmptbl (anal, fcn, depth, jmp_aop.addr, jmptbl_addr, op.ptr, 4, table_size, default_case, 4);
|
||||
if (ret) {
|
||||
lea_jmptbl_ip = jmp_aop.addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
r_anal_op_fini (&jmp_aop);
|
||||
@ -1123,7 +1127,7 @@ repeat:
|
||||
}
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_CMP: {
|
||||
ut64 val = is_x86 ? op.disp : op.ptr;
|
||||
ut64 val = is_x86 ? op.val : op.ptr;
|
||||
if (val) {
|
||||
cmpval = val;
|
||||
bb->cmpval = cmpval;
|
||||
@ -1264,7 +1268,7 @@ repeat:
|
||||
gotoBeach (R_ANAL_RET_END);
|
||||
}
|
||||
// switch statement
|
||||
if (anal->opt.jmptbl) {
|
||||
if (anal->opt.jmptbl && lea_jmptbl_ip != op.addr) {
|
||||
// op.ireg since rip relative addressing produces way too many false positives otherwise
|
||||
// op.ireg is 0 for rip relative, "rax", etc otherwise
|
||||
if (op.ptr != UT64_MAX && op.ireg) { // direct jump
|
||||
@ -1281,6 +1285,8 @@ repeat:
|
||||
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);
|
||||
leaddr = UT64_MAX;
|
||||
cmpval = UT64_MAX;
|
||||
} else if (movdisp != UT64_MAX) {
|
||||
ut64 table_size, default_case;
|
||||
|
||||
@ -1318,6 +1324,9 @@ repeat:
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lea_jmptbl_ip == op.addr) {
|
||||
lea_jmptbl_ip = UT64_MAX;
|
||||
}
|
||||
if (anal->opt.ijmp) {
|
||||
if (continue_after_jump) {
|
||||
r_anal_fcn_bb (anal, fcn, op.jump, depth);
|
||||
|
Loading…
x
Reference in New Issue
Block a user