/* radare - LGPL - Copyright 2015 - pancake */ #include #define DB esil->db_trace #define KEY(x) sdb_fmt (0, "%d."x, esil->trace_idx) #define KEYAT(x,y) sdb_fmt (0, "%d."x".0x%"PFMT64x, esil->trace_idx, y) #define KEYREG(x,y) sdb_fmt (0, "%d."x".%s", esil->trace_idx, y) static int ocbs_set = false; static RAnalEsilCallbacks ocbs = {0}; static int trace_hook_reg_read(RAnalEsil *esil, const char *name, ut64 *res, int *size) { int ret = 0; if (*name=='0') { //eprintf ("Register not found in profile\n"); return 0; } if (ocbs.hook_reg_read) { RAnalEsilCallbacks cbs = esil->cb; esil->cb = ocbs; ret = ocbs.hook_reg_read (esil, name, res, size); esil->cb = cbs; } if (!ret && esil->cb.reg_read) { ret = esil->cb.reg_read (esil, name, res, size); } if (ret) { ut64 val = *res; //eprintf ("[ESIL] REG READ %s 0x%08"PFMT64x"\n", name, val); sdb_array_add (DB, KEY ("reg.read"), name, 0); sdb_num_set (DB, KEYREG ("reg.read", name), val, 0); } else { eprintf ("[ESIL] REG READ %s FAILED\n", name); } return ret; } static int trace_hook_reg_write(RAnalEsil *esil, const char *name, ut64 val) { int ret = 0; //eprintf ("[ESIL] REG WRITE %s 0x%08"PFMT64x"\n", name, val); sdb_array_add (DB, KEY ("reg.write"), name, 0); sdb_num_set (DB, KEYREG ("reg.write", name), val, 0); if (ocbs.hook_reg_write) { RAnalEsilCallbacks cbs = esil->cb; esil->cb = ocbs; ret = ocbs.hook_reg_write (esil, name, val); esil->cb = cbs; } return ret; } static int trace_hook_mem_read(RAnalEsil *esil, ut64 addr, ut8 *buf, int len) { char *hexbuf = calloc ((1 + len), 4); int ret = 0; if (esil->cb.mem_read) { ret = esil->cb.mem_read (esil, addr, buf, len); } sdb_array_add_num (DB, KEY ("mem.read"), addr, 0); r_hex_bin2str (buf, len, hexbuf); sdb_set (DB, KEYAT ("mem.read.data", addr), hexbuf, 0); //eprintf ("[ESIL] MEM READ 0x%08"PFMT64x" %s\n", addr, hexbuf); free (hexbuf); if (ocbs.hook_mem_read) { RAnalEsilCallbacks cbs = esil->cb; esil->cb = ocbs; ret = ocbs.hook_mem_read (esil, addr, buf, len); esil->cb = cbs; } return ret; } static int trace_hook_mem_write(RAnalEsil *esil, ut64 addr, const ut8 *buf, int len) { int ret = 0; char *hexbuf = malloc ((1+len)*3); sdb_array_add_num (DB, KEY ("mem.write"), addr, 0); r_hex_bin2str (buf, len, hexbuf); sdb_set (DB, KEYAT ("mem.write.data", addr), hexbuf, 0); //eprintf ("[ESIL] MEM WRITE 0x%08"PFMT64x" %s\n", addr, hexbuf); free (hexbuf); if (ocbs.hook_mem_write) { RAnalEsilCallbacks cbs = esil->cb; esil->cb = ocbs; ret = ocbs.hook_mem_write (esil, addr, buf, len); esil->cb = cbs; } return ret; } R_API void r_anal_esil_trace (RAnalEsil *esil, RAnalOp *op) { const char *expr = r_strbuf_get (&op->esil); int esil_debug = esil->debug; if (ocbs_set) { eprintf ("cannot call recursively\n"); } ocbs = esil->cb; ocbs_set = true; if (!DB) DB = sdb_new0 (); sdb_num_set (DB, "idx", esil->trace_idx, 0); sdb_num_set (DB, KEY ("addr"), op->addr, 0); // sdb_set (DB, KEY ("opcode"), op->mnemonic, 0); // sdb_set (DB, KEY ("addr"), expr, 0); //eprintf ("[ESIL] ADDR 0x%08"PFMT64x"\n", op->addr); //eprintf ("[ESIL] OPCODE %s\n", op->mnemonic); //eprintf ("[ESIL] EXPR = %s\n", expr); /* set hooks */ esil->debug = 0; esil->cb.hook_reg_read = trace_hook_reg_read; esil->cb.hook_reg_write = trace_hook_reg_write; esil->cb.hook_mem_read = trace_hook_mem_read; esil->cb.hook_mem_write = trace_hook_mem_write; /* evaluate esil expression */ r_anal_esil_parse (esil, expr); /* restore hooks */ esil->cb = ocbs; ocbs_set = false; esil->debug = esil_debug; esil->trace_idx ++; } R_API void r_anal_esil_trace_list (RAnalEsil *esil) { /* TODO. make output more userfriendly */ sdb_list (esil->db_trace); } R_API void r_anal_esil_trace_show(RAnalEsil *esil, int idx) { PrintfCallback p = esil->anal->cb_printf; const char *str2; const char *str; int trace_idx = esil->trace_idx; esil->trace_idx = idx; str2 = sdb_const_get (DB, KEY ("addr"), 0); if (!str2) { return; } p ("dr pc = %s\n", str2); /* registers */ str = sdb_const_get (DB, KEY ("reg.read"), 0); if (str) { char regname[32]; const char *next, *ptr = str; if (ptr && *ptr) { do { const char *ztr = sdb_const_anext (ptr, &next); int len = next? (int)(size_t)(next-ztr)-1 : strlen (ztr); if (len trace_idx = trace_idx; }