Implement /ce to search esil expressions matching given string

This commit is contained in:
pancake 2017-11-26 19:56:09 +01:00
parent 1960a2c9f7
commit e467c81fe1
5 changed files with 60 additions and 33 deletions

View File

@ -2057,7 +2057,7 @@ const char* MACH0_(get_intrp)(struct MACH0_(obj_t)* bin) {
const char* MACH0_(get_os)(struct MACH0_(obj_t)* bin) {
if (bin)
switch (bin->os) {
case 1: return "osx";
case 1: return "macos";
case 2: return "ios";
case 3: return "watchos";
case 4: return "tvos";

View File

@ -62,7 +62,7 @@ R_API char* r_core_asm_search(RCore *core, const char *input) {
#define OPSZ 8
// TODO: add support for byte-per-byte opcode search
R_API RList *r_core_asm_strsearch(RCore *core, const char *input, ut64 from, ut64 to, int maxhits, int regexp, int everyByte) {
R_API RList *r_core_asm_strsearch(RCore *core, const char *input, ut64 from, ut64 to, int maxhits, int regexp, int everyByte, int mode) {
RCoreAsmHit *hit;
RAsmOp op;
RList *hits;
@ -103,6 +103,8 @@ R_API RList *r_core_asm_strsearch(RCore *core, const char *input, ut64 from, ut6
}
tokens[tokcount] = NULL;
r_cons_break_push (NULL, NULL);
int opsz = 0;
char *opst = NULL;
for (at = from, matchcount = 0; at < to; at += core->blocksize) {
matches = 0;
if (r_cons_is_breaked ()) {
@ -116,21 +118,34 @@ R_API RList *r_core_asm_strsearch(RCore *core, const char *input, ut64 from, ut6
while (addrbytes * (idx + 1) <= core->blocksize) {
ut64 addr = at + idx;
r_asm_set_pc (core->assembler, addr);
if (!(len = r_asm_disassemble (
core->assembler, &op,
buf + addrbytes * idx,
core->blocksize - addrbytes * idx))) {
idx = (matchcount)? tidx + 1: idx + 1;
matchcount = 0;
continue;
if (mode == 'e') {
RAnalOp analop = {0};
if (r_anal_op (core->anal, &analop, addr, buf + idx, 15) < 1) {
idx ++; // TODO: honor mininstrsz
continue;
}
opsz = analop.size;
opst = strdup (r_strbuf_get (&analop.esil));
r_anal_op_fini (&analop);
} else {
if (!(len = r_asm_disassemble (
core->assembler, &op,
buf + addrbytes * idx,
core->blocksize - addrbytes * idx))) {
idx = (matchcount)? tidx + 1: idx + 1;
matchcount = 0;
continue;
}
opsz = op.size;
opst = strdup (op.buf_asm);
}
matches = strcmp (op.buf_asm, "invalid") && strcmp (op.buf_asm, "unaligned");
matches = strcmp (opst, "invalid") && strcmp (opst, "unaligned");
if (matches && tokens[matchcount]) {
if (!regexp) {
matches = strstr(op.buf_asm, tokens[matchcount]) != NULL;
matches = strstr (opst, tokens[matchcount]) != NULL;
} else {
rx = r_regex_new (tokens[matchcount], "");
matches = r_regex_exec (rx, op.buf_asm, 0, 0, 0) == 0;
matches = r_regex_exec (rx, opst, 0, 0, 0) == 0;
r_regex_free (rx);
}
}
@ -140,7 +155,7 @@ R_API RList *r_core_asm_strsearch(RCore *core, const char *input, ut64 from, ut6
}
}
if (matches) {
code = r_str_appendf (code, "%s; ", op.buf_asm);
code = r_str_appendf (code, "%s; ", opst);
if (matchcount == tokcount - 1) {
if (tokcount == 1) {
tidx = idx;
@ -182,11 +197,12 @@ R_API RList *r_core_asm_strsearch(RCore *core, const char *input, ut64 from, ut6
if (everyByte) {
idx = matchcount? tidx + 1: idx + 1;
} else {
idx += R_MAX(1, len);
idx += R_MAX (1, len);
}
R_FREE (code);
matchcount = 0;
}
R_FREE (opst);
}
}
r_cons_break_pop ();
@ -195,6 +211,7 @@ beach:
free (buf);
free (ptr);
free (code);
R_FREE (opst);
r_cons_break_pop ();
return hits;
}

View File

@ -21,7 +21,8 @@ static const char *help_msg_slash[] = {
"/A", " jmp", "find analyzed instructions of this type (/A? for help)",
"/b", "", "search backwards, command modifier, followed by other command",
"/B", "", "search recognized RBin headers",
"/c", " jmp [esp]", "search for asm code",
"/c", " jmp [esp]", "search for asm code matching the given string",
"/ce", " rsp,rbp", "search for esil expressions matching",
"/C", "[ar]", "search for crypto materials",
"/d", " 101112", "search for a deltified sequence of bytes",
"/e", " /E.F/i", "match regular expression",
@ -874,32 +875,38 @@ static RList *construct_rop_gadget(RCore *core, ut64 addr, ut8 *buf, int idx, co
valid = false;
goto ret;
}
int opsz = 0;
char *opst = NULL;
while (nb_instr < max_instr) {
r_list_append (localbadstart, (void *) (intptr_t) idx);
r_asm_set_pc (core->assembler, addr);
if (!r_asm_disassemble (core->assembler, &asmop, buf + idx, 15)) {
opsz = 1;
goto ret;
} else {
opsz = asmop.size;
opst = asmop.buf_asm;
}
if (!strncasecmp (asmop.buf_asm, "invalid", strlen ("invalid")) ||
!strncasecmp (asmop.buf_asm, ".byte", strlen (".byte"))) {
if (!strncasecmp (opst, "invalid", strlen ("invalid")) ||
!strncasecmp (opst, ".byte", strlen (".byte"))) {
valid = false;
goto ret;
}
hit = r_core_asm_hit_new ();
hit->addr = addr;
hit->len = asmop.size;
hit->len = opsz;
r_list_append (hitlist, hit);
// Move on to the next instruction
idx += asmop.size;
addr += asmop.size;
idx += opsz;
addr += opsz;
if (rx) {
// grep_find = r_regex_exec (rx, asmop.buf_asm, 0, 0, 0);
grep_find = !r_regex_match (rx, "e", asmop.buf_asm);
grep_find = !r_regex_match (rx, "e", opst);
search_hit = (end && grep && (grep_find < 1));
} else {
search_hit = (end && grep && strstr (asmop.buf_asm, grep_str));
search_hit = (end && grep && strstr (opst, grep_str));
}
// Handle (possible) grep
@ -919,8 +926,8 @@ static RList *construct_rop_gadget(RCore *core, ut64 addr, ut8 *buf, int idx, co
}
}
if (endaddr <= (idx - asmop.size)) {
valid = (endaddr == idx - asmop.size);
if (endaddr <= (idx - opsz)) {
valid = (endaddr == idx - opsz);
goto ret;
}
nb_instr++;
@ -1851,7 +1858,7 @@ static void do_anal_search(RCore *core, struct search_parameters *param, const c
free (buf);
}
static void do_asm_search(RCore *core, struct search_parameters *param, const char *input) {
static void do_asm_search(RCore *core, struct search_parameters *param, const char *input, int mode) {
RCoreAsmHit *hit;
RListIter *iter, *itermap;
int count = 0, maxhits = 0, filter = 0;
@ -1908,7 +1915,7 @@ static void do_asm_search(RCore *core, struct search_parameters *param, const ch
hits = NULL;
} else {
hits = r_core_asm_strsearch (core, input + 2,
from, to, maxhits, regexp, everyByte);
from, to, maxhits, regexp, everyByte, mode);
}
if (hits) {
const char *cmdhit = r_config_get (core->config, "cmd.hit");
@ -2565,7 +2572,7 @@ reread:
int count = 0;
const int align = core->search->align;
r_list_foreach (param.boundaries, iter, map) {
eprintf ("-- %llx %llx\n", map->itv.addr, r_itv_end (map->itv));
// eprintf ("-- %llx %llx\n", map->itv.addr, r_itv_end (map->itv));
r_cons_break_push (NULL, NULL);
for (addr = map->itv.addr; addr < r_itv_end (map->itv); addr++) {
if (r_cons_is_breaked ()) {
@ -2988,11 +2995,14 @@ reread:
}
break;
case 'c': // "/c" search asm
dosearch = 0;
if (input[1] == '?') {
r_core_cmd_help (core, help_msg_slash_c);
} else if (input[1] == 'e') { // "/ce"
do_asm_search (core, &param, input + 1, 'e');
} else { // "/c"
do_asm_search (core, &param, input, 0);
}
do_asm_search (core, &param, input);
dosearch = 0;
break;
case '+': // "/+"
if (input[1] == ' ') {

View File

@ -1846,8 +1846,8 @@ R_API int r_core_rtr_cmds (RCore *core, const char *port) {
}
}
if (!r_config_get_i (core->config, "scr.prompt") &&
!strcmp ((char *)buf, "q!") ||
!strcmp ((char *)buf, ".--")) {
(!strcmp ((char *)buf, "q!") ||
!strcmp ((char *)buf, ".--"))) {
r_socket_close (ch);
break;
}

View File

@ -415,7 +415,7 @@ R_API RList *r_core_asm_hit_list_new(void);
R_API void r_core_asm_hit_free(void *_hit);
R_API void r_core_set_asm_configs(RCore *core, char *arch, ut32 bits, int segoff);
R_API char* r_core_asm_search(RCore *core, const char *input);
R_API RList *r_core_asm_strsearch(RCore *core, const char *input, ut64 from, ut64 to, int maxhits, int regexp, int everyByte);
R_API RList *r_core_asm_strsearch(RCore *core, const char *input, ut64 from, ut64 to, int maxhits, int regexp, int everyByte, int mode);
R_API RList *r_core_asm_bwdisassemble (RCore *core, ut64 addr, int n, int len);
R_API RList *r_core_asm_back_disassemble_instr (RCore *core, ut64 addr, int len, ut32 hit_count, ut32 extra_padding);
R_API RList *r_core_asm_back_disassemble_byte (RCore *core, ut64 addr, int len, ut32 hit_count, ut32 extra_padding);