- More work on r_bin write
  - Add elf & elf64 section resize
    Needs refactoring and split into basic operations
* rabin2
  - Rename flag -o to -O for operations
  - Add flag -o for output file
  - Add resize operation (-O r/.data/1024) for testing purposes
This commit is contained in:
Nibble 2010-03-11 02:14:34 +01:00
parent b65fbeb772
commit 423d6a75f4
7 changed files with 74 additions and 69 deletions

View File

@ -1,10 +1,18 @@
/* radare - LGPL - Copyright 2009-2010 nibble<.ds@gmail.com> */
#include <r_types.h>
#include <r_util.h>
#include <r_bin.h>
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;
}

View File

@ -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);

View File

@ -7,33 +7,31 @@
#include <r_util.h>
#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

View File

@ -2,15 +2,15 @@
#include <r_types.h>
#include <r_bin.h>
#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

View File

@ -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,
};

View File

@ -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;

View File

@ -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