* Initial implementation of rabin2 -c
- Allow to create tiny binaries with r_bin
- ATM only MACH0 format for x86-32 is supported
$ ./rabin2 -a x86_32 -c mach0:31c040682a00000081ec04000000cd80 a.out
* Rename r_bin_set_arch{idx} to r_bin_select{idx}
- New API r_bin_create and r_bin_use_arch()
This commit is contained in:
parent
1c1a307edc
commit
8d06dd2f02
8 changed files with 318 additions and 54 deletions
|
|
@ -33,6 +33,7 @@
|
|||
#define ACTION_EXTRACT 0x1000
|
||||
#define ACTION_RELOCS 0x2000
|
||||
#define ACTION_LISTARCHS 0x4000
|
||||
#define ACTION_CREATE 0x8000
|
||||
|
||||
static struct r_lib_t *l;
|
||||
static struct r_bin_t *bin = NULL;
|
||||
|
|
@ -42,36 +43,38 @@ static int va = R_FALSE;
|
|||
static ut64 gbaddr = 0LL;
|
||||
static char* file = NULL;
|
||||
static char* output = "out";
|
||||
static char* create = NULL;
|
||||
static ut64 at = 0LL;
|
||||
static char *name = NULL;
|
||||
|
||||
static int rabin_show_help() {
|
||||
printf ("rabin2 [options] [file]\n"
|
||||
" -A List archs\n"
|
||||
" -a [arch_bits] Set arch\n"
|
||||
" -f [str] Select sub-bin named str\n"
|
||||
" -b [addr] Override baddr\n"
|
||||
" -e Entrypoint\n"
|
||||
" -M Main\n"
|
||||
" -i Imports (symbols imported from libraries)\n"
|
||||
" -s Symbols (exports)\n"
|
||||
" -S Sections\n"
|
||||
" -z Strings\n"
|
||||
" -I Binary info\n"
|
||||
" -H Header fields\n"
|
||||
" -l Linked libraries\n"
|
||||
" -R Relocations\n"
|
||||
" -O [str] Write/Extract operations (str=help for help)\n"
|
||||
" -o [str] Output file/folder for write operations (out by default)\n"
|
||||
" -r radare output\n"
|
||||
" -v Use vaddr in radare output\n"
|
||||
" -m [addr] Show source line at addr\n"
|
||||
" -L List supported bin plugins\n"
|
||||
" -@ [addr] Show section, symbol or import at addr\n"
|
||||
" -n [str] Show section, symbol or import named str\n"
|
||||
" -x Extract bins contained in file\n"
|
||||
" -V Show version information\n"
|
||||
" -h This help\n");
|
||||
" -A list archs\n"
|
||||
" -a [arch_bits] set arch\n"
|
||||
" -b [addr] override baddr\n"
|
||||
" -c [fmt:C:D] create [fmt] binary with Code and Data hexpairs (see -a)\n"
|
||||
" -e entrypoint\n"
|
||||
" -f [str] select sub-bin named str\n"
|
||||
" -i imports (symbols imported from libraries)\n"
|
||||
" -s symbols (exports)\n"
|
||||
" -S sections\n"
|
||||
" -M main (show address of main symbol)\n"
|
||||
" -z strings\n"
|
||||
" -I binary info\n"
|
||||
" -H header fields\n"
|
||||
" -l linked libraries\n"
|
||||
" -R relocations\n"
|
||||
" -O [str] write/extract operations (str=help for help)\n"
|
||||
" -o [str] output file/folder for write operations (out by default)\n"
|
||||
" -r radare output\n"
|
||||
" -v use vaddr in radare output\n"
|
||||
" -m [addr] show source line at addr\n"
|
||||
" -L list supported bin plugins\n"
|
||||
" -@ [addr] show section, symbol or import at addr\n"
|
||||
" -n [str] show section, symbol or import named str\n"
|
||||
" -x extract bins contained in file\n"
|
||||
" -V show version information\n"
|
||||
" -h this help\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -105,13 +108,13 @@ static int rabin_show_entrypoints() {
|
|||
|
||||
static int rabin_show_main() {
|
||||
RBinAddr *binmain;
|
||||
ut64 baddr = gbaddr?gbaddr:r_bin_get_baddr (bin);
|
||||
ut64 baddr = gbaddr? gbaddr: r_bin_get_baddr (bin);
|
||||
|
||||
if ((binmain = r_bin_get_sym (bin, R_BIN_SYM_MAIN)) == NULL)
|
||||
return R_FALSE;
|
||||
if (rad) {
|
||||
printf ("fs symbols\n");
|
||||
printf ("f main @ 0x%08"PFMT64x"\n", va?baddr+binmain->rva:binmain->offset);
|
||||
printf ("f main @ 0x%08"PFMT64x"\n", va? baddr+binmain->rva: binmain->offset);
|
||||
} else {
|
||||
eprintf ("[Main]\n");
|
||||
printf ("addr=0x%08"PFMT64x" off=0x%08"PFMT64x"\n",
|
||||
|
|
@ -127,7 +130,7 @@ static int rabin_extract(int all) {
|
|||
// XXX: Wrong for w32 (/)
|
||||
if (all) {
|
||||
for (i=0; i<bin->narch; i++) {
|
||||
r_bin_set_archidx (bin, i);
|
||||
r_bin_select_idx (bin, i);
|
||||
if (bin->curarch.info == NULL) {
|
||||
eprintf ("No extract info found.\n");
|
||||
} else {
|
||||
|
|
@ -199,18 +202,22 @@ static int rabin_show_relocs() {
|
|||
if ((relocs = r_bin_get_relocs (bin)) == NULL)
|
||||
return R_FALSE;
|
||||
|
||||
if (rad) printf ("fs relocs\n");
|
||||
else eprintf ("[Relocations]\n");
|
||||
|
||||
r_list_foreach (relocs, iter, reloc) {
|
||||
if (rad) printf ("f reloc.%s @ 0x%08"PFMT64x"\n", reloc->name, va?baddr+reloc->rva:reloc->offset);
|
||||
else printf ("sym=%02i addr=0x%08"PFMT64x" off=0x%08"PFMT64x" type=0x%08x %s\n",
|
||||
if (rad) {
|
||||
printf ("fs relocs\n");
|
||||
r_list_foreach (relocs, iter, reloc) {
|
||||
printf ("f reloc.%s @ 0x%08"PFMT64x"\n", reloc->name, va?baddr+reloc->rva:reloc->offset);
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
eprintf ("[Relocations]\n");
|
||||
r_list_foreach (relocs, iter, reloc) {
|
||||
printf ("sym=%02i addr=0x%08"PFMT64x" off=0x%08"PFMT64x" type=0x%08x %s\n",
|
||||
reloc->sym, baddr+reloc->rva, reloc->offset, reloc->type, reloc->name);
|
||||
i++;
|
||||
i++;
|
||||
}
|
||||
eprintf ("\n%i relocations\n", i);
|
||||
}
|
||||
|
||||
if (!rad) eprintf ("\n%i relocations\n", i);
|
||||
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -665,7 +672,7 @@ int main(int argc, char **argv) {
|
|||
r_lib_opendir (l, LIBDIR"/radare2/");
|
||||
}
|
||||
|
||||
while ((c = getopt (argc, argv, "Af:a:B:b:Mm:n:@:VisSzIHelRwO:o:rvLhx")) != -1) {
|
||||
while ((c = getopt (argc, argv, "Af:a:B:b:c:Mm:n:@:VisSzIHelRwO:o:rvLhx")) != -1) {
|
||||
switch(c) {
|
||||
case 'A':
|
||||
action |= ACTION_LISTARCHS;
|
||||
|
|
@ -673,6 +680,10 @@ int main(int argc, char **argv) {
|
|||
case 'a':
|
||||
if (optarg) arch = strdup (optarg);
|
||||
break;
|
||||
case 'c':
|
||||
action = ACTION_CREATE;
|
||||
create = strdup (optarg);
|
||||
break;
|
||||
case 'f':
|
||||
if (optarg) arch_name = strdup (optarg);
|
||||
break;
|
||||
|
|
@ -759,10 +770,6 @@ int main(int argc, char **argv) {
|
|||
if (action == ACTION_HELP || action == ACTION_UNK || file == NULL)
|
||||
return rabin_show_help ();
|
||||
|
||||
if (!r_bin_load (bin, file, R_FALSE) && !r_bin_load (bin, file, R_TRUE)) {
|
||||
eprintf ("r_bin: Cannot open '%s'\n", file);
|
||||
return 1;
|
||||
}
|
||||
if (arch) {
|
||||
char *ptr;
|
||||
ptr = strchr (arch, '_');
|
||||
|
|
@ -771,8 +778,48 @@ int main(int argc, char **argv) {
|
|||
bits = r_num_math (NULL, ptr+1);
|
||||
}
|
||||
}
|
||||
if (action & ACTION_CREATE) {
|
||||
RBuffer *b;
|
||||
int datalen, codelen;
|
||||
ut8 *data = NULL, *code = NULL;
|
||||
char *p2, *p = strchr (create, ':');
|
||||
if (!p) {
|
||||
eprintf ("Invalid format for -c flag. Use 'format:codehexpair:datahexpair'\n");
|
||||
return 1;
|
||||
}
|
||||
*p++ = 0;
|
||||
p2 = strchr (p, ':');
|
||||
if (p2) {
|
||||
// has data
|
||||
*p2++ = 0;
|
||||
data = malloc (strlen (p2));
|
||||
datalen = r_hex_str2bin (p2, data);
|
||||
}
|
||||
code = malloc (strlen (p));
|
||||
codelen = r_hex_str2bin (p, code);
|
||||
if (!arch) arch = "x86";
|
||||
if (!bits) bits = 32;
|
||||
|
||||
if (!r_bin_use_arch (bin, arch, bits, create)) {
|
||||
eprintf ("Cannot set arch\n");
|
||||
return 1;
|
||||
}
|
||||
b = r_bin_create (bin, code, codelen, data, datalen);
|
||||
if (b) {
|
||||
if (r_file_dump (file, b->buf, b->length))
|
||||
eprintf ("dumped %d bytes in '%s'\n", b->length, file);
|
||||
else eprintf ("error dumping into a.out\n");
|
||||
r_buf_free (b);
|
||||
} else eprintf ("Cannot create binary for this format '%s'.\n", create);
|
||||
r_bin_free (bin);
|
||||
return 0;
|
||||
}
|
||||
if (!r_bin_load (bin, file, R_FALSE) && !r_bin_load (bin, file, R_TRUE)) {
|
||||
eprintf ("r_bin: Cannot open '%s'\n", file);
|
||||
return 1;
|
||||
}
|
||||
if (action & ACTION_LISTARCHS && (arch || bits || arch_name)) {
|
||||
if (!r_bin_set_arch (bin, arch, bits, arch_name)) {
|
||||
if (!r_bin_select (bin, arch, bits, arch_name)) {
|
||||
r_bin_list_archs (bin);
|
||||
free (arch);
|
||||
r_bin_free (bin);
|
||||
|
|
|
|||
|
|
@ -357,10 +357,26 @@ R_API RBin* r_bin_new() {
|
|||
return bin;
|
||||
}
|
||||
|
||||
R_API int r_bin_set_arch(RBin *bin, const char *arch, int bits, const char *name) {
|
||||
// TODO: handle ARCH and BITS
|
||||
R_API int r_bin_use_arch(RBin *bin, const char *arch, int bits, const char *name) {
|
||||
struct list_head *pos;
|
||||
|
||||
list_for_each_prev(pos, &bin->bins) {
|
||||
RBinPlugin *h = list_entry (pos, RBinPlugin, list);
|
||||
if (!strcmp (name, h->name)) {
|
||||
bin->curarch.curplugin = h;
|
||||
// TODO: set bits and name
|
||||
return R_TRUE;
|
||||
}
|
||||
}
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
// TODO: rename to r_bin_select
|
||||
R_API int r_bin_select(RBin *bin, const char *arch, int bits, const char *name) {
|
||||
int i;
|
||||
for (i = 0; i < bin->narch; i++) {
|
||||
r_bin_set_archidx (bin, i);
|
||||
r_bin_select_idx (bin, i);
|
||||
if (!bin->curarch.info || !bin->curarch.file ||
|
||||
(arch && !strstr (bin->curarch.info->arch, arch)) ||
|
||||
(bits && bits != bin->curarch.info->bits) ||
|
||||
|
|
@ -371,7 +387,8 @@ R_API int r_bin_set_arch(RBin *bin, const char *arch, int bits, const char *name
|
|||
return R_FALSE;
|
||||
}
|
||||
|
||||
R_API int r_bin_set_archidx(RBin *bin, int idx) {
|
||||
// TODO: rename to r_bin_select_idx
|
||||
R_API int r_bin_select_idx(RBin *bin, int idx) {
|
||||
r_bin_free_items (bin);
|
||||
if (r_bin_extract (bin, idx))
|
||||
return r_bin_init_items (bin, R_FALSE);
|
||||
|
|
@ -381,7 +398,7 @@ R_API int r_bin_set_archidx(RBin *bin, int idx) {
|
|||
R_API void r_bin_list_archs(RBin *bin) {
|
||||
int i;
|
||||
for (i = 0; i < bin->narch; i++)
|
||||
if (r_bin_set_archidx (bin, i) && bin->curarch.info)
|
||||
if (r_bin_select_idx (bin, i) && bin->curarch.info)
|
||||
printf ("%03i %s %s_%i (%s)\n", i, bin->curarch.file,
|
||||
bin->curarch.info->arch, bin->curarch.info->bits,
|
||||
bin->curarch.info->machine);
|
||||
|
|
@ -403,6 +420,13 @@ R_API void r_bin_bind (RBin *bin, RBinBind *b) {
|
|||
b->get_offset = getoffset;
|
||||
}
|
||||
|
||||
R_API RBuffer *r_bin_create (RBin *bin, const ut8 *code, int codelen, const ut8 *data, int datalen) {
|
||||
RBinArch *a = &bin->curarch;
|
||||
if (a && a->curplugin && a->curplugin->create)
|
||||
return a->curplugin->create (bin, code, codelen, data, datalen);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API RBinObj *r_bin_get_object(RBin *bin, int flags) {
|
||||
int i;
|
||||
RBinObj *obj = R_NEW (RBinObj);
|
||||
|
|
|
|||
|
|
@ -190,6 +190,154 @@ static int check(RBinArch *arch) {
|
|||
return R_FALSE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
typedef struct r_bin_create_t {
|
||||
int arch;
|
||||
ut8 *code;
|
||||
int codelen;
|
||||
ut8 *data;
|
||||
int datalen;
|
||||
} RBinCreate;
|
||||
#endif
|
||||
|
||||
static RBuffer* create(RBin* bin, const ut8 *code, int codelen, const ut8 *data, int datalen) {
|
||||
ut32 filesize, codeva, datava;
|
||||
ut32 ncmds, cmdsize, magiclen, headerlen;
|
||||
ut32 p_codefsz, p_codeva, p_codesz, p_codepa;
|
||||
ut32 p_datafsz, p_datava, p_datasz, p_datapa;
|
||||
ut32 p_cmdsize, p_entry, p_tmp;
|
||||
ut32 baddr = 0x1000;
|
||||
RBuffer *buf = r_buf_new ();
|
||||
|
||||
#define B(x,y) r_buf_append_bytes(buf,(const ut8*)x,y)
|
||||
#define D(x) r_buf_append_ut32(buf,x)
|
||||
#define Z(x) r_buf_append_nbytes(buf,x)
|
||||
#define W(x,y,z) r_buf_write_at(buf,x,(const ut8*)y,z)
|
||||
#define WZ(x,y) p_tmp=buf->length;Z(x);W(p_tmp,y,strlen(y))
|
||||
|
||||
/* MACH0 HEADER */
|
||||
B ("\xce\xfa\xed\xfe", 4); // header
|
||||
D (7); // cpu type (x86)
|
||||
D (3); // subtype (i386-all)
|
||||
D (2); // filetype (executable)
|
||||
|
||||
|
||||
if (data && datalen>0) {
|
||||
ncmds = 3;
|
||||
cmdsize = 0;
|
||||
} else {
|
||||
ncmds = 2;
|
||||
cmdsize = 0;
|
||||
}
|
||||
|
||||
/* COMMANDS */
|
||||
D (ncmds); // ncmds
|
||||
p_cmdsize = buf->length;
|
||||
D (-1); // cmdsize
|
||||
D (0); // flags
|
||||
magiclen = buf->length;
|
||||
|
||||
/* TEXT SEGMENT */
|
||||
D (1); // cmd.LC_SEGMENT
|
||||
D (124); // sizeof (cmd)
|
||||
WZ (16, "__TEXT");
|
||||
D (baddr); // vmaddr
|
||||
D (0x1000); // vmsize XXX
|
||||
D (0); // fileoff
|
||||
p_codefsz = buf->length;
|
||||
D (-1); // filesize
|
||||
D (7); // maxprot
|
||||
D (5); // initprot
|
||||
D (1); // nsects
|
||||
D (0); // flags
|
||||
WZ (16, "__text");
|
||||
WZ (16, "__TEXT");
|
||||
p_codeva = buf->length; // virtual address
|
||||
D (-1);
|
||||
p_codesz = buf->length; // size of code (end-start)
|
||||
D (-1);
|
||||
p_codepa = buf->length; // code - baddr
|
||||
D (-1); //_start-0x1000);
|
||||
D (2); // align
|
||||
D (0); // reloff
|
||||
D (0); // nrelocs
|
||||
D (0); // flags
|
||||
D (0); // reserved
|
||||
D (0);
|
||||
|
||||
if (data && datalen>0) {
|
||||
/* DATA SEGMENT */
|
||||
D (1); // cmd.LC_SEGMENT
|
||||
D (124); // sizeof (cmd)
|
||||
p_tmp = buf->length;
|
||||
Z (16);
|
||||
W (p_tmp, "__TEXT", 6); // segment name
|
||||
D (0x2000); // vmaddr
|
||||
D (0x1000); // vmsize
|
||||
D (0); // fileoff
|
||||
p_datafsz = buf->length;
|
||||
D (-1); // filesize
|
||||
D (6); // maxprot
|
||||
D (6); // initprot
|
||||
D (1); // nsects
|
||||
D (0); // flags
|
||||
|
||||
WZ (16, "__data");
|
||||
WZ (16, "__DATA");
|
||||
|
||||
p_datava = buf->length;
|
||||
D (-1);
|
||||
p_datasz = buf->length;
|
||||
D (-1);
|
||||
p_datapa = buf->length;
|
||||
D (-1); //_start-0x1000);
|
||||
D (2); // align
|
||||
D (0); // reloff
|
||||
D (0); // nrelocs
|
||||
D (0); // flags
|
||||
D (0); // reserved
|
||||
D (0);
|
||||
}
|
||||
|
||||
/* THREAD STATE */
|
||||
D (5); // LC_UNIXTHREAD
|
||||
D (80); // sizeof (cmd)
|
||||
D (1); // i386-thread-state
|
||||
D (16); // thread-state-count
|
||||
p_entry = buf->length + (10*sizeof (ut32));
|
||||
Z (16 * sizeof (ut32));
|
||||
|
||||
headerlen = buf->length - magiclen;
|
||||
|
||||
codeva = buf->length + baddr;
|
||||
datava = buf->length + codelen + baddr;
|
||||
W (p_entry, &codeva, 4); // set PC
|
||||
|
||||
/* fill header variables */
|
||||
W (p_cmdsize, &headerlen, 4);
|
||||
filesize = magiclen + headerlen + codelen + datalen;
|
||||
// TEXT SEGMENT //
|
||||
W (p_codefsz, &filesize, 4);
|
||||
W (p_codeva, &codeva, 4);
|
||||
W (p_codesz, &codelen, 4);
|
||||
p_tmp = codeva - baddr;
|
||||
W (p_codepa, &p_tmp, 4);
|
||||
|
||||
B (code, codelen);
|
||||
|
||||
if (data && datalen>0) {
|
||||
/* append data */
|
||||
W (p_datafsz, &filesize, 4);
|
||||
W (p_datava, &datava, 4);
|
||||
W (p_datasz, &datalen, 4);
|
||||
p_tmp = datava - baddr;
|
||||
W (p_datapa, &p_tmp, 4);
|
||||
B (data, datalen);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
struct r_bin_plugin_t r_bin_plugin_mach0 = {
|
||||
.name = "mach0",
|
||||
.desc = "mach0 bin plugin",
|
||||
|
|
@ -211,6 +359,7 @@ struct r_bin_plugin_t r_bin_plugin_mach0 = {
|
|||
.relocs = NULL,
|
||||
.meta = NULL,
|
||||
.write = NULL,
|
||||
.create = &create,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ LIBS+=${DL_LIBS}
|
|||
LDPATH=-L.. -L../../util
|
||||
LDPATH+=-lr_util
|
||||
|
||||
all: test_meta${EXT_EXE} rpathdel${EXT_EXE}
|
||||
all: test_meta${EXT_EXE} rpathdel${EXT_EXE} test_create${EXT_EXE}
|
||||
|
||||
test_meta${EXT_EXE}: test_meta.o
|
||||
${CC} test_meta.o ${LDPATH} ${LDFLAGS} -o test_meta${EXT_EXE}
|
||||
|
|
@ -15,6 +15,9 @@ test_meta${EXT_EXE}: test_meta.o
|
|||
rpathdel${EXT_EXE}: rpathdel.o
|
||||
${CC} rpathdel.o ${LDPATH} ${LDFLAGS} -o rpathdel${EXT_EXE}
|
||||
|
||||
test_create${EXT_EXE}: test_create.o
|
||||
${CC} test_create.o ${LDPATH} ${LDFLAGS} -o test_create${EXT_EXE}
|
||||
|
||||
myclean:
|
||||
rm -f test_meta${EXT_EXE} test_meta.o rpathdel${EXT_EXE} rpathdel.o
|
||||
|
||||
|
|
|
|||
22
libr/bin/t/test_create.c
Normal file
22
libr/bin/t/test_create.c
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#include <r_bin.h>
|
||||
|
||||
int main () {
|
||||
#define _BUFFER_SIZE 64
|
||||
unsigned char code[64] = {
|
||||
0x31, 0xc0, 0x40, 0x68, 0x2a, 0x00, 0x00, 0x00, 0x81, 0xec, 0x04,
|
||||
0x00, 0x00, 0x00, 0xcd, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
RBuffer *b;
|
||||
RBin *bin = r_bin_new ();
|
||||
if (!r_bin_use_arch (bin, "x86", 32, "mach0")) {
|
||||
eprintf ("Cannot set arch\n");
|
||||
return 1;
|
||||
}
|
||||
b = r_bin_create (bin, code, _BUFFER_SIZE, NULL, 0);
|
||||
if (b) {
|
||||
if (r_file_dump ("a.out", b->buf, b->length))
|
||||
eprintf ("dumped %d bytes in a.out\n", b->length);
|
||||
else eprintf ("error dumping into a.out\n");
|
||||
} else eprintf ("So fucking oops\n");
|
||||
r_bin_free (bin);
|
||||
r_buf_free (b);
|
||||
}
|
||||
|
|
@ -104,6 +104,7 @@ typedef struct r_bin_plugin_t {
|
|||
struct r_bin_meta_t *meta;
|
||||
struct r_bin_write_t *write;
|
||||
int (*get_offset)(RBinArch *arch, int type, int idx);
|
||||
RBuffer* (*create)(RBin *bin, const ut8 *code, int codelen, const ut8 *data, int datalen);
|
||||
struct list_head list; // TODO deprecate!!!
|
||||
} RBinPlugin;
|
||||
|
||||
|
|
@ -253,10 +254,12 @@ R_API int r_bin_has_dbg_linenums (RBin *bin);
|
|||
R_API int r_bin_has_dbg_syms (RBin *bin);
|
||||
R_API int r_bin_has_dbg_relocs (RBin *bin);
|
||||
R_API RBin* r_bin_new();
|
||||
R_API int r_bin_set_arch(RBin *bin, const char *arch, int bits, const char *name);
|
||||
R_API int r_bin_set_archidx(RBin *bin, int idx);
|
||||
R_API int r_bin_use_arch(RBin *bin, const char *arch, int bits, const char *name);
|
||||
R_API int r_bin_select(RBin *bin, const char *arch, int bits, const char *name);
|
||||
R_API int r_bin_select_idx(RBin *bin, int idx);
|
||||
R_API void r_bin_list_archs(RBin *bin);
|
||||
R_API void r_bin_set_user_ptr(RBin *bin, void *user);
|
||||
R_API RBuffer *r_bin_create (RBin *bin, const ut8 *code, int codelen, const ut8 *data, int datalen);
|
||||
/* bin_meta.c */
|
||||
R_API int r_bin_meta_get_line(RBin *bin, ut64 addr, char *file, int len, int *line);
|
||||
R_API char *r_bin_meta_get_source_line(RBin *bin, ut64 addr);
|
||||
|
|
|
|||
|
|
@ -192,6 +192,8 @@ R_API RBuffer *r_buf_new();
|
|||
R_API int r_buf_set_bits(RBuffer *b, int bitoff, int bitsize, ut64 value);
|
||||
R_API int r_buf_set_bytes(RBuffer *b, ut8 *buf, int length);
|
||||
R_API int r_buf_append_bytes(RBuffer *b, const ut8 *buf, int length);
|
||||
R_API int r_buf_append_nbytes(RBuffer *b, int length);
|
||||
R_API int r_buf_append_ut32(RBuffer *b, ut32 n);
|
||||
R_API int r_buf_prepend_bytes(RBuffer *b, const ut8 *buf, int length);
|
||||
R_API char *r_buf_to_string(RBuffer *b);
|
||||
R_API int r_buf_read_at(RBuffer *b, ut64 addr, ut8 *buf, int len);
|
||||
|
|
|
|||
|
|
@ -14,10 +14,8 @@ struct r_class_t {
|
|||
#define r_buf_init(x) r_buf_class->init
|
||||
#endif
|
||||
|
||||
R_API struct r_buf_t *r_buf_new() {
|
||||
RBuffer *b;
|
||||
|
||||
b = R_NEW (RBuffer);
|
||||
R_API RBuffer *r_buf_new() {
|
||||
RBuffer *b = R_NEW (RBuffer);
|
||||
if (b) {
|
||||
b->buf = NULL;
|
||||
b->length = 0;
|
||||
|
|
@ -67,6 +65,22 @@ R_API int r_buf_append_bytes(RBuffer *b, const ut8 *buf, int length) {
|
|||
return R_TRUE;
|
||||
}
|
||||
|
||||
R_API int r_buf_append_nbytes(RBuffer *b, int length) {
|
||||
if (!(b->buf = realloc (b->buf, b->length+length)))
|
||||
return R_FALSE;
|
||||
memset (b->buf+b->length, 0, length);
|
||||
b->length += length;
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
R_API int r_buf_append_ut32(RBuffer *b, ut32 n) {
|
||||
if (!(b->buf = realloc (b->buf, b->length+sizeof (n))))
|
||||
return R_FALSE;
|
||||
memcpy (b->buf+b->length, &n, sizeof (n));
|
||||
b->length += sizeof (n);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int r_buf_cpy(RBuffer *b, ut64 addr, ut8 *dst, const ut8 *src, int len, int write) {
|
||||
int end;
|
||||
addr = (addr==R_BUF_CUR)? b->cur: addr-b->base;
|
||||
|
|
|
|||
Loading…
Reference in a new issue