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:
parent
c7cb949060
commit
66f7403245
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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*)#
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
1250
libr/util/buf.c
1250
libr/util/buf.c
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
};
|
|
@ -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,
|
||||
};
|
|
@ -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,
|
||||
};
|
|
@ -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,
|
||||
};
|
|
@ -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,
|
||||
};
|
|
@ -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,
|
||||
};
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
25
shlr/ar/ar.c
25
shlr/ar/ar.c
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue