Add omu command to create a unique map ##io

* Add another broken project test
* Fix warning regression introduced in previous windows fix
This commit is contained in:
pancake 2022-07-04 21:24:40 +02:00
parent 5df05f446f
commit 21064e9473
5 changed files with 90 additions and 48 deletions

View File

@ -606,7 +606,7 @@ static void r_core_cmd_omt(RCore *core, const char *arg) {
r_table_free (t);
}
static bool cmd_om(RCore *core, const char *input) {
static bool cmd_om(RCore *core, const char *input, int arg) {
char *s = strdup (input + 2);
if (!s) {
return false;
@ -640,7 +640,7 @@ static bool cmd_om(RCore *core, const char *input) {
break;
}
if (fd < 3) {
eprintf ("Wrong fd, it must be greater than 3.\n");
R_LOG_ERROR ("Wrong fd, it must be greater than 3");
return false;
}
desc = r_io_desc_get (core->io, fd);
@ -648,13 +648,27 @@ static bool cmd_om(RCore *core, const char *input) {
if (!size) {
size = r_io_fd_size (core->io, fd);
}
RIOMap *map = r_io_map_add (core->io, fd, rwx_arg ? rwx : desc->perm, paddr, vaddr, size);
if (map) {
if (name) {
r_io_map_set_name (map, name);
bool addmap = true;
if (arg == 'u') {
// check if map exists before adding it
RIOMap *map = r_io_map_get_at (core->io, vaddr);
if (map) {
ut64 ms = r_itv_size (map->itv);
ut64 mp = map->delta; // itv.addr; // map->delta + map->itv.addr;
if (mp == paddr && ms == size && map->fd == fd) {
addmap = false;
}
}
}
if (addmap) {
RIOMap *map = r_io_map_add (core->io, fd, rwx_arg ? rwx : desc->perm, paddr, vaddr, size);
if (map) {
if (name) {
r_io_map_set_name (map, name);
}
} else {
R_LOG_ERROR ("Cannot add map");
}
} else {
eprintf ("Cannot add map.\n");
}
}
} else {
@ -662,7 +676,7 @@ static bool cmd_om(RCore *core, const char *input) {
if (r_io_desc_get (core->io, fd)) {
map_list (core, 0, core->print, fd);
} else {
eprintf ("Invalid fd %d\n", (int)fd);
R_LOG_ERROR ("Invalid fd %d", (int)fd);
}
}
free (s);
@ -942,7 +956,7 @@ static void cmd_open_map(RCore *core, const char *input) {
r_core_cmd_omt (core, input + 2);
break;
case ' ': // "om"
cmd_om (core, input);
cmd_om (core, input, 0);
break;
case 'n': // "omn"
if (input[2] == '?') { // "omn?"
@ -1046,6 +1060,10 @@ static void cmd_open_map(RCore *core, const char *input) {
r_io_map_del (core->io, r_num_math (core->num, input + 2));
}
break;
case 'u': // "omu"
// same as "om", but checks if already exists
cmd_om (core, input + 1, 'u');
break;
case 'd': // "omd"
cmd_omd (core, input + 2);
break;

View File

@ -1219,19 +1219,15 @@ typedef struct {
const char *needle;
int needle_len;
bool must_be_data;
char **valid_completions;
RCmdAliasVal **valid_completion_vals;
const char **valid_completions;
const RCmdAliasVal **valid_completion_vals;
int num_completions;
} AliasAutocompletions;
static bool check_alias_completion(void *in, const void *k, const void *v) {
// This repetition kind of sucks but we need
// to carry state somehow
AliasAutocompletions *c = in;
const char *needle = c->needle;
const int needle_len = c->needle_len;
const RCmdAliasVal *val = v;
/* Skip command aliases if we're filtering them out */
@ -1259,8 +1255,8 @@ static void autocomplete_alias(RLineCompletion *completion, RCmd *cmd, const cha
// Filter out command aliases?
c.must_be_data = must_be_data;
// Single block, borrowed pointers
c.valid_completions = R_NEWS (char *, cmd->aliases->count);
c.valid_completion_vals = R_NEWS (RCmdAliasVal *, cmd->aliases->count);
c.valid_completions = R_NEWS (const char *, cmd->aliases->count);
c.valid_completion_vals = R_NEWS (const RCmdAliasVal *, cmd->aliases->count);
c.num_completions = 0;
ht_pp_foreach (cmd->aliases, check_alias_completion, &c);
@ -1295,8 +1291,8 @@ static void autocomplete_alias(RLineCompletion *completion, RCmd *cmd, const cha
}
}
/* If 0 possible completions, do nothing */
free (c.valid_completions);
free (c.valid_completion_vals);
free ((void*)c.valid_completions);
free ((void*)c.valid_completion_vals);
}
static void autocomplete_process_path(RLineCompletion *completion, const char *str, const char *path) {

View File

@ -57,7 +57,7 @@ static int make_projects_directory(RCore *core) {
char *prjdir = r_file_abspath (r_config_get (core->config, "dir.projects"));
int ret = r_sys_mkdirp (prjdir);
if (!ret) {
eprintf ("Cannot mkdir dir.projects\n");
R_LOG_ERROR ("Cannot mkdir dir.projects");
}
free (prjdir);
return ret;
@ -139,18 +139,18 @@ R_API int r_core_project_list(RCore *core, int mode) {
R_API int r_core_project_delete(RCore *core, const char *prjfile) {
if (r_sandbox_enable (0)) {
eprintf ("Cannot delete project in sandbox mode\n");
R_LOG_ERROR ("Cannot delete project in sandbox mode");
return 0;
}
char *path = get_project_script_path (core, prjfile);
if (!path) {
eprintf ("Invalid project name '%s'\n", prjfile);
R_LOG_ERROR ("Invalid project name '%s'", prjfile);
return false;
}
if (r_core_is_project (core, prjfile)) {
char *prj_dir = r_file_dirname (path);
if (!prj_dir) {
eprintf ("Cannot resolve directory\n");
R_LOG_ERROR ("Cannot resolve directory");
free (path);
return false;
}
@ -328,7 +328,7 @@ static bool r_core_project_load(RCore *core, const char *prj_name, const char *r
core->prj->rvc = vc;
free (prj_path);
} else {
eprintf ( "Failed to load rvc\n");
R_LOG_ERROR ("Failed to load rvc");
}
r_config_set_b (core->config, "cfg.fortunes", cfg_fortunes);
r_config_set_b (core->config, "scr.interactive", scr_interactive);
@ -369,20 +369,20 @@ R_API bool r_core_project_open(RCore *core, const char *prj_path) {
bool close_current_session = true;
bool ask_for_closing = true;
if (r_project_is_loaded (core->prj)) {
eprintf ("There's a project already opened\n");
R_LOG_ERROR ("There's a project already opened");
ask_for_closing = false;
bool ccs = interactive? r_cons_yesno ('y', "Close current session? (Y/n)"): true;
if (ccs) {
r_core_cmd0 (core, "o--");
} else {
eprintf ("Project not loaded.\n");
R_LOG_ERROR ("Project not loaded");
return false;
}
}
char *prj_name = r_core_project_name (core, prj_path);
char *prj_script = get_project_script_path (core, prj_path);
if (!prj_script) {
eprintf ("Invalid project name '%s'\n", prj_path);
R_LOG_ERROR ("Invalid project name '%s'", prj_path);
return false;
}
if (ask_for_closing && r_project_is_loaded (core->prj)) {
@ -410,7 +410,7 @@ R_API char *r_core_project_name(RCore *core, const char *prjfile) {
}
char *prj = get_project_script_path (core, prjfile);
if (!prj) {
eprintf ("Invalid project name '%s'\n", prjfile);
R_LOG_ERROR ("Invalid project name '%s'", prjfile);
return NULL;
}
FILE *fd = r_sandbox_fopen (prj, "r");
@ -430,7 +430,7 @@ R_API char *r_core_project_name(RCore *core, const char *prjfile) {
}
fclose (fd);
} else {
eprintf ("Cannot open project info (%s)\n", prj);
R_LOG_ERROR ("Cannot open project info (%s)", prj);
}
free (prj);
if (R_STR_ISEMPTY (file)) {
@ -514,6 +514,7 @@ R_API bool r_core_project_save_script(RCore *core, const char *file, int opts) {
r_cons_flush ();
}
r_core_cmd (core, "o*", 0);
// save maps // r_core_cmd (core, "om*", 0);
r_core_cmd0 (core, "tcc*");
if (opts & R_CORE_PRJ_FCNS) {
r_cons_printf ("# functions\n");
@ -609,12 +610,12 @@ R_API bool r_core_project_save(RCore *core, const char *prj_name) {
r_return_val_if_fail (prj_name && *prj_name, false);
if (r_config_get_b (core->config, "cfg.debug")) {
eprintf ("radare2 does not support projects on debugged bins.\n");
R_LOG_ERROR ("radare2 does not support projects on debugged bins");
return false;
}
char *script_path = get_project_script_path (core, prj_name);
if (!script_path) {
eprintf ("Invalid project name '%s'\n", prj_name);
R_LOG_ERROR ("Invalid project name '%s'", prj_name);
return false;
}
char *prj_dir = r_str_endswith (script_path, R_SYS_DIR "rc.r2")
@ -622,14 +623,14 @@ R_API bool r_core_project_save(RCore *core, const char *prj_name) {
: r_str_newf ("%s.d", script_path);
if (r_file_exists (script_path)) {
if (r_file_is_directory (script_path)) {
eprintf ("Structural error: rc.r2 shouldnt be a directory.\n");
R_LOG_ERROR ("Structural error: rc.r2 shouldnt be a directory");
}
}
if (!prj_dir) {
prj_dir = strdup (prj_name);
}
if (r_core_is_project (core, prj_name) && strcmp (prj_name, r_config_get (core->config, "prj.name"))) {
eprintf ("A project with this name already exists. Use Ps-%s to delete it.\n", prj_name);
R_LOG_ERROR ("A project with this name already exists. Use Ps-%s to delete it", prj_name);
free (script_path);
free (prj_dir);
return false;
@ -637,8 +638,8 @@ R_API bool r_core_project_save(RCore *core, const char *prj_name) {
if (!r_file_is_directory (prj_dir)) {
r_sys_mkdirp (prj_dir);
}
if (r_config_get_i (core->config, "scr.null")) {
r_config_set_i (core->config, "scr.null", false);
if (r_config_get_b (core->config, "scr.null")) {
r_config_set_b (core->config, "scr.null", false);
scr_null = true;
}
make_projects_directory (core);
@ -656,13 +657,12 @@ R_API bool r_core_project_save(RCore *core, const char *prj_name) {
r_config_set (core->config, "prj.name", prj_name);
if (!r_core_project_save_script (core, script_path, R_CORE_PRJ_ALL)) {
eprintf ("Cannot open '%s' for writing\n", prj_name);
R_LOG_ERROR ("Cannot open '%s' for writing", prj_name);
ret = false;
r_config_set (core->config, "prj.name", "");
}
if (r_config_get_b (core->config, "prj.files")) {
eprintf ("TODO: prj.files: support copying more than one file into the project directory\n");
char *bin_file = r_core_project_name (core, prj_name);
const char *bin_filename = r_file_basename (bin_file);
char *prj_bin_dir = r_str_newf ("%s" R_SYS_DIR "bin", prj_dir);
@ -715,10 +715,10 @@ R_API bool r_core_project_save(RCore *core, const char *prj_name) {
r_sys_cmdf ("rm -f '%s.zip'; zip -r '%s'.zip '%s'",
prj_name, prj_name, prj_name);
} else {
eprintf ("Command injection attempt?\n");
R_LOG_WARN ("Command injection attempt?");
}
} else {
eprintf ("Cannot chdir %s\n", prj_dir);
R_LOG_ERROR ("Cannot chdir %s", prj_dir);
}
r_sys_chdir (cwd);
free (cwd);
@ -726,7 +726,7 @@ R_API bool r_core_project_save(RCore *core, const char *prj_name) {
// LEAK : not always in heap free (prj_name);
free (prj_dir);
if (scr_null) {
r_config_set_i (core->config, "scr.null", true);
r_config_set_b (core->config, "scr.null", true);
}
free (script_path);
r_config_set (core->config, "prj.name", prj_name);
@ -753,4 +753,3 @@ R_API void r_core_project_undirty(RCore *core) {
core->anal->is_dirty = false;
core->flags->is_dirty = false;
}

View File

@ -10,9 +10,9 @@
#include "r_skyline.h"
#include <r_util/r_w32dw.h>
#define R_IO_SEEK_SET 0
#define R_IO_SEEK_CUR 1
#define R_IO_SEEK_END 2
#define R_IO_SEEK_SET 0
#define R_IO_SEEK_CUR 1
#define R_IO_SEEK_END 2
#define R_IO_UNDOS 64
@ -328,7 +328,7 @@ R_API bool r_io_map_exists_for_id(RIO *io, ut32 id);
R_API RIOMap *r_io_map_get(RIO *io, ut32 id);
R_API RIOMap *r_io_map_add(RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size);
R_API RIOMap *r_io_map_add_bottom(RIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size);
R_API RIOMap *r_io_map_get_at(RIO *io, ut64 addr); //returns the map at vaddr with the highest priority
R_API RIOMap *r_io_map_get_at(RIO *io, ut64 vaddr); // returns the map at vaddr with the highest priority
R_API RIOMap *r_io_map_get_by_ref(RIO *io, RIOMapRef *ref);
R_API bool r_io_map_is_mapped(RIO* io, ut64 addr);
R_API RIOMap *r_io_map_get_paddr(RIO *io, ut64 paddr); //returns the map at paddr with the highest priority

View File

@ -1,3 +1,31 @@
NAME=Resaving maps fails
FILE=-
BROKEN=1
CMDS=<<EOF
om 3 0x8000 0x200 0x200 r--
om 3 0xc000 0x100 0x300 r--
rm a.r2
PS a.r2
om*
?e dos
o-*
cat a.r2~^om
?e tre
. a.r2
om*
rm a.r2
EOF
EXPECT=<<EOF
om 3 0x00000000 0x00000200 0x00000000 rwx
om 3 0x00008000 0x00000200 0x00000200 r--
om 3 0x0000c000 0x00000100 0x00000300 r--
dos
om 3 0x00000000 0x00000200 0x00000000 rwx
om 3 0x00008000 0x00000200 0x00000200 r--
om 3 0x0000c000 0x00000100 0x00000300 r--
EOF
RUN
NAME=Resaving fails
FILE=bins/mach0/ls-m1
BROKEN=1
@ -362,7 +390,7 @@ om*
?e --
P- hand
P+ hand > /dev/null
Po hand > /dev/null
P hand > /dev/null
om*
?e --
om*~?
@ -405,7 +433,7 @@ om*
?e --
P- hond
P+ hond > /dev/null
Po hond > /dev/null
P hond > /dev/null
om*
?e --
om*~?
@ -692,6 +720,7 @@ FILE=bins/elf/analysis/main
ARGS=-A -eprj.vc=false -edir.projects=.tmp/
CMDS=<<EOF
e prj.vc=false
P- hjkl
P+ hjkl
Pi~!/
Px