static int __io_posix_open(const char *file, int perm, int mode) { int fd; if (r_str_startswith (file, "file://")) { file += strlen ("file://"); } if (r_file_is_directory (file)) { return -1; } #if __WINDOWS__ // probably unnecessary to have this ifdef nowadays windows is posix enough if (perm & R_PERM_W) { fd = r_sandbox_open (file, O_BINARY | O_RDWR, 0); if (fd == -1 && perm & R_PERM_CREAT) { r_sandbox_creat (file, 0644); fd = r_sandbox_open (file, O_BINARY | O_RDWR | O_CREAT, 0); } } else { fd = r_sandbox_open (file, O_BINARY, 0); } #else const int posixFlags = (perm & R_PERM_W) ? (perm & R_PERM_CREAT) ? (O_RDWR | O_CREAT) : O_RDWR : O_RDONLY; fd = r_sandbox_open (file, posixFlags, mode); #endif return fd; }
RIOMMapFileObj *r_io_def_mmap_create_new_file(RIO *io, const char *filename, int mode, int flags) { if (!io) { return NULL; } RIOMMapFileObj *mmo = R_NEW0 (RIOMMapFileObj); if (!mmo) { return NULL; } mmo->nocache = !strncmp (filename, "nocache://", 10); if (mmo->nocache) { filename += 10; } mmo->filename = strdup (filename); mmo->mode = mode; mmo->flags = flags; mmo->io_backref = io; if (flags & R_IO_WRITE) { mmo->fd = r_sandbox_open (filename, O_CREAT|O_RDWR, mode); } else { mmo->fd = r_sandbox_open (filename, O_RDONLY, mode); } if (mmo->fd == -1) { free (mmo->filename); free (mmo); return NULL; } if (!r_io_def_mmap_refresh_def_mmap_buf (mmo)) { mmo->rawio = 1; if (!r_io_def_mmap_refresh_def_mmap_buf (mmo)) { r_io_def_mmap_free (mmo); mmo = NULL; } } return mmo; }
RIOMMapFileObj *r_io_def_mmap_create_new_file(RIO *io, const char *filename, int mode, int flags) { RIOMMapFileObj *mmo = NULL; if (!io) return NULL; mmo = R_NEW0 (RIOMMapFileObj); if (!mmo) return NULL; mmo->filename = strdup (filename); mmo->mode = mode; mmo->flags = flags; mmo->io_backref = io; if (flags & R_IO_WRITE) mmo->fd = r_sandbox_open (filename, O_CREAT|O_RDWR, mode); else mmo->fd = r_sandbox_open (filename, O_RDONLY, mode); if (!r_io_def_mmap_refresh_def_mmap_buf (mmo)) { mmo->rawio = 1; if (!r_io_def_mmap_refresh_def_mmap_buf (mmo)) { r_io_def_mmap_free (mmo); mmo = NULL; } } return mmo; }
static int __io_posix_open (RIO *io, const char *file, int flags, int mode) { int fd; #if __WINDOWS__ if (flags & R_IO_WRITE) { fd = r_sandbox_open (file, O_BINARY | 1, 0); if (fd == -1) r_sandbox_creat (file, O_BINARY); fd = r_sandbox_open (file, O_BINARY | 1, 0); } else fd = r_sandbox_open (file, O_BINARY, 0); #else fd = r_sandbox_open (file, (flags&R_IO_WRITE)? (O_RDWR|O_CREAT): O_RDONLY, mode); #endif return fd; }
RIOMMapFileObj *r_io_def_mmap_create_new_file(RIO *io, const char *filename, int mode, int perm) { if (!io) { return NULL; } RIOMMapFileObj *mmo = R_NEW0 (RIOMMapFileObj); if (!mmo) { return NULL; } mmo->nocache = !strncmp (filename, "nocache://", 10); if (mmo->nocache) { filename += 10; } mmo->filename = strdup (filename); mmo->mode = mode; mmo->perm = perm; mmo->io_backref = io; const int posixFlags = (perm & R_PERM_W) ? (perm & R_PERM_CREAT) ? (O_RDWR | O_CREAT) : O_RDWR : O_RDONLY; mmo->fd = r_sandbox_open (filename, posixFlags, mode); if (mmo->fd == -1) { free (mmo->filename); free (mmo); return NULL; } if (!r_io_def_mmap_refresh_def_mmap_buf (mmo)) { mmo->rawio = 1; if (!r_io_def_mmap_refresh_def_mmap_buf (mmo)) { r_io_def_mmap_free (mmo); mmo = NULL; } } return mmo; }
static int __io_posix_open (const char *file, int flags, int mode) { int fd; if (r_file_is_directory (file)) return -1; #if __WINDOWS__ if (flags & R_IO_WRITE) { fd = r_sandbox_open (file, O_BINARY | O_RDWR, 0); if (fd == -1) { r_sandbox_creat (file, 0644); fd = r_sandbox_open (file, O_BINARY | O_RDWR, 0); } } else fd = r_sandbox_open (file, O_BINARY, 0); #else fd = r_sandbox_open (file, (flags&R_IO_WRITE)? (O_RDWR|O_CREAT): O_RDONLY, mode); #endif return fd; }
R_API int r_sys_truncate(const char *file, int sz) { #if __WINDOWS__ int fd = r_sandbox_open (file, O_RDWR, 0644); if (!fd) return R_FALSE; ftruncate (fd, sz); close (fd); return R_TRUE; #else return truncate (file, sz)? R_FALSE: R_TRUE; #endif }
R_API int r_cons_pipe_open(const char *file, int fdn, int append) { char *targetFile; if (fdn < 1) { return -1; } if (!strncmp (file, "~/", 2) || !strncmp (file, "~\\", 2)) { targetFile = r_str_home (file + 2); } else { targetFile = strdup (file); } int fd = r_sandbox_open (targetFile, O_BINARY | O_RDWR | O_CREAT | (append? O_APPEND: O_TRUNC), 0644); if (fd==-1) { eprintf ("r_cons_pipe_open: Cannot open file '%s'\n", file); free (targetFile); return -1; }// else eprintf ("%s created\n", file); if (backup_fd != -1) { close (backup_fd); } backup_fdn = fdn; #if __WINDOWS__ && !__CYGWIN__ backup_fd = 2002-(fd-2); // windows xp has 2048 as limit fd if (_dup2 (fdn, backup_fd) == -1) { #else backup_fd = sysconf (_SC_OPEN_MAX)-(fd-2); // portable getdtablesize() if (backup_fd < 2) { backup_fd = 2002 - (fd - 2); // fallback } if (dup2 (fdn, backup_fd) == -1) { #endif eprintf ("Cannot dup stdout to %d\n", backup_fd); free (targetFile); return -1; } close (fdn); dup2 (fd, fdn); free (targetFile); return fd; } R_API void r_cons_pipe_close(int fd) { if (fd == -1) { return; } close (fd); if (backup_fd != -1) { dup2 (backup_fd, backup_fdn); close (backup_fd); backup_fd = -1; } }
R_API int r_core_project_save(RCore *core, const char *file) { int fd, tmp, ret = R_TRUE; char *prj; if (file == NULL || *file == '\0') return R_FALSE; prj = r_core_project_file (file); r_core_project_init (); fd = r_sandbox_open (prj, O_BINARY|O_RDWR|O_CREAT, 0644); if (fd != -1) { int fdold = r_cons_singleton ()->fdout; r_cons_singleton ()->fdout = fd; r_cons_singleton ()->is_interactive = R_FALSE; r_str_write (fd, "# r2 rdb project file\n"); //-- r_str_write (fd, "# flags\n"); tmp = core->flags->space_idx; core->flags->space_idx = -1; r_flag_list (core->flags, R_TRUE); core->flags->space_idx = tmp; r_cons_flush (); //-- r_str_write (fd, "# eval\n"); // TODO: r_str_writef (fd, "e asm.arch=%s", r_config_get ("asm.arch")); r_config_list (core->config, NULL, R_TRUE); r_cons_flush (); r_str_write (fd, "# sections\n"); r_io_section_list (core->io, core->offset, 1); r_cons_flush (); r_str_write (fd, "# meta\n"); r_meta_list (core->anal->meta, R_META_TYPE_ANY, 1); r_cons_flush (); r_core_cmd (core, "ar*", 0); r_cons_flush (); r_core_cmd (core, "af*", 0); r_cons_flush (); r_core_cmd (core, "ah*", 0); r_cons_flush (); r_str_write (fd, "# seek\n"); r_str_writef (fd, "s 0x%08"PFMT64x, core->offset); r_cons_flush (); close (fd); r_cons_singleton ()->fdout = fdold; r_cons_singleton ()->is_interactive = R_TRUE; } else { eprintf ("Cannot open '%s' for writing\n", prj); ret = R_FALSE; } free (prj); return ret; }
R_API RBuffer *r_buf_new_file(const char *file, bool newFile) { const int mode = 0644; int flags = O_RDWR; if (newFile) { flags |= O_CREAT; } int fd = r_sandbox_open (file, flags, mode); if (fd != -1) { RBuffer *b = r_buf_new (); if (!b) { r_sandbox_close (fd); return NULL; } b->fd = fd; return b; } return NULL; /* we just freed b, don't return it */ }
R_API int r_sys_truncate(const char *file, int sz) { #if __WINDOWS__ && !__CYGWIN__ int fd = r_sandbox_open (file, O_RDWR, 0644); if (fd == -1) { return false; } #ifdef _MSC_VER _chsize (fd, sz); #else ftruncate (fd, sz); #endif close (fd); return true; #else if (r_sandbox_enable (0)) { return false; } return truncate (file, sz)? false: true; #endif }
/* * handle an mmaped file. */ static int apprentice_compile(RMagic *ms, struct r_magic **magicp, ut32 *nmagicp, const char *fn) { int fd; char *dbname; int rv = -1; dbname = mkdbname(fn, 1); if (!dbname) goto out; if ((fd = r_sandbox_open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1) { file_error(ms, errno, "cannot open `%s'", dbname); goto out; } if (write(fd, ar, sizeof (ar)) != (ssize_t)sizeof (ar)) { file_error(ms, errno, "error writing `%s'", dbname); goto beach; } if (lseek(fd, (off_t)sizeof (struct r_magic), SEEK_SET) != sizeof (struct r_magic)) { file_error(ms, errno, "error seeking `%s'", dbname); goto beach; } if (write(fd, *magicp, (sizeof (struct r_magic) * *nmagicp)) != (ssize_t)(sizeof (struct r_magic) * *nmagicp)) { file_error(ms, errno, "error writing `%s'", dbname); goto beach; } rv = 0; beach: (void)close(fd); out: free(dbname); return rv; }
/* * handle a compiled file. */ static int apprentice_map(RMagic *ms, struct r_magic **magicp, ut32 *nmagicp, const char *fn) { int fd; struct stat st; ut32 *ptr; ut32 version; int needsbyteswap; char *dbname = NULL; void *mm = NULL; dbname = mkdbname (fn, 0); if (!dbname) goto error2; if ((fd = r_sandbox_open (dbname, O_RDONLY|O_BINARY, 0)) == -1) goto error2; if (fstat(fd, &st) == -1) { file_error (ms, errno, "cannot stat `%s'", dbname); goto error1; } if (st.st_size < 8) { file_error (ms, 0, "file `%s' is too small", dbname); goto error1; } #ifdef QUICK if ((mm = mmap (0, (size_t)st.st_size, PROT_READ, //OPENBSDBUG |PROT_WRITE, MAP_PRIVATE|MAP_FILE, fd, (off_t)0)) == MAP_FAILED) { file_error (ms, errno, "cannot map `%s'"); //, dbname); goto error1; } #define RET 2 #else if (!(mm = malloc ((size_t)st.st_size))) { file_oomem(ms, (size_t)st.st_size); goto error1; } if (read (fd, mm, (size_t)st.st_size) != (size_t)st.st_size) { file_badread(ms); goto error1; } #define RET 1 #endif *magicp = mm; (void)close (fd); fd = -1; ptr = (ut32 *)(void *)*magicp; if (*ptr != MAGICNO) { if (swap4(*ptr) != MAGICNO) { //OPENBSDBUG file_error(ms, 0, "bad magic in `%s'"); file_error(ms, 0, "bad magic in `%s'", dbname); goto error1; } needsbyteswap = 1; } else needsbyteswap = 0; version = needsbyteswap? swap4(ptr[1]): ptr[1]; if (version != VERSIONNO) { file_error(ms, 0, "File %d.%d supports only %d version magic " "files. `%s' is version %d", FILE_VERSION_MAJOR, patchlevel, VERSIONNO, dbname, version); goto error1; } *nmagicp = (ut32)(st.st_size / sizeof (struct r_magic)); if (*nmagicp > 0) (*nmagicp)--; (*magicp)++; if (needsbyteswap) byteswap (*magicp, *nmagicp); free (dbname); return RET; error1: if (fd != -1) (void)close (fd); if (mm) { #ifdef QUICK (void)munmap((void *)mm, (size_t)st.st_size); #else free(mm); #endif } else { *magicp = NULL; *nmagicp = 0; } error2: free (dbname); return -1; }
R_API int r_core_project_save(RCore *core, const char *file) { int fd, fdold, tmp, ret = R_TRUE; char *prj; if (file == NULL || *file == '\0') return R_FALSE; prj = r_core_project_file (core, file); if (r_file_is_directory (prj)) { eprintf ("Error: Target is a directory\n"); free (prj); return R_FALSE; } r_core_project_init (core); r_anal_project_save (core->anal, prj); fd = r_sandbox_open (prj, O_BINARY|O_RDWR|O_CREAT, 0644); if (fd != -1) { fdold = r_cons_singleton ()->fdout; r_cons_singleton ()->fdout = fd; r_cons_singleton ()->is_interactive = R_FALSE; r_str_write (fd, "# r2 rdb project file\n"); r_str_write (fd, "# flags\n"); tmp = core->flags->space_idx; core->flags->space_idx = -1; r_flag_list (core->flags, R_TRUE); core->flags->space_idx = tmp; r_cons_flush (); r_str_write (fd, "# eval\n"); // TODO: r_str_writef (fd, "e asm.arch=%s", r_config_get ("asm.arch")); r_config_list (core->config, NULL, R_TRUE); r_cons_flush (); r_str_write (fd, "# sections\n"); r_io_section_list (core->io, core->offset, 1); r_cons_flush (); r_str_write (fd, "# meta\n"); r_meta_list (core->anal, R_META_TYPE_ANY, 1); r_cons_flush (); { char buf[1024]; snprintf (buf, sizeof (buf), "%s.d/xrefs", prj); sdb_file (core->anal->sdb_xrefs, buf); sdb_sync (core->anal->sdb_xrefs); } r_core_cmd (core, "ax*", 0); r_cons_flush (); r_core_cmd (core, "af*", 0); r_cons_flush (); r_core_cmd (core, "ah*", 0); r_cons_flush (); r_str_write (fd, "# seek\n"); r_str_writef (fd, "s 0x%08"PFMT64x, core->offset); r_cons_flush (); close (fd); r_cons_singleton ()->fdout = fdold; r_cons_singleton ()->is_interactive = R_TRUE; } else { eprintf ("Cannot open '%s' for writing\n", prj); ret = R_FALSE; } free (prj); return ret; }