1 /* radare - LGPL - Copyright 2009-2021 - pancake */
2
3 #include <r_core.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #define UPDATE_TIME(a) (r->times->file_open_time = r_time_now_mono () - (a))
8
9 static int r_core_file_do_load_for_debug(RCore *r, ut64 loadaddr, const char *filenameuri);
10 static int r_core_file_do_load_for_io_plugin(RCore *r, ut64 baseaddr, ut64 loadaddr);
11
close_but_cb(void * user,void * data,ut32 id)12 static bool close_but_cb(void *user, void *data, ut32 id) {
13 RCore *core = (RCore *)user;
14 RIODesc *desc = (RIODesc *)data;
15 if (core && desc && core->io->desc) {
16 if (desc->fd != core->io->desc->fd) {
17 // TODO: use the API
18 r_core_cmdf (core, "o-%d", desc->fd);
19 }
20 }
21 return true;
22 }
23
24 // TODO: move to IO as a helper?
r_core_file_close_all_but(RCore * core)25 R_API bool r_core_file_close_all_but(RCore *core) {
26 r_id_storage_foreach (core->io->files, close_but_cb, core);
27 return true;
28 }
29
__isMips(RAsm * a)30 static bool __isMips (RAsm *a) {
31 return a && a->cur && a->cur->arch && strstr (a->cur->arch, "mips");
32 }
33
loadGP(RCore * core)34 static void loadGP(RCore *core) {
35 if (__isMips (core->rasm)) {
36 ut64 gp = r_num_math (core->num, "loc._gp");
37 if (!gp || gp == UT64_MAX) {
38 r_config_set (core->config, "anal.roregs", "zero");
39 r_core_cmd0 (core, "10aes@entry0");
40 r_config_set (core->config, "anal.roregs", "zero,gp");
41 gp = r_reg_getv (core->anal->reg, "gp");
42 }
43 // eprintf ("[mips] gp: 0x%08"PFMT64x"\n", gp);
44 r_config_set_i (core->config, "anal.gp", gp);
45 }
46 }
47
r_core_file_reopen(RCore * core,const char * args,int perm,int loadbin)48 R_API bool r_core_file_reopen(RCore *core, const char *args, int perm, int loadbin) {
49 int isdebug = r_config_get_i (core->config, "cfg.debug");
50 char *path;
51 ut64 laddr = r_config_get_i (core->config, "bin.laddr");
52 RIODesc *file = NULL;
53 RIODesc *odesc = core->io ? core->io->desc : NULL;
54 RBinFile *bf = odesc ? r_bin_file_find_by_fd (core->bin, odesc->fd) : NULL;
55 char *ofilepath = NULL, *obinfilepath = (bf && bf->file)? strdup (bf->file): NULL;
56 bool ret = false;
57 ut64 origoff = core->offset;
58 if (odesc) {
59 if (odesc->referer) {
60 ofilepath = odesc->referer;
61 } else if (odesc->uri) {
62 ofilepath = odesc->uri;
63 }
64 }
65
66 ut64 new_baddr = UT64_MAX;
67 if (args) {
68 new_baddr = r_num_math (core->num, args);
69 if (new_baddr && new_baddr != UT64_MAX) {
70 r_config_set_i (core->config, "bin.baddr", new_baddr);
71 } else {
72 new_baddr = UT64_MAX;
73 }
74 }
75 if (new_baddr == UT64_MAX) {
76 new_baddr = r_config_get_i (core->config, "bin.baddr");
77 }
78
79 if (r_sandbox_enable (0)) {
80 eprintf ("Cannot reopen in sandbox\n");
81 free (obinfilepath);
82 return false;
83 }
84 if (!odesc) {
85 eprintf ("No file opened to reopen\n");
86 free (ofilepath);
87 free (obinfilepath);
88 return false;
89 }
90 int newpid = odesc->fd;
91
92 if (isdebug) {
93 r_debug_kill (core->dbg, core->dbg->pid, core->dbg->tid, 9); // SIGKILL
94 do {
95 r_debug_continue (core->dbg);
96 } while (!r_debug_is_dead (core->dbg));
97 r_debug_detach (core->dbg, core->dbg->pid);
98 perm = 7;
99 } else {
100 if (!perm) {
101 perm = 4; //R_PERM_R;
102 }
103 }
104 if (!ofilepath) {
105 eprintf ("Unknown file path");
106 free (obinfilepath);
107 return false;
108 }
109
110 // HACK: move last mapped address to higher place
111 // XXX - why does this hack work?
112 // when the new memory maps are created.
113 path = strdup (ofilepath);
114 free (obinfilepath);
115 obinfilepath = strdup (ofilepath);
116
117 // r_str_trim (path);
118 file = r_core_file_open (core, path, perm, laddr);
119 if (isdebug) {
120 int newtid = newpid;
121 // XXX - select the right backend
122 if (core->io->desc) {
123 newpid = r_io_fd_get_pid (core->io, core->io->desc->fd);
124 #if __linux__
125 core->dbg->main_pid = newpid;
126 newtid = newpid;
127 #else
128 newtid = r_io_fd_get_tid (core->io, core->io->desc->fd);
129 #endif
130 }
131 // Reset previous pid and tid
132 core->dbg->pid = -1;
133 core->dbg->tid = -1;
134 core->dbg->recoil_mode = R_DBG_RECOIL_NONE;
135 memset (&core->dbg->reason, 0, sizeof (core->dbg->reason));
136 // Reopen and attach
137 r_core_setup_debugger (core, "native", true);
138 r_debug_select (core->dbg, newpid, newtid);
139 }
140
141 if (file) {
142 bool had_rbin_info = false;
143
144 if (odesc && bf) {
145 if (r_bin_file_delete (core->bin, bf->id)) {
146 had_rbin_info = true;
147 }
148 }
149 r_io_fd_close (core->io, odesc->fd);
150 eprintf ("File %s reopened in %s mode\n", path,
151 (perm & R_PERM_W)? "read-write": "read-only");
152
153 if (loadbin && (loadbin == 2 || had_rbin_info)) {
154 ut64 baddr;
155 if (isdebug) {
156 baddr = r_debug_get_baddr (core->dbg, path);
157 } else if (new_baddr != UT64_MAX) {
158 baddr = new_baddr;
159 } else {
160 baddr = r_config_get_i (core->config, "bin.baddr");
161 }
162 ret = r_core_bin_load (core, obinfilepath, baddr);
163 r_core_bin_update_arch_bits (core);
164 if (!ret) {
165 eprintf ("Error: Failed to reload rbin for: %s", path);
166 }
167 origoff = r_num_math (core->num, "entry0");
168 }
169
170 if (core->bin->cur && core->io && r_io_desc_get (core->io, file->fd) && !loadbin) {
171 //force here NULL because is causing uaf look this better in future XXX @alvarofe
172 core->bin->cur = NULL;
173 }
174 // close old file
175 } else if (odesc) {
176 eprintf ("r_core_file_reopen: Cannot reopen file: %s with perms 0x%x,"
177 " attempting to open read-only.\n", path, perm);
178 // lower it down back
179 //ofile = r_core_file_open (core, path, R_PERM_R, addr);
180 } else {
181 eprintf ("Cannot reopen\n");
182 }
183 if (core->io->desc) {
184 core->switch_file_view = 1;
185 r_core_block_read (core);
186 }
187 r_core_seek (core, origoff, true);
188 if (isdebug) {
189 r_core_cmd0 (core, ".dm*");
190 r_core_cmd0 (core, ".dr*");
191 r_core_cmd0 (core, "sr PC");
192 } else {
193 loadGP (core);
194 }
195 // update anal io bind
196 r_io_bind (core->io, &(core->anal->iob));
197 if (core->io->desc && core->io->desc->fd >= 0) {
198 r_core_cmd0 (core, "o-!");
199 }
200 r_core_file_close_all_but (core);
201 // This is done to ensure that the file is correctly
202 // loaded into the view
203 free (obinfilepath);
204 //free (ofilepath);
205 // causes double free . dont free file here // R_FREE (file);
206 free (path);
207 return ret;
208 }
209
r_core_sysenv_end(RCore * core,const char * cmd)210 R_API void r_core_sysenv_end(RCore *core, const char *cmd) {
211 // TODO: remove tmpfilez
212 if (strstr (cmd, "R2_BLOCK")) {
213 // remove temporary BLOCK file
214 char *f = r_sys_getenv ("R2_BLOCK");
215 if (f) {
216 r_file_rm (f);
217 r_sys_setenv ("R2_BLOCK", NULL);
218 free (f);
219 }
220 }
221 r_sys_setenv ("R2_FILE", NULL);
222 r_sys_setenv ("R2_BYTES", NULL);
223 r_sys_setenv ("R2_OFFSET", NULL);
224
225 // remove temporary R2_CONFIG file
226 char *r2_config = r_sys_getenv ("R2_CONFIG");
227 if (r2_config) {
228 r_file_rm (r2_config);
229 r_sys_setenv ("R2_CONFIG", NULL);
230 free (r2_config);
231 }
232 }
233
r_core_sysenv_begin(RCore * core,const char * cmd)234 R_API char *r_core_sysenv_begin(RCore * core, const char *cmd) {
235 char *f, *ret = cmd? strdup (cmd): NULL;
236 RIODesc *desc = core->io->desc;
237 if (cmd && strstr (cmd, "R2_BYTES")) {
238 char *s = r_hex_bin2strdup (core->block, core->blocksize);
239 r_sys_setenv ("R2_BYTES", s);
240 free (s);
241 }
242 r_sys_setenv ("RABIN2_PDBSERVER", r_config_get (core->config, "pdb.server"));
243 if (desc && desc->name) {
244 r_sys_setenv ("R2_FILE", desc->name);
245 r_sys_setenv ("R2_SIZE", sdb_fmt ("%"PFMT64d, r_io_desc_size (desc)));
246 if (cmd && strstr (cmd, "R2_BLOCK")) {
247 // replace BLOCK in RET string
248 if ((f = r_file_temp ("r2block"))) {
249 if (r_file_dump (f, core->block, core->blocksize, 0)) {
250 r_sys_setenv ("R2_BLOCK", f);
251 }
252 free (f);
253 }
254 }
255 }
256 r_sys_setenv ("R2_OFFSET", sdb_fmt ("%"PFMT64d, core->offset));
257 r_sys_setenv ("R2_XOFFSET", sdb_fmt ("0x%08"PFMT64x, core->offset));
258 r_sys_setenv ("R2_ENDIAN", core->rasm->big_endian? "big": "little");
259 r_sys_setenv ("R2_BSIZE", sdb_fmt ("%d", core->blocksize));
260
261 // dump current config file so other r2 tools can use the same options
262 char *config_sdb_path = NULL;
263 int config_sdb_fd = r_file_mkstemp (NULL, &config_sdb_path);
264 if (config_sdb_fd >= 0) {
265 close (config_sdb_fd);
266 }
267
268 Sdb *config_sdb = sdb_new (NULL, config_sdb_path, 0);
269 r_config_serialize (core->config, config_sdb);
270 sdb_sync (config_sdb);
271 sdb_free (config_sdb);
272 r_sys_setenv ("R2_CONFIG", config_sdb_path);
273
274 r_sys_setenv ("RABIN2_LANG", r_config_get (core->config, "bin.lang"));
275 r_sys_setenv ("RABIN2_DEMANGLE", r_config_get (core->config, "bin.demangle"));
276 r_sys_setenv ("R2_ARCH", r_config_get (core->config, "asm.arch"));
277 r_sys_setenv ("R2_BITS", sdb_fmt ("%"PFMT64u, r_config_get_i (core->config, "asm.bits")));
278 r_sys_setenv ("R2_COLOR", r_config_get_i (core->config, "scr.color")? "1": "0");
279 r_sys_setenv ("R2_DEBUG", r_config_get_i (core->config, "cfg.debug")? "1": "0");
280 r_sys_setenv ("R2_IOVA", r_config_get_i (core->config, "io.va")? "1": "0");
281 free (config_sdb_path);
282 return ret;
283 }
284
285 #if !__linux__ && !__WINDOWS__
get_base_from_maps(RCore * core,const char * file)286 static ut64 get_base_from_maps(RCore *core, const char *file) {
287 RDebugMap *map;
288 RListIter *iter;
289 ut64 b = 0LL;
290
291 r_debug_map_sync (core->dbg); // update process memory maps
292 r_list_foreach (core->dbg->maps, iter, map) {
293 if ((map->perm & 5) == 5) {
294 // TODO: make this more flexible
295 // XXX - why "copy/" here?
296 if (map->name && strstr (map->name, "copy/")) {
297 return map->addr;
298 }
299 if (map->file && !strcmp (map->file, file)) {
300 return map->addr;
301 }
302 if (map->name && !strcmp (map->name, file)) {
303 return map->addr;
304 }
305 // XXX - Commented out, as this could unexpected results
306 //b = map->addr;
307 }
308 }
309 // fallback resolution copied from cmd_debug.c:r_debug_get_baddr
310 r_list_foreach (core->dbg->maps, iter, map) {
311 if (map->perm == 5) { // r-x
312 return map->addr;
313 }
314 }
315
316 return b;
317 }
318 #endif
319
320 #if __linux__ || __APPLE__
setbpint(RCore * r,const char * mode,const char * sym)321 static bool setbpint(RCore *r, const char *mode, const char *sym) {
322 RBreakpointItem *bp;
323 RFlagItem *fi = r_flag_get (r->flags, sym);
324 if (!fi) {
325 return false;
326 }
327 bp = r_bp_add_sw (r->dbg->bp, fi->offset, 1, R_BP_PROT_EXEC);
328 if (bp) {
329 bp->internal = true;
330 #if __linux__
331 bp->data = r_str_newf ("?e %s: %s", mode, sym);
332 #else
333 bp->data = r_str_newf ("?e %s: %s;ps@rdi", mode, sym);
334 #endif
335 return true;
336 }
337 eprintf ("Cannot set breakpoint at %s\n", sym);
338 return false;
339 }
340 #endif
341
342 // XXX - need to handle index selection during debugging
r_core_file_do_load_for_debug(RCore * r,ut64 baseaddr,const char * filenameuri)343 static int r_core_file_do_load_for_debug(RCore *r, ut64 baseaddr, const char *filenameuri) {
344 RIODesc *desc = r->io->desc;
345 RBinFile *binfile = NULL;
346 RBinPlugin *plugin;
347 int xtr_idx = 0; // if 0, load all if xtr is used
348
349 // TODO : Honor file.path eval var too?
350 if (!strncmp ("dbg://", filenameuri, 6)) {
351 filenameuri += 6;
352 }
353 if (!desc) {
354 return false;
355 }
356 int fd = desc->fd;
357 r_debug_select (r->dbg, r_io_fd_get_pid (r->io, fd),
358 r_io_fd_get_tid (r->io, fd));
359 #if !__linux__
360 #if !__WINDOWS__
361 baseaddr = get_base_from_maps (r, filenameuri);
362 #endif
363 if (baseaddr != UT64_MAX) {
364 r_config_set_i (r->config, "bin.baddr", baseaddr);
365 }
366 #endif
367 RBinOptions opt;
368 r_bin_options_init (&opt, fd, baseaddr, UT64_MAX, false);
369 opt.xtr_idx = xtr_idx;
370 if (!r_bin_open (r->bin, filenameuri, &opt)) {
371 eprintf ("RBinLoad: Cannot open %s\n", filenameuri);
372 if (r_config_get_i (r->config, "bin.rawstr")) {
373 r_bin_options_init (&opt, fd, baseaddr, UT64_MAX, true);
374 opt.xtr_idx = xtr_idx;
375 if (!r_bin_open (r->bin, filenameuri, &opt)) {
376 return false;
377 }
378 }
379 }
380
381 if (*r_config_get (r->config, "dbg.libs")) {
382 r_core_cmd0 (r, ".dmm*");
383 #if __linux__
384 setbpint (r, "dbg.libs", "sym.imp.dlopen");
385 setbpint (r, "dbg.libs", "sym.imp.dlmopen");
386 setbpint (r, "dbg.unlibs", "sym.imp.dlclose");
387 #elif __APPLE__
388 setbpint (r, "dbg.libs", "sym._dlopen");
389 setbpint (r, "dbg.libs", "sym._dlclose");
390 #endif
391 }
392 binfile = r_bin_cur (r->bin);
393 r_core_bin_set_env (r, binfile);
394 plugin = r_bin_file_cur_plugin (binfile);
395 if (plugin && !strcmp (plugin->name, "any")) {
396 // set use of raw strings
397 // r_config_set_i (r->config, "io.va", false);
398 //\\ r_config_set (r->config, "bin.rawstr", "true");
399 // get bin.minstr
400 r->bin->minstrlen = r_config_get_i (r->config, "bin.minstr");
401 r->bin->maxstrbuf = r_config_get_i (r->config, "bin.maxstrbuf");
402 } else if (binfile) {
403 RBinObject *obj = r_bin_cur_object (r->bin);
404 RBinInfo *info = obj? obj->info: NULL;
405 if (plugin && info) {
406 r_core_bin_set_arch_bits (r, binfile->file, info->arch, info->bits);
407 }
408 }
409
410 if (plugin && !strcmp (plugin->name, "dex")) {
411 r_core_cmd0 (r, "\"(fix-dex,wx `ph sha1 $s-32 @32` @12 ; wx `ph adler32 $s-12 @12` @8)\"\n");
412 }
413
414 return true;
415 }
416
r_core_file_do_load_for_io_plugin(RCore * r,ut64 baseaddr,ut64 loadaddr)417 static int r_core_file_do_load_for_io_plugin(RCore *r, ut64 baseaddr, ut64 loadaddr) {
418 RIODesc *cd = r->io->desc;
419 int fd = cd ? cd->fd : -1;
420 RBinFile *binfile = NULL;
421 int xtr_idx = 0; // if 0, load all if xtr is used
422 RBinPlugin *plugin;
423
424 if (fd < 0) {
425 return false;
426 }
427 r_io_use_fd (r->io, fd);
428 RBinOptions opt;
429 r_bin_options_init (&opt, fd, baseaddr, loadaddr, r->bin->rawstr);
430 opt.xtr_idx = xtr_idx;
431 if (!r_bin_open_io (r->bin, &opt)) {
432 //eprintf ("Failed to load the bin with an IO Plugin.\n");
433 return false;
434 }
435 binfile = r_bin_cur (r->bin);
436 if (r_core_bin_set_env (r, binfile)) {
437 if (!r->anal->sdb_cc->path) {
438 R_LOG_WARN ("No calling convention defined for this file, analysis may be inaccurate.\n");
439 }
440 }
441 plugin = r_bin_file_cur_plugin (binfile);
442 if (plugin && !strcmp (plugin->name, "any")) {
443 RBinObject *obj = r_bin_cur_object (r->bin);
444 RBinInfo *info = obj? obj->info: NULL;
445 if (!info) {
446 return false;
447 }
448 info->bits = r->rasm->bits;
449 // set use of raw strings
450 r_core_bin_set_arch_bits (r, binfile->file, info->arch, info->bits);
451 // r_config_set_i (r->config, "io.va", false);
452 // r_config_set (r->config, "bin.rawstr", "true");
453 // get bin.minstr
454 r->bin->minstrlen = r_config_get_i (r->config, "bin.minstr");
455 r->bin->maxstrbuf = r_config_get_i (r->config, "bin.maxstrbuf");
456 } else if (binfile) {
457 RBinObject *obj = r_bin_cur_object (r->bin);
458 RBinInfo *info = obj? obj->info: NULL;
459 if (!info) {
460 return false;
461 }
462 if (plugin) {
463 r_core_bin_set_arch_bits (r, binfile->file,
464 info->arch, info->bits);
465 }
466 }
467
468 if (plugin && !strcmp (plugin->name, "dex")) {
469 r_core_cmd0 (r, "\"(fix-dex,wx `ph sha1 $s-32 @32` @12 ; wx `ph adler32 $s-12 @12` @8)\"\n");
470 }
471 return true;
472 }
473
try_loadlib(RCore * core,const char * lib,ut64 addr)474 static bool try_loadlib(RCore *core, const char *lib, ut64 addr) {
475 void *p = r_core_file_open (core, lib, 0, addr);
476 if (p) {
477 r_core_bin_load (core, lib, addr);
478 R_FREE (p);
479 return true;
480 }
481 return false;
482 }
483
r_core_file_loadlib(RCore * core,const char * lib,ut64 libaddr)484 R_API bool r_core_file_loadlib(RCore *core, const char *lib, ut64 libaddr) {
485 const char *dirlibs = r_config_get (core->config, "dir.libs");
486 bool free_libdir = true;
487 #ifdef __WINDOWS__
488 char *libdir = r_str_r2_prefix (R2_LIBDIR);
489 #else
490 char *libdir = strdup (R2_LIBDIR);
491 #endif
492 if (!libdir) {
493 libdir = R2_LIBDIR;
494 free_libdir = false;
495 }
496 if (!dirlibs || !*dirlibs) {
497 dirlibs = "." R_SYS_DIR;
498 }
499 const char *ldlibrarypath[] = {
500 dirlibs,
501 libdir,
502 #ifndef __WINDOWS__
503 "/usr/local/lib",
504 "/usr/lib",
505 "/lib",
506 #endif
507 "." R_SYS_DIR,
508 NULL
509 };
510 const char * *libpath = (const char * *) &ldlibrarypath;
511
512 bool ret = false;
513 #ifdef __WINDOWS__
514 if (strlen (lib) >= 3 && lib[1] == ':' && lib[2] == '\\') {
515 #else
516 if (*lib == '/') {
517 #endif
518 if (try_loadlib (core, lib, libaddr)) {
519 ret = true;
520 }
521 } else {
522 while (*libpath) {
523 char *s = r_str_newf ("%s" R_SYS_DIR "%s", *libpath, lib);
524 if (try_loadlib (core, s, libaddr)) {
525 ret = true;
526 }
527 free (s);
528 if (ret) {
529 break;
530 }
531 libpath++;
532 }
533 }
534 if (free_libdir) {
535 free (libdir);
536 }
537 return ret;
538 }
539
540 R_API int r_core_bin_rebase(RCore *core, ut64 baddr) {
541 if (!core || !core->bin || !core->bin->cur) {
542 return 0;
543 }
544 if (baddr == UT64_MAX) {
545 return 0;
546 }
547 RBinFile *bf = core->bin->cur;
548 bf->o->baddr = baddr;
549 bf->o->loadaddr = baddr;
550 r_bin_object_set_items (bf, bf->o);
551 return 1;
552 }
553
554 static void load_scripts_for(RCore *core, const char *name) {
555 // TODO:
556 char *file;
557 RListIter *iter;
558 char *hdir = r_str_newf (R_JOIN_2_PATHS (R2_HOME_BINRC, "bin-%s"), name);
559 char *path = r_str_home (hdir);
560 RList *files = r_sys_dir (path);
561 if (!r_list_empty (files)) {
562 eprintf ("[binrc] path: %s\n", path);
563 }
564 r_list_foreach (files, iter, file) {
565 if (*file && *file != '.') {
566 eprintf ("[binrc] loading %s\n", file);
567 r_core_cmdf (core, ". %s/%s", path, file);
568 }
569 }
570 r_list_free (files);
571 free (path);
572 free (hdir);
573 }
574
575 typedef struct {
576 const char *name;
577 bool found;
578 } MyFileData;
579
580 static bool filecb(void *user, void *data, ut32 id) {
581 MyFileData *filedata = user;
582 RIODesc *desc = (RIODesc *)data;
583 if (!strcmp (desc->name, filedata->name)) {
584 filedata->found = true;
585 }
586 return true;
587 }
588
589 static bool file_is_loaded(RCore *core, const char *lib) {
590 MyFileData filedata = {lib, false};
591 r_id_storage_foreach (core->io->files, filecb, &filedata);
592 return filedata.found;
593 }
594
595 typedef struct {
596 const char *name;
597 ut64 addr;
598 RBin *bin;
599 } RCoreLinkData;
600
601 static bool linkcb(void *user, void *data, ut32 id) {
602 RCoreLinkData *ld = user;
603 RIODesc *desc = (RIODesc *)data;
604
605 RBinFile *bf = r_bin_file_find_by_fd (ld->bin, desc->fd);
606 if (bf) {
607 RListIter *iter;
608 RBinSymbol *sym;
609 RList *symbols = r_bin_file_get_symbols (bf);
610 r_list_foreach (symbols, iter, sym) {
611 if (!strcmp (sym->name, ld->name)) {
612 ld->addr = sym->vaddr;
613 return false;
614 }
615 }
616 }
617 return true;
618 }
619
620 R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
621 RIODesc *desc = r->io->desc;
622 ut64 laddr = r_config_get_i (r->config, "bin.laddr");
623 RBinFile *binfile = NULL;
624 RBinPlugin *plugin = NULL;
625 bool is_io_load;
626 const char *cmd_load;
627 if (!desc) {
628 return false;
629 }
630 // NULL deref guard
631 if (desc) {
632 is_io_load = desc && desc->plugin;
633 if (!filenameuri || !*filenameuri) {
634 filenameuri = desc->name;
635 }
636 } else {
637 is_io_load = false;
638 }
639
640 if (!filenameuri) {
641 eprintf ("r_core_bin_load: no file specified\n");
642 return false;
643 }
644
645 r->bin->minstrlen = r_config_get_i (r->config, "bin.minstr");
646 r->bin->maxstrbuf = r_config_get_i (r->config, "bin.maxstrbuf");
647 if (is_io_load) {
648 // TODO? necessary to restore the desc back?
649 // Fix to select pid before trying to load the binary
650 if ((desc->plugin && desc->plugin->isdbg) || r_config_get_i (r->config, "cfg.debug")) {
651 r_core_file_do_load_for_debug (r, baddr, filenameuri);
652 } else {
653 r_core_file_do_load_for_io_plugin (r, baddr, 0LL);
654 }
655 r_io_use_fd (r->io, desc->fd);
656 // Restore original desc
657 }
658 if (binfile && desc) {
659 binfile->fd = desc->fd;
660 }
661 binfile = r_bin_cur (r->bin);
662 if (r->bin->cur && r->bin->cur->o && r->bin->cur->o->plugin && r->bin->cur->o->plugin->strfilter) {
663 char msg[2];
664 msg[0] = r->bin->cur->o->plugin->strfilter;
665 msg[1] = 0;
666 r_config_set (r->config, "bin.str.filter", msg);
667 }
668 //r_core_bin_set_env (r, binfile);
669 plugin = r_bin_file_cur_plugin (binfile);
670 if (plugin && plugin->name) {
671 load_scripts_for (r, plugin->name);
672 }
673 cmd_load = r_config_get (r->config, "cmd.load");
674 if (cmd_load && *cmd_load) {
675 r_core_cmd (r, cmd_load, 0);
676 }
677
678 if (plugin && plugin->name) {
679 if (!strcmp (plugin->name, "any")) {
680 if (r_str_startswith (desc->name, "rap") && strstr (desc->name, "://")) {
681 r_io_map_new (r->io, desc->fd, desc->perm, 0, laddr, UT64_MAX);
682 } else {
683 r_io_map_new (r->io, desc->fd, desc->perm, 0, laddr, r_io_desc_size (desc));
684 }
685 // set use of raw strings
686 //r_config_set (r->config, "bin.rawstr", "true");
687 // r_config_set_i (r->config, "io.va", false);
688 // get bin.minstr
689 r->bin->minstrlen = r_config_get_i (r->config, "bin.minstr");
690 r->bin->maxstrbuf = r_config_get_i (r->config, "bin.maxstrbuf");
691 } else if (binfile) {
692 RBinObject *obj = r_bin_cur_object (r->bin);
693 if (obj) {
694 bool va = obj->info ? obj->info->has_va : 0;
695 if (!va) {
696 r_config_set_i (r->config, "io.va", 0);
697 }
698 //workaround to map correctly malloc:// and raw binaries
699 if (r_io_desc_is_dbg (desc) || (!obj->sections || !va)) {
700 r_io_map_new (r->io, desc->fd, desc->perm, 0, laddr, r_io_desc_size (desc));
701 }
702 RBinInfo *info = obj->info;
703 if (info) {
704 r_core_bin_set_arch_bits (r, binfile->file, info->arch, info->bits);
705 } else {
706 r_core_bin_set_arch_bits (r, binfile->file,
707 r_config_get (r->config, "asm.arch"),
708 r_config_get_i (r->config, "asm.bits"));
709 }
710 }
711 }
712 } else {
713 if (desc) {
714 r_io_map_new (r->io, desc->fd, desc->perm, 0, laddr, r_io_desc_size (desc));
715 }
716 if (binfile) {
717 r_core_bin_set_arch_bits (r, binfile->file,
718 r_config_get (r->config, "asm.arch"),
719 r_config_get_i (r->config, "asm.bits"));
720 }
721 }
722 if (desc && r_config_get_i (r->config, "io.exec")) {
723 desc->perm |= R_PERM_X;
724 }
725 if (plugin && plugin->name && !strcmp (plugin->name, "dex")) {
726 r_core_cmd0 (r, "\"(fix-dex,wx `ph sha1 $s-32 @32` @12 ;"
727 " wx `ph adler32 $s-12 @12` @8)\"\n");
728 }
729 if (!r_config_get_i (r->config, "cfg.debug")) {
730 loadGP (r);
731 }
732 if (r_config_get_i (r->config, "bin.libs")) {
733 const char *lib;
734 RListIter *iter;
735 RList *libs = r_bin_get_libs (r->bin);
736 r_list_foreach (libs, iter, lib) {
737 if (file_is_loaded (r, lib)) {
738 continue;
739 }
740 eprintf ("[bin.libs] Opening %s\n", lib);
741 ut64 baddr = r_io_map_location (r->io, 0x200000);
742 if (baddr != UT64_MAX) {
743 r_core_file_loadlib (r, lib, baddr);
744 }
745 }
746 r_core_cmd0 (r, "obb 0;s entry0");
747 r_config_set_i (r->config, "bin.at", true);
748 eprintf ("[bin.libs] Linking imports...\n");
749 RBinImport *imp;
750 RList *imports = r_bin_get_imports (r->bin);
751 r_list_foreach (imports, iter, imp) {
752 // PLT finding
753 RFlagItem *impsym = r_flag_get (r->flags, sdb_fmt ("sym.imp.%s", imp->name));
754 if (!impsym) {
755 //eprintf ("Cannot find '%s' import in the PLT\n", imp->name);
756 continue;
757 }
758 ut64 imp_addr = impsym->offset;
759 eprintf ("Resolving %s... ", imp->name);
760 RCoreLinkData linkdata = {imp->name, UT64_MAX, r->bin};
761 r_id_storage_foreach (r->io->files, linkcb, &linkdata);
762 if (linkdata.addr != UT64_MAX) {
763 eprintf ("0x%08"PFMT64x"\n", linkdata.addr);
764 ut64 a = linkdata.addr;
765 ut64 b = imp_addr;
766 r_core_cmdf (r, "ax 0x%08"PFMT64x" 0x%08"PFMT64x, a, b);
767 } else {
768 eprintf ("NO\n");
769 }
770 }
771 }
772
773 //If type == R_BIN_TYPE_CORE, we need to create all the maps
774 if (plugin && binfile && plugin->file_type
775 && plugin->file_type (binfile) == R_BIN_TYPE_CORE) {
776 ut64 sp_addr = (ut64)-1;
777 RIOMap *stack_map = NULL;
778
779 // Setting the right arch and bits, so regstate will be shown correctly
780 if (plugin->info) {
781 RBinInfo *inf = plugin->info (binfile);
782 eprintf ("Setting up coredump arch-bits to: %s-%d\n", inf->arch, inf->bits);
783 r_config_set (r->config, "asm.arch", inf->arch);
784 r_config_set_i (r->config, "asm.bits", inf->bits);
785 r_bin_info_free (inf);
786 }
787 if (binfile->o->regstate) {
788 if (r_reg_arena_set_bytes (r->anal->reg, binfile->o->regstate)) {
789 eprintf ("Setting up coredump: Problem while setting the registers\n");
790 } else {
791 eprintf ("Setting up coredump: Registers have been set\n");
792 const char *regname = r_reg_get_name (r->anal->reg, R_REG_NAME_SP);
793 if (regname) {
794 RRegItem *reg = r_reg_get (r->anal->reg, regname, -1);
795 if (reg) {
796 sp_addr = r_reg_get_value (r->anal->reg, reg);
797 stack_map = r_io_map_get (r->io, sp_addr);
798 }
799 }
800 regname = r_reg_get_name (r->anal->reg, R_REG_NAME_PC);
801 if (regname) {
802 RRegItem *reg = r_reg_get (r->anal->reg, regname, -1);
803 if (reg) {
804 ut64 seek = r_reg_get_value (r->anal->reg, reg);
805 r_core_seek (r, seek, true);
806 }
807 }
808 }
809 }
810
811 RBinObject *o = binfile->o;
812 int map = 0;
813 if (o && o->maps) {
814 RList *maps = o->maps;
815 RListIter *iter;
816 RBinMap *mapcore;
817
818 r_list_foreach (maps, iter, mapcore) {
819 RIOMap *iomap = r_io_map_get (r->io, mapcore->addr);
820 if (iomap && (mapcore->file || stack_map == iomap)) {
821 r_io_map_set_name (iomap, r_str_get_fail (mapcore->file, "[stack]"));
822 }
823 map++;
824 }
825 r_list_free (maps);
826 o->maps = NULL;
827 }
828 eprintf ("Setting up coredump: %d maps have been found and created\n", map);
829 goto beach;
830 }
831 beach:
832 return true;
833 }
834
835 R_API RIODesc *r_core_file_open_many(RCore *r, const char *file, int perm, ut64 loadaddr) {
836 const bool openmany = r_config_get_i (r->config, "file.openmany");
837 int opened_count = 0;
838 RListIter *fd_iter, *iter2;
839 RIODesc *fd;
840
841 RList *list_fds = r_io_open_many (r->io, file, perm, 0644);
842
843 if (!list_fds || r_list_length (list_fds) == 0) {
844 r_list_free (list_fds);
845 return NULL;
846 }
847
848 r_list_foreach_safe (list_fds, fd_iter, iter2, fd) {
849 opened_count++;
850 if (openmany && opened_count > 1) {
851 // XXX - Open Many should limit the number of files
852 // loaded in io plugin area this needs to be more premptive
853 // like down in the io plugin layer.
854 // start closing down descriptors
855 r_list_delete (list_fds, fd_iter);
856 continue;
857 }
858 r_core_bin_load (r, fd->name, loadaddr);
859 }
860 return NULL;
861 }
862
863 /* loadaddr is r2 -m (mapaddr) */
864 R_API RIODesc *r_core_file_open(RCore *r, const char *file, int flags, ut64 loadaddr) {
865 r_return_val_if_fail (r && file, NULL);
866 ut64 prev = r_time_now_mono ();
867 const bool openmany = r_config_get_i (r->config, "file.openmany");
868
869 if (!strcmp (file, "-")) {
870 file = "malloc://512";
871 }
872 //if not flags was passed open it with -r--
873 if (!flags) {
874 flags = R_PERM_R;
875 }
876 r->io->bits = r->rasm->bits; // TODO: we need an api for this
877 RIODesc *fd = r_io_open_nomap (r->io, file, flags, 0644);
878 if (r_cons_is_breaked()) {
879 goto beach;
880 }
881 if (!fd && openmany) {
882 // XXX - make this an actual option somewhere?
883 fd = r_core_file_open_many (r, file, flags, loadaddr);
884 if (fd) {
885 goto beach;
886 }
887 }
888 if (!fd) {
889 if (flags & R_PERM_W) {
890 // flags |= R_IO_CREAT;
891 if (!(fd = r_io_open_nomap (r->io, file, flags, 0644))) {
892 goto beach;
893 }
894 } else {
895 goto beach;
896 }
897 }
898 if (r_io_is_listener (r->io)) {
899 r_core_serve (r, fd);
900 r_io_desc_free (fd);
901 fd = NULL;
902 goto beach;
903 }
904
905 {
906 const char *cp = r_config_get (r->config, "cmd.open");
907 if (cp && *cp) {
908 r_core_cmd (r, cp, 0);
909 }
910 }
911
912 r_io_use_fd (r->io, fd->fd);
913
914 if (r_config_get_i (r->config, "cfg.debug")) {
915 bool swstep = true;
916 if (r->dbg->h && r->dbg->h->canstep) {
917 swstep = false;
918 }
919 r_config_set_i (r->config, "dbg.swstep", swstep);
920 // Set the correct debug handle
921 if (fd->plugin && fd->plugin->isdbg) {
922 char *dh = r_str_ndup (file, (strstr (file, "://") - file));
923 if (dh) {
924 r_debug_use (r->dbg, dh);
925 free (dh);
926 }
927 }
928 }
929 //used by r_core_bin_load otherwise won't load correctly
930 //this should be argument of r_core_bin_load <shrug>
931 if (loadaddr != UT64_MAX) {
932 r_config_set_i (r->config, "bin.laddr", loadaddr);
933 }
934 r_core_cmd0 (r, "=!");
935 beach:
936 r->times->file_open_time = r_time_now_mono () - prev;
937 return fd;
938 }
939