Fix aecs and add test emulating hello world without libc ##esil

This commit is contained in:
pancake 2022-03-16 12:44:30 +01:00 committed by pancake
parent c7f9503e72
commit 3020803a39
10 changed files with 89 additions and 76 deletions

View File

@ -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

View File

@ -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;

View File

@ -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) {

View File

@ -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"

View File

@ -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);
}

View File

@ -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"

View File

@ -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) {

View File

@ -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);

View File

@ -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

View File

@ -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