diff --git a/libr/bin/bin_write.c b/libr/bin/bin_write.c index bf5c3f636a..28b6f6dc5c 100644 --- a/libr/bin/bin_write.c +++ b/libr/bin/bin_write.c @@ -1,10 +1,18 @@ /* radare - LGPL - Copyright 2009-2010 nibble<.ds@gmail.com> */ #include +#include #include -R_API int r_bin_wr_scn_set(RBin *bin, RBinSection *scn) { - if (bin && bin->cur && bin->cur->write && bin->cur->write->scn_set) - return bin->cur->write->scn_set (bin, scn); +/* XXX Implement r__bin_wr_scn_{set, del} instead */ +R_API ut64 r_bin_wr_scn_resize(RBin *bin, const char *name, ut64 size) { + if (bin && bin->cur && bin->cur->write && bin->cur->write->scn_resize) + return bin->cur->write->scn_resize (bin, name, size); return R_FALSE; } + +R_API int r_bin_wr_output(RBin *bin, const char *filename) { + if (!r_file_dump (filename, bin->buf->buf, bin->buf->length)) + return R_FALSE; + return R_TRUE; +} diff --git a/libr/bin/format/elf/elf.h b/libr/bin/format/elf/elf.h index 4d4f285ee4..aa7f71bdbf 100644 --- a/libr/bin/format/elf/elf.h +++ b/libr/bin/format/elf/elf.h @@ -84,3 +84,5 @@ struct r_bin_elf_symbol_t* Elf_(r_bin_elf_get_symbols)(struct Elf_(r_bin_elf_obj struct r_bin_elf_field_t* Elf_(r_bin_elf_get_fields)(struct Elf_(r_bin_elf_obj_t) *bin); void* Elf_(r_bin_elf_free)(struct Elf_(r_bin_elf_obj_t)* bin); struct Elf_(r_bin_elf_obj_t)* Elf_(r_bin_elf_new)(const char* file); + +ut64 Elf_(r_bin_elf_resize_section)(struct Elf_(r_bin_elf_obj_t) *bin, const char *name, ut64 size); diff --git a/libr/bin/format/elf/elf_write.c b/libr/bin/format/elf/elf_write.c index 0601933ccc..6a45440e65 100644 --- a/libr/bin/format/elf/elf_write.c +++ b/libr/bin/format/elf/elf_write.c @@ -7,33 +7,31 @@ #include #include "elf.h" -#if 0 +// XXX UGLY CODE /* TODO: Take care of endianess */ /* TODO: Real error handling */ /* TODO: Resize sections before .init */ -u64 Elf_(r_bin_elf_resize_section)(struct Elf_(r_bin_elf_obj_t) *bin, const char *name, u64 size) -{ +ut64 Elf_(r_bin_elf_resize_section)(struct Elf_(r_bin_elf_obj_t) *bin, const char *name, ut64 size) { Elf_(Ehdr) *ehdr = &bin->ehdr; Elf_(Phdr) *phdr = bin->phdr, *phdrp; Elf_(Shdr) *shdr = bin->shdr, *shdrp; const char *strtab = bin->strtab; - u8 *buf; - u64 off, got_offset, got_addr = 0, rsz_offset, delta = 0; - u64 rsz_osize = 0, rsz_fsize, rsz_size = size, rest_size = 0; + ut8 *buf; + ut64 off, got_offset, got_addr = 0, rsz_offset, delta = 0; + ut64 rsz_osize = 0, rsz_size = size, rest_size = 0; int i, j, done = 0; if (size == 0) { printf("0 size section?\n"); return 0; } - rsz_fsize = lseek(bin->fd, 0, SEEK_END); /* calculate delta */ for (i = 0, shdrp = shdr; i < ehdr->e_shnum; i++, shdrp++) if (!strncmp(name, &strtab[shdrp->sh_name], ELF_STRING_LENGTH)) { delta = rsz_size - shdrp->sh_size; - rsz_offset = (u64)shdrp->sh_offset; - rsz_osize = (u64)shdrp->sh_size; + rsz_offset = (ut64)shdrp->sh_offset; + rsz_osize = (ut64)shdrp->sh_size; } if (delta == 0) { @@ -46,7 +44,7 @@ u64 Elf_(r_bin_elf_resize_section)(struct Elf_(r_bin_elf_obj_t) *bin, const char /* rewrite rel's (imports) */ for (i = 0, shdrp = shdr; i < ehdr->e_shnum; i++, shdrp++) { if (!strcmp(&strtab[shdrp->sh_name], ".got")) - got_addr = (u64)shdrp->sh_offset; + got_addr = (ut64)shdrp->sh_offset; } if (got_addr == 0) { /* TODO: Unknown GOT address */ @@ -58,25 +56,22 @@ u64 Elf_(r_bin_elf_resize_section)(struct Elf_(r_bin_elf_obj_t) *bin, const char rel = (Elf_(Rel) *)malloc(shdrp->sh_size); if (rel == NULL) { perror("malloc"); - return -1; + return 0; } - if (lseek(bin->fd, shdrp->sh_offset, SEEK_SET) < 0) - perror("lseek"); - if (read(bin->fd, rel, shdrp->sh_size) != shdrp->sh_size) - perror("read"); + eprintf ("shdrp->sh_offset = %08llx\n", (ut64)shdrp->sh_offset); + if (r_buf_read_at(bin->b, shdrp->sh_offset, (ut8*)rel, shdrp->sh_size) == -1) + perror("read (rel)"); got_offset = (rel->r_offset - bin->baddr - got_addr) & ELF_GOTOFF_MASK; for (j = 0, relp = rel; j < shdrp->sh_size; j += sizeof(Elf_(Rel)), relp++) { - r_mem_copyendian((u8*)&(relp->r_offset), sizeof(Elf_(Addr)), !bin->endian); + r_mem_copyendian((ut8*)&(relp->r_offset), (ut8*)&(relp->r_offset), + sizeof(Elf_(Addr)), !bin->endian); /* rewrite relp->r_offset */ if (relp->r_offset - bin->baddr - got_offset >= rsz_offset + rsz_osize) { relp->r_offset+=delta; off = shdrp->sh_offset + j; - - if (lseek(bin->fd, off, SEEK_SET) < 0) - perror("lseek"); - if (write(bin->fd, &relp, sizeof(Elf_(Rel))) != sizeof(Elf_(Rel))) + if (r_buf_write_at (bin->b, off, (ut8*)relp, sizeof (Elf_(Rel))) == -1) perror("write (imports)"); } } @@ -87,25 +82,22 @@ u64 Elf_(r_bin_elf_resize_section)(struct Elf_(r_bin_elf_obj_t) *bin, const char rel = (Elf_(Rela) *)malloc(shdrp->sh_size); if (rel == NULL) { perror("malloc"); - return -1; + return 0; } - if (lseek(bin->fd, shdrp->sh_offset, SEEK_SET) < 0) - perror("lseek"); - if (read(bin->fd, rel, shdrp->sh_size) != shdrp->sh_size) - perror("read"); + if (r_buf_read_at(bin->b, shdrp->sh_offset, (ut8*)rel, shdrp->sh_size) == -1) + perror("read (rel)"); got_offset = (rel->r_offset - bin->baddr - got_addr) & ELF_GOTOFF_MASK; for (j = 0, relp = rel; j < shdrp->sh_size; j += sizeof(Elf_(Rela)), relp++) { - r_mem_copyendian((u8*)&(relp->r_offset), sizeof(Elf_(Addr)), !bin->endian); + r_mem_copyendian((ut8*)&(relp->r_offset), (ut8*)&(relp->r_offset), + sizeof(Elf_(Addr)), !bin->endian); /* rewrite relp->r_offset */ if (relp->r_offset - bin->baddr - got_offset >= rsz_offset + rsz_osize) { relp->r_offset+=delta; off = shdrp->sh_offset + j; - if (lseek(bin->fd, off, SEEK_SET) < 0) - perror("lseek"); - if (write(bin->fd, &relp, sizeof(Elf_(Rela))) != sizeof(Elf_(Rela))) + if (r_buf_write_at (bin->b, off, (ut8*)relp, sizeof (Elf_(Rela))) == -1) perror("write (imports)"); } } @@ -125,9 +117,7 @@ u64 Elf_(r_bin_elf_resize_section)(struct Elf_(r_bin_elf_obj_t) *bin, const char } off = ehdr->e_shoff + i * sizeof(Elf_(Shdr)); - if (lseek(bin->fd, off, SEEK_SET) < 0) - perror("lseek"); - if (write(bin->fd, shdrp, sizeof(Elf_(Shdr))) != sizeof(Elf_(Shdr))) + if (r_buf_write_at (bin->b, off, (ut8*)shdrp, sizeof (Elf_(Shdr))) == -1) perror("write (shdr)"); printf("-> elf section (%s)\n", &strtab[shdrp->sh_name]); } @@ -146,11 +136,9 @@ u64 Elf_(r_bin_elf_resize_section)(struct Elf_(r_bin_elf_obj_t) *bin, const char if (phdrp->p_paddr) phdrp->p_paddr += delta; } off = ehdr->e_phoff + i * sizeof(Elf_(Phdr)); - if (lseek(bin->fd, off, SEEK_SET) < 0) - perror("lseek"); - if (write(bin->fd, phdrp, sizeof(Elf_(Phdr))) != sizeof(Elf_(Phdr))) + if (r_buf_write_at (bin->b, off, (ut8*)phdrp, sizeof (Elf_(Phdr))) == -1) perror("write (phdr)"); - printf("-> program header (%08llx)\n", (u64) phdrp->p_offset); + printf("-> program header (%08llx)\n", (ut64) phdrp->p_offset); } /* rewrite other elf pointers (entrypoint, phoff, shoff) */ @@ -160,28 +148,24 @@ u64 Elf_(r_bin_elf_resize_section)(struct Elf_(r_bin_elf_obj_t) *bin, const char ehdr->e_phoff += delta; if (ehdr->e_shoff >= rsz_offset + rsz_osize) ehdr->e_shoff += delta; - if (lseek(bin->fd, 0, SEEK_SET) < 0) - perror("lseek"); - if (write(bin->fd, ehdr, sizeof(Elf_(Ehdr))) != sizeof(Elf_(Ehdr))) + if (r_buf_write_at (bin->b, 0, (ut8*)ehdr, sizeof (Elf_(Ehdr))) == -1) perror("write (ehdr)"); /* inverse order to write bodies .. avoid overlapping here */ /* XXX Check when delta is negative */ - rest_size = rsz_fsize - (rsz_offset + rsz_osize); - buf = (u8 *)malloc(rest_size); - printf("COPY FROM 0x%08llx\n", (u64) rsz_offset+rsz_osize); - lseek(bin->fd, rsz_offset+rsz_osize, SEEK_SET); - read(bin->fd, buf, rest_size); + rest_size = bin->size - (rsz_offset + rsz_osize); - printf("COPY TO 0x%08llx\n", (u64) rsz_offset+rsz_size); - lseek(bin->fd, rsz_offset+rsz_size, SEEK_SET); - write(bin->fd, buf, rest_size); + buf = (ut8 *)malloc (bin->size); + r_buf_read_at (bin->b, 0, (ut8*)buf, bin->size); + r_buf_set_bytes (bin->b, (ut8*)buf, rsz_offset+rsz_size+rest_size); + + printf("COPY FROM 0x%08llx\n", (ut64) rsz_offset+rsz_osize); + r_buf_read_at(bin->b, rsz_offset+rsz_osize, (ut8*)buf, rest_size); + printf("COPY TO 0x%08llx\n", (ut64) rsz_offset+rsz_size); + r_buf_write_at (bin->b, rsz_offset+rsz_size, (ut8*)buf, rest_size); printf("Shifted %d bytes\n", (int)delta); free(buf); - - /* Reinit structs*/ - Elf_(r_bin_elf_init)(bin); + bin->size = rsz_offset+rsz_size+rest_size; return delta; } -#endif diff --git a/libr/bin/p/bin_write_elf.c b/libr/bin/p/bin_write_elf.c index e3882eb5e8..3d7cf5a992 100644 --- a/libr/bin/p/bin_write_elf.c +++ b/libr/bin/p/bin_write_elf.c @@ -2,15 +2,15 @@ #include #include +#include "elf/elf.h" -static int scn_set(RBin *bin, RBinSection *scn) { - /* TODO */ - return R_FALSE; +static ut64 scn_resize(RBin *bin, const char *name, ut64 size) { + return Elf_(r_bin_elf_resize_section) (bin->bin_obj, name, size); } #if !R_BIN_ELF64 struct r_bin_write_t r_bin_write_elf = { - .scn_set = &scn_set, + .scn_resize = &scn_resize, }; #endif diff --git a/libr/bin/p/bin_write_elf64.c b/libr/bin/p/bin_write_elf64.c index 81a62fddee..77083437ef 100644 --- a/libr/bin/p/bin_write_elf64.c +++ b/libr/bin/p/bin_write_elf64.c @@ -4,5 +4,5 @@ #include "bin_write_elf.c" struct r_bin_write_t r_bin_write_elf64 = { - .scn_set = &scn_set, + .scn_resize = &scn_resize, }; diff --git a/libr/bin/t/rabin2.c b/libr/bin/t/rabin2.c index 3493120ce0..31d26f1ed6 100644 --- a/libr/bin/t/rabin2.c +++ b/libr/bin/t/rabin2.c @@ -28,11 +28,12 @@ #define ACTION_LIBS 0x0200 static struct r_lib_t l; -static struct r_bin_t *bin; +static struct r_bin_t *bin = NULL; static int rad = R_FALSE; static int rw = R_FALSE; static int va = R_FALSE; -static char* file; +static char* file = NULL; +static char* output = "a.out"; static int rabin_show_help() { printf ("rabin2 [options] [file]\n" @@ -44,7 +45,8 @@ static int rabin_show_help() { " -I Binary info\n" " -H Header fields\n" " -l Linked libraries\n" - " -o [str] Write/Extract operations (str=help for help)\n" + " -O [str] Write/Extract operations (str=help for help)\n" + " -o [file] Output file for write operations (a.out by default)\n" " -f [format] Override file format autodetection\n" " -r radare output\n" " -v Use vaddr in radare output\n" @@ -439,7 +441,8 @@ static int rabin_do_operation(const char *op) { if (!strcmp (op, "help")) { printf ("Operation string:\n" " Dump symbols: d/s/1024\n" - " Dump section: d/S/.text\n"); + " Dump section: d/S/.text\n" + " Resize section: r/.data/1024\n"); return R_FALSE; } arg = alloca (strlen(op)+1); @@ -472,9 +475,13 @@ static int rabin_do_operation(const char *op) { return R_FALSE; } else goto _rabin_do_operation_error; break; + case 'r': + r_bin_wr_scn_resize (bin, ptr, r_num_math (NULL, ptr2)); + r_bin_wr_output (bin, output); + break; default: -_rabin_do_operation_error: - printf ("Unknown operation. use -o help\n"); + _rabin_do_operation_error: + printf ("Unknown operation. use -O help\n"); return R_FALSE; } @@ -513,7 +520,7 @@ int main(int argc, char **argv) r_lib_opendir (&l, LIBDIR"/radare2/"); } - while ((c = getopt (argc, argv, "@:VisSzIHelwo:f:rvLh")) != -1) + while ((c = getopt (argc, argv, "@:VisSzIHelwO:o:f:rvLh")) != -1) { switch(c) { case 'i': @@ -543,10 +550,13 @@ int main(int argc, char **argv) case 'w': rw = R_TRUE; break; - case 'o': + case 'O': op = optarg; action |= ACTION_OPERATION; break; + case 'o': + output = optarg; + break; case 'f': format = optarg; break; diff --git a/libr/include/r_bin.h b/libr/include/r_bin.h index 9bb0341cd3..b65c5b649b 100644 --- a/libr/include/r_bin.h +++ b/libr/include/r_bin.h @@ -130,7 +130,7 @@ typedef struct r_bin_meta_t { } RBinMeta; typedef struct r_bin_write_t { - int (*scn_set)(RBin *bin, struct r_bin_section_t *scn); + ut64 (*scn_resize)(RBin *bin, const char *name, ut64 size); } RBinWrite; #ifdef R_API @@ -158,7 +158,8 @@ R_API void r_bin_set_user_ptr(RBin *bin, void *user); R_API int r_bin_meta_get_line(RBin *bin, ut64 addr, char *file, int len, int *line); /* bin_write.c */ -R_API int r_bin_wr_scn_set(RBin *bin, RBinSection *scn); +R_API ut64 r_bin_wr_scn_resize(RBin *bin, const char *name, ut64 size); +R_API int r_bin_wr_output(RBin *bin, const char *filename); #endif #endif