Initial implementation of the new ESIL. (RPNESIL)
Use the 's' key with static analysis to step Anal backends must be updated to use the new syntax Uses 'ar' to get/set regs, and anal->io for read/write mem Some few commands implemented, no extend api yet
This commit is contained in:
parent
3f7e1935fa
commit
dfb9d11474
|
@ -21,7 +21,7 @@ STATIC_OBJS=$(addprefix $(LTOP)/anal/p/,$(STATIC_OBJ))
|
|||
OBJLIBS=meta.o reflines.o ref.o op.o fcn.o bb.o var.o
|
||||
OBJLIBS+=cond.o value.o cc.o diff.o types.o fcnstore.o
|
||||
OBJLIBS+=hint.o vm.o anal.o data.o xrefs.o esil.o sign.o
|
||||
OBJLIBS+=anal_ex.o switch.o state.o kvesil.o cycles.o
|
||||
OBJLIBS+=anal_ex.o switch.o state.o kvesil.o cycles.o rpnesil.o
|
||||
|
||||
OBJS=${STATIC_OBJS} ${OBJLIBS} ${CPARSE_OBJS}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#if 0
|
||||
/* radare - LGPL - Copyright 2013-2014 - pancake */
|
||||
|
||||
#include <r_anal.h>
|
||||
|
@ -355,3 +356,4 @@ R_API int r_anal_esil_eval(RAnal *anal, const char *str) {
|
|||
C (str);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,371 @@
|
|||
/* radare - LGPL - Copyright 2013-2014 - pancake */
|
||||
|
||||
#include <r_anal.h>
|
||||
|
||||
static int esil_reg_write (RAnalEsil *esil, const char *dst, ut64 num);
|
||||
static int esil_reg_read (RAnalEsil *esil, const char *regname, ut64 *num);
|
||||
|
||||
R_API RAnalEsil *r_anal_esil_new() {
|
||||
RAnalEsil *esil = R_NEW0(RAnalEsil);
|
||||
esil->stackptr = 0;
|
||||
return esil;
|
||||
}
|
||||
|
||||
R_API void r_anal_esil_free (RAnalEsil *esil) {
|
||||
int i;
|
||||
for (i=0; i<esil->stackptr;i++)
|
||||
free (esil->stack[i]);
|
||||
free (esil);
|
||||
}
|
||||
|
||||
static int internal_esil_mem_read(RAnalEsil *esil, ut64 addr, ut8 *buf, int len) {
|
||||
if (!esil || !esil->anal || !esil->anal->iob.io)
|
||||
return 0;
|
||||
return esil->anal->iob.read_at (esil->anal->iob.io, addr, buf, len);
|
||||
}
|
||||
|
||||
static int esil_mem_read(RAnalEsil *esil, ut64 addr, ut8 *buf, int len) {
|
||||
int i, ret = 0;
|
||||
if (!buf || !esil)
|
||||
return 0;
|
||||
if (esil->hook_mem_read) {
|
||||
ret = esil->hook_mem_read (esil, addr, buf, len);
|
||||
}
|
||||
if (!ret && esil->mem_read) {
|
||||
ret = esil->mem_read (esil, addr, buf, len);
|
||||
}
|
||||
if (esil->debug) {
|
||||
eprintf ("0x%08"PFMT64x" R> ", addr);
|
||||
for (i=0;i<len;i++)
|
||||
eprintf ("%02x", buf[i]);
|
||||
eprintf ("\n");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int internal_esil_mem_write (THIS *esil, ut64 addr, const ut8 *buf, int len) {
|
||||
if (!esil || !esil->anal || !esil->anal->iob.io)
|
||||
return 0;
|
||||
return esil->anal->iob.write_at (esil->anal->iob.io, addr, buf, len);
|
||||
}
|
||||
|
||||
static int esil_mem_write (THIS *esil, ut64 addr, const ut8 *buf, int len) {
|
||||
int i, ret = 0;
|
||||
if (!buf || !esil)
|
||||
return 0;
|
||||
if (esil->debug) {
|
||||
eprintf ("0x%08"PFMT64x" <W ", addr);
|
||||
for (i=0;i<len;i++)
|
||||
eprintf ("%02x", buf[i]);
|
||||
eprintf ("\n");
|
||||
}
|
||||
if (esil->hook_mem_write) {
|
||||
ret = esil->hook_mem_write (esil, addr, buf, len);
|
||||
}
|
||||
if (!ret && esil->mem_write) {
|
||||
ret = esil->mem_write (esil, addr, buf, len);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int internal_esil_reg_read(RAnalEsil *esil, const char *regname, ut64 *num) {
|
||||
RRegItem *reg = r_reg_get (esil->anal->reg, regname, -1);
|
||||
if (reg) {
|
||||
if (num)
|
||||
*num = r_reg_get_value (esil->anal->reg, reg);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int internal_esil_reg_write(RAnalEsil *esil, const char *regname, ut64 num) {
|
||||
RRegItem *reg = r_reg_get (esil->anal->reg, regname, -1);
|
||||
if (reg) {
|
||||
r_reg_set_value (esil->anal->reg, reg, num);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
R_API int r_anal_esil_setup (RAnalEsil *esil, RAnal *anal) {
|
||||
// register callbacks using this anal module.
|
||||
// this is: set
|
||||
esil->debug = 1;
|
||||
esil->anal = anal;
|
||||
//esil->user = NULL;
|
||||
esil->reg_read = internal_esil_reg_read;
|
||||
esil->reg_write = internal_esil_reg_write;
|
||||
esil->mem_read = internal_esil_mem_read;
|
||||
esil->mem_write = internal_esil_mem_write;
|
||||
return 1;
|
||||
}
|
||||
|
||||
R_API int r_anal_esil_pushnum(RAnalEsil *esil, ut64 num) {
|
||||
char str[64];
|
||||
snprintf (str, sizeof (str)-1, "0x%"PFMT64x, num);
|
||||
return r_anal_esil_push (esil, str);
|
||||
}
|
||||
|
||||
R_API int r_anal_esil_push(RAnalEsil *esil, const char *str) {
|
||||
if (!str || !esil || !*str || esil->stackptr>30)
|
||||
return 0;
|
||||
esil->stack[esil->stackptr++] = strdup (str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
R_API char *r_anal_esil_pop(RAnalEsil *esil) {
|
||||
if (esil->stackptr<1)
|
||||
return NULL;
|
||||
return esil->stack[--esil->stackptr];
|
||||
}
|
||||
|
||||
static int isnum (RAnalEsil *esil, const char *str, ut64 *num) {
|
||||
if (*str >= '0' && *str <= '9') {
|
||||
if (num)
|
||||
*num = r_num_get (NULL, str);
|
||||
return 1;
|
||||
}
|
||||
if (num)
|
||||
*num = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int isregornum(RAnalEsil *esil, const char *str, ut64 *num) {
|
||||
if (!esil_reg_read (esil, str, num))
|
||||
if (!isnum (esil, str, num))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int esil_reg_write (RAnalEsil *esil, const char *dst, ut64 num) {
|
||||
int ret = 0;
|
||||
if (esil->debug) {
|
||||
eprintf ("%s=0x%"PFMT64x"\n", dst, num);
|
||||
}
|
||||
if (esil->hook_reg_write) {
|
||||
ret = esil->hook_reg_write (esil, dst, num);
|
||||
if (!ret)
|
||||
return ret;
|
||||
}
|
||||
if (esil->reg_write) {
|
||||
return esil->reg_write (esil, dst, num);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int esil_reg_read (RAnalEsil *esil, const char *regname, ut64 *num) {
|
||||
int ret = 0;
|
||||
if (num)
|
||||
*num = 0LL;
|
||||
if (esil->hook_reg_read) {
|
||||
ret = esil->hook_reg_read (esil, regname, num);
|
||||
}
|
||||
if (!ret && esil->reg_read) {
|
||||
ret = esil->reg_read (esil, regname, num);
|
||||
}
|
||||
if (ret && num && esil->debug) {
|
||||
eprintf ("%s=0x%"PFMT64x"\n", regname, *num);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int esil_eq (RAnalEsil *esil) {
|
||||
int ret = 0;
|
||||
ut64 num;
|
||||
char *dst = r_anal_esil_pop (esil);
|
||||
char *src = r_anal_esil_pop (esil);
|
||||
if (src && dst && esil_reg_read (esil, dst, NULL)) {
|
||||
if (isregornum (esil, src, &num))
|
||||
ret = esil_reg_write (esil, dst, num);
|
||||
else eprintf ("esil_eq: invalid src\n");
|
||||
} else {
|
||||
eprintf ("esil_eq: invalid parameters\n");
|
||||
}
|
||||
free (src);
|
||||
free (dst);
|
||||
return ret;
|
||||
}
|
||||
|
||||
R_API int r_anal_esil_dumpstack (RAnalEsil *esil) {
|
||||
int i;
|
||||
if (esil->stackptr<1)
|
||||
return 0;
|
||||
eprintf ("StackDump:\n");
|
||||
for (i=esil->stackptr-1;i>=0; i--) {
|
||||
eprintf (" [%d] %s\n", i, esil->stack[i]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int esil_div(RAnalEsil *esil) {
|
||||
int ret = 0;
|
||||
ut64 s, d;
|
||||
char *dst = r_anal_esil_pop (esil);
|
||||
char *src = r_anal_esil_pop (esil);
|
||||
if (src && isregornum (esil, src, &s)) {
|
||||
if (dst && isregornum (esil, dst, &d)) {
|
||||
// TODO: check overflow
|
||||
if (s == 0) {
|
||||
eprintf ("esil_div: Division by zero!\n");
|
||||
} else {
|
||||
r_anal_esil_pushnum (esil, d/s);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
eprintf ("esil_eq: invalid parameters");
|
||||
}
|
||||
free (src);
|
||||
free (dst);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int esil_mul(RAnalEsil *esil) {
|
||||
int ret = 0;
|
||||
ut64 s, d;
|
||||
char *dst = r_anal_esil_pop (esil);
|
||||
char *src = r_anal_esil_pop (esil);
|
||||
if (src && isregornum (esil, src, &s)) {
|
||||
if (dst && isregornum (esil, dst, &d)) {
|
||||
// TODO: check overflow
|
||||
r_anal_esil_pushnum (esil, d*s);
|
||||
}
|
||||
} else {
|
||||
eprintf ("esil_eq: invalid parameters");
|
||||
}
|
||||
free (src);
|
||||
free (dst);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int esil_add (RAnalEsil *esil) {
|
||||
int ret = 0;
|
||||
ut64 s, d;
|
||||
char *dst = r_anal_esil_pop (esil);
|
||||
char *src = r_anal_esil_pop (esil);
|
||||
if (src && isregornum (esil, src, &s)) {
|
||||
if (dst && isregornum (esil, dst, &d)) {
|
||||
// TODO: check overflow
|
||||
r_anal_esil_pushnum (esil, d+s);
|
||||
}
|
||||
} else {
|
||||
eprintf ("esil_eq: invalid parameters");
|
||||
}
|
||||
free (src);
|
||||
free (dst);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int esil_sub (RAnalEsil *esil) {
|
||||
int ret = 0;
|
||||
ut64 s, d;
|
||||
char *dst = r_anal_esil_pop (esil);
|
||||
char *src = r_anal_esil_pop (esil);
|
||||
if (src && isregornum (esil, src, &s)) {
|
||||
if (dst && isregornum (esil, dst, &d)) {
|
||||
// TODO: check overflow
|
||||
r_anal_esil_pushnum (esil, s-d);
|
||||
}
|
||||
} else {
|
||||
eprintf ("esil_eq: invalid parameters");
|
||||
}
|
||||
free (src);
|
||||
free (dst);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int esil_poke4(RAnalEsil *esil) {
|
||||
int ret = 0;
|
||||
ut64 num, addr;
|
||||
ut32 num4;
|
||||
char *dst = r_anal_esil_pop (esil);
|
||||
char *src = r_anal_esil_pop (esil);
|
||||
if (src && isregornum (esil, src, &num)) {
|
||||
if (dst && isregornum (esil, dst, &addr)) {
|
||||
num4 = (ut32)num;
|
||||
ret = esil_mem_write (esil, addr,
|
||||
(const ut8*)&num4, 4);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int esil_peek4(RAnalEsil *esil) {
|
||||
int ret = 0;
|
||||
char res[32];
|
||||
ut64 num;
|
||||
char *dst = r_anal_esil_pop (esil);
|
||||
if (dst && isregornum (esil, dst, &num)) {
|
||||
ut8 buf[4];
|
||||
ut32 *n32 = (ut32 *)&buf;
|
||||
ret = esil_mem_read (esil, num, buf, 4);
|
||||
snprintf (res, sizeof (res), "0x%x", *n32);
|
||||
r_anal_esil_push (esil, res);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int esil_peek(RAnalEsil *esil) {
|
||||
switch (esil->anal->bits) {
|
||||
//case 64: return esil_peek8 (esil);
|
||||
case 32: return esil_peek4 (esil);
|
||||
//case 16: return esil_peek2 (esil);
|
||||
//case 8: return esil_peek1 (esil);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef int RAnalEsilCmd(RAnalEsil *esil);
|
||||
|
||||
static int iscommand (RAnalEsil *esil, const char *word, RAnalEsilCmd **cmd) {
|
||||
//TODO: use RCmd here?
|
||||
if (!strcmp (word, "=")) { *cmd = &esil_eq; return 1; } else
|
||||
if (!strcmp (word, "*")) { *cmd = &esil_mul; return 1; } else
|
||||
if (!strcmp (word, "+")) { *cmd = &esil_add; return 1; } else
|
||||
if (!strcmp (word, "-")) { *cmd = &esil_sub; return 1; } else
|
||||
if (!strcmp (word, "=[4]")) { *cmd = &esil_poke4; return 1; } else
|
||||
if (!strcmp (word, "[4]")) { *cmd = &esil_peek4; return 1; } else
|
||||
if (!strcmp (word, "[]")) { *cmd = &esil_peek; return 1; } else {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int runword (RAnalEsil *esil, const char *word) {
|
||||
RAnalEsilCmd *cmd = NULL;
|
||||
if (iscommand (esil, word, &cmd)) {
|
||||
// run action
|
||||
if (cmd)
|
||||
return cmd (esil);
|
||||
}
|
||||
// push value
|
||||
r_anal_esil_push (esil, word);
|
||||
return 0;
|
||||
}
|
||||
|
||||
R_API int r_anal_esil_parse(RAnalEsil *esil, const char *str) {
|
||||
// split str by commas
|
||||
int wordi = 0;
|
||||
char word[32];
|
||||
while (*str) {
|
||||
if (wordi>30) {
|
||||
eprintf ("Invalid esil string\n");
|
||||
return -1;
|
||||
}
|
||||
if (*str == ',') {
|
||||
word[wordi] = 0;
|
||||
wordi = 0;
|
||||
runword (esil, word);
|
||||
str++;
|
||||
}
|
||||
word[wordi++] = *str;
|
||||
str++;
|
||||
}
|
||||
word[wordi] = 0;
|
||||
runword (esil, word);
|
||||
return 0;
|
||||
}
|
||||
|
||||
R_API int r_anal_esil_register_cmd() {
|
||||
// TODO: register new commands
|
||||
return 0;
|
||||
}
|
|
@ -32,9 +32,9 @@ static void var_help(char ch) {
|
|||
eprintf ("|See also: afa? afv? -- add arguments and locals\n");
|
||||
} else {
|
||||
eprintf ("See afv? and afa?\n");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: fastrg == 'A'
|
||||
// TODO: fastrg == 'A'
|
||||
}
|
||||
|
||||
static int var_cmd(RCore *core, const char *str) {
|
||||
|
@ -135,7 +135,7 @@ static int var_cmd(RCore *core, const char *str) {
|
|||
var_help (*str);
|
||||
break;
|
||||
}
|
||||
end:
|
||||
end:
|
||||
free (ostr);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ static void r_core_anal_bytes (RCore *core, const ut8 *buf, int len, int nops, i
|
|||
}
|
||||
for (i=idx=ret=0; idx<len && (!nops|| (nops&&i<nops)); i++, idx+=ret) {
|
||||
addr = core->offset+idx;
|
||||
// TODO: use more anal hints
|
||||
// TODO: use more anal hints
|
||||
hint = r_anal_hint_get (core->anal, addr);
|
||||
r_asm_set_pc (core->assembler, addr);
|
||||
ret = r_asm_disassemble (core->assembler, &asmop, buf+idx, len-idx);
|
||||
|
@ -561,7 +561,7 @@ static int cmd_anal_fcn(RCore *core, const char *input) {
|
|||
switch (input[2]) {
|
||||
case '\0':
|
||||
case ' ':
|
||||
// TODO: sdbize!
|
||||
// TODO: sdbize!
|
||||
// list xrefs from current address
|
||||
{
|
||||
ut64 addr = input[2]? r_num_math (core->num, input+2): core->offset;
|
||||
|
@ -672,22 +672,23 @@ static void cmd_anal_reg(RCore *core, const char *str) {
|
|||
int size = 0, i, type = R_REG_TYPE_GPR;
|
||||
int bits = (core->anal->bits & R_SYS_BITS_64)? 64: 32;
|
||||
int use_colors = r_config_get_i(core->config, "scr.color");
|
||||
struct r_reg_item_t *r;
|
||||
const char *use_color;
|
||||
const char *name;
|
||||
char *arg;
|
||||
|
||||
if (use_colors) {
|
||||
#define ConsP(x) (core->cons && core->cons->pal.x)? core->cons->pal.x
|
||||
use_color = ConsP(creg): Color_BWHITE;
|
||||
} else {
|
||||
use_color = NULL;
|
||||
}
|
||||
struct r_reg_item_t *r;
|
||||
const char *name;
|
||||
char *arg;
|
||||
switch (str[0]) {
|
||||
case '?':
|
||||
if (str[1]) {
|
||||
ut64 off = r_reg_getv (core->anal->reg, str+1);
|
||||
r_cons_printf ("0x%08"PFMT64x"\n", off);
|
||||
} else
|
||||
} else {
|
||||
r_cons_printf (
|
||||
"|Usage: ar Analysis Register status\n"
|
||||
"| ar Show 'gpr' registers\n"
|
||||
|
@ -710,6 +711,7 @@ static void cmd_anal_reg(RCore *core, const char *str) {
|
|||
"| .ar* Include common register values in flags\n"
|
||||
"| .ar- Unflag all registers\n");
|
||||
// TODO: 'drs' to swap register arenas and display old register valuez
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
{ // WORK IN PROGRESS // DEBUG COMMAND
|
||||
|
@ -720,7 +722,7 @@ static void cmd_anal_reg(RCore *core, const char *str) {
|
|||
}
|
||||
break;
|
||||
case 'c':
|
||||
// TODO: set flag values with drc zf=1
|
||||
// TODO: set flag values with drc zf=1
|
||||
{
|
||||
RRegItem *r;
|
||||
const char *name = str+1;
|
||||
|
@ -737,7 +739,7 @@ static void cmd_anal_reg(RCore *core, const char *str) {
|
|||
core->num->value = o;
|
||||
// ORLY?
|
||||
r_cons_printf ("%d\n", o);
|
||||
free (rf);
|
||||
free (rf);
|
||||
} else eprintf ("unknown conditional or flag register\n");
|
||||
}
|
||||
} else {
|
||||
|
@ -885,27 +887,73 @@ static int cmd_anal(void *data, const char *input) {
|
|||
} else eprintf ("Usage: ab [hexpair-bytes]\n");
|
||||
break;
|
||||
case 'r':
|
||||
cmd_anal_reg(core, input+1);
|
||||
cmd_anal_reg (core, input+1);
|
||||
break;
|
||||
case 'e':
|
||||
if (input[1] == 'r') {
|
||||
r_debug_reg_list (core->dbg, 0, 0, 0, use_color);
|
||||
} else if (input[1] == ' ') {
|
||||
r_anal_esil_eval (core->anal, input+2);
|
||||
} else eprintf ("Usage: ae [esil] # wip. analyze esil. (evaluable string intermediate language)\n");
|
||||
switch (input[1]) {
|
||||
case 'r':
|
||||
// 'aer' is an alias for 'ar'
|
||||
return cmd_anal (core, input+1);
|
||||
case ' ':
|
||||
{
|
||||
//r_anal_esil_eval (core->anal, input+2);
|
||||
RAnalEsil *esil = r_anal_esil_new ();
|
||||
r_anal_esil_setup (esil, core->anal); // setup io
|
||||
r_anal_esil_parse (esil, input+2);
|
||||
r_anal_esil_dumpstack (esil);
|
||||
r_anal_esil_free (esil);
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
// stepping
|
||||
{
|
||||
int ret;
|
||||
ut8 code[32];
|
||||
RAnalOp op;
|
||||
const char *name = r_reg_get_name (core->anal->reg, r_reg_get_name_idx ("pc"));
|
||||
ut64 addr = r_reg_getv (core->anal->reg, name);
|
||||
if (addr == 0) {
|
||||
eprintf ("PC=OFF\n");
|
||||
addr = core->offset;
|
||||
}
|
||||
r_io_read_at (core->io, addr, code, 32);
|
||||
eprintf ("PC=0x%llx\n", (ut64)addr);
|
||||
r_asm_set_pc (core->assembler, addr);
|
||||
ret = r_anal_op (core->anal, &op, addr, code, 32);
|
||||
eprintf ("EMULATE %s\n", R_STRBUF_SAFEGET (&op.esil));
|
||||
{
|
||||
//r_anal_esil_eval (core->anal, input+2);
|
||||
RAnalEsil *esil = r_anal_esil_new ();
|
||||
r_anal_esil_setup (esil, core->anal); // setup io
|
||||
r_anal_esil_parse (esil, R_STRBUF_SAFEGET (&op.esil));
|
||||
r_anal_esil_dumpstack (esil);
|
||||
r_anal_esil_free (esil);
|
||||
}
|
||||
ut64 newaddr = r_reg_getv (core->anal->reg, name);
|
||||
if (addr == newaddr || addr == core->offset) {
|
||||
r_reg_setv (core->anal->reg, name, addr + op.size);
|
||||
}
|
||||
//sleep (1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
eprintf ("Usage: ae [esil] # aes = step, aer = 'ar' alias\n");
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
if (input[1] == '?') {
|
||||
switch (input [1]) {
|
||||
case '?':
|
||||
r_cons_printf (
|
||||
"Usage: ao[e?] [len]\n"
|
||||
" aoj display opcode analysis information in JSON\n"
|
||||
" aoe emulate opcode at current offset\n"
|
||||
" aos show sdb representation of esil expression\n"
|
||||
" aos [esil] show sdb representation of esil expression\n"
|
||||
// " aos show sdb representation of esil expression\n"
|
||||
// " aos [esil] show sdb representation of esil expression\n"
|
||||
" aoe 4 emulate 4 opcodes starting at current offset\n"
|
||||
" ao 5 display opcode analysis of 5 opcodes\n");
|
||||
} else
|
||||
if (input[1] == 'j') {
|
||||
break;
|
||||
case 'j':
|
||||
{
|
||||
int count = 0;
|
||||
if (input[2] && input[3]) {
|
||||
l = (int) r_num_get (core->num, input+2);
|
||||
|
@ -919,8 +967,10 @@ static int cmd_anal(void *data, const char *input) {
|
|||
count = 1;
|
||||
}
|
||||
r_core_anal_bytes (core, core->block, len, count, 'j');
|
||||
} else
|
||||
if (input[1]=='s') {
|
||||
}
|
||||
break;
|
||||
#if DEPRECATED
|
||||
case 's':
|
||||
if (input[2]==' ') {
|
||||
char *esil = strdup (input+2);
|
||||
char *o = r_anal_esil_to_sdb (esil);
|
||||
|
@ -940,10 +990,13 @@ static int cmd_anal(void *data, const char *input) {
|
|||
r_anal_op_free (op);
|
||||
}
|
||||
}
|
||||
} else
|
||||
if (input[1] == 'e') {
|
||||
eprintf ("TODO: r_anal_op_execute: TODO: USE ESIL\n");
|
||||
} else {
|
||||
break;
|
||||
#endif
|
||||
case 'e':
|
||||
eprintf ("TODO: See 'ae' command\n");
|
||||
break;
|
||||
default:
|
||||
{
|
||||
int count = 0;
|
||||
if (input[0] && input[1]) {
|
||||
l = (int) r_num_get (core->num, input+2);
|
||||
|
@ -958,6 +1011,7 @@ static int cmd_anal(void *data, const char *input) {
|
|||
}
|
||||
r_core_anal_bytes (core, core->block, len, count, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'F':
|
||||
r_core_anal_fcn (core, core->offset, -1, R_ANAL_REF_TYPE_NULL, 1);
|
||||
|
@ -1339,8 +1393,8 @@ static int cmd_anal(void *data, const char *input) {
|
|||
);
|
||||
break;
|
||||
#if 0
|
||||
in core/disasm we call
|
||||
R_API int r_core_hint(RCore *core, ut64 addr) {
|
||||
in core/disasm we call
|
||||
R_API int r_core_hint(RCore *core, ut64 addr) {
|
||||
static int hint_bits = 0;
|
||||
RAnalHint *hint = r_anal_hint_get (core->anal, addr);
|
||||
if (hint->bits) {
|
||||
|
@ -1465,5 +1519,5 @@ R_API int r_core_hint(RCore *core, ut64 addr) {
|
|||
eprintf ("Interrupted\n");
|
||||
r_cons_break_end();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -629,6 +629,7 @@ R_API int r_core_init(RCore *core) {
|
|||
r_config_set_i (core->config, "asm.bits", 32);
|
||||
r_config_set (core->config, "asm.arch", R_SYS_ARCH);
|
||||
update_sdb (core);
|
||||
r_core_cmd0 (core, "ar `arn pc`=$$");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -851,7 +851,10 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
|
|||
r_core_cmd (core, "ds", 0);
|
||||
r_core_cmd (core, ".dr*", 0);
|
||||
}
|
||||
} else visual_offset (core);
|
||||
} else {
|
||||
r_core_cmd (core, "aes", 0);
|
||||
r_core_cmd (core, ".ar*", 0);
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
if (curset) {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#ifndef R2_ANAL_H
|
||||
#define R2_ANAL_H
|
||||
|
||||
#define NEW_ESIL 1
|
||||
#define FCN_SDB 1
|
||||
#define FCN_OLD 1
|
||||
#define USE_VARSUBS 0
|
||||
|
@ -922,8 +923,56 @@ R_API int r_anal_op(RAnal *anal, RAnalOp *op, ut64 addr,
|
|||
R_API RAnalOp *r_anal_op_hexstr(RAnal *anal, ut64 addr,
|
||||
const char *hexstr);
|
||||
R_API char *r_anal_op_to_string(RAnal *anal, RAnalOp *op);
|
||||
|
||||
#if NEW_ESIL
|
||||
typedef struct r_anal_esil_word_t {
|
||||
int type;
|
||||
const char *str;
|
||||
} RAnalEsilWord;
|
||||
|
||||
#define THIS struct r_anal_esil_t
|
||||
typedef struct r_anal_esil_t {
|
||||
void *user;
|
||||
RAnal *anal;
|
||||
char *stack[32];
|
||||
int stackptr;
|
||||
int debug;
|
||||
/* callbacks */
|
||||
int (*hook_mem_read)(THIS *esil, ut64 addr, ut8 *buf, int len);
|
||||
int (*mem_read)(THIS *esil, ut64 addr, ut8 *buf, int len);
|
||||
int (*hook_mem_write)(THIS *esil, ut64 addr, const ut8 *buf, int len);
|
||||
int (*mem_write)(THIS *esil, ut64 addr, const ut8 *buf, int len);
|
||||
int (*hook_reg_read)(THIS *esil, const char *name, ut64 *res);
|
||||
int (*reg_read)(THIS *esil, const char *name, ut64 *res);
|
||||
int (*hook_reg_write)(THIS *esil, const char *name, ut64 val);
|
||||
int (*reg_write)(THIS *esil, const char *name, ut64 val);
|
||||
} RAnalEsil;
|
||||
|
||||
|
||||
enum R_ANAL_ESIL_TYPE {
|
||||
NUMBER,
|
||||
REGISTER,
|
||||
};
|
||||
|
||||
struct r_anal_esil_op_t {
|
||||
const char *str;
|
||||
int in; // num of input parameters
|
||||
int out; // num of output paramters
|
||||
int (*run)(RAnalEsil *esil);
|
||||
};
|
||||
|
||||
R_API RAnalEsil *r_anal_esil_new();
|
||||
R_API int r_anal_esil_setup (RAnalEsil *esil, RAnal *anal);
|
||||
R_API void r_anal_esil_free (RAnalEsil *esil);
|
||||
R_API int r_anal_esil_parse(RAnalEsil *esil, const char *str);
|
||||
R_API int r_anal_esil_dumpstack (RAnalEsil *esil);
|
||||
R_API int r_anal_esil_pushnum(RAnalEsil *esil, ut64 num);
|
||||
R_API int r_anal_esil_push(RAnalEsil *esil, const char *str);
|
||||
R_API char *r_anal_esil_pop(RAnalEsil *esil);
|
||||
#else
|
||||
R_API const char *r_anal_op_to_esil_string(RAnal *anal, RAnalOp *op);
|
||||
R_API char *r_anal_esil_to_sdb(char *str);
|
||||
#endif
|
||||
|
||||
/* fcn.c */
|
||||
R_API RAnalFunction *r_anal_fcn_new();
|
||||
|
|
|
@ -46,6 +46,8 @@ R_API const char *r_lib_types_get(int idx) {
|
|||
|
||||
R_API void *r_lib_dl_open(const char *libname) {
|
||||
void *ret;
|
||||
if (!libname || !*libname)
|
||||
return NULL;
|
||||
ret = DLOPEN (libname);
|
||||
if (__has_debug && ret == NULL)
|
||||
#if __UNIX__
|
||||
|
|
Loading…
Reference in New Issue