* Major refactoring of r_io (api has changed)
- filedescriptor is only defined by r_io_set() - the rest of functions just take one argument less - there are not enought filedescriptor changes to force fd resolution all the time * Fix memory leak in r_io_open - Better error management - Fix Makefile warnings in libr/io/p * Added read_at and write_at helper functions * Random indentation fixups * Added shm.mk and malloc.mk * More useless work for r_iter
This commit is contained in:
parent
bca428f994
commit
2ca850007f
22 changed files with 207 additions and 177 deletions
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
|| search ||
|
||||
------------
|
||||
- bytepat and so should be buggy now, bugfix required
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -212,44 +211,44 @@ static int javasm_init(struct r_bin_java_t *bin)
|
|||
|
||||
/* read bytes */
|
||||
switch(c->tag) {
|
||||
case 1: // utf 8 string
|
||||
read(bin->fd, buf, 2);
|
||||
sz = R_BIN_JAVA_USHORT(buf,0); //(buf[0]<<8)|buf[1];
|
||||
bin->cp_items[i].length = sz;
|
||||
bin->cp_items[i].off += 3;
|
||||
read(bin->fd, buf, sz);
|
||||
buf[sz] = '\0';
|
||||
break;
|
||||
default:
|
||||
read(bin->fd, buf, c->len);
|
||||
case 1: // utf 8 string
|
||||
read(bin->fd, buf, 2);
|
||||
sz = R_BIN_JAVA_USHORT(buf,0); //(buf[0]<<8)|buf[1];
|
||||
bin->cp_items[i].length = sz;
|
||||
bin->cp_items[i].off += 3;
|
||||
read(bin->fd, buf, sz);
|
||||
buf[sz] = '\0';
|
||||
break;
|
||||
default:
|
||||
read(bin->fd, buf, c->len);
|
||||
}
|
||||
|
||||
memcpy(bin->cp_items[i].bytes, buf, 5);
|
||||
|
||||
/* parse value */
|
||||
switch(c->tag) {
|
||||
case 1:
|
||||
IFDBG printf("%s\n", buf);
|
||||
bin->cp_items[i].value = strdup(buf);
|
||||
break;
|
||||
case 7:
|
||||
IFDBG printf("%d\n", R_BIN_JAVA_USHORT(buf,0));
|
||||
break;
|
||||
case 8:
|
||||
IFDBG printf("string ptr %d\n", R_BIN_JAVA_USHORT(buf, 0));
|
||||
break;
|
||||
case 9:
|
||||
case 11:
|
||||
case 10: // METHOD REF
|
||||
IFDBG printf("class = %d, ", R_BIN_JAVA_USHORT(buf,0));
|
||||
IFDBG printf("name_type = %d\n", R_BIN_JAVA_USHORT(buf,2));
|
||||
break;
|
||||
case 12:
|
||||
IFDBG printf("name = %d, ", R_BIN_JAVA_USHORT(buf,0));
|
||||
IFDBG printf("descriptor = %d\n", R_BIN_JAVA_USHORT(buf,2));
|
||||
break;
|
||||
default:
|
||||
printf("%d\n", R_BIN_JAVA_UINT(buf, 40));
|
||||
case 1:
|
||||
IFDBG printf("%s\n", buf);
|
||||
bin->cp_items[i].value = strdup(buf);
|
||||
break;
|
||||
case 7:
|
||||
IFDBG printf("%d\n", R_BIN_JAVA_USHORT(buf,0));
|
||||
break;
|
||||
case 8:
|
||||
IFDBG printf("string ptr %d\n", R_BIN_JAVA_USHORT(buf, 0));
|
||||
break;
|
||||
case 9:
|
||||
case 11:
|
||||
case 10: // METHOD REF
|
||||
IFDBG printf("class = %d, ", R_BIN_JAVA_USHORT(buf,0));
|
||||
IFDBG printf("name_type = %d\n", R_BIN_JAVA_USHORT(buf,2));
|
||||
break;
|
||||
case 12:
|
||||
IFDBG printf("name = %d, ", R_BIN_JAVA_USHORT(buf,0));
|
||||
IFDBG printf("descriptor = %d\n", R_BIN_JAVA_USHORT(buf,2));
|
||||
break;
|
||||
default:
|
||||
printf("%d\n", R_BIN_JAVA_UINT(buf, 40));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -356,20 +355,17 @@ int r_bin_java_get_version(struct r_bin_java_t *bin, char *version)
|
|||
ut64 r_bin_java_get_entrypoint(struct r_bin_java_t *bin)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i=0; i < bin->methods_count; i++)
|
||||
if (!strcmp(bin->methods[i].name, "<init>"))
|
||||
for (j=0; j < bin->methods[i].attr_count; j++)
|
||||
if (bin->methods[i].attributes[j].type == R_BIN_JAVA_TYPE_CODE)
|
||||
return (ut64)bin->methods[i].attributes->info.code.code_offset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r_bin_java_get_symbols(struct r_bin_java_t *bin, struct r_bin_java_sym_t *sym)
|
||||
{
|
||||
int i, j, ctr = 0;
|
||||
|
||||
for (i=0; i < bin->methods_count; i++) {
|
||||
memcpy(sym[ctr].name, bin->methods[i].name, R_BIN_JAVA_MAXSTR);
|
||||
sym[ctr].name[R_BIN_JAVA_MAXSTR-1] = '\0';
|
||||
|
|
@ -380,26 +376,22 @@ int r_bin_java_get_symbols(struct r_bin_java_t *bin, struct r_bin_java_sym_t *sy
|
|||
ctr++;
|
||||
}
|
||||
}
|
||||
|
||||
return ctr;
|
||||
}
|
||||
|
||||
int r_bin_java_get_symbols_count(struct r_bin_java_t *bin)
|
||||
{
|
||||
int i, j, ctr = 0;
|
||||
|
||||
for (i=0; i < bin->methods_count; i++)
|
||||
for (j=0; j < bin->methods[i].attr_count; j++)
|
||||
if (bin->methods[i].attributes[j].type == R_BIN_JAVA_TYPE_CODE)
|
||||
ctr++;
|
||||
|
||||
return ctr;
|
||||
}
|
||||
|
||||
int r_bin_java_get_strings(struct r_bin_java_t *bin, struct r_bin_java_str_t *str)
|
||||
{
|
||||
int i, ctr = 0;
|
||||
|
||||
for(i=0;i<bin->cf.cp_count;i++)
|
||||
if (bin->cp_items[i].tag == 1) {
|
||||
str[ctr].offset = (ut64)bin->cp_items[i].off;
|
||||
|
|
@ -408,17 +400,14 @@ int r_bin_java_get_strings(struct r_bin_java_t *bin, struct r_bin_java_str_t *st
|
|||
memcpy(str[ctr].str, bin->cp_items[i].value, R_BIN_JAVA_MAXSTR);
|
||||
ctr++;
|
||||
}
|
||||
|
||||
return ctr;
|
||||
}
|
||||
|
||||
int r_bin_java_get_strings_count(struct r_bin_java_t *bin)
|
||||
{
|
||||
int i, ctr = 0;
|
||||
|
||||
for(i=0;i<bin->cf.cp_count;i++)
|
||||
if (bin->cp_items[i].tag == 1)
|
||||
ctr++;
|
||||
|
||||
return ctr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -685,7 +685,6 @@ int PE_(r_bin_pe_get_subsystem)(PE_(r_bin_pe_obj) *bin, char *str)
|
|||
snprintf(str, PE_NAME_LENGTH, "XBOX");
|
||||
break;
|
||||
}
|
||||
|
||||
return bin->nt_headers->optional_header.Subsystem;
|
||||
}
|
||||
|
||||
|
|
@ -736,6 +735,5 @@ int PE_(r_bin_pe_open)(PE_(r_bin_pe_obj) *bin, const char *file)
|
|||
close(bin->fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return bin->fd;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ STATIC_ASM_PLUGINS=p/x86olly.mk p/x86nasm.mk p/mips.mk p/java.mk
|
|||
STATIC_PARSE_PLUGINS=p/dummy.mk p/x86_pseudo.mk p/mreplace.mk
|
||||
STATIC_BIN_PLUGINS=p/elf.mk p/elf64.mk p/pe.mk p/pe64.mk p/java.mk p/dummy.mk
|
||||
STATIC_BP_PLUGINS=p/x86.mk
|
||||
STATIC_IO_PLUGINS=p/ptrace.mk p/dbg.mk
|
||||
STATIC_IO_PLUGINS=p/ptrace.mk p/dbg.mk p/shm.mk p/malloc.mk
|
||||
STATIC_BININFO_PLUGINS=p/addr2line.mk
|
||||
STATIC_DEBUG_PLUGINS=p/ptrace.mk
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
|
||||
static int cmd_io_system(void *data, const char *input);
|
||||
|
||||
static int cmd_iopipe(void *data, const char *input)
|
||||
{
|
||||
struct r_core_t *core = (struct r_core_t *)data;
|
||||
|
|
@ -17,7 +19,7 @@ static int cmd_iopipe(void *data, const char *input)
|
|||
r_io_handle_list(&core->io);
|
||||
break;
|
||||
default:
|
||||
r_io_system(&core->io, core->file->fd, input);
|
||||
cmd_io_system(data, input);
|
||||
break;
|
||||
}
|
||||
return R_TRUE;
|
||||
|
|
@ -644,8 +646,8 @@ static int cmd_write(void *data, const char *input)
|
|||
case ' ':
|
||||
/* write string */
|
||||
len = r_str_escape(str);
|
||||
r_io_lseek(&core->io, core->file->fd, core->seek, R_IO_SEEK_SET);
|
||||
r_io_write(&core->io, core->file->fd, (const ut8*)str, len);
|
||||
r_io_set_fd(&core->io, core->file->fd);
|
||||
r_io_write_at(&core->io, core->seek, (const ut8*)str, len);
|
||||
r_core_block_read(core, 0);
|
||||
break;
|
||||
case 't':
|
||||
|
|
@ -668,7 +670,8 @@ static int cmd_write(void *data, const char *input)
|
|||
if (buf == NULL) {
|
||||
eprintf("Cannot open file '%s'\n", arg);
|
||||
} else {
|
||||
r_io_write(&core->io, core->file->fd, buf, size);
|
||||
r_io_set_fd(&core->io, core->file->fd);
|
||||
r_io_write_at(&core->io, core->seek, buf, size);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
|
@ -681,7 +684,8 @@ static int cmd_write(void *data, const char *input)
|
|||
if (buf == NULL) {
|
||||
eprintf("Cannot open file '%s'\n", arg);
|
||||
} else {
|
||||
r_io_write(&core->io, core->file->fd, buf, size);
|
||||
r_io_set_fd(&core->io, core->file->fd);
|
||||
r_io_write_at(&core->io, core->seek, buf, size);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
|
@ -698,8 +702,8 @@ static int cmd_write(void *data, const char *input)
|
|||
str = tmp;
|
||||
|
||||
// write strifng
|
||||
r_io_lseek(&core->io, core->file->fd, core->seek, R_IO_SEEK_SET);
|
||||
r_io_write(&core->io, core->file->fd, str, len);
|
||||
r_io_set_fd(&core->io, core->file->fd);
|
||||
r_io_write_at(&core->io, core->seek, str, len);
|
||||
r_core_block_read(core, 0);
|
||||
break;
|
||||
case 'x':
|
||||
|
|
@ -750,14 +754,15 @@ static int cmd_write(void *data, const char *input)
|
|||
case '?':
|
||||
break;
|
||||
case '-':
|
||||
r_io_set_write_mask(&core->io, -1, 0, 0);
|
||||
r_io_set_write_mask(&core->io, 0, 0);
|
||||
fprintf(stderr, "Write mask disabled\n");
|
||||
break;
|
||||
case ' ':
|
||||
if (len == 0) {
|
||||
fprintf(stderr, "Invalid string\n");
|
||||
} else {
|
||||
r_io_set_write_mask(&core->io, core->file->fd, str, len);
|
||||
r_io_set_fd(&core->io, core->file->fd);
|
||||
r_io_set_write_mask(&core->io, str, len);
|
||||
fprintf(stderr, "Write mask set to '");
|
||||
for (i=0;i<len;i++)
|
||||
fprintf(stderr, "%02x", str[i]);
|
||||
|
|
@ -770,20 +775,21 @@ static int cmd_write(void *data, const char *input)
|
|||
case 'v':
|
||||
{
|
||||
ut64 off = r_num_math(&core->num, input+1);
|
||||
r_io_lseek(&core->io, core->file->fd, core->seek, R_IO_SEEK_SET);
|
||||
r_io_set_fd(&core->io, core->file->fd);
|
||||
r_io_lseek(&core->io, core->seek, R_IO_SEEK_SET);
|
||||
if (off&UT64_32U) {
|
||||
/* 8 byte addr */
|
||||
ut64 addr8;
|
||||
memcpy((ut8*)&addr8, (ut8*)&off, 8); // XXX needs endian here
|
||||
// endian_memcpy((ut8*)&addr8, (ut8*)&off, 8);
|
||||
r_io_write(&core->io, core->file->fd, (const ut8 *)&addr8, 8);
|
||||
r_io_write(&core->io, (const ut8 *)&addr8, 8);
|
||||
} else {
|
||||
/* 4 byte addr */
|
||||
ut32 addr4, addr4_ = (ut32)off;
|
||||
//drop_endian((ut8*)&addr4_, (ut8*)&addr4, 4); /* addr4_ = addr4 */
|
||||
//endian_memcpy((ut8*)&addr4, (ut8*)&addr4_, 4); /* addr4 = addr4_ */
|
||||
memcpy((ut8*)&addr4, (ut8*)&addr4_, 4); // XXX needs endian here too
|
||||
r_io_write(&core->io, core->file->fd, (const ut8 *)&addr4, 4);
|
||||
r_io_write(&core->io, (const ut8 *)&addr4, 4);
|
||||
}
|
||||
r_core_block_read(core, 0);
|
||||
}
|
||||
|
|
@ -834,7 +840,8 @@ static int cmd_write(void *data, const char *input)
|
|||
case '?':
|
||||
if (core->oobi) {
|
||||
fprintf(stderr, "Writing oobi buffer!\n");
|
||||
r_io_write(&core->io, core->file->fd, core->oobi, core->oobi_len);
|
||||
r_io_set_fd(&core->io, core->file->fd);
|
||||
r_io_write(&core->io, core->oobi, core->oobi_len);
|
||||
} else
|
||||
r_cons_printf("Usage: w[x] [str] [<file] [<<EOF] [@addr]\n"
|
||||
" w foobar ; write string 'foobar'\n"
|
||||
|
|
@ -948,8 +955,8 @@ static int cmd_search(void *data, const char *input)
|
|||
for(at = core->seek; at < core->file->size; at += core->blocksize) {
|
||||
if (r_cons_breaked)
|
||||
break;
|
||||
r_io_lseek(&core->io, core->file->fd, at, R_IO_SEEK_SET);
|
||||
ret = r_io_read(&core->io, core->file->fd, buf, core->blocksize);
|
||||
r_io_set_fd(&core->io, core->file->fd);
|
||||
ret = r_io_read_at(&core->io, at, buf, core->blocksize);
|
||||
if (ret != core->blocksize)
|
||||
break;
|
||||
if (r_search_update(core->search, &at, buf, ret) == -1) {
|
||||
|
|
@ -1157,7 +1164,8 @@ static int cmd_undowrite(void *data, const char *input)
|
|||
static int cmd_io_system(void *data, const char *input)
|
||||
{
|
||||
struct r_core_t *core = (struct r_core_t *)data;
|
||||
return r_io_system(&core->io, core->file->fd, input);
|
||||
r_io_set_fd(&core->io, core->file->fd);
|
||||
return r_io_system(&core->io, input);
|
||||
}
|
||||
|
||||
static int cmd_macro(void *data, const char *input)
|
||||
|
|
|
|||
|
|
@ -70,7 +70,8 @@ R_API int r_core_write_op(struct r_core_t *core, const char *arg, char op)
|
|||
R_API int r_core_seek(struct r_core_t *core, ut64 addr, int rb)
|
||||
{
|
||||
int ret;
|
||||
ret = r_io_lseek(&core->io, core->file->fd, addr, R_IO_SEEK_SET);
|
||||
r_io_set_fd(&core->io, core->file->fd);
|
||||
ret = r_io_lseek(&core->io, addr, R_IO_SEEK_SET);
|
||||
if (ret) {
|
||||
core->seek = addr;
|
||||
if (rb) return r_core_block_read (core, 0);
|
||||
|
|
@ -81,11 +82,12 @@ R_API int r_core_seek(struct r_core_t *core, ut64 addr, int rb)
|
|||
|
||||
int r_core_write_at(struct r_core_t *core, ut64 addr, const ut8 *buf, int size)
|
||||
{
|
||||
int ret;
|
||||
r_io_lseek(&core->io, core->file->fd, addr, R_IO_SEEK_SET);
|
||||
ret = r_io_write(&core->io, core->file->fd, buf, size);
|
||||
if (addr >= core->seek && addr <= core->seek+core->blocksize)
|
||||
r_core_block_read(core, 0);
|
||||
int ret = r_io_set_fd(&core->io, core->file->fd);
|
||||
if (ret != -1) {
|
||||
ret = r_io_write_at(&core->io, addr, buf, size);
|
||||
if (addr >= core->seek && addr <= core->seek+core->blocksize)
|
||||
r_core_block_read(core, 0);
|
||||
}
|
||||
return (ret==-1)?R_FALSE:R_TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -93,15 +95,15 @@ R_API int r_core_block_read(struct r_core_t *core, int next)
|
|||
{
|
||||
if (core->file == NULL)
|
||||
return -1;
|
||||
r_io_lseek(&core->io, core->file->fd, core->seek+((next)?core->blocksize:0), R_IO_SEEK_SET);
|
||||
return r_io_read(&core->io, core->file->fd, core->block, core->blocksize);
|
||||
r_io_set_fd (&core->io, core->file->fd);
|
||||
r_io_lseek(&core->io, core->seek+((next)?core->blocksize:0), R_IO_SEEK_SET);
|
||||
return r_io_read(&core->io, core->block, core->blocksize);
|
||||
}
|
||||
|
||||
int r_core_read_at(struct r_core_t *core, ut64 addr, ut8 *buf, int size)
|
||||
{
|
||||
int ret;
|
||||
r_io_lseek(&core->io, core->file->fd, addr, R_IO_SEEK_SET);
|
||||
ret = r_io_read(&core->io, core->file->fd, buf, size);
|
||||
int ret = r_io_set_fd (&core->io, core->file->fd);
|
||||
ret = r_io_read_at(&core->io, addr, buf, size);
|
||||
if (addr >= core->seek && addr <= core->seek+core->blocksize)
|
||||
r_core_block_read(core, 0);
|
||||
return (ret==-1)?R_FALSE:R_TRUE;
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ static int r_debug_ptrace_wait(int pid)
|
|||
struct r_debug_regset_t * r_debug_ptrace_reg_read(int pid)
|
||||
{
|
||||
struct r_debug_regset_t *r = NULL;
|
||||
// XXX this must be defined somewhere else
|
||||
#if __linux__
|
||||
#include <sys/user.h>
|
||||
#include <limits.h>
|
||||
|
|
|
|||
|
|
@ -16,29 +16,37 @@ int main(int argc, char **argv)
|
|||
r_io_handle_list(io);
|
||||
|
||||
ret = r_io_open(io, "dbg:///bin/ls", 0, 0);
|
||||
r_io_set_fd(io, ret);
|
||||
printf("r_io_open dbg:///bin/ls' = %s\n", r_str_bool(ret));
|
||||
if (!ret) {
|
||||
printf("Cannot open dbg:///bin/ls\n");
|
||||
goto beach;
|
||||
}
|
||||
|
||||
{
|
||||
/* dump process memory */
|
||||
char buf[128];
|
||||
int ret = r_io_read_at(io, buf, 128);
|
||||
printf("%02x\n", buf[0]);
|
||||
}
|
||||
|
||||
dbg = r_debug_new();
|
||||
printf("Supported debugger backends:\n");
|
||||
|
||||
ret = r_debug_handle_set (dbg, "dbg_ptrace");
|
||||
printf("Using 'dbg_ptrace' = %s\n", r_str_bool(ret));
|
||||
|
||||
tid = pid = r_io_system(io, -1, "pid");
|
||||
tid = pid = r_io_system(io, "pid");
|
||||
r_debug_select(dbg, pid, tid);
|
||||
|
||||
printf("--> regs pre step\n");
|
||||
r_io_system(io, -1, "reg");
|
||||
r_io_system(io, "reg");
|
||||
|
||||
printf("--> perform 2 steps (only 1 probably?\n");
|
||||
printf("--> perform 2 steps (only 1 probably?)\n");
|
||||
r_debug_step(dbg, 2);
|
||||
|
||||
printf("--> regs post step\n");
|
||||
r_io_system(io, -1, "reg");
|
||||
r_io_system(io, "reg");
|
||||
|
||||
printf("---\n");
|
||||
r_debug_continue (dbg);
|
||||
|
|
|
|||
|
|
@ -94,14 +94,17 @@ R_API struct r_io_handle_t *r_io_handle_resolve_fd(struct r_io_t *io, int fd);
|
|||
|
||||
/* io/io.c */
|
||||
R_API int r_io_init(struct r_io_t *io);
|
||||
R_API int r_io_set_write_mask(struct r_io_t *io, int fd, const ut8 *buf, int len);
|
||||
R_API int r_io_set_write_mask(struct r_io_t *io, const ut8 *buf, int len);
|
||||
R_API int r_io_open(struct r_io_t *io, const char *file, int flags, int mode);
|
||||
R_API int r_io_redirect(struct r_io_t *io, const char *file);
|
||||
R_API int r_io_read(struct r_io_t *io, int fd, ut8 *buf, int len);
|
||||
R_API ut64 r_io_read_i(struct r_io_t *io, int fd, ut64 addr, int sz, int endian);
|
||||
R_API int r_io_write(struct r_io_t *io, int fd, const ut8 *buf, int len);
|
||||
R_API ut64 r_io_lseek(struct r_io_t *io, int fd, ut64 offset, int whence);
|
||||
R_API int r_io_system(struct r_io_t *io, int fd, const char *cmd);
|
||||
R_API int r_io_set_fd(struct r_io_t *io, int fd);
|
||||
R_API int r_io_read(struct r_io_t *io, ut8 *buf, int len);
|
||||
R_API int r_io_read_at(struct r_io_t *io, ut64 addr, ut8 *buf, int len);
|
||||
R_API ut64 r_io_read_i(struct r_io_t *io, ut64 addr, int sz, int endian);
|
||||
R_API int r_io_write(struct r_io_t *io, const ut8 *buf, int len);
|
||||
R_API int r_io_write_at(struct r_io_t *io, ut64 addr, const ut8 *buf, int len);
|
||||
R_API ut64 r_io_lseek(struct r_io_t *io, ut64 offset, int whence);
|
||||
R_API int r_io_system(struct r_io_t *io, const char *cmd);
|
||||
R_API int r_io_close(struct r_io_t *io, int fd);
|
||||
R_API ut64 r_io_size(struct r_io_t *io, int fd);
|
||||
|
||||
|
|
@ -125,6 +128,7 @@ struct r_io_section_t {
|
|||
struct list_head list;
|
||||
};
|
||||
|
||||
// TODO: rename SECTION to PERMISION or so
|
||||
enum {
|
||||
R_IO_SECTION_R = 4,
|
||||
R_IO_SECTION_W = 2,
|
||||
|
|
|
|||
|
|
@ -14,3 +14,12 @@ UNDO - records all write ops allowing undo, redo, reset operations
|
|||
r_io_undo_*
|
||||
CACHE - caches write operations to emulate fake reads
|
||||
r_io_cache_*
|
||||
|
||||
-------------------------------------------
|
||||
|
||||
NOTES: each plugin handle must provide a 'optimal' read size.. or io must be configured to this
|
||||
|
||||
var io = new Radare.IO();
|
||||
int fd = io.open("/bin/ls");
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
static struct r_io_handle_t *io_static_plugins[] =
|
||||
{ R_IO_STATIC_PLUGINS };
|
||||
|
||||
|
||||
R_API int r_io_handle_add(struct r_io_t *io, struct r_io_handle_t *plugin)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -68,6 +67,7 @@ R_API struct r_io_handle_t *r_io_handle_resolve_fd(struct r_io_t *io, int fd)
|
|||
R_API int r_io_handle_generate(struct r_io_t *io)
|
||||
{
|
||||
// TODO: ensure srand here (( implement in r_util a decent random helper
|
||||
// TODO: register io plugin with new fd
|
||||
return (rand()%666)+1024;
|
||||
}
|
||||
|
||||
|
|
@ -109,6 +109,7 @@ R_API int r_io_handle_close(struct r_io_t *io, int fd, struct r_io_handle_t *plu
|
|||
return -1;
|
||||
}
|
||||
|
||||
// TODO: must return an r_iter ator
|
||||
R_API int r_io_handle_list(struct r_io_t *io)
|
||||
{
|
||||
int n = 0;
|
||||
|
|
|
|||
131
libr/io/io.c
131
libr/io/io.c
|
|
@ -38,15 +38,15 @@ R_API int r_io_redirect(struct r_io_t *io, const char *file)
|
|||
|
||||
R_API int r_io_open(struct r_io_t *io, const char *file, int flags, int mode)
|
||||
{
|
||||
const char *uri = strdup(file);
|
||||
int fd = -2;
|
||||
char *uri = strdup(file);
|
||||
struct r_io_handle_t *plugin;
|
||||
if (io != NULL) {
|
||||
do {
|
||||
for(;;) {
|
||||
plugin = r_io_handle_resolve(io, uri);
|
||||
if (plugin) {
|
||||
int fd = plugin->open(io, uri, flags, mode);
|
||||
fd = plugin->open(io, uri, flags, mode);
|
||||
if (io->redirect) {
|
||||
printf("REDIRECT FOO => (%s)\n", io->redirect);
|
||||
free((void *)uri);
|
||||
uri = strdup(io->redirect);
|
||||
r_io_redirect(io, NULL);
|
||||
|
|
@ -56,61 +56,62 @@ R_API int r_io_open(struct r_io_t *io, const char *file, int flags, int mode)
|
|||
r_io_handle_open(io, fd, plugin);
|
||||
if (fd != io->fd)
|
||||
io->plugin = plugin;
|
||||
io->fd = fd;
|
||||
return fd;
|
||||
}
|
||||
break;
|
||||
} while(1);
|
||||
} else fprintf(stderr, "WARNING: Using uninitialized r_io\n");
|
||||
return open(file, flags, mode);
|
||||
}
|
||||
}
|
||||
if (fd == -2)
|
||||
fd = open(file, flags, mode);
|
||||
if (fd > -1) r_io_set_fd(io, fd);
|
||||
else fd = -1;
|
||||
free((void *)uri);
|
||||
return fd;
|
||||
}
|
||||
|
||||
R_API int r_io_set_fd(struct r_io_t *io, int fd)
|
||||
{
|
||||
if (fd == -1)
|
||||
fd = io->fd;
|
||||
else if (fd != io->fd) {
|
||||
if (fd != -1 && fd != io->fd) {
|
||||
io->plugin = r_io_handle_resolve_fd(io, fd);
|
||||
io->fd = fd;
|
||||
}
|
||||
return fd;
|
||||
return io->fd;
|
||||
}
|
||||
|
||||
R_API int r_io_read(struct r_io_t *io, int fd, ut8 *buf, int len)
|
||||
R_API int r_io_read(struct r_io_t *io, ut8 *buf, int len)
|
||||
{
|
||||
fd = r_io_set_fd(io, fd);
|
||||
// TODO: support read of partial pages
|
||||
if (r_io_map_read_at(io, io->seek, buf, len) != 0)
|
||||
return len;
|
||||
if (io->plugin && io->plugin->read) {
|
||||
io->fd = fd;
|
||||
if (io->plugin->read != NULL)
|
||||
return io->plugin->read(io, fd, buf, len);
|
||||
else fprintf(stderr, "IO handler for fd=%d has no read()\n",fd);
|
||||
return io->plugin->read(io, io->fd, buf, len);
|
||||
else fprintf(stderr, "IO handler for fd=%d has no read()\n", io->fd);
|
||||
}
|
||||
return read(fd, buf, len);
|
||||
return read(io->fd, buf, len);
|
||||
}
|
||||
|
||||
R_API ut64 r_io_read_i(struct r_io_t *io, int fd, ut64 addr, int sz, int endian)
|
||||
R_API int r_io_read_at(struct r_io_t *io, ut64 addr, ut8 *buf, int len)
|
||||
{
|
||||
if (r_io_lseek(io, addr, R_IO_SEEK_SET)<0)
|
||||
return -1;
|
||||
return r_io_read(io, buf, len);
|
||||
}
|
||||
|
||||
R_API ut64 r_io_read_i(struct r_io_t *io, ut64 addr, int sz, int endian)
|
||||
{
|
||||
ut64 ret = 0LL;
|
||||
int err;
|
||||
char buf[128], dst[128];
|
||||
ut8 buf[8];
|
||||
if (sz > 8) sz = 8;
|
||||
if (sz < 0) sz = 1;
|
||||
err = r_io_lseek(io, fd, addr, R_IO_SEEK_SET);
|
||||
// XXX do something with err
|
||||
err = r_io_read(io, fd, buf, sz);
|
||||
if (err != sz) {
|
||||
perror("Cannot read");
|
||||
} else {
|
||||
r_mem_copyendian(&ret, buf, sz, endian);
|
||||
}
|
||||
err = r_io_read_at(io, addr, buf, sz);
|
||||
if (err == sz) r_mem_copyendian((ut8*)&ret, buf, sz, endian);
|
||||
else perror("Cannot read");
|
||||
return ret;
|
||||
}
|
||||
|
||||
R_API int r_io_resize(struct r_io_t *io, int fd, const char *file, int flags, int mode)
|
||||
R_API int r_io_resize(struct r_io_t *io, const char *file, int flags, int mode)
|
||||
{
|
||||
fd = r_io_set_fd(io, fd);
|
||||
#if 0
|
||||
/* TODO */
|
||||
struct r_io_handle_t *plugin = r_io_handle_resolve(file);
|
||||
|
|
@ -124,34 +125,29 @@ R_API int r_io_resize(struct r_io_t *io, int fd, const char *file, int flags, in
|
|||
return -1;
|
||||
}
|
||||
|
||||
R_API int r_io_set_write_mask(struct r_io_t *io, int fd, const ut8 *buf, int len)
|
||||
R_API int r_io_set_write_mask(struct r_io_t *io, const ut8 *buf, int len)
|
||||
{
|
||||
int ret;
|
||||
fd = r_io_set_fd(io, fd);
|
||||
int ret = R_FALSE;
|
||||
if (len) {
|
||||
io->write_mask_fd = fd;
|
||||
io->write_mask_fd = io->fd;
|
||||
io->write_mask_buf = (ut8 *)malloc(len);
|
||||
memcpy(io->write_mask_buf, buf, len);
|
||||
io->write_mask_len = len;
|
||||
ret = R_TRUE;
|
||||
} else {
|
||||
io->write_mask_fd = -1;
|
||||
ret = R_FALSE;
|
||||
}
|
||||
} else io->write_mask_fd = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
R_API int r_io_write(struct r_io_t *io, int fd, const ut8 *buf, int len)
|
||||
R_API int r_io_write(struct r_io_t *io, const ut8 *buf, int len)
|
||||
{
|
||||
int i, ret = -1;
|
||||
fd = r_io_set_fd(io, fd);
|
||||
|
||||
/* apply write binary mask */
|
||||
if (io->write_mask_fd != -1) {
|
||||
ut8 *data = alloca(len);
|
||||
r_io_lseek(io, fd, io->seek, R_IO_SEEK_SET);
|
||||
r_io_read(io, fd, data, len);
|
||||
r_io_lseek(io, fd, io->seek, R_IO_SEEK_SET);
|
||||
r_io_lseek(io, io->seek, R_IO_SEEK_SET);
|
||||
r_io_read(io, data, len);
|
||||
r_io_lseek(io, io->seek, R_IO_SEEK_SET);
|
||||
for(i=0;i<len;i++) {
|
||||
data[i] = buf[i] & \
|
||||
io->write_mask_buf[i%io->write_mask_len];
|
||||
|
|
@ -162,26 +158,30 @@ R_API int r_io_write(struct r_io_t *io, int fd, const ut8 *buf, int len)
|
|||
if (r_io_map_write_at(io, io->seek, buf, len) != 0)
|
||||
return len;
|
||||
if (io->plugin) {
|
||||
io->fd = fd;
|
||||
if (io->plugin->write)
|
||||
ret = io->plugin->write(io, fd, buf, len);
|
||||
} else ret = write(fd, buf, len);
|
||||
ret = io->plugin->write(io, io->fd, buf, len);
|
||||
else fprintf(stderr, "r_io_write: io handler with no write callback\n");
|
||||
} else ret = write(io->fd, buf, len);
|
||||
if (ret == -1)
|
||||
fprintf(stderr, "r_io_write: cannot write\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
R_API ut64 r_io_lseek(struct r_io_t *io, int fd, ut64 offset, int whence)
|
||||
R_API int r_io_write_at(struct r_io_t *io, ut64 addr, const ut8 *buf, int len)
|
||||
{
|
||||
int posix_whence = 0;
|
||||
fd = r_io_set_fd(io, fd);
|
||||
if (r_io_lseek(io, addr, R_IO_SEEK_SET)<0)
|
||||
return -1;
|
||||
return r_io_write(io, buf, len);
|
||||
}
|
||||
|
||||
if (whence == SEEK_SET)
|
||||
offset = r_io_section_align(io, offset, 0, 0);
|
||||
R_API ut64 r_io_lseek(struct r_io_t *io, ut64 offset, int whence)
|
||||
{
|
||||
int posix_whence = SEEK_SET;
|
||||
|
||||
/* pwn seek value */
|
||||
switch(whence) {
|
||||
case R_IO_SEEK_SET:
|
||||
offset = r_io_section_align(io, offset, 0, 0);
|
||||
io->seek = offset;
|
||||
posix_whence = SEEK_SET;
|
||||
break;
|
||||
|
|
@ -190,38 +190,37 @@ R_API ut64 r_io_lseek(struct r_io_t *io, int fd, ut64 offset, int whence)
|
|||
posix_whence = SEEK_CUR;
|
||||
break;
|
||||
case R_IO_SEEK_END:
|
||||
io->seek = 0xffffffff;
|
||||
io->seek = 0xffffffff; // XXX
|
||||
posix_whence = SEEK_END;
|
||||
break;
|
||||
}
|
||||
|
||||
if (io->plugin && io->plugin->lseek) {
|
||||
io->fd = fd;
|
||||
return io->plugin->lseek(io, fd, offset, whence);
|
||||
}
|
||||
if (io->plugin && io->plugin->lseek)
|
||||
io->seek = io->plugin->lseek(io, io->fd, offset, whence);
|
||||
// XXX can be problematic on w32..so no 64 bit offset?
|
||||
return lseek(fd, offset, posix_whence);
|
||||
else io->seek = lseek(io->fd, offset, posix_whence);
|
||||
|
||||
return io->seek;
|
||||
}
|
||||
|
||||
R_API ut64 r_io_size(struct r_io_t *io, int fd)
|
||||
{
|
||||
ut64 size, here;
|
||||
fd = r_io_set_fd(io, fd);
|
||||
here = r_io_lseek(io, fd, 0, R_IO_SEEK_CUR);
|
||||
size = r_io_lseek(io, fd, 0, R_IO_SEEK_END);
|
||||
r_io_lseek(io, fd, here, R_IO_SEEK_SET);
|
||||
here = r_io_lseek(io, 0, R_IO_SEEK_CUR);
|
||||
size = r_io_lseek(io, 0, R_IO_SEEK_END);
|
||||
r_io_lseek(io, here, R_IO_SEEK_SET);
|
||||
return size;
|
||||
}
|
||||
|
||||
R_API int r_io_system(struct r_io_t *io, int fd, const char *cmd)
|
||||
R_API int r_io_system(struct r_io_t *io, const char *cmd)
|
||||
{
|
||||
fd = r_io_set_fd(io, fd);
|
||||
if (io->plugin && io->plugin->system) {
|
||||
return io->plugin->system(io, fd, cmd);
|
||||
}
|
||||
if (io->plugin && io->plugin->system)
|
||||
return io->plugin->system(io, io->fd, cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: remove int fd here???
|
||||
R_API int r_io_close(struct r_io_t *io, int fd)
|
||||
{
|
||||
fd = r_io_set_fd(io, fd);
|
||||
|
|
|
|||
|
|
@ -73,17 +73,14 @@ int r_io_map_read_at(struct r_io_t *io, ut64 off, ut8 *buf, ut64 len)
|
|||
{
|
||||
struct list_head *pos;
|
||||
|
||||
return 0;
|
||||
/* XXX This makes radare segfault ?? */
|
||||
if (io == NULL) {
|
||||
if (io == NULL)
|
||||
return 0;
|
||||
}
|
||||
list_for_each_prev(pos, &io->maps) {
|
||||
struct r_io_maps_t *im = list_entry(pos, struct r_io_maps_t, list);
|
||||
/* segfaults here coz im is invalid */
|
||||
if (im)
|
||||
if (im->file && im->file[0] != '\0' && off >= im->from && off < im->to) {
|
||||
r_io_lseek(io, im->fd, off-im->from, SEEK_SET);
|
||||
return r_io_read(io, im->fd, buf, len);
|
||||
r_io_set_fd(io, im->fd);
|
||||
return r_io_read_at(io, off-im->from, buf, len);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -95,9 +92,10 @@ int r_io_map_write_at(struct r_io_t *io, ut64 off, const ut8 *buf, ut64 len)
|
|||
|
||||
list_for_each_prev(pos, &io->maps) {
|
||||
struct r_io_maps_t *im = list_entry(pos, struct r_io_maps_t, list);
|
||||
if (im)
|
||||
if (im->file[0] != '\0' && off >= im->from && off < im->to) {
|
||||
r_io_lseek(io, im->fd, off-im->from, SEEK_SET);
|
||||
return r_io_write(io, im->fd, buf, len);
|
||||
r_io_set_fd(io, im->fd);
|
||||
return r_io_write_at(io, off-im->from, buf, len);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -111,6 +109,7 @@ int r_io_map_read_rest(struct r_io_t *io, ut64 off, ut8 *buf, ut64 len)
|
|||
struct r_io_maps_t *im = list_entry(pos, struct r_io_maps_t, list);
|
||||
if (im->file[0] != '\0' && off+len >= im->from && off < im->to) {
|
||||
lseek(im->fd, 0, SEEK_SET);
|
||||
// XXX VERY BROKEN
|
||||
return read(im->fd, buf+(im->from-(off+len)), len);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
include ../../../config-user.mk
|
||||
|
||||
OBJ_IODBG=io_dbg.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_IODBG}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
include ../../../config-user.mk
|
||||
|
||||
OBJ_MALLOC=io_malloc.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_MALLOC}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
include ../../../config-user.mk
|
||||
|
||||
OBJ_PTRACE=io_ptrace.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_PTRACE}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
include ../../../config-user.mk
|
||||
|
||||
OBJ_SHM=io_shm.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_SHM}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ int main(int argc, char **argv)
|
|||
|
||||
fd = r_io_open(&io, argc>1?argv[1]:"/etc/issue", R_IO_READ, 0);
|
||||
memset(buf, '\0', 4096);
|
||||
r_io_read(&io, fd, buf, 4095);
|
||||
//r_io_set_fd(&io, fd);
|
||||
r_io_read(&io, buf, 4095);
|
||||
|
||||
puts(buf);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ int main(int argc, char **argv)
|
|||
|
||||
fd = r_io_open(&io, argc>1?argv[1]:"/bin/ls", R_IO_READ, 0);
|
||||
printf("FD = %d\n", fd);
|
||||
r_io_lseek(&io, fd, 1, R_IO_SEEK_SET);
|
||||
r_io_lseek(&io, 1, R_IO_SEEK_SET);
|
||||
memset(buf, '\0', sizeof(buf));
|
||||
r_io_read(&io, -1, buf, 4);
|
||||
r_io_read(&io, buf, 4);
|
||||
buf[4]='\0';
|
||||
printf("%llx\n", r_io_read_i(&io, fd, 0LL, 4, 0));
|
||||
printf("%llx\n", r_io_read_i(&io, 0LL, 4, 0));
|
||||
|
||||
puts(buf);
|
||||
|
||||
|
|
|
|||
|
|
@ -68,3 +68,14 @@ R_API const ut8 *r_mem_mem(const ut8 *haystack, int hlen, const ut8 *needle, int
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// TODO: implement pack/unpack helpers use vararg or wtf?
|
||||
R_API int r_mem_pack()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
R_API int r_mem_unpack(const u8)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ namespace Radare {
|
|||
public class Database {
|
||||
/* lifecycle */
|
||||
public Database();
|
||||
/**
|
||||
* Initializes a database object
|
||||
*/
|
||||
public void init();
|
||||
public void free();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
using Radare;
|
||||
|
||||
//public class IterableObject<G> : Radare.Iter<G> : base(number) {
|
||||
[Compact]
|
||||
//[Compact]
|
||||
public class IterableObject {
|
||||
public string name; // { get;set; }
|
||||
|
||||
|
|
@ -10,18 +10,24 @@ public class IterableObject {
|
|||
}
|
||||
}
|
||||
|
||||
IterableObject a;
|
||||
IterableObject b;
|
||||
IterableObject c;
|
||||
|
||||
Radare.Iter<IterableObject> get_iter_list ()
|
||||
{
|
||||
Radare.Iter<unowned IterableObject> list = new Radare.Iter<unowned IterableObject>(3);
|
||||
Radare.Iter<IterableObject> list = new Radare.Iter<IterableObject>(3);
|
||||
b = new IterableObject("barata");
|
||||
c = new IterableObject("allalt");
|
||||
list.set(0, new IterableObject("patata"));
|
||||
list.set(1, new IterableObject("barata"));
|
||||
list.set(2, new IterableObject("lalata"));
|
||||
list.set(1, b);
|
||||
list.set(2, c);
|
||||
return list;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
Radare.Iter<unowned IterableObject> foo = get_iter_list ();
|
||||
Radare.Iter<IterableObject> foo = get_iter_list ();
|
||||
//Radare.Iter<IterableObject> ptr = foo;
|
||||
//for(Radare.Iter<IterableObject> ptr = foo; !ptr.last(); ptr = ptr.next()) {
|
||||
while(!foo.last()) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue