Add analysis.jmp.tblmaxoffset configuration option
Allows the user to configure the maximum offset from the jump table jump instruction to consider it valid
This commit is contained in:
parent
2eba4e190d
commit
d8dd2c5097
3 changed files with 18 additions and 5 deletions
|
|
@ -12,7 +12,6 @@
|
|||
#define SDB_KEY_BB "bb.0x%" PFMT64x ".0x%" PFMT64x
|
||||
// XXX must be configurable by the user
|
||||
#define JMPTBL_LEA_SEARCH_SZ 64
|
||||
#define JMPTBL_MAXFCNSIZE 4096
|
||||
#define BB_ALIGN 0x10
|
||||
#define MAX_SCAN_SIZE 0x7ffffff
|
||||
|
||||
|
|
@ -164,7 +163,7 @@ static bool isSymbolNextInstruction(RzAnalysis *analysis, RzAnalysisOp *op) {
|
|||
return (fi && fi->name && (strstr(fi->name, "imp.") || strstr(fi->name, "sym.") || strstr(fi->name, "entry") || strstr(fi->name, "main")));
|
||||
}
|
||||
|
||||
static bool is_delta_pointer_table(RzAnalysis *analysis, RzAnalysisFunction *fcn, ut64 addr, ut64 lea_ptr, ut64 *jmptbl_addr, ut64 *casetbl_addr, RzAnalysisOp *jmp_aop) {
|
||||
static bool is_delta_pointer_table(RzAnalysis *analysis, ut64 addr, ut64 lea_ptr, ut64 *jmptbl_addr, ut64 *casetbl_addr, RzAnalysisOp *jmp_aop) {
|
||||
int i;
|
||||
ut64 dst;
|
||||
st32 jmptbl[64] = { 0 };
|
||||
|
|
@ -244,12 +243,17 @@ static bool is_delta_pointer_table(RzAnalysis *analysis, RzAnalysisFunction *fcn
|
|||
for (i = 0; i < 3; i++) {
|
||||
dst = lea_ptr + (st32)rz_read_le32(jmptbl);
|
||||
if (!analysis->iob.is_valid_offset(analysis->iob.io, dst, 0)) {
|
||||
RZ_LOG_VERBOSE("Jump table target is not valid: 0x%" PFMT64x "\n", dst);
|
||||
return false;
|
||||
}
|
||||
if (dst > fcn->addr + JMPTBL_MAXFCNSIZE) {
|
||||
if (!UT64_ADD_OVFCHK(jmp_aop->addr, analysis->opt.jmptbl_maxoffset) &&
|
||||
dst > jmp_aop->addr + analysis->opt.jmptbl_maxoffset) {
|
||||
RZ_LOG_VERBOSE("Jump table target is too far away: 0x%" PFMT64x "\n", dst);
|
||||
return false;
|
||||
}
|
||||
if (analysis->opt.jmpabove && dst < (fcn->addr < JMPTBL_MAXFCNSIZE ? 0 : fcn->addr - JMPTBL_MAXFCNSIZE)) {
|
||||
if (analysis->opt.jmpabove && !UT64_SUB_OVFCHK(jmp_aop->addr, analysis->opt.jmptbl_maxoffset) &&
|
||||
dst < jmp_aop->addr - analysis->opt.jmptbl_maxoffset) {
|
||||
RZ_LOG_VERBOSE("Jump table target is too far away: 0x%" PFMT64x "\n", dst);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -985,7 +989,7 @@ static RzAnalysisBBEndCause run_basic_block_analysis(RzAnalysisTaskItem *item, R
|
|||
RzAnalysisOp jmp_aop = { 0 };
|
||||
ut64 jmptbl_addr = op.ptr;
|
||||
ut64 casetbl_addr = op.ptr;
|
||||
if (is_delta_pointer_table(analysis, fcn, op.addr, op.ptr, &jmptbl_addr, &casetbl_addr, &jmp_aop)) {
|
||||
if (is_delta_pointer_table(analysis, op.addr, op.ptr, &jmptbl_addr, &casetbl_addr, &jmp_aop)) {
|
||||
// we require both checks here since rz_analysis_get_jmptbl_info uses
|
||||
// BB info of the final jmptbl jump, which is no present with
|
||||
// is_delta_pointer_table just scanning ahead
|
||||
|
|
|
|||
|
|
@ -2649,6 +2649,13 @@ static bool cb_analysis_jmptblmax(void *user, void *data) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool cb_analysis_jmptblmaxoffset(void *user, void *data) {
|
||||
RzCore *core = (RzCore *)user;
|
||||
RzConfigNode *node = (RzConfigNode *)data;
|
||||
core->analysis->opt.jmptbl_maxoffset = node->i_value > UT32_MAX ? UT32_MAX : node->i_value;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cb_analysis_cjmpref(void *user, void *data) {
|
||||
RzCore *core = (RzCore *)user;
|
||||
RzConfigNode *node = (RzConfigNode *)data;
|
||||
|
|
@ -2935,6 +2942,7 @@ RZ_API int rz_core_config_init(RzCore *core) {
|
|||
|
||||
SETCB("analysis.jmp.tbl", "true", &cb_analysis_jmptbl, "Analyze jump tables in switch statements");
|
||||
SETICB("analysis.jmp.tblmax", 512, &cb_analysis_jmptblmax, "Maximum amount of entries to analyze in jump tables");
|
||||
SETICB("analysis.jmp.tblmaxoffset", 4096, &cb_analysis_jmptblmaxoffset, "Maximum offset from the jump table jump instruction to consider it valid");
|
||||
|
||||
SETCB("analysis.jmp.cref", "false", &cb_analysis_cjmpref, "Create references for conditional jumps");
|
||||
SETCB("analysis.jmp.ref", "true", &cb_analysis_jmpref, "Create references for unconditional jumps");
|
||||
|
|
|
|||
|
|
@ -533,6 +533,7 @@ typedef struct rz_analysis_options_t {
|
|||
int hpskip; // skip `mov reg,reg` and `lea reg,[reg]`
|
||||
int jmptbl; // analyze jump tables
|
||||
int jmptbl_maxcount; // maximum amount of entries to analyse in a jump table
|
||||
ut32 jmptbl_maxoffset; // maximum offset from the jump table jump instruction to consider it valid
|
||||
int nonull;
|
||||
bool pushret; // analyze push+ret as jmp
|
||||
bool armthumb; //
|
||||
|
|
|
|||
Loading…
Reference in a new issue