Skip to content

Commit 089700a

Browse files
committed
Add support for esil.{romem/nonull} in core_esil
1 parent e909ad1 commit 089700a

File tree

3 files changed

+83
-19
lines changed

3 files changed

+83
-19
lines changed

libr/core/cconfig.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2609,26 +2609,48 @@ static bool cb_graphformat(void *user, void *data) {
26092609
}
26102610

26112611
static bool cb_exectrap(void *user, void *data) {
2612-
RConfigNode *node = (RConfigNode *) data;
2613-
RCore *core = (RCore*) user;
2612+
RConfigNode *node = (RConfigNode *)data;
2613+
RCore *core = (RCore*)user;
26142614
if (core->anal && core->anal->esil) {
26152615
core->anal->esil->exectrap = node->i_value;
26162616
}
26172617
return true;
26182618
}
26192619

26202620
static bool cb_iotrap(void *user, void *data) {
2621-
RConfigNode *node = (RConfigNode *) data;
2622-
RCore *core = (RCore*) user;
2621+
RConfigNode *node = (RConfigNode *)data;
2622+
RCore *core = (RCore*)user;
26232623
if (core->anal && core->anal->esil) {
26242624
core->anal->esil->iotrap = node->i_value;
26252625
}
26262626
return true;
26272627
}
26282628

2629+
static bool cb_romem(void *user, void *data) {
2630+
RConfigNode *node = (RConfigNode *)data;
2631+
RCore *core = (RCore*)user;
2632+
if (node->i_value) {
2633+
core->esil.cfg |= R_CORE_ESIL_RO;
2634+
} else {
2635+
core->esil.cfg &= ~R_CORE_ESIL_RO;
2636+
}
2637+
return true;
2638+
}
2639+
2640+
static bool cb_esilnonull(void *user, void *data) {
2641+
RConfigNode *node = (RConfigNode *)data;
2642+
RCore *core = (RCore*)user;
2643+
if (node->i_value) {
2644+
core->esil.cfg |= R_CORE_ESIL_NONULL;
2645+
} else {
2646+
core->esil.cfg &= ~R_CORE_ESIL_NONULL;
2647+
}
2648+
return true;
2649+
}
2650+
26292651
static bool cb_scr_bgfill(void *user, void *data) {
2630-
RCore *core = (RCore*) user;
2631-
RConfigNode *node = (RConfigNode *) data;
2652+
RCore *core = (RCore*)user;
2653+
RConfigNode *node = (RConfigNode *)data;
26322654
if (node->i_value) {
26332655
core->print->flags |= R_PRINT_FLAGS_BGFILL;
26342656
} else {
@@ -4310,9 +4332,9 @@ R_API int r_core_config_init(RCore *core) {
43104332

43114333
SETCB ("esil.exectrap", "false", &cb_exectrap, "trap when executing code in non-executable memory");
43124334
SETCB ("esil.iotrap", "true", &cb_iotrap, "invalid read or writes produce a trap exception");
4313-
SETBPREF ("esil.romem", "false", "set memory as read-only for ESIL");
4335+
SETCB ("esil.romem", "false", &cb_romem, "set memory as read-only for ESIL");
43144336
SETBPREF ("esil.stats", "false", "statistics from ESIL emulation stored in sdb");
4315-
SETBPREF ("esil.nonull", "false", "prevent memory read, memory write at null pointer");
4337+
SETCB ("esil.nonull", "false", &cb_esilnonull, "prevent memory read, memory write at null pointer");
43164338
SETCB ("esil.mdev.range", "", &cb_mdevrange, "specify a range of memory to be handled by cmd.esil.mdev");
43174339
SETBPREF ("esil.dfg.mapinfo", "false", "use mapinfo for esil dfg");
43184340
SETBPREF ("esil.dfg.maps", "false", "set ro maps for esil dfg");

libr/core/core_esil.c

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,48 @@ static bool core_esil_mem_switch (void *core, ut32 idx) {
5858
}
5959

6060
static bool core_esil_mem_read (void *core, ut64 addr, ut8 *buf, int len) {
61-
return r_io_read_at (((RCore *)core)->io, addr, buf, len);
61+
if ((UT64_MAX - len + 1) < addr) {
62+
if (!core_esil_mem_read (core, 0ULL, buf + (UT64_MAX - addr + 1),
63+
len - (UT64_MAX - addr + 1))) {
64+
return false;
65+
}
66+
len = UT64_MAX - addr + 1;
67+
}
68+
RCore *c = core;
69+
if (!addr && c->esil.cfg & R_CORE_ESIL_NONULL) {
70+
return false;
71+
}
72+
return r_io_read_at (c->io, addr, buf, len);
6273
}
6374

6475
static bool core_esil_mem_write (void *core, ut64 addr, const ut8 *buf, int len) {
65-
return r_io_write_at (((RCore *)core)->io, addr, buf, len);
76+
if ((UT64_MAX - len + 1) < addr) {
77+
if (!core_esil_mem_write (core, 0ULL, buf + (UT64_MAX - addr + 1),
78+
len - (UT64_MAX - addr + 1))) {
79+
return false;
80+
}
81+
len = UT64_MAX - addr + 1;
82+
}
83+
RCore *c = core;
84+
if (!addr && c->esil.cfg & R_CORE_ESIL_NONULL) {
85+
return false;
86+
}
87+
if (c->esil.cfg & R_CORE_ESIL_RO) {
88+
RIORegion region;
89+
if (!r_io_get_region_at (c->io, &region, addr)) {
90+
//maybe check voidwrites config here
91+
return true;
92+
}
93+
if (!(region.perm & R_PERM_W)) {
94+
return false;
95+
}
96+
if (r_itv_contain (region.itv, addr + len - 1)) {
97+
return true;
98+
}
99+
return core_esil_mem_write (core, r_itv_end (region.itv),
100+
NULL, addr + len - r_itv_end (region.itv)); //no need to pass buf, because this is RO mode
101+
}
102+
return r_io_write_at (c->io, addr, buf, len);
66103
}
67104

68105
static REsilMemInterface core_esil_mem_if = {
@@ -101,14 +138,15 @@ R_API void r_core_esil_fini(RCoreEsil *cesil) {
101138
r_esil_fini (&cesil->esil);
102139
if (cesil->reg) {
103140
r_reg_free (cesil->reg);
141+
cesil->reg = NULL;
104142
}
105-
free (cesil->cmd_step);
106-
free (cesil->cmd_step_out);
107-
free (cesil->cmd_intr);
108-
free (cesil->cmd_trap);
109-
free (cesil->cmd_mdev);
110-
free (cesil->cmd_todo);
111-
free (cesil->cmd_ioer);
112-
free (cesil->mdev_range);
113-
*cesil = (const RCoreEsil){0};
143+
R_FREE (cesil->cmd_step);
144+
R_FREE (cesil->cmd_step_out);
145+
R_FREE (cesil->cmd_intr);
146+
R_FREE (cesil->cmd_trap);
147+
R_FREE (cesil->cmd_mdev);
148+
R_FREE (cesil->cmd_todo);
149+
R_FREE (cesil->cmd_ioer);
150+
R_FREE (cesil->mdev_range);
151+
cesil->esil = (const REsil){0};
114152
}

libr/include/r_core.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,12 @@ typedef struct r_core_esil_t {
313313
char *cmd_todo; // command to run when esil expr contains TODO
314314
char *cmd_ioer; // command to run when esil fails to IO
315315
char *mdev_range; // string containing the r_str_range to match for read/write accesses
316+
ut8 cfg;
316317
} RCoreEsil;
317318

319+
#define R_CORE_ESIL_RO 0x1
320+
#define R_CORE_ESIL_NONULL 0x2
321+
318322
typedef struct RCorePriv RCorePriv;
319323

320324
struct r_core_t {

0 commit comments

Comments
 (0)