Skip to content

Commit

Permalink
Add jumptable support for main() in bins/elf/analysis/ls-alxchk (#15266
Browse files Browse the repository at this point in the history
…) ##anal
  • Loading branch information
kazarmy authored and radare committed Oct 13, 2019
1 parent 77e73c1 commit 17cdb75
Showing 1 changed file with 40 additions and 4 deletions.
44 changes: 40 additions & 4 deletions libr/anal/fcn.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,11 @@ static void check_purity(HtUP *ht, RAnal *anal, RAnalFunction *fcn) {
r_list_free (refs);
}

typedef struct {
ut64 op_addr;
ut64 leaddr;
} leaddr_pair;

static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 len, int depth) {
const int continue_after_jump = anal->opt.afterjmp;
const int addrbytes = anal->iob.io ? anal->iob.io->addrbytes : 1;
Expand Down Expand Up @@ -741,7 +746,14 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 len, int
return R_ANAL_RET_ERROR; // MUST BE NOT DUP
}

static ut64 leaddr = UT64_MAX;
static RList *leaddrs = NULL;
if (!leaddrs) {
leaddrs = r_list_new (); // TODO: leaks
if (!leaddrs) {
eprintf ("Cannot create leaddr list\n");
return R_ANAL_RET_ERROR;
}
}
static ut64 lea_jmptbl_ip = UT64_MAX;
char *last_reg_mov_lea_name = NULL;
ut64 last_reg_mov_lea_val = UT64_MAX;
Expand Down Expand Up @@ -999,7 +1011,14 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 len, int
ut8 buf[4];
anal->iob.read_at (anal->iob.io, op.ptr, buf, sizeof (buf));
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
leaddr_pair *pair = R_NEW (leaddr_pair);
if (!pair) {
eprintf ("Cannot create leaddr_pair\n");
gotoBeach (R_ANAL_RET_ERROR);
}
pair->op_addr = op.addr;
pair->leaddr = op.ptr; // XXX movdisp is dupped but seems to be trashed sometimes(?), better track leaddr separately
r_list_append (leaddrs, pair);
}
if (op.dst && op.dst->reg && op.dst->reg->name && op.ptr > 0 && op.ptr != UT64_MAX) {
free (last_reg_mov_lea_name);
Expand Down Expand Up @@ -1282,10 +1301,27 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 len, int
ret = try_walkthrough_jmptbl (anal, fcn, depth, op.addr, op.ptr, op.ptr, anal->bits >> 3, table_size, default_case, ret);
}
} else if (movdisp == 0) {
ut64 jmptbl_base = leaddr;
ut64 jmptbl_base = UT64_MAX;
ut64 lea_op_off = UT64_MAX;
RListIter *lea_op_iter = NULL;
RListIter *iter;
leaddr_pair *pair;
// find nearest candidate leaddr before op.addr
r_list_foreach (leaddrs, iter, pair) {
if (pair->op_addr >= op.addr) {
continue;
}
if (lea_op_off == UT64_MAX || lea_op_off > op.addr - pair->op_addr) {
lea_op_off = op.addr - pair->op_addr;
jmptbl_base = pair->leaddr;
lea_op_iter = iter;
}
}
if (lea_op_iter) {
r_list_delete (leaddrs, lea_op_iter);
}
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;
Expand Down

0 comments on commit 17cdb75

Please sign in to comment.