mirror of
https://github.com/radareorg/radare2.git
synced 2025-03-06 13:29:46 +00:00
Jump tables #1: direct jump
This commit is contained in:
parent
02643892fe
commit
5d4001cf13
@ -19,6 +19,9 @@
|
||||
// 256KB max function size
|
||||
#define MAX_FCN_SIZE (1024*256)
|
||||
|
||||
#define MAX_JMPTBL_SIZE 1000
|
||||
#define MAX_JMPTBL_JMP 10000
|
||||
|
||||
#define DB a->sdb_fcns
|
||||
#define EXISTS(x,y...) snprintf (key, sizeof(key)-1,x,##y),sdb_exists(DB,key)
|
||||
#define SETKEY(x,y...) snprintf (key, sizeof (key)-1, x,##y);
|
||||
@ -601,6 +604,25 @@ repeat:
|
||||
#endif
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_UJMP:
|
||||
// switch statement
|
||||
if (op.ptr != UT64_MAX && anal->opt.jmptbl) {
|
||||
ut8 *jmptbl = malloc(MAX_JMPTBL_SIZE);
|
||||
ut64 offs, sz = anal->bits >> 3;
|
||||
anal->iob.read_at (anal->iob.io, op.ptr, jmptbl, MAX_JMPTBL_SIZE);
|
||||
for (offs = 0; offs < MAX_JMPTBL_SIZE; offs += sz) {
|
||||
ut64 jmpptr = 0;
|
||||
r_mem_copyendian ((ut8*)&jmpptr, jmptbl + offs, sz, !anal->big_endian);
|
||||
if (anal->limit) {
|
||||
if (jmpptr < anal->limit->from || jmpptr > anal->limit->to)
|
||||
break;
|
||||
}
|
||||
if (jmpptr < addr + idx - MAX_JMPTBL_JMP ||
|
||||
jmpptr > addr + idx + MAX_JMPTBL_JMP)
|
||||
break;
|
||||
recurseAt (jmpptr);
|
||||
}
|
||||
free(jmptbl);
|
||||
}
|
||||
if (continue_after_jump)
|
||||
break;
|
||||
/* fallthru */
|
||||
|
@ -1000,15 +1000,13 @@ SETL/SETNGE
|
||||
break;
|
||||
case X86_OP_MEM:
|
||||
op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
op->ptr = INSOP(0).mem.disp;
|
||||
if (INSOP(0).mem.base == X86_REG_RIP) {
|
||||
op->ptr = INSOP(0).mem.disp;
|
||||
op->ptr += addr + insn->size;
|
||||
op->refptr = 8;
|
||||
} else {
|
||||
cs_x86_op in = INSOP(0);
|
||||
if (in.mem.index == 0 && in.mem.base == 0 && in.mem.scale == 1) {
|
||||
op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
op->ptr = in.mem.disp;
|
||||
if (a->decode) {
|
||||
esilprintf (op, "0x%"PFMT64x",[],%s,=", op->ptr, pc);
|
||||
}
|
||||
|
@ -1233,6 +1233,12 @@ static int cb_anal_limits(void *user, RConfigNode *node) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cb_anal_jmptbl(void *user, void *data) {
|
||||
RCore *core = (RCore*) user;
|
||||
RConfigNode *node = (RConfigNode*) data;
|
||||
core->anal->opt.jmptbl = node->i_value;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define SLURP_LIMIT (10*1024*1024)
|
||||
R_API int r_core_config_init(RCore *core) {
|
||||
@ -1273,6 +1279,8 @@ R_API int r_core_config_init(RCore *core) {
|
||||
SETI("anal.ptrdepth", 3, "Maximum number of nested pointers to follow in analysis");
|
||||
SETICB("anal.maxreflines", 0, &cb_analmaxrefs, "Maximum number of reflines to be analyzed and displayed in asm.lines with pd");
|
||||
|
||||
SETCB("anal.jmptbl", "false", &cb_anal_jmptbl, "Analyze jump tables in switch statements");
|
||||
|
||||
SETPREF("esil.prestep", "true", "Step before esil evaluation in `de` commands");
|
||||
SETCB("esil.debug", "false", &cb_esildebug, "Show ESIL debug info");
|
||||
SETICB("esil.gotolimit", core->anal->esil_goto_limit, &cb_gotolimit, "Maximum number of gotos per ESIL expression");
|
||||
|
@ -573,6 +573,7 @@ typedef struct r_anal_options_t {
|
||||
int bbsplit;
|
||||
int noncode;
|
||||
int nopskip; // skip nops at the beginning of functions
|
||||
int jmptbl; // analyze jump tables
|
||||
} RAnalOptions;
|
||||
|
||||
typedef struct r_anal_t {
|
||||
|
Loading…
x
Reference in New Issue
Block a user