Rewrite the RBuffer API to make it safer and adjust the codebase ##refactor (#13656)

* Reimplement r_buf_fread/fwrite
* Add slice buffer and introduce readonly field
* Do nothing if size is 0
* Prevents an overflow when 8 is subtracted from size.
* Fix ragg2 when patching outside currently existing buffer
* Implement r_mem_mmap_resize for systems where mremap is not defined
* r_buf_buffer can be called with no size arg as well
* Use size_t instead of ut64
This commit is contained in:
Riccardo Schirone 2019-05-15 15:34:06 +02:00 committed by radare
parent c7cb949060
commit 66f7403245
68 changed files with 1393 additions and 1055 deletions

15
configure vendored
View File

@ -167,8 +167,7 @@ System types:
--target=TARGET configure for building compilers for TARGET [HOST]
EOF2
printf "
Optional Features:
printf "\nOptional Features:
--disable-debugger disable native debugger features
--with-sysmagic force to use system's magic
--with-capstone5 build next branch of the capstone repository
@ -187,10 +186,8 @@ Optional Features:
--with-ostype Choose OS type ( gnulinux windows darwin haiku ) (USEROSTYPE=auto)
--with-libversion specify different libversion (LIBVERSION=xxx)
--without-jemalloc build without jemalloc
--with-checks-level value between 0 and 3 to enable different level of assert (see R_CHECKS_LEVEL) (R_CHECKS_LEVEL=2)
"
printf "
Some influential environment variables:
--with-checks-level value between 0 and 3 to enable different level of assert (see R_CHECKS_LEVEL) (R_CHECKS_LEVEL=2)\n"
printf "\nSome influential environment variables:
CC C compiler command
CFLAGS C compiler flags
CPPFLAGS C preprocessor flags
@ -198,10 +195,8 @@ Some influential environment variables:
nonstandard directory <lib dir>
CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
headers in a nonstandard directory <include dir>
CPP C preprocessor
"
printf "
Report bugs to: pancake <pancake@nopcode.org>"
CPP C preprocessor\n"
printf "\nReport bugs to: pancake <pancake@nopcode.org>"
echo ""
exit 0
}

View File

@ -1383,7 +1383,7 @@ static RFlirtNode *flirt_parse(const RAnal *anal, RBuffer *flirt_buf) {
if (!(node = R_NEW0 (RFlirtNode))) {
goto exit;
}
r_buf = r_buf_new_with_pointers (buf, size);
r_buf = r_buf_new_with_pointers (buf, size, false);
#if DEBUG
r_file_dump ("sig_dump", r_buf->buf, r_buf_size (r_buf));
#endif

View File

@ -476,7 +476,8 @@ R_API char* r_anal_reflines_str(void *_core, ut64 addr, int opts) {
}
}
add_spaces (b, 0, pos, wide);
str = r_buf_free_to_string (b);
str = r_buf_to_string (b);
r_buf_free (b);
b = NULL;
if (!str) {
r_list_free (lvls);

View File

@ -993,7 +993,8 @@ R_API RAsmCode *r_asm_massemble(RAsm *a, const char *assembly) {
memcpy (acode->bytes + idx, r_strbuf_get (&op.buf), r_strbuf_length (&op.buf));
memset (acode->bytes + idx + ret, 0, idx + ret);
if (op.buf_inc && r_buf_size (op.buf_inc) > 1) {
char *inc = r_buf_free_to_string (op.buf_inc);
char *inc = r_buf_to_string (op.buf_inc);
r_buf_free (op.buf_inc);
if (inc) {
ret += r_hex_str2bin (inc, acode->bytes + idx + ret);
free (inc);

View File

@ -354,9 +354,7 @@ R_IPI RBinFile *r_bin_file_new(RBin *bin, const char *file, const ut8 *bytes, ut
binfile->xtr_obj = NULL;
if (!binfile->buf) {
//r_bin_file_free (binfile);
binfile->buf = r_buf_new ();
// return NULL;
}
if (sdb) {
@ -408,7 +406,7 @@ R_API bool r_bin_file_object_new_from_xtr_data(RBin *bin, RBinFile *bf, ut64 bas
ut64 sz = data->size;
RBinPlugin *plugin = get_plugin_with_buffer (bin, data->buf);
bf->buf = r_buf_new_with_bufref (data->buf);
bf->buf = r_buf_ref (data->buf);
RBinObject *o = r_bin_object_new (bf, plugin, baseaddr, loadaddr, offset, sz);
if (!o) {
@ -735,7 +733,6 @@ R_IPI bool r_bin_file_set_bytes(RBinFile *bf, const ut8 *bytes, ut64 sz, bool st
r_return_val_if_fail (bf && bytes, false);
r_buf_free (bf->buf);
bf->buf = r_buf_new ();
#if LIMIT_SIZE
if (sz > 1024 * 1024) {
eprintf ("Too big\n");
@ -744,9 +741,9 @@ R_IPI bool r_bin_file_set_bytes(RBinFile *bf, const ut8 *bytes, ut64 sz, bool st
}
#else
if (steal_ptr) {
r_buf_set_bytes_steal (bf->buf, bytes, sz);
bf->buf = r_buf_new_with_pointers (bytes, sz, true);
} else {
r_buf_set_bytes (bf->buf, bytes, sz);
bf->buf = r_buf_new_with_bytes (bytes, sz);
}
#endif
return bf->buf != NULL;

View File

@ -1247,7 +1247,7 @@ R_API RBuffer *r_bin_package(RBin *bin, const char *type, const char *file, RLis
RListIter *iter;
ut32 num;
ut8 *num8 = (ut8*)&num;
RBuffer *buf = r_buf_new_file (file, true);
RBuffer *buf = r_buf_new_file (file, O_RDWR | O_CREAT, 0644);
if (!buf) {
eprintf ("Cannot open file %s - Permission Denied.\n", file);
return NULL;

View File

@ -38,7 +38,7 @@ R_API bool r_bin_wr_output(RBin *bin, const char *filename) {
return false;
}
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (binfile->buf, &tmpsz);
const ut8 *tmp = r_buf_data (binfile->buf, &tmpsz);
return r_file_dump (filename, tmp, tmpsz, 0);
}

View File

@ -115,7 +115,7 @@ static bool r_bin_coff_init_hdr(struct r_bin_coff_obj *obj) {
return false;
}
if (obj->hdr.f_magic == COFF_FILE_TI_COFF) {
ret = r_buf_fread_at (obj->b, R_BUF_CUR, (ut8 *)&obj->target_id, obj->endian? "S": "s", 1);
ret = r_buf_fread (obj->b, (ut8 *)&obj->target_id, obj->endian? "S": "s", 1);
if (ret != sizeof (ut16)) {
return false;
}

View File

@ -36,7 +36,7 @@ RBinDexObj *r_bin_dex_new_buf(RBuffer *buf) {
goto fail;
}
r_buf_seek (bin->b, 0, 0);
r_buf_seek (bin->b, 0, R_BUF_SET);
r_buf_read (bin->b, (ut8 *)&dexhdr->magic, 8);
dexhdr->checksum = r_buf_read_le32 (bin->b);
r_buf_read (bin->b, (ut8 *)&dexhdr->signature, 20);
@ -100,7 +100,7 @@ RBinDexObj *r_bin_dex_new_buf(RBuffer *buf) {
free (bin->classes);
goto fail;
}
r_buf_seek (bin->b, offset, 0);
r_buf_seek (bin->b, offset, R_BUF_SET);
bin->classes[i].class_id = r_buf_read_le32 (bin->b);
bin->classes[i].access_flags = r_buf_read_le32 (bin->b);
bin->classes[i].super_class = r_buf_read_le32 (bin->b);
@ -129,7 +129,7 @@ RBinDexObj *r_bin_dex_new_buf(RBuffer *buf) {
free (bin->methods);
goto fail;
}
r_buf_seek (bin->b, offset, 0);
r_buf_seek (bin->b, offset, R_BUF_SET);
bin->methods[i].class_id = r_buf_read_le16 (bin->b);
bin->methods[i].proto_id = r_buf_read_le16 (bin->b);
bin->methods[i].name_id = r_buf_read_le32 (bin->b);
@ -177,7 +177,7 @@ RBinDexObj *r_bin_dex_new_buf(RBuffer *buf) {
free (bin->fields);
goto fail;
}
r_buf_seek (bin->b, offset, 0);
r_buf_seek (bin->b, offset, R_BUF_SET);
bin->fields[i].class_id = r_buf_read_le16 (bin->b);
bin->fields[i].type_id = r_buf_read_le16 (bin->b);
bin->fields[i].name_id = r_buf_read_le32 (bin->b);
@ -205,7 +205,7 @@ RBinDexObj *r_bin_dex_new_buf(RBuffer *buf) {
free (bin->protos);
goto fail;
}
r_buf_seek (bin->b, offset, 0);
r_buf_seek (bin->b, offset, R_BUF_SET);
bin->protos[i].shorty_id = r_buf_read_le32 (bin->b);
bin->protos[i].return_type_id = r_buf_read_le32 (bin->b);
bin->protos[i].parameters_off = r_buf_read_le32 (bin->b);

View File

@ -519,7 +519,7 @@ static int bin_pe_init_hdr(struct PE_(r_bin_pe_obj_t)* bin) {
r_sys_perror ("malloc (dos header)");
return false;
}
if (r_buf_read_at (bin->b, 0, (ut8*) bin->dos_header, sizeof(PE_(image_dos_header))) == -1) {
if (r_buf_read_at (bin->b, 0, (ut8*) bin->dos_header, sizeof(PE_(image_dos_header))) < 0) {
bprintf ("Warning: read (dos header)\n");
return false;
}
@ -537,7 +537,7 @@ static int bin_pe_init_hdr(struct PE_(r_bin_pe_obj_t)* bin) {
return false;
}
bin->nt_header_offset = bin->dos_header->e_lfanew;
if (r_buf_read_at (bin->b, bin->dos_header->e_lfanew, (ut8*) bin->nt_headers, sizeof (PE_(image_nt_headers))) < -1) {
if (r_buf_read_at (bin->b, bin->dos_header->e_lfanew, (ut8*) bin->nt_headers, sizeof (PE_(image_nt_headers))) < 0) {
bprintf ("Warning: read (dos header)\n");
return false;
}
@ -596,10 +596,10 @@ static int bin_pe_init_hdr(struct PE_(r_bin_pe_obj_t)* bin) {
bin->optional_header = &bin->nt_headers->optional_header;
bin->data_directory = (PE_(image_data_directory*)) & bin->optional_header->DataDirectory;
if (strncmp ((char*) &bin->dos_header->e_magic, "MZ", 2) ||
(strncmp ((char*) &bin->nt_headers->Signature, "PE", 2) &&
/* Check also for Phar Lap TNT DOS extender PL executable */
strncmp ((char*) &bin->nt_headers->Signature, "PL", 2))) {
if (strncmp ((char *)&bin->dos_header->e_magic, "MZ", 2) ||
(strncmp ((char *)&bin->nt_headers->Signature, "PE", 2) &&
/* Check also for Phar Lap TNT DOS extender PL executable */
strncmp ((char *)&bin->nt_headers->Signature, "PL", 2))) {
return false;
}
return true;
@ -672,7 +672,7 @@ static struct r_bin_pe_export_t* parse_symbol_table(struct PE_(r_bin_pe_obj_t)*
}
}
symctr = 0;
if (r_buf_read_at (bin->b, sym_tbl_off, (ut8*) buf, bufsz)) {
if (r_buf_read_at (bin->b, sym_tbl_off, (ut8*) buf, bufsz) > 0) {
for (i = 0; i < shsz; i += srsz) {
sr = (SymbolRecord*) (buf + i);
//bprintf ("SECNUM %d\n", sr->secnum);
@ -730,8 +730,7 @@ static int bin_pe_init_sections(struct PE_(r_bin_pe_obj_t)* bin) {
}
bin->section_header_offset = bin->dos_header->e_lfanew + 4 + sizeof (PE_(image_file_header)) +
bin->nt_headers->file_header.SizeOfOptionalHeader;
if (r_buf_read_at (bin->b, bin->section_header_offset,
(ut8*) bin->section_header, sections_size) == -1) {
if (r_buf_read_at (bin->b, bin->section_header_offset, (ut8*) bin->section_header, sections_size) < 0) {
bprintf ("Warning: read (sections)\n");
R_FREE (bin->section_header);
goto out_error;
@ -954,7 +953,7 @@ static int bin_pe_init_metadata_hdr(struct PE_(r_bin_pe_obj_t)* bin) {
goto fail;
}
rr = r_buf_read_at (bin->b, metadata_directory + 16, (ut8*)(metadata->VersionString), len);
rr = r_buf_read_at (bin->b, metadata_directory + 16, (ut8*)(metadata->VersionString), len);
if (rr != len) {
eprintf ("Warning: read (metadata header) - cannot parse version string\n");
free (metadata->VersionString);
@ -1135,7 +1134,7 @@ static int bin_pe_init_imports(struct PE_(r_bin_pe_obj_t)* bin) {
import_dir = new_import_dir;
new_import_dir = NULL;
curr_import_dir = import_dir + (indx - 1);
if (r_buf_read_at (bin->b, import_dir_offset + (indx - 1) * dir_size, (ut8*) (curr_import_dir), dir_size) < 1) {
if (r_buf_read_at (bin->b, import_dir_offset + (indx - 1) * dir_size, (ut8*) (curr_import_dir), dir_size) <= 0) {
bprintf ("Warning: read (import directory)\n");
R_FREE (import_dir);
break; //return false;
@ -1203,7 +1202,7 @@ static int bin_pe_init_exports(struct PE_(r_bin_pe_obj_t)* bin) {
r_sys_perror ("malloc (export directory)");
return false;
}
if (r_buf_read_at (bin->b, export_dir_paddr, (ut8*) bin->export_directory, sizeof (PE_(image_export_directory))) == -1) {
if (r_buf_read_at (bin->b, export_dir_paddr, (ut8*) bin->export_directory, sizeof (PE_(image_export_directory))) < 0) {
bprintf ("Warning: read (export directory)\n");
R_FREE (bin->export_directory);
return false;
@ -2265,14 +2264,16 @@ static void _parse_resource_directory(struct PE_(r_bin_pe_obj_t) *bin, Pe_image_
if (entry.u1.s.NameIsString) {
int i;
ut16 buf, resourceEntryNameLength;
r_buf_read_at (bin->b, bin->resource_directory_offset + entry.u1.s.NameOffset, (ut8*)&buf, sizeof (ut16));
if (r_buf_read_at (bin->b, bin->resource_directory_offset + entry.u1.s.NameOffset, (ut8*)&buf, sizeof (ut16)) != sizeof (ut16)) {
break;
}
resourceEntryNameLength = r_read_le16 (&buf);
resourceEntryName = calloc (resourceEntryNameLength + 1, sizeof (ut8));
if (resourceEntryName) {
for (i = 0; i < resourceEntryNameLength; i++) { /* Convert Unicode to ASCII */
ut8 byte;
int r = r_buf_read_at (bin->b, bin->resource_directory_offset + entry.u1.s.NameOffset + 2 + (i*2), &byte, sizeof (ut8));
if (r < 1 || !byte) {
if (r != sizeof (ut8) || !byte) {
R_FREE (resourceEntryName);
break;
}
@ -2467,6 +2468,9 @@ static void bin_pe_get_certificate(struct PE_ (r_bin_pe_obj_t) * bin) {
bin->cms = NULL;
size = bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
vaddr = bin->data_directory[PE_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress;
if (size == 0) {
return;
}
data = calloc (1, size);
if (!data) {
return;
@ -3584,7 +3588,7 @@ struct PE_(r_bin_pe_obj_t)* PE_(r_bin_pe_new)(const char* file, bool verbose) {
return bin;
}
struct PE_(r_bin_pe_obj_t)* PE_(r_bin_pe_new_buf)(RBuffer * buf, bool verbose) {
struct PE_(r_bin_pe_obj_t)* PE_(r_bin_pe_new_buf)(RBuffer *buf, bool verbose) {
struct PE_(r_bin_pe_obj_t)* bin = R_NEW0 (struct PE_(r_bin_pe_obj_t));
if (!bin) {
return NULL;

View File

@ -30,7 +30,7 @@ static ut32 consume_r(RBuffer *b, ut64 max, size_t *n_out, ConsumeFcn consume_fc
free (buf);
return 0;
}
r_buf_seek (b, cur + n, R_IO_SEEK_SET);
r_buf_seek (b, cur + n, R_BUF_SET);
*n_out = n;
free (buf);
return tmp;
@ -235,7 +235,7 @@ static RList *get_entries_from_section(RBinWasmObj *bin, RBinWasmSection *sec, P
return NULL;
}
RBuffer *b = bin->buf;
r_buf_seek (b, sec->payload_data, R_IO_SEEK_SET);
r_buf_seek (b, sec->payload_data, R_BUF_SET);
ut32 r = 0;
ut64 max = r_buf_tell (b) + sec->payload_len - 1;
if (!(max < r_buf_size (b))) {
@ -403,7 +403,7 @@ static void *parse_code_entry(RBuffer *b, ut64 max) {
}
ptr->code = r_buf_tell (b);
ptr->len = ptr->body_size - ptr->code + j;
r_buf_seek (b, ptr->len - 1, R_IO_SEEK_CUR); // consume bytecode
r_buf_seek (b, ptr->len - 1, R_BUF_CUR); // consume bytecode
r_buf_read (b, &ptr->byte, 1);
if (ptr->byte != R_BIN_WASM_END_OF_CODE) {
goto beach;
@ -430,7 +430,7 @@ static void *parse_data_entry(RBuffer *b, ut64 max) {
goto beach;
}
ptr->data = r_buf_tell (b);
r_buf_seek (b, ptr->size, R_IO_SEEK_CUR);
r_buf_seek (b, ptr->size, R_BUF_CUR);
return ptr;
beach:
@ -575,7 +575,7 @@ static RBinWasmStartEntry *r_bin_wasm_get_start(RBinWasmObj *bin, RBinWasmSectio
}
RBuffer *b = bin->buf;
r_buf_seek (b, sec->payload_data, R_IO_SEEK_SET);
r_buf_seek (b, sec->payload_data, R_BUF_SET);
ut64 max = r_buf_tell (b) + sec->payload_len - 1;
if (!(max < r_buf_size (b))) {
goto beach;
@ -675,7 +675,7 @@ RList *r_bin_wasm_get_sections (RBinWasmObj *bin) {
}
RBuffer *b = bin->buf;
ut64 max = r_buf_size (b) - 1;
r_buf_seek (b, 8, R_IO_SEEK_SET);
r_buf_seek (b, 8, R_BUF_SET);
while (r_buf_tell (b) <= max) {
if (!(ptr = R_NEW0 (RBinWasmSection))) {
return ret;
@ -765,7 +765,7 @@ RList *r_bin_wasm_get_sections (RBinWasmObj *bin) {
break;
default:
eprintf("[wasm] error: unkown section id: %d\n", ptr->id);
r_buf_seek (b, ptr->size - 1, R_IO_SEEK_CUR);
r_buf_seek (b, ptr->size - 1, R_BUF_CUR);
continue;
}
if (ptr->id != R_BIN_WASM_SECTION_START
@ -780,7 +780,7 @@ RList *r_bin_wasm_get_sections (RBinWasmObj *bin) {
if (ptr->payload_len > ptr->size) {
goto beach;
}
r_buf_seek (b, ptr->payload_len, R_IO_SEEK_CUR);
r_buf_seek (b, ptr->payload_len, R_BUF_CUR);
if (!r_list_append (ret, ptr)) {
free (ptr);
// should it jump to beach?

View File

@ -501,8 +501,7 @@ static RCFValueData *r_cf_value_data_new(char *string) {
r_base64_decode (out, string, len);
data->type = R_CF_DATA;
data->value = r_buf_new ();
r_buf_set_bytes_steal (data->value, out, out_len);
data->value = r_buf_new_with_pointers (out, out_len, true);
return data;
}

View File

@ -111,7 +111,7 @@ static RList *patch_relocs(RBin *b) {
R_FREE (bin->reloc_table);
}
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (bin->b, &tmpsz);
const ut8 *tmp = r_buf_data (bin->b, &tmpsz);
b->iob.write_at (b->iob.io, 0, tmp, tmpsz);
return list;
}

View File

@ -798,7 +798,7 @@ static RBinInfo *info(RBinFile *bf) {
ret->os = strdup ("linux");
const char *kw = "Landroid/support/wearable/view";
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (bf->buf, &tmpsz);
const ut8 *tmp = r_buf_data (bf->buf, &tmpsz);
if (r_mem_mem (tmp, tmpsz, (const ut8 *)kw, strlen (kw))) {
ret->subsystem = strdup ("android-wear");
} else {
@ -824,7 +824,7 @@ static RBinInfo *info(RBinFile *bf) {
{
ut32 fc = r_buf_read_le32_at (bf->buf, 8);
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (bf->buf, &tmpsz);
const ut8 *tmp = r_buf_data (bf->buf, &tmpsz);
ut32 cc = __adler32 (tmp + 12, tmpsz - 12);
if (fc != cc) {
eprintf ("# adler32 checksum doesn't match. Type this to fix it:\n");
@ -1233,7 +1233,7 @@ static const ut8 *parse_dex_class_method(RBinFile *binfile, RBinDexObj *bin,
}
// TODO: catch left instead of null
st64 size;
r_buf_seek (binfile->buf, off, 0);
r_buf_seek (binfile->buf, off, R_BUF_SET);
int r = r_buf_sleb128 (binfile->buf, &size);
if (r <= 0) {
break;
@ -1548,7 +1548,7 @@ static void parse_class(RBinFile *binfile, RBinDexObj *bin, RBinDexClass *c,
}
ut64 bufbufsz;
const ut8 *bufbuf = r_buf_buffer (binfile->buf, &bufbufsz);
const ut8 *bufbuf = r_buf_data (binfile->buf, &bufbufsz);
p = bufbuf + c->class_data_offset;
// XXX may overflow
if (bufbufsz < c->class_data_offset) {
@ -2081,7 +2081,7 @@ static RList *dex_fields(RBinFile *bf) {
r_list_append (ret, r_bin_field_new (addr, addr, siz, nam, sdb_fmt ("0x%08"PFMT64x, (ut64)val), fmt)); \
addr += siz;
r_buf_seek (bf->buf, 0, 0);
r_buf_seek (bf->buf, 0, R_BUF_SET);
ut64 magic = r_buf_read_le64 (bf->buf);
ROW ("dex_magic", 8, magic, "[8]c");
ut32 checksum = r_buf_read_le32 (bf->buf);

View File

@ -62,7 +62,7 @@ static bool load(RBinFile *bf) {
return false;
}
ut64 sz;
const ut8 *bytes = r_buf_buffer (bf->buf, &sz);
const ut8 *bytes = r_buf_data (bf->buf, &sz);
ut64 la = bf->o->loadaddr;
return load_bytes (bf, &bf->o->bin_obj, bytes, sz, la, bf->sdb);
}
@ -89,7 +89,7 @@ static RBinInfo* info(RBinFile *bf) {
if (!bf) {
return NULL;
}
bytes = r_buf_buffer (bf->buf, &sz);
bytes = r_buf_data (bf->buf, &sz);
if (!bytes) {
return NULL;
}

View File

@ -99,7 +99,7 @@ static bool load(RBinFile *bf) {
int result = false;
ut64 sz;
const ut8 *bytes = r_buf_buffer (bf->buf, &sz);
const ut8 *bytes = r_buf_data (bf->buf, &sz);
struct r_bin_java_obj_t *bin_obj = NULL;
load_bytes (bf, (void **)&bin_obj, bytes, sz, bf->o->loadaddr, bf->sdb);

View File

@ -23,7 +23,7 @@ static SBLHDR sb = {0};
static bool check_bytes(const ut8 *buf, ut64 bufsz) {
if (buf && bufsz >= sizeof (SBLHDR)) {
RBuffer *b = r_buf_new_with_pointers (buf, bufsz);
RBuffer *b = r_buf_new_with_pointers (buf, bufsz, false);
int ret = r_buf_fread_at (b, 0, (ut8*)&sb, "10i", 1);
r_buf_free (b);
if (!ret) {
@ -78,7 +78,7 @@ static bool load_bytes(RBinFile *bf, void **bin_obj, const ut8 *buf, ut64 sz, ut
static bool load(RBinFile *bf) {
if (bf && bf->buf) {
ut64 sz;
const ut8 *bytes = r_buf_buffer (bf->buf, &sz);
const ut8 *bytes = r_buf_data (bf->buf, &sz);
return load_bytes (bf, &bf->o->bin_obj, bytes, sz, bf->o->loadaddr, bf->sdb);
}
return false;

View File

@ -226,7 +226,7 @@ static bool load(RBinFile *bf) {
}
ut64 sz;
const ut8 *bytes = r_buf_buffer (bf->buf, &sz);
const ut8 *bytes = r_buf_data (bf->buf, &sz);
return load_bytes (bf, &bf->o->bin_obj, bytes, sz, bf->o->loadaddr, bf->sdb);
}

View File

@ -68,7 +68,7 @@ static bool load_bytes(RBinFile *bf, void **bin_obj, const ut8 *buf, ut64 sz, ut
static bool load(RBinFile *bf) {
ut64 sz;
const ut8 *bytes = r_buf_buffer (bf->buf, &sz);
const ut8 *bytes = r_buf_data (bf->buf, &sz);
ut64 la = (bf && bf->o)? bf->o->loadaddr: 0;
return load_bytes (bf, bf? &bf->o->bin_obj: NULL, bytes, sz, la, bf? bf->sdb: NULL);
}

View File

@ -17,7 +17,7 @@ static bool load_bytes(RBinFile *bf, void **bin_obj, const ut8 *buf, ut64 sz, ut
static void *load_buffer(RBinFile *bf, RBuffer *buf, ut64 loadaddr, Sdb *sdb) {
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (buf, &tmpsz);
const ut8 *tmp = r_buf_data (buf, &tmpsz);
if (!check_bytes (tmp, tmpsz)) {
return NULL;
}

View File

@ -26,7 +26,7 @@ static bool load(RBinFile *bf) {
return false;
}
ut64 sz;
const ut8 *bytes = r_buf_buffer (bf->buf, &sz);
const ut8 *bytes = r_buf_data (bf->buf, &sz);
load_bytes (bf, &bf->o->bin_obj, bytes, sz, bf->o->loadaddr, bf->sdb);
return check_bytes (bytes, sz);
}

View File

@ -37,7 +37,7 @@ static bool load(RBinFile *bf) {
return false;
}
ut64 sz;
const ut8 *bytes = r_buf_buffer (bf->buf, &sz);
const ut8 *bytes = r_buf_data (bf->buf, &sz);
load_bytes (bf, &bf->o->bin_obj, bytes, sz, bf->o->loadaddr, bf->sdb);
return check_bytes (bytes, sz);
}

View File

@ -25,7 +25,7 @@ static bool load(RBinFile *bf) {
return false;
}
ut64 sz;
const ut8 *bytes = r_buf_buffer (bf->buf, &sz);
const ut8 *bytes = r_buf_data (bf->buf, &sz);
ut64 la = bf->o->loadaddr;
load_bytes (bf, &bf->o->bin_obj, bytes, sz, la, bf->sdb);
return check_bytes (bytes, sz);

View File

@ -21,7 +21,7 @@ static bool load(RBinFile *bf) {
return false;
}
ut64 sz;
const ut8 *bytes = r_buf_buffer (bf->buf, &sz);
const ut8 *bytes = r_buf_data (bf->buf, &sz);
bf->rbin->maxstrbuf = 0x20000000;
return check_bytes (bytes, sz);
}

View File

@ -58,7 +58,7 @@ static bool load(RBinFile *bf) {
}
ut64 sz;
const ut64 la = bf->o->loadaddr;
const ut8 *bytes = r_buf_buffer (bf->buf, &sz);
const ut8 *bytes = r_buf_data (bf->buf, &sz);
load_bytes (bf, &bf->o->bin_obj, bytes, sz, la, bf->sdb);
return bf->o->bin_obj != NULL;
}

View File

@ -114,7 +114,7 @@ static bool load_bytes(RBinFile *bf, void **bin_obj, const ut8 *buf, ut64 sz, ut
R_FREE (tmp);
/* Load unpacked binary */
const ut8 *tmpbuf = r_buf_buffer (newbuf, &total_size);
const ut8 *tmpbuf = r_buf_data (newbuf, &total_size);
r_io_write_at (rbin->iob.io, ba, tmpbuf, total_size);
ut32 modoff = readLE32 (newbuf, NSO_OFFSET_MODMEMOFF);
RBinNXOObj *bin = nso_new ();

View File

@ -19,7 +19,7 @@ static bool load(RBinFile *bf) {
return false;
}
ut64 size;
const ut8 *byte = r_buf_buffer (bf->buf, &size);
const ut8 *byte = r_buf_data (bf->buf, &size);
return load_bytes (bf, &bf->o->bin_obj, byte, size, bf->o->loadaddr, bf->sdb);
}

View File

@ -53,7 +53,7 @@ static bool load(RBinFile *bf) {
if (!bf || !bf->o) {
return false;
}
bytes = r_buf_buffer (bf->buf, &sz);
bytes = r_buf_data (bf->buf, &sz);
return load_bytes (bf, &bf->o->bin_obj, bytes, sz, bf->o->loadaddr, bf->sdb);
}
@ -446,7 +446,7 @@ static int haschr(const RBinFile* bf, ut16 dllCharacteristic) {
if (!bf) {
return false;
}
buf = r_buf_buffer (bf->buf, &sz);
buf = r_buf_data (bf->buf, &sz);
if (!buf) {
return false;
}

View File

@ -45,7 +45,7 @@ static bool load_bytes(RBinFile *bf, void **bin_obj, const ut8 *buf, ut64 sz, ut
static bool load(RBinFile *bf) {
ut64 sz;
const ut8 *bytes = r_buf_buffer (bf->buf, &sz);
const ut8 *bytes = r_buf_data (bf->buf, &sz);
return check_bytes (bytes, sz);
}

View File

@ -29,7 +29,7 @@ static int check_buffer(RBuffer *b) {
}
static bool check_bytes(const ut8 *buf, ut64 len) {
RBuffer *b = r_buf_new_with_pointers (buf, len);
RBuffer *b = r_buf_new_with_pointers (buf, len, false);
if (b) {
int res = check_buffer (b);
r_buf_free (b);

View File

@ -40,7 +40,7 @@ static bool load(RBinFile *bf) {
}
ut64 sz;
const ut8 *bytes = r_buf_buffer (bf->buf, &sz);
const ut8 *bytes = r_buf_data (bf->buf, &sz);
load_bytes (bf, &bf->o->bin_obj, bytes, sz, bf->o->loadaddr, bf->sdb);
return bf->o->bin_obj? true: false;
}

View File

@ -21,7 +21,7 @@ static bool load(RBinFile *bf) {
return false;
}
r_bin_xbe_obj_t *obj = NULL;
const ut8 *bytes = r_buf_buffer (bf->buf, NULL);
const ut8 *bytes = r_buf_data (bf->buf, NULL);
bf->o->bin_obj = malloc (sizeof (r_bin_plugin_xbe));
obj = bf->o->bin_obj;
if (obj) {

View File

@ -90,7 +90,7 @@ static bool load(RBinFile *bf) {
return false;
}
ut64 sz;
const ut8 *bytes = r_buf_buffer (bf->buf, &sz);
const ut8 *bytes = r_buf_data (bf->buf, &sz);
load_bytes (bf, &bf->o->bin_obj, bytes, sz, bf->o->loadaddr, bf->sdb);
return check_bytes (bytes, sz);
}

View File

@ -35,7 +35,7 @@ static bool load(RBinFile *bf) {
return false;
}
ut64 size;
const ut8 *bytes = r_buf_buffer (bf->buf, &size);
const ut8 *bytes = r_buf_data (bf->buf, &size);
return load_bytes (bf, &bf->o->bin_obj, bytes, size, bf->o->loadaddr, bf->sdb);
}

View File

@ -472,7 +472,8 @@ static bool pdb7_parse(R_PDB *pdb) {
}
p_tmp = root_page_data;
for (i = 0; i < num_root_index_pages; i++) {
r_buf_seek (pdb->buf, root_index_pages[i] * page_size, 0);
r_buf_seek (pdb->buf, root_index_pages[i] * page_size,
R_BUF_SET);
r_buf_read (pdb->buf, p_tmp, page_size);
p_tmp = (char *) p_tmp + page_size;
}
@ -1198,7 +1199,7 @@ R_API bool init_pdb_parser(R_PDB *pdb, const char *filename) {
goto error;
}
r_buf_seek (pdb->buf, 0, 0);
r_buf_seek (pdb->buf, 0, R_BUF_SET);
if (!memcmp (signature, PDB7_SIGNATURE, PDB7_SIGNATURE_LEN)) {
pdb->pdb_parse = pdb7_parse;

View File

@ -35,7 +35,7 @@ static void stream_file_read_pages(R_STREAM_FILE *stream_file, int start_indx, i
if (page_offset < 1) {
return;
}
r_buf_seek (stream_file->buf, page_offset, 0);
r_buf_seek (stream_file->buf, page_offset, R_BUF_SET);
r_buf_read_at (stream_file->buf, page_offset,
(ut8 *)res, stream_file->page_size);
res += stream_file->page_size;

View File

@ -135,7 +135,7 @@ R_API int r_core_write_op(RCore *core, const char *arg, char op) {
goto beach;
}
} else { // use clipboard as key
const ut8 *tmp = r_buf_buffer (core->yank_buf, &len);
const ut8 *tmp = r_buf_data (core->yank_buf, &len);
str = r_mem_dup (tmp, len);
if (!str) {
goto beach;

View File

@ -684,7 +684,7 @@ static int cmd_yank(void *data, const char *input) {
if (input[1] == 'f') { // "wtf"
ut64 tmpsz;
const char *file = r_str_trim_ro (input + 2);
const ut8 *tmp = r_buf_buffer (core->yank_buf, &tmpsz);
const ut8 *tmp = r_buf_data (core->yank_buf, &tmpsz);
if (!r_file_dump (file, tmp, tmpsz, false)) {
eprintf ("Cannot dump to '%s'\n", file);
}

View File

@ -4457,7 +4457,7 @@ static void consumeBuffer(RBuffer *buf, const char *cmd, const char *errmsg) {
r_cons_printf ("%s", cmd);
}
int i;
r_buf_seek (buf, 0, 0);
r_buf_seek (buf, 0, R_BUF_SET);
for (i = 0; i < r_buf_size (buf); i++) {
r_cons_printf ("%02x", r_buf_read8 (buf));
}
@ -5019,7 +5019,7 @@ static int cmd_debug(void *data, const char *input) {
char *corefile = get_corefile_name (input + 1, core->dbg->pid);
eprintf ("Writing to file '%s'\n", corefile);
r_file_rm (corefile);
RBuffer *dst = r_buf_new_file (corefile, true);
RBuffer *dst = r_buf_new_file (corefile, O_RDWR | O_CREAT, 0644);
if (dst) {
if (!core->dbg->h->gcore (core->dbg, dst)) {
eprintf ("dg: coredump failed\n");
@ -5107,7 +5107,7 @@ static int cmd_debug(void *data, const char *input) {
r_asm_set_pc (core->assembler, core->offset);
r_reg_arena_push (core->dbg->reg);
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (b, &tmpsz);
const ut8 *tmp = r_buf_data (b, &tmpsz);
r_debug_execute (core->dbg, tmp, tmpsz, 0);
r_reg_arena_pop (core->dbg->reg);
break;

View File

@ -44,7 +44,7 @@ static void cmd_egg_option(REgg *egg, const char *key, const char *input) {
static void showBuffer(RBuffer *b) {
int i;
if (b && r_buf_size (b) > 0) {
r_buf_seek (b, 0, 0);
r_buf_seek (b, 0, R_BUF_SET);
for (i = 0; i < r_buf_size (b); i++) {
r_cons_printf ("%02x", r_buf_read8 (b));
}

View File

@ -99,7 +99,7 @@ static int __core_patch_bracket(RCore *core, const char *str, ut64 *noff) {
*noff = r_num_math (core->num, off);
}
ut64 tmpsz;
const ut8 *tmpbuf = r_buf_buffer (b, &tmpsz);
const ut8 *tmpbuf = r_buf_data (b, &tmpsz);
r_core_write_at (core, *noff, tmpbuf, tmpsz);
*noff += r_buf_size (b);
free (off);

View File

@ -1122,7 +1122,7 @@ static RDebugMap* linux_map_alloc (RDebug *dbg, ut64 addr, int size) {
r_reg_arena_push (dbg->reg);
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (buf, &tmpsz);
const ut8 *tmp = r_buf_data (buf, &tmpsz);
map_addr = r_debug_execute (dbg, tmp, tmpsz, 1);
r_reg_arena_pop (dbg->reg);
if (map_addr != (ut64)-1) {
@ -1165,7 +1165,7 @@ static int linux_map_dealloc(RDebug *dbg, ut64 addr, int size) {
if (buf) {
r_reg_arena_push (dbg->reg);
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (buf, &tmpsz);
const ut8 *tmp = r_buf_data (buf, &tmpsz);
ret = r_debug_execute (dbg, tmp, tmpsz, 1) == 0;
r_reg_arena_pop (dbg->reg);
}
@ -2014,7 +2014,7 @@ static int r_debug_native_map_protect (RDebug *dbg, ut64 addr, int size, int per
if (buf) {
r_reg_arena_push (dbg->reg);
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (buf, &tmpsz);
const ut8 *tmp = r_buf_data (buf, &tmpsz);
r_debug_execute (dbg, tmp, tmpsz, 1);
r_reg_arena_pop (dbg->reg);
return true;

View File

@ -333,7 +333,7 @@ R_API bool r_egg_assemble(REgg *egg) {
}
R_API int r_egg_compile(REgg *egg) {
r_buf_seek (egg->src, 0, 0);
r_buf_seek (egg->src, 0, R_BUF_SET);
char b;
int r = r_buf_read (egg->src, (ut8 *)&b, sizeof (b));
if (r != sizeof (b) || !egg->remit) {
@ -379,7 +379,7 @@ R_API void r_egg_append(REgg *egg, const char *src) {
/* JIT : TODO: accept arguments here */
R_API int r_egg_run(REgg *egg) {
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (egg->bin, &tmpsz);
const ut8 *tmp = r_buf_data (egg->bin, &tmpsz);
bool res = r_sys_run (tmp, tmpsz);
return res;
}
@ -476,7 +476,7 @@ R_API int r_egg_shellcode(REgg *egg, const char *name) {
return false;
}
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (b, &tmpsz);
const ut8 *tmp = r_buf_data (b, &tmpsz);
r_egg_raw (egg, tmp, tmpsz);
return true;
}
@ -527,16 +527,19 @@ R_API void r_egg_finalize(REgg *egg) {
r_list_foreach (egg->patches, iter, ep) {
if (ep->off < 0) {
ut64 sz;
const ut8 *buf = r_buf_buffer (ep->b, &sz);
const ut8 *buf = r_buf_data (ep->b, &sz);
r_egg_append_bytes (egg, buf, sz);
} else {
} else if (ep->off < r_buf_size (egg->bin)) {
ut64 sz;
const ut8 *buf = r_buf_buffer (ep->b, &sz);
const ut8 *buf = r_buf_data (ep->b, &sz);
int r = r_buf_write_at (egg->bin, ep->off, buf, sz);
if (r < sz) {
eprintf ("Cannot patch outside\n");
eprintf ("Error during patch\n");
return;
}
} else {
eprintf ("Cannot patch outside\n");
return;
}
}
}

View File

@ -224,6 +224,7 @@ typedef int (*RIOFdOpen) (RIO *io, const char *uri, int flags, int mode);
typedef bool (*RIOFdClose) (RIO *io, int fd);
typedef ut64 (*RIOFdSeek) (RIO *io, int fd, ut64 addr, int whence);
typedef ut64 (*RIOFdSize) (RIO *io, int fd);
typedef bool (*RIOFdResize) (RIO *io, int fd, ut64 newsize);
typedef ut64 (*RIOP2V) (RIO *io, ut64 pa);
typedef ut64 (*RIOV2P) (RIO *io, ut64 va);
typedef int (*RIOFdRead) (RIO *io, int fd, ut8 *buf, int len);
@ -260,6 +261,7 @@ typedef struct r_io_bind_t {
RIOFdClose fd_close;
RIOFdSeek fd_seek; //needed for esil
RIOFdSize fd_size;
RIOFdResize fd_resize;
RIOFdRead fd_read; //needed for esil
RIOFdWrite fd_write; //needed for esil
RIOFdReadAt fd_read_at;

View File

@ -8,35 +8,52 @@ extern "C" {
// TODO: choose whether the _at operations should preserve the current seek or not
#define R_BUF_CUR UT64_MAX
#define R_BUF_SET 0
#define R_BUF_CUR 1
#define R_BUF_END 2
typedef struct r_buf_t RBuffer;
typedef bool (*RBufferInit)(RBuffer *b, const void *user);
typedef bool (*RBufferFini)(RBuffer *b);
typedef int (*RBufferRead)(RBuffer *b, ut8 *buf, size_t len);
typedef int (*RBufferWrite)(RBuffer *b, const ut8 *buf, size_t len);
typedef ut64 (*RBufferGetSize)(RBuffer *b);
typedef bool (*RBufferResize)(RBuffer *b, ut64 newsize);
typedef int (*RBufferSeek)(RBuffer *b, st64 addr, int whence);
typedef ut8 *(*RBufferGetWholeBuf)(RBuffer *b, ut64 *sz);
typedef void (*RBufferFreeWholeBuf)(RBuffer *b);
typedef RList *(*RBufferNonEmptyList)(RBuffer *b);
typedef struct r_buffer_methods_t {
RBufferInit init;
RBufferFini fini;
RBufferRead read;
RBufferWrite write;
RBufferGetSize get_size;
RBufferResize resize;
RBufferSeek seek;
RBufferGetWholeBuf get_whole_buf;
RBufferFreeWholeBuf free_whole_buf;
RBufferNonEmptyList nonempty_list;
} RBufferMethods;
typedef struct r_buf_t {
ut8 *buf_priv;
ut64 length_priv;
st64 cur_priv;
// FIXME: some direct accesses to base_priv still exist unfortunately
ut64 base_priv;
RMmap *mmap_priv;
bool empty_priv;
bool ro_priv; // read-only
int fd_priv;
const RBufferMethods *methods;
void *priv;
ut8 *whole_buf;
bool readonly;
int Oxff_priv;
RList *sparse_priv;
int refctr;
// RIOBind *iob;
// forward declaration
void *iob;
ut64 offset_priv;
ut64 limit_priv;
struct r_buf_t *parent_priv;
} RBuffer;
// XXX: this should not be public
typedef struct r_buf_cache_t {
ut64 from;
ut64 to;
int size;
ut8 *data;
int written;
ut64 to;
int size;
ut8 *data;
int written;
} RBufferSparse;
/* constructors */
@ -44,48 +61,51 @@ R_API RBuffer *r_buf_new(void);
R_API RBuffer *r_buf_new_with_io(void *iob, int fd);
R_API RBuffer *r_buf_new_with_bytes(const ut8* bytes, ut64 len);
R_API RBuffer *r_buf_new_with_string(const char *msg);
R_API RBuffer *r_buf_new_with_pointers(const ut8 *bytes, ut64 len);
R_API RBuffer *r_buf_new_with_pointers(const ut8 *bytes, ut64 len, bool steal);
R_API RBuffer *r_buf_new_file(const char *file, int perm, int mode);
R_API RBuffer *r_buf_new_with_buf(RBuffer *b);
R_API RBuffer *r_buf_new_with_bufref(RBuffer *b);
R_API RBuffer *r_buf_new_file(const char *file, bool newFile);
R_API RBuffer *r_buf_new_slurp(const char *file);
R_API RBuffer *r_buf_new_empty (ut64 len);
R_API RBuffer *r_buf_mmap(const char *file, int flags);
R_API RBuffer *r_buf_new_sparse(ut8 Oxff);
R_API RBuffer *r_buf_new_slice(RBuffer *b, ut64 offset, ut64 size);
R_API bool r_buf_dump (RBuffer *buf, const char *file);
R_API RBuffer *r_buf_ref(RBuffer *b);
R_API RBuffer *r_buf_new_empty(ut64 len);
R_API RBuffer *r_buf_new_mmap(const char *file, int flags);
R_API RBuffer *r_buf_new_sparse(ut8 Oxff);
/* methods */
R_API bool r_buf_set_bits(RBuffer *b, ut64 at, const ut8* buf, int bitoff, int count);
R_API int r_buf_set_bytes(RBuffer *b, const ut8 *buf, ut64 length);
R_API int r_buf_set_bytes_steal(RBuffer *b, const ut8 *buf, ut64 length);
R_API bool r_buf_dump(RBuffer *buf, const char *file);
R_API bool r_buf_set_bytes(RBuffer *b, const ut8 *buf, ut64 length);
R_API int r_buf_append_string(RBuffer *b, const char *str);
R_API bool r_buf_append_buf(RBuffer *b, RBuffer *a);
R_API bool r_buf_append_buf_slice(RBuffer *b, RBuffer *a, ut64 offset, ut64 size);
R_API bool r_buf_append_bytes(RBuffer *b, const ut8 *buf, int length);
R_API bool r_buf_append_nbytes(RBuffer *b, int length);
R_API bool r_buf_append_bytes(RBuffer *b, const ut8 *buf, size_t length);
R_API bool r_buf_append_nbytes(RBuffer *b, size_t length);
R_API bool r_buf_append_ut16(RBuffer *b, ut16 n);
R_API bool r_buf_append_buf_slice(RBuffer *b, RBuffer *a, ut64 offset, int size);
R_API bool r_buf_append_ut32(RBuffer *b, ut32 n);
R_API bool r_buf_append_ut64(RBuffer *b, ut64 n);
R_API bool r_buf_append_ut16(RBuffer *b, ut16 n);
R_API bool r_buf_prepend_bytes(RBuffer *b, const ut8 *buf, int length);
R_API bool r_buf_prepend_bytes(RBuffer *b, const ut8 *buf, size_t length);
R_API int r_buf_insert_bytes(RBuffer *b, ut64 addr, const ut8 *buf, size_t length);
R_API char *r_buf_to_string(RBuffer *b);
R_API char *r_buf_get_string(RBuffer *b, ut64 addr);
#define r_buf_read(a,b,c) r_buf_read_at(a,R_BUF_CUR,b,c)
#define r_buf_write(a,b,c) r_buf_write_at(a,R_BUF_CUR,b,c)
#define r_buf_read8(b) r_buf_read8_at(b,R_BUF_CUR)
R_API char *r_buf_get_string (RBuffer *b, ut64 addr);
R_API int r_buf_read(RBuffer *b, ut8 *buf, size_t len);
R_API ut8 r_buf_read8(RBuffer *b);
R_API int r_buf_fread(RBuffer *b, ut8 *buf, const char *fmt, int n);
R_API int r_buf_read_at(RBuffer *b, ut64 addr, ut8 *buf, int len);
R_API ut8 r_buf_read8_at(RBuffer *b, ut64 addr);
R_API ut64 r_buf_tell(RBuffer *b);
R_API int r_buf_seek(RBuffer *b, st64 addr, int whence);
R_API int r_buf_fread_at(RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int n);
R_API int r_buf_write(RBuffer *b, const ut8 *buf, size_t len);
R_API int r_buf_fwrite(RBuffer *b, const ut8 *buf, const char *fmt, int n);
R_API int r_buf_write_at(RBuffer *b, ut64 addr, const ut8 *buf, int len);
R_API int r_buf_fwrite_at(RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int n);
R_API void r_buf_free(RBuffer *b);
R_API bool r_buf_fini(RBuffer *b);
R_API char *r_buf_free_to_string(RBuffer *b);
R_API const ut8 *r_buf_buffer(RBuffer *b, ut64 *size);
R_API int r_buf_fwrite_at(RBuffer *b, ut64 addr, const ut8 *buf, const char *fmt, int n);
// WARNING: this function should be used with care because it may allocate the
// entire buffer in memory. Consider using the r_buf_read* APIs instead and read
// only the chunks you need.
R_API const ut8 *r_buf_data(RBuffer *b, ut64 *size);
R_API ut64 r_buf_size(RBuffer *b);
R_API bool r_buf_resize(RBuffer *b, ut64 newsize);
R_API RBuffer *r_buf_ref(RBuffer *b);
R_API void r_buf_free(RBuffer *b);
R_API bool r_buf_fini(RBuffer *b);
R_API RList *r_buf_nonempty_list(RBuffer *b);
static inline ut16 r_buf_read_be16(RBuffer *b) {
@ -182,12 +202,12 @@ R_API int r_buf_uleb128(RBuffer *b, ut64 *v);
R_API int r_buf_sleb128(RBuffer *b, st64 *v);
static inline int r_buf_uleb128_at(RBuffer *b, ut64 addr, ut64 *v) {
r_buf_seek (b, addr, 0);
r_buf_seek (b, addr, R_BUF_SET);
return r_buf_uleb128 (b, v);
}
static inline int r_buf_sleb128_at(RBuffer *b, ut64 addr, st64 *v) {
r_buf_seek (b, addr, 0);
return r_buf_sleb128(b, v);
r_buf_seek (b, addr, R_BUF_SET);
return r_buf_sleb128 (b, v);
}
#ifdef __cplusplus

View File

@ -44,6 +44,7 @@ R_API char *r_file_tmpdir(void);
R_API char *r_file_readlink(const char *path);
R_API bool r_file_copy (const char *src, const char *dst);
R_API RList* r_file_globsearch (const char *globbed_path, int maxdepth);
R_API RMmap *r_file_mmap_arch (RMmap *map, const char *filename, int fd);
#ifdef __cplusplus
}

View File

@ -11,6 +11,7 @@ typedef struct r_mmap_t {
int len;
int fd;
int rw;
char *filename;
#if __WINDOWS__
HANDLE fh;
HANDLE fm;
@ -54,6 +55,7 @@ R_API const ut8 *r_mem_mem_aligned(const ut8 *haystack, int hlen, const ut8 *nee
R_API int r_mem_count(const ut8 **addr);
R_API bool r_mem_is_printable (const ut8 *a, int la);
R_API bool r_mem_is_zero(const ut8 *b, int l);
R_API void *r_mem_mmap_resize(RMmap *m, ut64 newsize);
#ifdef __cplusplus
}

View File

@ -27,6 +27,7 @@ R_API HANDLE r_sandbox_opendir(const char *path, WIN32_FIND_DATAW *entry);
#else
R_API DIR* r_sandbox_opendir(const char *path);
#endif
R_API int r_sandbox_truncate(int fd, ut64 length);
R_API int r_sandbox_lseek(int fd, ut64 addr, int mode);
R_API int r_sandbox_close(int fd);
R_API int r_sandbox_read(int fd, ut8 *buf, int len);

View File

@ -125,7 +125,7 @@ R_API RIODesc *r_io_open_buffer(RIO *io, RBuffer *b, int perm, int mode) {
char *uri = r_str_newf ("malloc://%d", bufSize);
RIODesc *desc = r_io_open_nomap (io, uri, perm, mode);
if (desc) {
const ut8 *tmp = r_buf_buffer (b, &bufSize);
const ut8 *tmp = r_buf_data (b, &bufSize);
r_io_desc_write (desc, tmp, bufSize);
}
return desc;
@ -513,6 +513,7 @@ R_API void r_io_bind(RIO *io, RIOBind *bnd) {
bnd->fd_close = r_io_fd_close;
bnd->fd_seek = r_io_fd_seek;
bnd->fd_size = r_io_fd_size;
bnd->fd_resize = r_io_fd_resize;
bnd->fd_read = r_io_fd_read;
bnd->fd_write = r_io_fd_write;
bnd->fd_read_at = r_io_fd_read_at;

View File

@ -48,17 +48,17 @@ static ut64 r_io_ar_lseek(RIO *io, RIODesc *fd, ut64 offset, int whence) {
case SEEK_SET:
seek_val = (r_buf_size (b) < offset)? r_buf_size (b) : offset;
io->off = seek_val;
r_buf_seek (b, b->base_priv + seek_val, 0);
r_buf_seek (b, seek_val, R_BUF_SET);
return seek_val;
case SEEK_CUR:
seek_val = (r_buf_size (b) < offset)? r_buf_size (b) : offset;
io->off = seek_val;
r_buf_seek (b, b->base_priv + seek_val, 0);
r_buf_seek (b, seek_val, R_BUF_SET);
return seek_val;
case SEEK_END:
seek_val = r_buf_size (b);
io->off = seek_val;
r_buf_seek (b, b->base_priv + seek_val, 0);
r_buf_seek (b, seek_val, R_BUF_SET);
return seek_val;
}
return seek_val;

View File

@ -46,8 +46,6 @@ static int __io_posix_open(const char *file, int perm, int mode) {
}
static ut64 r_io_def_mmap_seek(RIO *io, RIOMMapFileObj *mmo, ut64 offset, int whence) {
ut64 seek_val = UT64_MAX;
if (!mmo) {
return UT64_MAX;
}
@ -58,21 +56,8 @@ static ut64 r_io_def_mmap_seek(RIO *io, RIOMMapFileObj *mmo, ut64 offset, int wh
return UT64_MAX;
}
seek_val = r_buf_tell (mmo->buf);
switch (whence) {
case SEEK_SET:
seek_val = R_MIN (r_buf_size (mmo->buf), offset);
break;
case SEEK_CUR:
seek_val = R_MIN (r_buf_size (mmo->buf),
(offset + r_buf_tell (mmo->buf)));
break;
case SEEK_END:
seek_val = r_buf_size (mmo->buf);
break;
}
r_buf_seek (mmo->buf, io->off = seek_val, 0);
return seek_val;
io->off = r_buf_seek (mmo->buf, offset, whence);
return io->off;
}
static int r_io_def_mmap_refresh_def_mmap_buf(RIOMMapFileObj *mmo) {
@ -99,7 +84,7 @@ static int r_io_def_mmap_refresh_def_mmap_buf(RIOMMapFileObj *mmo) {
}
return (mmo->fd != -1);
}
mmo->buf = r_buf_mmap (mmo->filename, mmo->perm);
mmo->buf = r_buf_new_mmap (mmo->filename, mmo->perm);
if (mmo->buf) {
r_io_def_mmap_seek (io, mmo, cur, SEEK_SET);
return true;
@ -237,7 +222,12 @@ static int r_io_def_mmap_read(RIO *io, RIODesc *fd, ut8 *buf, int count) {
if (r_buf_size (mmo->buf) < io->off) {
io->off = r_buf_size (mmo->buf);
}
return r_buf_read_at (mmo->buf, io->off, buf, count);
int r = r_buf_read_at (mmo->buf, io->off, buf, count);
if (r < 0) {
return r;
}
io->off += r;
return r;
}
static int r_io_def_mmap_write(RIO *io, RIODesc *fd, const ut8 *buf, int count) {
@ -323,8 +313,9 @@ static RIODesc *r_io_def_mmap_open(RIO *io, const char *file, int perm, int mode
d->name = strdup (file);
}
if (r_str_startswith (d->name, "file://")) {
free (d->name);
d->name = strdup (d->name + strlen ("file://"));
char *oldname = d->name;
d->name = strdup (oldname + strlen ("file://"));
free (oldname);
}
return d;
}

View File

@ -101,7 +101,7 @@ static void gprobe_frame_i2c(RBuffer *frame) {
r_buf_prepend_bytes (frame, header, sizeof (header));
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (frame, &tmpsz);
const ut8 *tmp = r_buf_data (frame, &tmpsz);
ut8 checksum = gprobe_checksum_i2c (tmp, tmpsz, GPROBE_I2C_ADDR);
r_buf_append_bytes (frame, &checksum, 1);
@ -148,7 +148,7 @@ static int gprobe_get_reply_i2c(struct gport *port, ut8 cmd, RBuffer *reply) {
static int gprobe_send_request_i2c(struct gport *port, RBuffer *request) {
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (request, &tmpsz);
const ut8 *tmp = r_buf_data (request, &tmpsz);
if (write (port->fd, tmp, tmpsz) != r_buf_size (request)) {
return -1;
}
@ -659,7 +659,7 @@ static ut8 gprobe_checksum (const ut8 *p, unsigned int size) {
static void gprobe_frame_sp(RBuffer *frame) {
ut64 size;
const ut8 *tmp = r_buf_buffer (frame, &size);
const ut8 *tmp = r_buf_data (frame, &size);
size += 2;
ut8 checksum;
@ -707,7 +707,7 @@ static int gprobe_send_request_sp(struct gport *port, RBuffer *request) {
sp_flush (port);
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (request, &tmpsz);
const ut8 *tmp = r_buf_data (request, &tmpsz);
if (sp_blocking_write (port, tmp, tmpsz, 100) != tmpsz) {
return -1;
}
@ -1009,7 +1009,7 @@ static int gprobe_getinformation (struct gport *port) {
}
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (reply, &tmpsz);
const ut8 *tmp = r_buf_data (reply, &tmpsz);
r_print_hexdump (NULL, 0, tmp, tmpsz, 16, 1, 1);
r_buf_free (request);

View File

@ -20,15 +20,15 @@ static ut64 r_io_mmap_seek(RIO *io, RIOMMapFileObj *mmo, ut64 offset, int whence
switch (whence) {
case SEEK_SET:
seek_val = (r_buf_size (mmo->buf) < offset)? r_buf_size (mmo->buf): offset;
r_buf_seek (mmo->buf, io->off = seek_val, 0);
r_buf_seek (mmo->buf, io->off = seek_val, R_BUF_SET);
return seek_val;
case SEEK_CUR:
seek_val = (r_buf_size (mmo->buf) < (offset + r_buf_tell (mmo->buf)))? r_buf_size (mmo->buf): offset + r_buf_tell (mmo->buf);
r_buf_seek (mmo->buf, io->off = seek_val, 0);
r_buf_seek (mmo->buf, io->off = seek_val, R_BUF_SET);
return seek_val;
case SEEK_END:
seek_val = r_buf_size (mmo->buf);
r_buf_seek (mmo->buf, io->off = seek_val, 0);
r_buf_seek (mmo->buf, io->off = seek_val, R_BUF_SET);
return seek_val;
}
return seek_val;
@ -41,7 +41,7 @@ static bool r_io_mmap_refresh_buf(RIOMMapFileObj *mmo) {
r_buf_free (mmo->buf);
mmo->buf = NULL;
}
mmo->buf = r_buf_mmap (mmo->filename, mmo->flags);
mmo->buf = r_buf_new_mmap (mmo->filename, mmo->flags);
if (mmo->buf) {
r_io_mmap_seek (io, mmo, cur, SEEK_SET);
}

View File

@ -197,7 +197,7 @@ int r_io_zip_flush_file(RIOZipFileObj *zfo) {
}
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (zfo->b, &tmpsz);
const ut8 *tmp = r_buf_data (zfo->b, &tmpsz);
struct zip_source *s = zip_source_buffer (zipArch, tmp, tmpsz, 0);
if (s && zfo->entry != -1) {
if (zip_replace(zipArch, zfo->entry, s) == 0) {
@ -531,17 +531,17 @@ static ut64 r_io_zip_lseek(RIO *io, RIODesc *fd, ut64 offset, int whence) {
case SEEK_SET:
seek_val = (r_buf_size (zfo->b) < offset)? r_buf_size (zfo->b): offset;
io->off = seek_val;
r_buf_seek (zfo->b, seek_val, 0);
r_buf_seek (zfo->b, seek_val, R_BUF_SET);
return seek_val;
case SEEK_CUR:
seek_val = (r_buf_size (zfo->b) < (offset + r_buf_tell (zfo->b)))? r_buf_size (zfo->b): offset + r_buf_tell (zfo->b);
io->off = seek_val;
r_buf_seek (zfo->b, seek_val, 0);
r_buf_seek (zfo->b, seek_val, R_BUF_SET);
return seek_val;
case SEEK_END:
seek_val = r_buf_size (zfo->b);
io->off = seek_val;
r_buf_seek (zfo->b, seek_val, 0);
r_buf_seek (zfo->b, seek_val, R_BUF_SET);
return seek_val;
}
return seek_val;

View File

@ -908,7 +908,7 @@ R_API int r_main_rabin2(int argc, char **argv) {
b = r_bin_create (bin, create, code, codelen, data, datalen, &opts);
if (b) {
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (b, &tmpsz);
const ut8 *tmp = r_buf_data (b, &tmpsz);
if (r_file_dump (file, tmp, tmpsz, 0)) {
eprintf ("Dumped %" PFMT64d " bytes in '%s'\n",
tmpsz, file);

View File

@ -73,7 +73,7 @@ static int create(const char *format, const char *arch, int bits, const ut8 *cod
b = r_bin_create (bin, format, code, codelen, NULL, 0, &opts);
if (b) {
ut64 blen;
const ut8 *tmp = r_buf_buffer (b, &blen);
const ut8 *tmp = r_buf_data (b, &blen);
if (write (1, tmp, blen) != blen) {
eprintf ("Failed to write buffer\n");
}
@ -527,7 +527,7 @@ R_API int r_main_ragg2(int argc, char **argv) {
b = r_egg_get_bin (egg);
if (show_raw) {
ut64 blen;
const ut8 *tmp = r_buf_buffer (b, &blen);
const ut8 *tmp = r_buf_data (b, &blen);
if (write (1, tmp, blen) != blen) {
eprintf ("Failed to write buffer\n");
goto fail;
@ -539,7 +539,7 @@ R_API int r_main_ragg2(int argc, char **argv) {
}
RPrint *p = r_print_new ();
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (b, &tmpsz);
const ut8 *tmp = r_buf_data (b, &tmpsz);
switch (*format) {
case 'c':
r_print_code (p, 0, tmp, tmpsz, 'c');
@ -555,7 +555,7 @@ R_API int r_main_ragg2(int argc, char **argv) {
}
printf ("\"\n");
} else if (show_hex) {
r_buf_seek (b, 0, 0);
r_buf_seek (b, 0, R_BUF_SET);
for (i = 0; i < tmpsz; i++) {
printf ("%02x", tmp[i]);
}

File diff suppressed because it is too large Load Diff

139
libr/util/buf_bytes.c Normal file
View File

@ -0,0 +1,139 @@
#include <r_util.h>
struct buf_bytes_user {
const ut8 *data;
const ut8 *data_steal;
ut64 length;
bool steal;
};
struct buf_bytes_priv {
ut8 *buf;
ut64 length;
ut64 offset;
bool is_bufowner;
};
static inline struct buf_bytes_priv *get_priv_bytes(RBuffer *b) {
struct buf_bytes_priv *priv = (struct buf_bytes_priv *)b->priv;
r_warn_if_fail (priv);
return priv;
}
static bool buf_bytes_init(RBuffer *b, const void *user) {
const struct buf_bytes_user *u = (const struct buf_bytes_user *)user;
struct buf_bytes_priv *priv = R_NEW0 (struct buf_bytes_priv);
if (!priv) {
return false;
}
priv->offset = 0;
priv->length = u->length;
if (u->data_steal) {
priv->buf = (ut8 *)u->data_steal;
priv->is_bufowner = u->steal;
} else {
priv->buf = malloc (priv->length);
if (!priv->buf) {
free (priv);
return NULL;
}
if (priv->length) {
memmove (priv->buf, u->data, priv->length);
}
priv->is_bufowner = true;
}
b->priv = priv;
return true;
}
static bool buf_bytes_fini(RBuffer *b) {
struct buf_bytes_priv *priv = get_priv_bytes (b);
if (priv->is_bufowner) {
free (priv->buf);
}
R_FREE (b->priv);
return true;
}
static bool buf_bytes_resize(RBuffer *b, ut64 newsize) {
struct buf_bytes_priv *priv = get_priv_bytes (b);
if (newsize > priv->length) {
ut8 *t = realloc (priv->buf, newsize);
if (!t) {
return false;
}
priv->buf = t;
memset (priv->buf + priv->length, b->Oxff_priv, newsize - priv->length);
}
priv->length = newsize;
return true;
}
static int buf_bytes_read(RBuffer *b, ut8 *buf, size_t len) {
struct buf_bytes_priv *priv = get_priv_bytes (b);
size_t real_len = priv->length < priv->offset? 0: R_MIN (priv->length - priv->offset, len);
memmove (buf, priv->buf + priv->offset, real_len);
priv->offset += real_len;
return real_len;
}
static int buf_bytes_write(RBuffer *b, const ut8 *buf, size_t len) {
struct buf_bytes_priv *priv = get_priv_bytes (b);
if (priv->offset > priv->length || priv->offset + len >= priv->length) {
bool r = r_buf_resize (b, priv->offset + len);
if (!r) {
return -1;
}
}
memmove (priv->buf + priv->offset, buf, len);
priv->offset += len;
return len;
}
static ut64 buf_bytes_get_size(RBuffer *b) {
struct buf_bytes_priv *priv = get_priv_bytes (b);
return priv->length;
}
static int buf_bytes_seek(RBuffer *b, st64 addr, int whence) {
struct buf_bytes_priv *priv = get_priv_bytes (b);
if (addr < 0 && (-addr) > (st64)priv->offset) {
return -1;
}
switch (whence) {
case R_BUF_CUR:
priv->offset += addr;
break;
case R_BUF_SET:
priv->offset = addr;
break;
case R_BUF_END:
priv->offset = priv->length + addr;
break;
default:
r_warn_if_reached ();
return -1;
}
return priv->offset;
}
static ut8 *buf_bytes_get_whole_buf(RBuffer *b, ut64 *sz) {
struct buf_bytes_priv *priv = get_priv_bytes (b);
if (sz) {
*sz = priv->length;
}
return priv->buf;
}
static const RBufferMethods buffer_bytes_methods = {
.init = buf_bytes_init,
.fini = buf_bytes_fini,
.read = buf_bytes_read,
.write = buf_bytes_write,
.get_size = buf_bytes_get_size,
.resize = buf_bytes_resize,
.seek = buf_bytes_seek,
.get_whole_buf = buf_bytes_get_whole_buf
};

85
libr/util/buf_file.c Normal file
View File

@ -0,0 +1,85 @@
#include <r_types.h>
#include <r_util.h>
struct buf_file_user {
const char *file;
int perm;
int mode;
};
struct buf_file_priv {
int fd;
ut8 tmp[8];
};
static inline struct buf_file_priv *get_priv_file(RBuffer *b) {
struct buf_file_priv *priv = (struct buf_file_priv *)b->priv;
r_warn_if_fail (priv);
return priv;
}
static bool buf_file_init(RBuffer *b, const void *user) {
const struct buf_file_user *u = (const struct buf_file_user *)user;
struct buf_file_priv *priv = R_NEW0 (struct buf_file_priv);
if (!priv) {
return false;
}
int fd = r_sandbox_open (u->file, u->perm, u->mode);
if (fd == -1) {
free (priv);
return false;
}
priv->fd = fd;
b->priv = priv;
return true;
}
static bool buf_file_fini(RBuffer *b) {
struct buf_file_priv *priv = get_priv_file (b);
r_sandbox_close (priv->fd);
R_FREE (b->priv);
return true;
}
static ut64 buf_file_get_size(RBuffer *b) {
struct buf_file_priv *priv = get_priv_file (b);
int pos = r_sandbox_lseek (priv->fd, 0, SEEK_CUR);
int res = r_sandbox_lseek (priv->fd, 0, SEEK_END);
r_sandbox_lseek (priv->fd, pos, SEEK_SET);
return (ut64)res;
}
static int buf_file_read(RBuffer *b, ut8 *buf, size_t len) {
struct buf_file_priv *priv = get_priv_file (b);
return r_sandbox_read (priv->fd, buf, len);
}
static int buf_file_write(RBuffer *b, const ut8 *buf, size_t len) {
struct buf_file_priv *priv = get_priv_file (b);
return r_sandbox_write (priv->fd, buf, len);
}
static int buf_file_seek(RBuffer *b, st64 addr, int whence) {
struct buf_file_priv *priv = get_priv_file (b);
switch (whence) {
case R_BUF_CUR: whence = SEEK_CUR; break;
case R_BUF_SET: whence = SEEK_SET; break;
case R_BUF_END: whence = SEEK_END; break;
}
return r_sandbox_lseek (priv->fd, addr, whence);
}
static bool buf_file_resize(RBuffer *b, ut64 newsize) {
struct buf_file_priv *priv = get_priv_file (b);
return r_sandbox_truncate (priv->fd, newsize) >= 0;
}
static const RBufferMethods buffer_file_methods = {
.init = buf_file_init,
.fini = buf_file_fini,
.read = buf_file_read,
.write = buf_file_write,
.get_size = buf_file_get_size,
.resize = buf_file_resize,
.seek = buf_file_seek,
};

87
libr/util/buf_io.c Normal file
View File

@ -0,0 +1,87 @@
#include <r_util.h>
#include <r_io.h>
struct buf_io_user {
RIOBind *iob;
int fd;
};
struct buf_io_priv {
RIOBind *iob;
int fd;
};
static inline struct buf_io_priv *get_priv_io(RBuffer *b) {
struct buf_io_priv *priv = (struct buf_io_priv *)b->priv;
r_warn_if_fail (priv);
return priv;
}
static bool buf_io_init(RBuffer *b, const void *user) {
const struct buf_io_user *u = (const struct buf_io_user *)user;
struct buf_io_priv *priv = R_NEW0 (struct buf_io_priv);
if (!priv) {
return false;
}
priv->iob = u->iob;
priv->fd = u->fd;
b->priv = priv;
return true;
}
static bool buf_io_fini(RBuffer *b) {
struct buf_io_priv *priv = get_priv_io (b);
priv->iob->close (priv->iob->io, priv->fd);
R_FREE (b->priv);
return true;
}
static int buf_io_seek(RBuffer *b, st64 addr, int whence) {
struct buf_io_priv *priv = get_priv_io (b);
int io_whence;
switch (whence) {
default:
r_warn_if_reached ();
case R_BUF_SET:
io_whence = R_IO_SEEK_SET;
break;
case R_BUF_END:
io_whence = R_IO_SEEK_END;
break;
case R_BUF_CUR:
io_whence = R_IO_SEEK_CUR;
break;
}
return priv->iob->fd_seek (priv->iob->io, priv->fd, addr, io_whence);
}
static ut64 buf_io_get_size(RBuffer *b) {
struct buf_io_priv *priv = get_priv_io (b);
return priv->iob->fd_size (priv->iob->io, priv->fd);
}
static bool buf_io_resize(RBuffer *b, ut64 newsize) {
struct buf_io_priv *priv = get_priv_io (b);
return priv->iob->fd_resize (priv->iob->io, priv->fd, newsize);
}
static int buf_io_read(RBuffer *b, ut8 *buf, size_t len) {
struct buf_io_priv *priv = get_priv_io (b);
return priv->iob->fd_read (priv->iob->io, priv->fd, buf, len);
}
static int buf_io_write(RBuffer *b, const ut8 *buf, size_t len) {
struct buf_io_priv *priv = get_priv_io (b);
return priv->iob->fd_write (priv->iob->io, priv->fd, buf, len);
}
static const RBufferMethods buffer_io_methods = {
.init = buf_io_init,
.fini = buf_io_fini,
.read = buf_io_read,
.write = buf_io_write,
.get_size = buf_io_get_size,
.resize = buf_io_resize,
.seek = buf_io_seek,
};

68
libr/util/buf_mmap.c Normal file
View File

@ -0,0 +1,68 @@
#include <r_util.h>
struct buf_mmap_user {
const char *filename;
int perm;
};
// "subclass"" of buf_bytes_priv
struct buf_mmap_priv {
// NOTE: this needs to be first, so that bytes operations will work without changes
struct buf_bytes_priv bytes_priv;
RMmap *mmap;
};
static inline struct buf_mmap_priv *get_priv_mmap(RBuffer *b) {
struct buf_mmap_priv *priv = (struct buf_mmap_priv *)b->priv;
r_warn_if_fail (priv);
return priv;
}
static bool buf_mmap_init(RBuffer *b, const void *user) {
const struct buf_mmap_user *u = (const struct buf_mmap_user *)user;
struct buf_mmap_priv *priv = R_NEW0 (struct buf_mmap_priv);
if (!priv) {
return false;
}
priv->mmap = r_file_mmap (u->filename, u->perm & R_PERM_W, 0);
if (!priv->mmap) {
free (priv);
return false;
}
priv->bytes_priv.buf = priv->mmap->buf;
priv->bytes_priv.length = priv->mmap->len;
priv->bytes_priv.offset = 0;
b->priv = priv;
return true;
}
static bool buf_mmap_fini(RBuffer *b) {
struct buf_mmap_priv *priv = get_priv_mmap (b);
r_file_mmap_free (priv->mmap);
R_FREE (b->priv);
return true;
}
static bool buf_mmap_resize(RBuffer *b, ut64 newsize) {
struct buf_mmap_priv *priv = get_priv_mmap (b);
if (newsize > priv->mmap->len) {
ut8 *t = r_mem_mmap_resize (priv->mmap, newsize);
if (!t) {
return false;
}
priv->bytes_priv.buf = t;
}
priv->bytes_priv.length = newsize;
return true;
}
static const RBufferMethods buffer_mmap_methods = {
.init = buf_mmap_init,
.fini = buf_mmap_fini,
.read = buf_bytes_read,
.write = buf_bytes_write,
.get_size = buf_bytes_get_size,
.resize = buf_mmap_resize,
.seek = buf_bytes_seek,
};

98
libr/util/buf_ref.c Normal file
View File

@ -0,0 +1,98 @@
#include <r_util.h>
struct buf_ref_user {
RBuffer *parent;
ut64 offset;
ut64 size;
};
struct buf_ref_priv {
RBuffer *parent;
ut64 cur;
ut64 base;
ut64 size;
};
static inline struct buf_ref_priv *get_priv_ref(RBuffer *b) {
struct buf_ref_priv *priv = (struct buf_ref_priv *)b->priv;
r_warn_if_fail (priv);
return priv;
}
static bool buf_ref_init(RBuffer *b, const void *user) {
const struct buf_ref_user *u = (const struct buf_ref_user *)user;
struct buf_ref_priv *priv = R_NEW0 (struct buf_ref_priv);
if (!priv) {
return false;
}
// NOTE: we only support readonly ref-buffers for now. Supporting
// read-write would mean to choose how we want to handle writing to the
// referencer. Copy-on-write? Write to the buffer underneath?
b->readonly = true;
priv->parent = r_buf_ref (u->parent);
priv->base = u->offset;
priv->size = u->size;
b->priv = priv;
return true;
}
static bool buf_ref_fini(RBuffer *b) {
struct buf_ref_priv *priv = get_priv_ref (b);
r_buf_free (priv->parent);
R_FREE (b->priv);
return true;
}
static bool buf_ref_resize(RBuffer *b, ut64 newsize) {
struct buf_ref_priv *priv = get_priv_ref (b);
priv->size = newsize;
return true;
}
static int buf_ref_read(RBuffer *b, ut8 *buf, size_t len) {
struct buf_ref_priv *priv = get_priv_ref (b);
if (priv->size < priv->cur) {
return -1;
}
len = R_MIN (len, priv->size - priv->cur);
int r = r_buf_read_at (priv->parent, priv->base + priv->cur, buf, len);
if (r < 0) {
return r;
}
priv->cur += r;
return r;
}
static ut64 buf_ref_get_size(RBuffer *b) {
struct buf_ref_priv *priv = get_priv_ref (b);
return priv->size;
}
static int buf_ref_seek(RBuffer *b, st64 addr, int whence) {
struct buf_ref_priv *priv = get_priv_ref (b);
switch (whence) {
case R_BUF_CUR:
priv->cur += addr;
break;
case R_BUF_SET:
priv->cur = addr;
break;
case R_BUF_END:
priv->cur = priv->size + addr;
break;
default:
r_warn_if_reached ();
return -1;
}
return priv->cur;
}
static const RBufferMethods buffer_ref_methods = {
.init = buf_ref_init,
.fini = buf_ref_fini,
.read = buf_ref_read,
.get_size = buf_ref_get_size,
.resize = buf_ref_resize,
.seek = buf_ref_seek,
};

219
libr/util/buf_sparse.c Normal file
View File

@ -0,0 +1,219 @@
#include <r_util.h>
struct buf_sparse_priv {
RList *sparse;
ut64 offset;
};
static void buffer_sparse_free(void *a) {
RBufferSparse *s = (RBufferSparse *)a;
free (s->data);
free (s);
}
static bool sparse_limits(RList *l, ut64 *max) {
bool set = false;
RBufferSparse *s;
RListIter *iter;
r_list_foreach (l, iter, s) {
if (set) {
if (max && s->to > *max) {
*max = s->to;
}
} else {
set = true;
if (max) {
*max = s->to;
}
}
}
return set;
}
static RBufferSparse *sparse_append(RList *l, ut64 addr, const ut8 *data, int len) {
if (l && data && len > 0) {
RBufferSparse *s = R_NEW0 (RBufferSparse);
if (s) {
s->data = calloc (1, len);
if (s->data) {
s->from = addr;
s->to = addr + len;
s->size = len;
memcpy (s->data, data, len);
return r_list_append (l, s)? s: NULL;
}
free (s);
}
}
return NULL;
}
//ret -1 if failed; # of bytes copied if success
static int sparse_write(RList *l, ut64 addr, const ut8 *data, int len) {
RBufferSparse *s;
RListIter *iter;
int olen = len;
r_list_foreach (l, iter, s) {
if (addr >= s->from && addr < s->to) {
int delta = addr - s->from;
int reallen = s->size - delta >= len? len: s->size - delta;
memcpy (s->data + delta, data, reallen);
data += reallen;
len -= reallen;
addr += reallen;
}
if (len == 0) {
return olen;
}
}
if (len > 0 && !sparse_append (l, addr, data, len)) {
return -1;
}
return olen;
}
static inline struct buf_sparse_priv *get_priv_sparse(RBuffer *b) {
struct buf_sparse_priv *priv = (struct buf_sparse_priv *)b->priv;
r_warn_if_fail (priv);
return priv;
}
static bool buf_sparse_init(RBuffer *b, const void *user) {
struct buf_sparse_priv *priv = R_NEW0 (struct buf_sparse_priv);
if (!priv) {
return false;
}
priv->sparse = r_list_newf (buffer_sparse_free);
priv->offset = 0;
b->priv = priv;
return true;
}
static bool buf_sparse_fini(RBuffer *b) {
struct buf_sparse_priv *priv = get_priv_sparse (b);
r_list_free (priv->sparse);
R_FREE (b->priv);
return true;
}
static bool buf_sparse_resize(RBuffer *b, ut64 newsize) {
struct buf_sparse_priv *priv = get_priv_sparse (b);
RListIter *iter, *tmp;
RBufferSparse *s;
r_list_foreach_safe (priv->sparse, iter, tmp, s) {
if (s->from >= newsize) {
r_list_delete (priv->sparse, iter);
} else if (s->to >= newsize) {
RBufferSparse *ns = R_NEW (RBufferSparse);
ns->from = s->from;
ns->to = newsize;
ns->size = ns->to - ns->from;
ut8 *tmp = realloc (s->data, s->size);
if (!tmp) {
free (ns);
return false;
}
// otherwise it will be double-freed by r_list_delete
s->data = NULL;
ns->data = tmp;
ns->written = s->written;
r_list_append (priv->sparse, ns);
r_list_delete (priv->sparse, iter);
}
}
ut64 max;
max = sparse_limits (priv->sparse, &max)? max: 0;
if (max < newsize) {
return !!sparse_write (priv->sparse, newsize - 1, (ut8 *)&b->Oxff_priv, 1);
}
return true;
}
static ut64 buf_sparse_size(RBuffer *b) {
struct buf_sparse_priv *priv = get_priv_sparse (b);
ut64 max;
return sparse_limits (priv->sparse, &max)? max: 0;
}
static int buf_sparse_read(RBuffer *b, ut8 *buf, size_t len) {
struct buf_sparse_priv *priv = get_priv_sparse (b);
RBufferSparse *c;
RListIter *iter;
ut64 max = 0;
memset (buf, b->Oxff_priv, len);
r_list_foreach (priv->sparse, iter, c) {
if (max < c->to) {
max = c->to;
}
if (priv->offset < c->to && c->from < priv->offset + len) {
if (priv->offset < c->from) {
int l = R_MIN (priv->offset + len - c->from, c->size);
memcpy (buf + c->from - priv->offset, c->data, l);
} else {
int l = R_MIN (c->to - priv->offset, len);
memcpy (buf, c->data + priv->offset - c->from, l);
}
}
}
if (priv->offset > max) {
return -1;
}
int r = R_MIN (max - priv->offset, len);
priv->offset += r;
return r;
}
static int buf_sparse_write(RBuffer *b, const ut8 *buf, size_t len) {
struct buf_sparse_priv *priv = get_priv_sparse (b);
int r = sparse_write (priv->sparse, priv->offset, buf, len);
priv->offset += r;
return r;
}
static int buf_sparse_seek(RBuffer *b, st64 addr, int whence) {
struct buf_sparse_priv *priv = get_priv_sparse (b);
ut64 max;
if (addr < 0 && (-addr) > (st64)priv->offset) {
return -1;
}
switch (whence) {
case R_BUF_CUR:
priv->offset += addr;
break;
case R_BUF_SET:
priv->offset = addr;
break;
case R_BUF_END:
if (!sparse_limits (priv->sparse, &max)) {
max = 0;
}
priv->offset = max + addr;
break;
default:
r_warn_if_reached ();
return -1;
}
return priv->offset;
}
static RList *buf_sparse_nonempty_list(RBuffer *b) {
struct buf_sparse_priv *priv = get_priv_sparse (b);
return r_list_clone (priv->sparse);
}
static const RBufferMethods buffer_sparse_methods = {
.init = buf_sparse_init,
.fini = buf_sparse_fini,
.read = buf_sparse_read,
.write = buf_sparse_write,
.get_size = buf_sparse_size,
.resize = buf_sparse_resize,
.seek = buf_sparse_seek,
.nonempty_list = buf_sparse_nonempty_list,
};

View File

@ -858,8 +858,22 @@ static RMmap *r_file_mmap_other (RMmap *m) {
}
#endif
R_API RMmap *r_file_mmap_arch(RMmap *mmap, const char *filename, int fd) {
#if __WINDOWS__
(void)fd;
return r_file_mmap_windows (mmap, filename);
#elif __UNIX__
(void)filename;
return r_file_mmap_unix (mmap, fd);
#else
(void)filename;
(void)fd;
return r_file_mmap_other (mmap);
#endif
}
// TODO: add rwx support?
R_API RMmap *r_file_mmap (const char *file, bool rw, ut64 base) {
R_API RMmap *r_file_mmap(const char *file, bool rw, ut64 base) {
RMmap *m = NULL;
int fd = -1;
if (!rw && !r_file_exists (file)) {
@ -882,6 +896,7 @@ R_API RMmap *r_file_mmap (const char *file, bool rw, ut64 base) {
m->rw = rw;
m->fd = fd;
m->len = fd != -1? lseek (fd, (off_t)0, SEEK_END) : 0;
m->filename = strdup (file);
if (m->fd == -1) {
return m;
@ -922,6 +937,7 @@ R_API void r_file_mmap_free (RMmap *m) {
free (m);
return;
}
free (m->filename);
#if __UNIX__
munmap (m->buf, m->len);
#endif

View File

@ -341,3 +341,28 @@ R_API void r_mem_memzero(void *dst, size_t l) {
#endif
#endif
}
R_API void *r_mem_mmap_resize(RMmap *m, ut64 newsize) {
#if __WINDOWS__
if (m->fm != INVALID_HANDLE_VALUE) {
CloseHandle (m->fm);
}
if (m->fh != INVALID_HANDLE_VALUE) {
CloseHandle (m->fh);
}
if (m->buf) {
UnmapViewOfFile (m->buf);
}
#elif __UNIX__
if (munmap (m->buf, m->len) != 0) {
return NULL;
}
#endif
if (!r_sys_truncate (m->filename, newsize)) {
return NULL;
}
m->len = newsize;
r_file_mmap_arch (m, m->filename, m->fd);
return m->buf;
}

View File

@ -224,27 +224,38 @@ static char *expand_home(const char *p) {
return strdup (p);
}
R_API int r_sandbox_lseek (int fd, ut64 addr, int whence) {
R_API int r_sandbox_lseek(int fd, ut64 addr, int whence) {
if (enabled) {
return -1;
}
return lseek (fd, (off_t)addr, whence);
}
R_API int r_sandbox_read (int fd, ut8* buf, int len) {
return enabled? -1 : read (fd, buf, len);
R_API int r_sandbox_truncate(int fd, ut64 length) {
if (enabled) {
return -1;
}
#ifdef _MSC_VER
return _chsize_s (fd, length);
#else
return ftruncate (fd, (off_t)length);
#endif
}
R_API int r_sandbox_write (int fd, const ut8* buf, int len) {
return enabled? -1 : write (fd, buf, len);
R_API int r_sandbox_read(int fd, ut8 *buf, int len) {
return enabled? -1: read (fd, buf, len);
}
R_API int r_sandbox_close (int fd) {
return enabled? -1 : close (fd);
R_API int r_sandbox_write(int fd, const ut8* buf, int len) {
return enabled? -1: write (fd, buf, len);
}
R_API int r_sandbox_close(int fd) {
return enabled? -1: close (fd);
}
/* perm <-> mode */
R_API int r_sandbox_open (const char *path, int mode, int perm) {
R_API int r_sandbox_open(const char *path, int mode, int perm) {
if (!path) {
return -1;
}

View File

@ -18,7 +18,7 @@ static int index_filename = -2;
R_API RBuffer *ar_open_file(const char *arname, const char *filename) {
int r;
RList *files = NULL;
RBuffer *b = r_buf_new_file (arname, 0);
RBuffer *b = r_buf_new_file (arname, O_RDWR, 0);
if (!b) {
r_sys_perror (__FUNCTION__);
return NULL;
@ -39,7 +39,7 @@ R_API RBuffer *ar_open_file(const char *arname, const char *filename) {
ar_read_filename_table (b, buffer, files, filename);
/* If b->base is set, then we found the file root in the archive */
while (r && !b->base_priv) {
while (r) {
r = ar_read_file (b, buffer, false, files, filename);
}
@ -72,11 +72,11 @@ R_API int ar_close(RBuffer *b) {
}
R_API int ar_read_at(RBuffer *b, ut64 off, void *buf, int count) {
return r_buf_read_at (b, off + b->base_priv, buf, count);
return r_buf_read_at (b, off, buf, count);
}
R_API int ar_write_at(RBuffer *b, ut64 off, void *buf, int count) {
return r_buf_write_at (b, off + b->base_priv, buf, count);
return r_buf_write_at (b, off, buf, count);
}
int ar_read(RBuffer *b, void *dest, int len) {
@ -84,7 +84,7 @@ int ar_read(RBuffer *b, void *dest, int len) {
if (!r) {
return 0;
}
r_buf_seek (b, r, 1);
r_buf_seek (b, r, R_BUF_CUR);
return r;
}
@ -129,7 +129,7 @@ int ar_read_file(RBuffer *b, char *buffer, bool lookup, RList *files, const char
/* Fix padding issues */
if (*buffer == '\n') {
buffer[0] = buffer[1];
r_buf_seek (b, -1, 1);
r_buf_seek (b, -1, R_BUF_CUR);
ar_read (b, buffer, 2);
}
ar_read (b, buffer + 2, AR_FILENAME_LEN - 2);
@ -145,7 +145,7 @@ int ar_read_file(RBuffer *b, char *buffer, bool lookup, RList *files, const char
int dif = (int) (tmp - buffer);
dif = 31 - dif;
// Re-read the whole filename
r_buf_seek (b, -dif, 1);
r_buf_seek (b, -dif, R_BUF_CUR);
r = ar_read (b, buffer, AR_FILENAME_LEN);
if (r != AR_FILENAME_LEN) {
goto fail;
@ -193,16 +193,13 @@ int ar_read_file(RBuffer *b, char *buffer, bool lookup, RList *files, const char
/* Check filename */
if (index == index_filename || !strcmp (curfile, filename)) {
r_buf_resize(b, filesize);
// FIXME: direct access to base should be avoided (use _sparse
// when you need buffer that starts at given addr)
b->base_priv = r_buf_tell (b);
free (curfile);
return r_buf_size (b);
}
}
(void)ar_read (b, buffer, 1);
r_buf_seek (b, filesize - 1, 1);
r_buf_seek (b, filesize - 1, R_BUF_CUR);
free (curfile);
return filesize;
fail:
@ -217,12 +214,12 @@ int ar_read_filename_table(RBuffer *b, char *buffer, RList *files, const char *f
}
if (strncmp (buffer, "//", 2)) {
// What we read was not a filename table, just go back
r_buf_seek (b, -AR_FILENAME_LEN, 1);
r_buf_seek (b, -AR_FILENAME_LEN, R_BUF_CUR);
return 0;
}
/* Read table size */
r_buf_seek (b, 32, 1);
r_buf_seek (b, 32, R_BUF_CUR);
r = ar_read (b, buffer, 10);
if (r != 10) {
return 0;
@ -250,7 +247,7 @@ int ar_read_filename_table(RBuffer *b, char *buffer, RList *files, const char *f
/* End slash plus separation character ("/\n") */
len += r + 2;
/* Separation character (not always '\n') */
r_buf_seek (b, 1, 1);
r_buf_seek (b, 1, R_BUF_CUR);
index++;
}
return len;

View File

@ -3136,7 +3136,7 @@ R_API RBinJavaObj *r_bin_java_new_buf(RBuffer *buf, ut64 loadaddr, Sdb *kv) {
return NULL;
}
ut64 tmpsz;
const ut8 *tmp = r_buf_buffer (buf, &tmpsz);
const ut8 *tmp = r_buf_data (buf, &tmpsz);
if (!r_bin_java_new_bin (bin, loadaddr, kv, tmp, tmpsz)) {
return r_bin_java_free (bin);
}