mirror of
https://github.com/radareorg/radare2.git
synced 2025-04-02 09:31:45 +00:00
Various enhancements to aae
This commit is contained in:
parent
ed06c5bcb6
commit
eda7899adc
185
libr/core/anal.c
185
libr/core/anal.c
@ -1082,6 +1082,7 @@ R_API int r_core_anal_bb_seek(RCore *core, ut64 addr) {
|
||||
R_API int r_core_anal_esil_fcn(RCore *core, ut64 at, ut64 from, int reftype, int depth) {
|
||||
const char *esil;
|
||||
RAnalOp *op;
|
||||
eprintf ("TODO\n");
|
||||
while (1) {
|
||||
// TODO: Implement the proper logic for doing esil analysis
|
||||
op = r_core_anal_op (core, at);
|
||||
@ -1104,11 +1105,10 @@ R_API int r_core_anal_esil_fcn(RCore *core, ut64 at, ut64 from, int reftype, int
|
||||
* If the function has been already analyzed, it adds a
|
||||
* reference to that fcn */
|
||||
R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int depth) {
|
||||
bool use_esil = r_config_get_i (core->config, "anal.esil");
|
||||
RAnalFunction *fcn;
|
||||
RListIter *iter;
|
||||
|
||||
int use_esil = r_config_get_i (core->config, "anal.esil");
|
||||
|
||||
if (core->io->va && !core->io->raw) {
|
||||
if (!r_io_is_valid_offset (core->io, at, !core->anal->opt.noncode)) {
|
||||
// eprintf ("Invalid address: 0x%08"PFMT64x"\n", at);
|
||||
@ -2597,55 +2597,67 @@ static int esilbreak_mem_write(RAnalEsil *esil, ut64 addr, const ut8 *buf, int l
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* TODO: move into RCore? */
|
||||
static ut64 esilbreak_last_read = UT64_MAX;
|
||||
#if 0
|
||||
static ut32 esilbreak_last_data = UT32_MAX;
|
||||
#endif
|
||||
|
||||
static ut64 ntarget = UT64_MAX;
|
||||
|
||||
static int esilbreak_mem_read(RAnalEsil *esil, ut64 addr, ut8 *buf, int len) {
|
||||
ut8 str[128];
|
||||
char cmd[128];
|
||||
esilbreak_last_read = UT64_MAX;
|
||||
if (myvalid (addr) && r_io_is_valid_offset (mycore->io, addr, 0)) {
|
||||
ut32 refptr = 0;
|
||||
if (r_io_read_at (mycore->io, addr, (ut8*)&refptr, sizeof (refptr)) != sizeof (refptr)) {
|
||||
/* invalid read */
|
||||
refptr = -1;
|
||||
}
|
||||
if (myvalid (refptr) && r_io_is_valid_offset (mycore->io, (ut64)refptr, 0)) {
|
||||
esilbreak_last_read = addr;
|
||||
snprintf (cmd, sizeof (cmd), "axd 0x%"PFMT64x" 0x%"PFMT64x,
|
||||
(ut64)refptr, esil->address);
|
||||
str[0] = 0;
|
||||
if (r_io_read_at (mycore->io, refptr, str, sizeof (str)) < 1) {
|
||||
eprintf ("Invalid read\n");
|
||||
if (ntarget == UT64_MAX || ntarget == addr) {
|
||||
if (myvalid (addr) && r_io_is_valid_offset (mycore->io, addr, 0)) {
|
||||
ut8 buf[4];
|
||||
ut64 refptr;
|
||||
if (r_io_read_at (mycore->io, addr, (ut8*)buf, sizeof (buf)) != sizeof (buf)) {
|
||||
/* invalid read */
|
||||
refptr = UT32_MAX;
|
||||
} else {
|
||||
refptr = r_read_ble32 (buf, esil->anal->big_endian);
|
||||
}
|
||||
|
||||
if (myvalid (refptr) && r_io_is_valid_offset (mycore->io, (ut64)refptr, 0)) {
|
||||
esilbreak_last_read = addr;
|
||||
snprintf (cmd, sizeof (cmd), "axd 0x%"PFMT64x" 0x%"PFMT64x,
|
||||
(ut64)refptr, esil->address);
|
||||
str[0] = 0;
|
||||
}
|
||||
str[sizeof(str)-1] = 0;
|
||||
add_string_ref (mycore, refptr); //ut64 xref_to) {
|
||||
#if 0
|
||||
char cmd2[128];
|
||||
int slen = 0;
|
||||
if (is_string (str, sizeof (str)-1, &slen)) {
|
||||
char *str2[256];
|
||||
esilbreak_last_data = refptr;
|
||||
snprintf (str2, sizeof (str2) - 1, "esilref: '%s'", str);
|
||||
r_meta_set_string (mycore->anal, R_META_TYPE_COMMENT, esil->address, str2);
|
||||
r_meta_set_string (mycore->anal, R_META_TYPE_COMMENT, refptr, str2);
|
||||
if (refptr) {
|
||||
snprintf (cmd2, sizeof (cmd2), "axd 0x%"PFMT64x" 0x%"PFMT64x,
|
||||
esil->address, addr);
|
||||
//eprintf ("%s\n", cmd2);
|
||||
r_core_cmd0 (mycore, cmd2);
|
||||
if (r_io_read_at (mycore->io, refptr, str, sizeof (str)) < 1) {
|
||||
eprintf ("Invalid read\n");
|
||||
str[0] = 0;
|
||||
}
|
||||
str[sizeof(str)-1] = 0;
|
||||
add_string_ref (mycore, refptr);
|
||||
#if 0
|
||||
char cmd2[128];
|
||||
int slen = 0;
|
||||
if (is_string (str, sizeof (str)-1, &slen)) {
|
||||
char *str2[256];
|
||||
esilbreak_last_data = refptr;
|
||||
snprintf (str2, sizeof (str2) - 1, "esilref: '%s'", str);
|
||||
r_meta_set_string (mycore->anal, R_META_TYPE_COMMENT, esil->address, str2);
|
||||
r_meta_set_string (mycore->anal, R_META_TYPE_COMMENT, refptr, str2);
|
||||
if (refptr) {
|
||||
snprintf (cmd2, sizeof (cmd2), "axd 0x%"PFMT64x" 0x%"PFMT64x,
|
||||
esil->address, addr);
|
||||
//eprintf ("%s\n", cmd2);
|
||||
r_core_cmd0 (mycore, cmd2);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
snprintf (cmd, sizeof (cmd), "axd 0x%"PFMT64x" 0x%"PFMT64x,
|
||||
esil->address, addr);
|
||||
} else {
|
||||
snprintf (cmd, sizeof (cmd), "axd 0x%"PFMT64x" 0x%"PFMT64x,
|
||||
addr, esil->address); //, addr);
|
||||
//eprintf ("Spurious reference pointer from to: 0x%08"PFMT64x"\n", addr);
|
||||
}
|
||||
//eprintf ("%s\n", cmd);
|
||||
if (*cmd) {
|
||||
r_core_cmd0 (mycore, cmd);
|
||||
}
|
||||
}
|
||||
//eprintf ("%s\n", cmd);
|
||||
r_core_cmd0 (mycore, cmd);
|
||||
}
|
||||
return 0; // fallback
|
||||
}
|
||||
@ -2675,7 +2687,8 @@ static void add_string_ref (RCore *core, ut64 xref_to) {
|
||||
}
|
||||
}
|
||||
|
||||
R_API void r_core_anal_esil (RCore *core, const char *str) {
|
||||
|
||||
R_API void r_core_anal_esil(RCore *core, const char *str, const char *target) {
|
||||
bool cfg_anal_strings = r_config_get_i (core->config, "anal.strings");
|
||||
RAnalEsil *ESIL = core->anal->esil;
|
||||
const char *pcname;
|
||||
@ -2690,10 +2703,16 @@ R_API void r_core_anal_esil (RCore *core, const char *str) {
|
||||
|
||||
mycore = core;
|
||||
if (!strcmp (str, "?")) {
|
||||
eprintf ("Usage: aae[f] [len] - analyze refs in function, section or len bytes with esil\n");
|
||||
eprintf (" aae $SS @ $S - analyze the whole section\n");
|
||||
eprintf ("Usage: aae[f] [len] [addr] - analyze refs in function, section or len bytes with esil\n");
|
||||
eprintf (" aae $SS @ $S - analyze the whole section\n");
|
||||
eprintf (" aae $SS str.Hello @ $S - find references for str.Hellow\n");
|
||||
return;
|
||||
}
|
||||
if (target) {
|
||||
ntarget = r_num_math (core->num, target);
|
||||
} else {
|
||||
ntarget = UT64_MAX;
|
||||
}
|
||||
if (!strcmp (str, "f")) {
|
||||
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
|
||||
if (fcn) {
|
||||
@ -2702,7 +2721,7 @@ R_API void r_core_anal_esil (RCore *core, const char *str) {
|
||||
}
|
||||
}
|
||||
if (str[0] == ' ') {
|
||||
end = addr + r_num_math (core->num, str+1);
|
||||
end = addr + r_num_math (core->num, str + 1);
|
||||
} else {
|
||||
RIOSection *sect = r_io_section_vget (core->io, addr);
|
||||
if (sect) {
|
||||
@ -2750,7 +2769,7 @@ R_API void r_core_anal_esil (RCore *core, const char *str) {
|
||||
}
|
||||
r_cons_break (cccb, core);
|
||||
cur = addr + i;
|
||||
if (!r_anal_op (core->anal, &op, cur, buf + i, iend-i)) {
|
||||
if (!r_anal_op (core->anal, &op, cur, buf + i, iend - i)) {
|
||||
i += minopsize - 1;
|
||||
}
|
||||
r_asm_set_pc (core->assembler, cur);
|
||||
@ -2759,11 +2778,11 @@ R_API void r_core_anal_esil (RCore *core, const char *str) {
|
||||
if (i > iend) {
|
||||
break;
|
||||
}
|
||||
if (r_asm_disassemble (core->assembler, &asmop, buf+i, iend-i) > 0) {
|
||||
if (r_asm_disassemble (core->assembler, &asmop, buf + i, iend - i) > 0) {
|
||||
op.mnemonic = strdup (asmop.buf_asm);
|
||||
}
|
||||
if (op.size < 1) {
|
||||
i++;
|
||||
i += minopsize - 1;
|
||||
continue;
|
||||
}
|
||||
if (1) {
|
||||
@ -2780,10 +2799,14 @@ R_API void r_core_anal_esil (RCore *core, const char *str) {
|
||||
|
||||
switch (op.type) {
|
||||
case R_ANAL_OP_TYPE_LEA:
|
||||
if (strcmp (core->anal->cpu, "arm")) {
|
||||
if (cfg_anal_strings) {
|
||||
r_anal_ref_add (core->anal, op.ptr, cur, 'd');
|
||||
add_string_ref (core, op.ptr);
|
||||
if ((target && op.ptr == ntarget) || !target) {
|
||||
if (strcmp (core->anal->cpu, "arm")) {
|
||||
if (cfg_anal_strings) {
|
||||
r_anal_ref_add (core->anal, op.ptr, cur, 'd');
|
||||
if ((target && op.ptr == ntarget) || !target) {
|
||||
add_string_ref (core, op.ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -2791,35 +2814,39 @@ R_API void r_core_anal_esil (RCore *core, const char *str) {
|
||||
/* TODO: test if this is valid for other archs too */
|
||||
if (core->anal->bits == 64 && !strcmp (core->anal->cpu, "arm")) {
|
||||
ut64 dst = ESIL->cur;
|
||||
r_anal_ref_add (core->anal, dst, cur, 'd');
|
||||
if ((target && dst == ntarget) || !target) {
|
||||
r_anal_ref_add (core->anal, dst, cur, 'd');
|
||||
}
|
||||
} else if ((core->anal->bits == 32 && !strcmp (core->anal->cpu, "mips"))) {
|
||||
ut64 dst = ESIL->cur;
|
||||
|
||||
if (!op.src[0] || !op.src[0]->reg || !op.src[0]->reg->name)
|
||||
break;
|
||||
|
||||
if (!strcmp(op.src[0]->reg->name, "sp"))
|
||||
if (!strcmp (op.src[0]->reg->name, "sp"))
|
||||
break;
|
||||
if (!strcmp(op.src[0]->reg->name, "zero"))
|
||||
if (!strcmp (op.src[0]->reg->name, "zero"))
|
||||
break;
|
||||
|
||||
|
||||
if (dst > 0xffff && op.src[1] && (dst & 0xffff) == (op.src[1]->imm & 0xffff) &&
|
||||
myvalid (dst) && r_io_is_valid_offset (mycore->io, dst, 0)) {
|
||||
RFlagItem *f;
|
||||
char *str;
|
||||
if ((target && dst == ntarget) || !target) {
|
||||
if (dst > 0xffff && op.src[1] && (dst & 0xffff) == (op.src[1]->imm & 0xffff) &&
|
||||
myvalid (dst) && r_io_is_valid_offset (mycore->io, dst, 0)) {
|
||||
RFlagItem *f;
|
||||
char *str;
|
||||
|
||||
r_anal_ref_add (core->anal, dst, cur, 'd');
|
||||
if (cfg_anal_strings) {
|
||||
add_string_ref (core, dst);
|
||||
}
|
||||
r_anal_ref_add (core->anal, dst, cur, 'd');
|
||||
if (cfg_anal_strings) {
|
||||
add_string_ref (core, dst);
|
||||
}
|
||||
|
||||
if ((f = r_flag_get_i2 (core->flags, dst))) {
|
||||
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, cur, f->name);
|
||||
} else if ((str = is_string_at (mycore, dst, NULL))) {
|
||||
char *str2 = sdb_fmt (0, "esilref: '%s'", str);
|
||||
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, cur, str2);
|
||||
free (str);
|
||||
if ((f = r_flag_get_i2 (core->flags, dst))) {
|
||||
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, cur, f->name);
|
||||
} else if ((str = is_string_at (mycore, dst, NULL))) {
|
||||
char *str2 = sdb_fmt (0, "esilref: '%s'", str);
|
||||
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, cur, str2);
|
||||
free (str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2827,10 +2854,22 @@ R_API void r_core_anal_esil (RCore *core, const char *str) {
|
||||
case R_ANAL_OP_TYPE_LOAD:
|
||||
{
|
||||
ut64 dst = esilbreak_last_read;
|
||||
if (myvalid (dst) && r_io_is_valid_offset (mycore->io, dst, 0)) {
|
||||
r_anal_ref_add (core->anal, dst, cur, 'd');
|
||||
if (cfg_anal_strings) {
|
||||
add_string_ref (core, dst);
|
||||
if ((target && dst == ntarget) || !target) {
|
||||
if (myvalid (dst) && r_io_is_valid_offset (mycore->io, dst, 0)) {
|
||||
r_anal_ref_add (core->anal, dst, cur, 'd');
|
||||
if (cfg_anal_strings) {
|
||||
add_string_ref (core, dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_CALL:
|
||||
{
|
||||
ut64 dst = op.jump;
|
||||
if ((target && dst == ntarget) || !target) {
|
||||
if (myvalid (dst) && r_io_is_valid_offset (mycore->io, dst, 0)) {
|
||||
r_anal_ref_add (core->anal, dst, cur, 'C');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2843,8 +2882,10 @@ R_API void r_core_anal_esil (RCore *core, const char *str) {
|
||||
if (dst == UT64_MAX) {
|
||||
dst = r_reg_getv (core->anal->reg, pcname);
|
||||
}
|
||||
if (myvalid (dst) && r_io_is_valid_offset (mycore->io, dst, 0)) {
|
||||
r_anal_ref_add (core->anal, dst, cur, 'c');
|
||||
if ((target && dst == ntarget) || !target) {
|
||||
if (myvalid (dst) && r_io_is_valid_offset (mycore->io, dst, 0)) {
|
||||
r_anal_ref_add (core->anal, dst, cur, 'c');
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -4081,7 +4081,7 @@ static int cmd_anal_all(RCore *core, const char *input) {
|
||||
"aa*", "", "analyze all flags starting with sym. (af @@ sym.*)",
|
||||
"aaa", "", "autoname functions after aa (see afna)",
|
||||
"aac", " [len]", "analyze function calls (af @@ `pi len~call[1]`)",
|
||||
"aae", " [len]", "analyze references with ESIL",
|
||||
"aae", " [len] ([addr])", "analyze references with ESIL (optionally to address)",
|
||||
"aai", "[j]", "show info of all analysis parameters",
|
||||
"aar", " [len]", "analyze len bytes of instructions for references",
|
||||
"aan", "", "autoname functions that either start with fcn.* or sym.func.*",
|
||||
@ -4206,7 +4206,15 @@ static int cmd_anal_all(RCore *core, const char *input) {
|
||||
break;
|
||||
}
|
||||
case 'e': // "aae"
|
||||
r_core_anal_esil (core, input + 1);
|
||||
{
|
||||
char *len = strdup (input + 1);
|
||||
char *addr = (len && *len) ? strchr (len + 1, ' ') : NULL;
|
||||
if (addr) {
|
||||
*addr++ = 0;
|
||||
}
|
||||
r_core_anal_esil (core, len, addr);
|
||||
free (len);
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
(void)r_core_anal_refs (core, input + 1);
|
||||
|
@ -325,7 +325,7 @@ R_API int r_core_process_input_pade(RCore *core, const char *input, char** hex,
|
||||
|
||||
/* anal.c */
|
||||
R_API RAnalOp* r_core_anal_op(RCore *core, ut64 addr);
|
||||
R_API void r_core_anal_esil (RCore *core, const char *str);
|
||||
R_API void r_core_anal_esil (RCore *core, const char *str, const char *addr);
|
||||
R_API void r_core_anal_fcn_merge (RCore *core, ut64 addr, ut64 addr2);
|
||||
R_API const char *r_core_anal_optype_colorfor(RCore *core, ut64 addr);
|
||||
R_API ut64 r_core_anal_address (RCore *core, ut64 addr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user