mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-26 17:15:38 +00:00
Fix aecs and add test emulating hello world without libc ##esil
This commit is contained in:
parent
c7f9503e72
commit
3020803a39
@ -44,24 +44,22 @@ R_ABI bool r_anal_function_islineal(RAnalFunction *fcn) {
|
||||
|
||||
// pin.c
|
||||
|
||||
#define DB a->sdb_pins
|
||||
R_ABI const char *r_anal_pin_get(RAnal *a, const char *name) {
|
||||
r_strf_buffer (128);
|
||||
char *ckey = r_strf ("cmd.%s", name);
|
||||
return sdb_const_get (DB, ckey, NULL);
|
||||
return sdb_const_get (a->sdb_pins, ckey, NULL);
|
||||
}
|
||||
|
||||
R_ABI const char *r_anal_pin_at(RAnal *a, ut64 addr) {
|
||||
char buf[64];
|
||||
const char *key = sdb_itoa (addr, buf, 16);
|
||||
return sdb_const_get (DB, key, NULL);
|
||||
return sdb_const_get (a->sdb_pins, key, NULL);
|
||||
}
|
||||
|
||||
R_ABI bool r_anal_pin_set(RAnal *a, const char *name, const char *cmd) {
|
||||
r_strf_buffer (128);
|
||||
char *ckey = r_strf ("cmd.%s", name);
|
||||
return sdb_add (DB, ckey, cmd, 0);
|
||||
return sdb_add (a->sdb_pins, ckey, cmd, 0);
|
||||
}
|
||||
#undef DB
|
||||
|
||||
#endif
|
||||
|
@ -300,8 +300,7 @@ R_API bool r_anal_esil_mem_read(RAnalEsil *esil, ut64 addr, ut8 *buf, int len) {
|
||||
return false;
|
||||
}
|
||||
if (!ret && esil->cb.mem_read) {
|
||||
ret = esil->cb.mem_read (esil, addr, buf, len);
|
||||
if (ret != len) {
|
||||
if (!esil->cb.mem_read (esil, addr, buf, len)) {
|
||||
if (esil->iotrap) {
|
||||
esil->trap = R_ANAL_TRAP_READ_ERR;
|
||||
esil->trap_code = addr;
|
||||
|
@ -2048,7 +2048,6 @@ R_API int r_anal_function_count_edges(const RAnalFunction *fcn, R_NULLABLE int *
|
||||
return edges;
|
||||
}
|
||||
|
||||
#include "abi.inc"
|
||||
|
||||
R_API bool r_anal_function_purity(RAnalFunction *fcn) {
|
||||
if (fcn->has_changed) {
|
||||
|
@ -3575,9 +3575,9 @@ static char *get_reg_profile(RAnal *anal) {
|
||||
break;
|
||||
case 32: p =
|
||||
"=PC eip\n"
|
||||
"=R0 eax\n"
|
||||
"=SP esp\n"
|
||||
"=BP ebp\n"
|
||||
"=R0 eax\n"
|
||||
"=A0 eax\n"
|
||||
"=A1 ebx\n"
|
||||
"=A2 ecx\n"
|
||||
@ -3688,28 +3688,29 @@ static char *get_reg_profile(RAnal *anal) {
|
||||
"# RSI preserved source\n"
|
||||
"# RDI preserved destination\n"
|
||||
"# RSP stack pointer\n"
|
||||
"=PC rip\n"
|
||||
"=SP rsp\n"
|
||||
"=R0 rax\n"
|
||||
"=BP rbp\n"
|
||||
"=A0 rcx\n"
|
||||
"=A1 rdx\n"
|
||||
"=A2 r8\n"
|
||||
"=A3 r9\n"
|
||||
"=SN rax\n"
|
||||
"=PC rip\n"
|
||||
"=SP rsp\n"
|
||||
"=R0 rax\n"
|
||||
"=BP rbp\n"
|
||||
"=A0 rcx\n"
|
||||
"=A1 rdx\n"
|
||||
"=A2 r8\n"
|
||||
"=A3 r9\n"
|
||||
"=SN rax\n"
|
||||
: // System V AMD64 ABI
|
||||
"=PC rip\n"
|
||||
"=SP rsp\n"
|
||||
"=BP rbp\n"
|
||||
"=A0 rdi\n"
|
||||
"=A1 rsi\n"
|
||||
"=A2 rdx\n"
|
||||
"=A3 rcx\n"
|
||||
"=A4 r8\n"
|
||||
"=A5 r9\n"
|
||||
"=A6 r10\n"
|
||||
"=A7 r11\n"
|
||||
"=SN rax\n";
|
||||
"=PC rip\n"
|
||||
"=SP rsp\n"
|
||||
"=BP rbp\n"
|
||||
"=R0 rax\n"
|
||||
"=A0 rdi\n"
|
||||
"=A1 rsi\n"
|
||||
"=A2 rdx\n"
|
||||
"=A3 rcx\n"
|
||||
"=A4 r8\n"
|
||||
"=A5 r9\n"
|
||||
"=A6 r10\n"
|
||||
"=A7 r11\n"
|
||||
"=SN rax\n";
|
||||
char *prof = r_str_newf ("%s%s", args_prof,
|
||||
"gpr rax .64 80 0\n"
|
||||
"gpr eax .32 80 0\n"
|
||||
|
@ -5,26 +5,6 @@
|
||||
|
||||
typedef void (*RAnalEsilPin)(RAnal *a);
|
||||
|
||||
#if 0
|
||||
// TODO: those hardcoded functions should go
|
||||
/* default pins from libc */
|
||||
static void pin_strlen(RAnal *a) {
|
||||
// get a0 register
|
||||
// read memory and interpret it as a string
|
||||
// set a0 to the result of strlen;
|
||||
eprintf ("esilpin: strlen\n");
|
||||
}
|
||||
|
||||
static void pin_write(RAnal *a) {
|
||||
// get a0 register for fd
|
||||
// get a1 register for data
|
||||
// get a2 register for len
|
||||
// read len bytes from data and print them to screen + fd
|
||||
// set a0 to the result of write;
|
||||
eprintf ("esilpin: write\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* pin api */
|
||||
|
||||
#define DB a->sdb_pins
|
||||
@ -35,6 +15,7 @@ R_API void r_anal_pin_init(RAnal *a) {
|
||||
r_anal_pin_set (a, "strlen", "dr R0=`pszl@r:A0`;aexa ret");
|
||||
r_anal_pin_set (a, "memcpy", "wf `dr?A1` `dr?A2` @ `dr?A0`;aexa ret");
|
||||
r_anal_pin_set (a, "puts", "psz@r:A0; aexa ret");
|
||||
r_anal_pin_set (a, "ret0", "dr A0=0;aexa ret");
|
||||
// sdb_ptr_set (DB, "strlen", pin_strlen, 0);
|
||||
// sdb_ptr_set (DB, "write", pin_write, 0);
|
||||
}
|
||||
|
@ -6876,16 +6876,16 @@ static void cmd_aeg(RCore *core, int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_anal_esil(RCore *core, const char *input) {
|
||||
static void cmd_anal_esil(RCore *core, const char *input, bool verbose) {
|
||||
RAnalEsil *esil = core->anal->esil;
|
||||
ut64 addr = core->offset;
|
||||
ut64 adr ;
|
||||
char *n, *n1;
|
||||
int off;
|
||||
int stacksize = r_config_get_i (core->config, "esil.stack.depth");
|
||||
int iotrap = r_config_get_i (core->config, "esil.iotrap");
|
||||
int romem = r_config_get_i (core->config, "esil.romem");
|
||||
int stats = r_config_get_i (core->config, "esil.stats");
|
||||
bool iotrap = r_config_get_b (core->config, "esil.iotrap");
|
||||
bool romem = r_config_get_b (core->config, "esil.romem");
|
||||
bool stats = r_config_get_b (core->config, "esil.stats");
|
||||
bool nonull = r_config_get_b (core->config, "esil.nonull");
|
||||
ut64 until_addr = UT64_MAX;
|
||||
unsigned int addrsize = r_config_get_i (core->config, "esil.addr.size");
|
||||
@ -6983,6 +6983,7 @@ static void cmd_anal_esil(RCore *core, const char *input) {
|
||||
}
|
||||
break;
|
||||
case ' ':
|
||||
case 'q':
|
||||
//r_anal_esil_eval (core->anal, input+1);
|
||||
if (!esil && !(core->anal->esil = esil = r_anal_esil_new (stacksize, iotrap, addrsize))) {
|
||||
return;
|
||||
@ -6990,7 +6991,9 @@ static void cmd_anal_esil(RCore *core, const char *input) {
|
||||
r_anal_esil_setup (esil, core->anal, romem, stats, nonull); // setup io
|
||||
r_anal_esil_set_pc (esil, core->offset);
|
||||
r_anal_esil_parse (esil, input + 1);
|
||||
r_anal_esil_dumpstack (esil);
|
||||
if (verbose && *input != 'q') {
|
||||
r_anal_esil_dumpstack (esil);
|
||||
}
|
||||
r_anal_esil_stack_free (esil);
|
||||
break;
|
||||
case 's': // "aes"
|
||||
@ -7143,25 +7146,29 @@ static void cmd_anal_esil(RCore *core, const char *input) {
|
||||
} else if (input[1] == 's') { // "aecs"
|
||||
const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
|
||||
for (;;) {
|
||||
if (!r_core_esil_step (core, UT64_MAX, NULL, NULL, false)) {
|
||||
break;
|
||||
}
|
||||
// ignore return value is not an error, should 0, 1, -1 imho
|
||||
(void)r_core_esil_step (core, UT64_MAX, NULL, NULL, false);
|
||||
r_core_cmd0 (core, ".ar*");
|
||||
addr = r_num_get (core->num, pc);
|
||||
op = r_core_anal_op (core, addr, R_ANAL_OP_MASK_BASIC | R_ANAL_OP_MASK_HINT);
|
||||
if (!op) {
|
||||
eprintf ("invalid instruction at 0x%08" PFMT64x "\n", addr);
|
||||
break;
|
||||
}
|
||||
if (op->type == R_ANAL_OP_TYPE_SWI) {
|
||||
eprintf ("syscall at 0x%08" PFMT64x "\n", addr);
|
||||
eprintf ("syscall instruction at 0x%08" PFMT64x "\n", addr);
|
||||
break;
|
||||
} else if (op->type == R_ANAL_OP_TYPE_TRAP) {
|
||||
eprintf ("trap at 0x%08" PFMT64x "\n", addr);
|
||||
eprintf ("trap instruction at 0x%08" PFMT64x "\n", addr);
|
||||
break;
|
||||
}
|
||||
r_anal_op_free (op);
|
||||
op = NULL;
|
||||
if (core->anal->esil->trap || core->anal->esil->trap_code) {
|
||||
eprintf ("esil trap '%s' (%d) at 0x%08" PFMT64x "\n",
|
||||
r_anal_esil_trapstr (core->anal->esil->trap),
|
||||
core->anal->esil->trap_code,
|
||||
addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -7172,9 +7179,7 @@ static void cmd_anal_esil(RCore *core, const char *input) {
|
||||
} else if (input[1] == 'c') { // "aecc"
|
||||
const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
|
||||
for (;;) {
|
||||
if (!r_core_esil_step (core, UT64_MAX, NULL, NULL, false)) {
|
||||
break;
|
||||
}
|
||||
(void)r_core_esil_step (core, UT64_MAX, NULL, NULL, false);
|
||||
r_core_cmd0 (core, ".ar*");
|
||||
addr = r_num_get (core->num, pc);
|
||||
op = r_core_anal_op (core, addr, R_ANAL_OP_MASK_BASIC);
|
||||
@ -7182,7 +7187,7 @@ static void cmd_anal_esil(RCore *core, const char *input) {
|
||||
break;
|
||||
}
|
||||
if (op->type == R_ANAL_OP_TYPE_CALL || op->type == R_ANAL_OP_TYPE_UCALL) {
|
||||
eprintf ("call at 0x%08" PFMT64x "\n", addr);
|
||||
eprintf ("stop in call instruction at 0x%08" PFMT64x "\n", addr);
|
||||
break;
|
||||
}
|
||||
r_anal_op_free (op);
|
||||
@ -7531,8 +7536,12 @@ static void cmd_anal_esil(RCore *core, const char *input) {
|
||||
if (ret > 0) {
|
||||
const char *str = R_STRBUF_SAFEGET (&aop.esil);
|
||||
char *str2 = r_str_newf (" %s", str);
|
||||
cmd_anal_esil (core, str2);
|
||||
cmd_anal_esil (core, str2, false);
|
||||
free (str2);
|
||||
core->num->value = 1;
|
||||
} else {
|
||||
// fail to exevute, update code
|
||||
core->num->value = 0;
|
||||
}
|
||||
r_anal_op_fini (&aop);
|
||||
} else if (input[1] == 'a') { // "aexa"
|
||||
@ -12129,7 +12138,7 @@ static int cmd_anal(void *data, const char *input) {
|
||||
break;
|
||||
case 'i': cmd_anal_info (core, input + 1); break; // "ai"
|
||||
case 'r': cmd_anal_reg (core, input + 1); break; // "ar"
|
||||
case 'e': cmd_anal_esil (core, input + 1); break; // "ae"
|
||||
case 'e': cmd_anal_esil (core, input + 1, true); break; // "ae"
|
||||
case 'L': return r_core_cmd0 (core, "e asm.arch=??"); break;
|
||||
case 'o': cmd_anal_opcode (core, input + 1); break; // "ao"
|
||||
case 'O': cmd_anal_bytes (core, input + 1); break; // "aO"
|
||||
|
@ -253,7 +253,7 @@ static char* rop_classify_constant(RCore *core, RList *ropList) {
|
||||
goto continue_error;
|
||||
}
|
||||
esil_split_flg (esil_str, &esil_main, &esil_flg);
|
||||
cmd_anal_esil (core, esil_main? esil_main: esil_str);
|
||||
cmd_anal_esil (core, esil_main? esil_main: esil_str, false);
|
||||
out = sdb_querys (core->anal->esil->stats, NULL, 0, "*");
|
||||
if (!out) {
|
||||
goto continue_error;
|
||||
@ -332,7 +332,7 @@ static char* rop_classify_mov(RCore *core, RList *ropList) {
|
||||
goto out_error;
|
||||
}
|
||||
esil_split_flg (esil_str, &esil_main, &esil_flg);
|
||||
cmd_anal_esil (core, esil_main? esil_main: esil_str);
|
||||
cmd_anal_esil (core, esil_main? esil_main: esil_str, false);
|
||||
out = sdb_querys (core->anal->esil->stats, NULL, 0, "*");
|
||||
if (out) {
|
||||
ops_list = parse_list (strstr (out, "ops.list"));
|
||||
@ -432,9 +432,9 @@ static char* rop_classify_arithmetic(RCore *core, RList *ropList) {
|
||||
}
|
||||
esil_split_flg (esil_str, &esil_main, &esil_flg);
|
||||
if (esil_main) {
|
||||
cmd_anal_esil (core, esil_main);
|
||||
cmd_anal_esil (core, esil_main, false);
|
||||
} else {
|
||||
cmd_anal_esil (core, esil_str);
|
||||
cmd_anal_esil (core, esil_str, false);
|
||||
}
|
||||
out = sdb_querys (core->anal->esil->stats, NULL, 0, "*");
|
||||
// r_cons_println (out);
|
||||
@ -565,9 +565,9 @@ static char* rop_classify_arithmetic_const(RCore *core, RList *ropList) {
|
||||
}
|
||||
esil_split_flg (esil_str, &esil_main, &esil_flg);
|
||||
if (esil_main) {
|
||||
cmd_anal_esil (core, esil_main);
|
||||
cmd_anal_esil (core, esil_main, false);
|
||||
} else {
|
||||
cmd_anal_esil (core, esil_str);
|
||||
cmd_anal_esil (core, esil_str, false);
|
||||
}
|
||||
char *out = sdb_querys (core->anal->esil->stats, NULL, 0, "*");
|
||||
// r_cons_println (out);
|
||||
@ -669,7 +669,7 @@ static int rop_classify_nops(RCore *core, RList *ropList) {
|
||||
fillRegisterValues (core);
|
||||
|
||||
// r_cons_printf ("Emulating nop:%s\n", esil_str);
|
||||
cmd_anal_esil (core, esil_str);
|
||||
cmd_anal_esil (core, esil_str, false);
|
||||
char *out = sdb_querys (core->anal->esil->stats, NULL, 0, "*");
|
||||
// r_cons_println (out);
|
||||
if (out) {
|
||||
|
@ -1565,6 +1565,7 @@ R_API int r_anal_add(RAnal *anal, RAnalPlugin *foo);
|
||||
R_API int r_anal_archinfo(RAnal *anal, int query);
|
||||
R_API bool r_anal_use(RAnal *anal, const char *name);
|
||||
R_API bool r_anal_esil_use(RAnal *anal, const char *name);
|
||||
R_API const char *r_anal_esil_trapstr(int type);
|
||||
R_API bool r_anal_set_reg_profile(RAnal *anal, const char *rp);
|
||||
R_API char *r_anal_get_reg_profile(RAnal *anal);
|
||||
R_API ut64 r_anal_get_bbaddr(RAnal *anal, ut64 addr);
|
||||
|
@ -53,6 +53,9 @@ aes
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
aep test @ 0x5
|
||||
"aep memcpy=wf `dr?A1` `dr?A2` @ `dr?A0`;aexa ret"
|
||||
"aep strlen=dr R0=`pszl@r:A0`;aexa ret"
|
||||
"aep puts=psz@r:A0; aexa ret"
|
||||
test
|
||||
EOF
|
||||
RUN
|
||||
@ -73,6 +76,28 @@ aes
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
aep test @ 0x5
|
||||
"aep memcpy=wf `dr?A1` `dr?A2` @ `dr?A0`;aexa ret"
|
||||
"aep strlen=dr R0=`pszl@r:A0`;aexa ret"
|
||||
"aep puts=psz@r:A0; aexa ret"
|
||||
test
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=emulate imports
|
||||
FILE=bins/mach0/hello-puts
|
||||
CMDS=<<EOF
|
||||
s main
|
||||
aepc $$
|
||||
aeim
|
||||
aaep
|
||||
aep
|
||||
aecs
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
"aep memcpy=wf `dr?A1` `dr?A2` @ `dr?A0`;aexa ret"
|
||||
"aep strlen=dr R0=`pszl@r:A0`;aexa ret"
|
||||
"aep puts=psz@r:A0; aexa ret"
|
||||
aep puts @ 0x1050
|
||||
Hello World
|
||||
EOF
|
||||
RUN
|
||||
|
@ -34,16 +34,16 @@ tccl
|
||||
tcc*
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
{"amd64":{"ret":"rax","signature":"rax amd64 (rdi, rsi, rdx, rcx, r8, r9, xmm0, xmm1, xmm2, xmm3, xmm4);","args":["rdi","rsi","rdx","rcx","r8","r9","xmm0","xmm1","xmm2","xmm3","xmm4"]},"amd64syscall":{"ret":"rax","signature":"rax amd64syscall (rdi, rsi, rdx, r10, r8, r9);","args":["rdi","rsi","rdx","r10","r8","r9"]},"ms":{"ret":"rax","signature":"rax ms (rcx, rdx, r8, r9, stack);","args":["rcx","rdx","r8","r9"],"argn":"stack"},"reg":{"ret":"rdi","signature":"rdi reg (rdi, rsi, rdx, rcx);","args":["rdi","rsi","rdx","rcx"]},"swift":{"ret":"rax","signature":"rax r13.swift (rdi, rsi, rdx, rcx, r8, r9, xmm0, xmm1, xmm2, xmm3, xmm4) r12;","args":["rdi","rsi","rdx","rcx","r8","r9","xmm0","xmm1","xmm2","xmm3","xmm4"],"error":"r12"}}
|
||||
{"amd64":{"ret":"rax","signature":"rax amd64 (rdi, rsi, rdx, rcx, r8, r9, xmm0, xmm1, xmm2, xmm3, xmm4);","args":["rdi","rsi","rdx","rcx","r8","r9","xmm0","xmm1","xmm2","xmm3","xmm4"]},"amd64syscall":{"ret":"rax","signature":"rax amd64syscall (rdi, rsi, rdx, r10, r8, r9);","args":["rdi","rsi","rdx","r10","r8","r9"]},"ms":{"ret":"rax","signature":"rax ms (rcx, rdx, r8, r9, stack);","args":["rcx","rdx","r8","r9"],"argn":"stack"},"reg":{"ret":"rax","signature":"rax reg (rdi, rsi, rdx, rcx);","args":["rdi","rsi","rdx","rcx"]},"swift":{"ret":"rax","signature":"rax r13.swift (rdi, rsi, rdx, rcx, r8, r9, xmm0, xmm1, xmm2, xmm3, xmm4) r12;","args":["rdi","rsi","rdx","rcx","r8","r9","xmm0","xmm1","xmm2","xmm3","xmm4"],"error":"r12"}}
|
||||
rax amd64 (rdi, rsi, rdx, rcx, r8, r9, xmm0, xmm1, xmm2, xmm3, xmm4);
|
||||
rax amd64syscall (rdi, rsi, rdx, r10, r8, r9);
|
||||
rax ms (rcx, rdx, r8, r9, stack);
|
||||
rdi reg (rdi, rsi, rdx, rcx);
|
||||
rax reg (rdi, rsi, rdx, rcx);
|
||||
rax r13.swift (rdi, rsi, rdx, rcx, r8, r9, xmm0, xmm1, xmm2, xmm3, xmm4) r12;
|
||||
tcc rax amd64 (rdi, rsi, rdx, rcx, r8, r9, xmm0, xmm1, xmm2, xmm3, xmm4);
|
||||
tcc rax amd64syscall (rdi, rsi, rdx, r10, r8, r9);
|
||||
tcc rax ms (rcx, rdx, r8, r9, stack);
|
||||
tcc rdi reg (rdi, rsi, rdx, rcx);
|
||||
tcc rax reg (rdi, rsi, rdx, rcx);
|
||||
tcc rax r13.swift (rdi, rsi, rdx, rcx, r8, r9, xmm0, xmm1, xmm2, xmm3, xmm4) r12;
|
||||
EOF
|
||||
RUN
|
||||
|
Loading…
x
Reference in New Issue
Block a user