diff --git a/libr/bin/bin.c b/libr/bin/bin.c index af6952ba9f..c96cf8c6bf 100644 --- a/libr/bin/bin.c +++ b/libr/bin/bin.c @@ -25,7 +25,7 @@ static struct r_bin_string_t *get_strings(struct r_bin_t *bin, int min) u8 *buf = NULL; u64 len, max_str = 0; int i, matches = 0, ctr = 0; - char str[R_BIN_SIZEOF_NAMES]; + char str[R_BIN_SIZEOF_STRINGS]; len = lseek(bin->fd, 0, SEEK_END); max_str = (u64)(len/min); @@ -52,8 +52,8 @@ static struct r_bin_string_t *get_strings(struct r_bin_t *bin, int min) ret[ctr].rva = ret[ctr].offset = i-matches; ret[ctr].size = matches; ret[ctr].ordinal = ctr; - memcpy(ret[ctr].string, str, R_BIN_SIZEOF_NAMES); - ret[ctr].string[R_BIN_SIZEOF_NAMES-1] = '\0'; + memcpy(ret[ctr].string, str, R_BIN_SIZEOF_STRINGS); + ret[ctr].string[R_BIN_SIZEOF_STRINGS-1] = '\0'; ret[ctr].last = 0; ctr++; } @@ -127,7 +127,7 @@ int r_bin_open(struct r_bin_t *bin, const char *file, int rw, char *plugin_name) { if (file != NULL) bin->file = file; - else return R_FALSE; + else return -1; bin->rw = rw; struct list_head *pos; @@ -141,7 +141,7 @@ int r_bin_open(struct r_bin_t *bin, const char *file, int rw, char *plugin_name) if (bin->cur && bin->cur->open) return bin->cur->open(bin); if (plugin_name && !strcmp(plugin_name, "bin_dummy")) - return R_FALSE; + return -1; return r_bin_open(bin, file, rw, "bin_dummy"); } @@ -150,7 +150,7 @@ int r_bin_close(struct r_bin_t *bin) if (bin->cur && bin->cur->close) return bin->cur->close(bin); - return R_FALSE; + return -1; } u64 r_bin_get_baddr(struct r_bin_t *bin) @@ -158,7 +158,7 @@ u64 r_bin_get_baddr(struct r_bin_t *bin) if (bin->cur && bin->cur->baddr) return bin->cur->baddr(bin); - return R_FALSE; + return -1; } struct r_bin_entry_t* r_bin_get_entry(struct r_bin_t *bin) @@ -218,32 +218,32 @@ struct r_bin_field_t* r_bin_get_fields(struct r_bin_t *bin) return NULL; } +/*XXX*/ +#if 0 u64 r_bin_resize_section(struct r_bin_t *bin, char *name, u64 size) { if (bin->cur && bin->cur->resize_section) return bin->cur->resize_section(bin, name, size); - return 0; + return -1; } +#endif u64 r_bin_get_section_offset(struct r_bin_t *bin, char *name) { - struct r_bin_section_t *sections, *sectionsp; + struct r_bin_section_t *sections; u64 ret = -1; + int i; if (!(sections = r_bin_get_sections(bin))) return R_FALSE; - sectionsp = sections; - while (!sectionsp->last) { - if (!strcmp(sectionsp->name, name)) { - ret = sectionsp->offset; + for (i = 0; !sections[i].last; i++) + if (!strcmp(sections[i].name, name)) { + ret = sections[i].offset; break; } - sectionsp++; - } - free(sections); return ret; @@ -251,20 +251,18 @@ u64 r_bin_get_section_offset(struct r_bin_t *bin, char *name) u64 r_bin_get_section_rva(struct r_bin_t *bin, char *name) { - struct r_bin_section_t *sections, *sectionsp; + struct r_bin_section_t *sections; u64 ret = -1; + int i; if (!(sections = r_bin_get_sections(bin))) return R_FALSE; - sectionsp = sections; - while (!sectionsp->last) { - if (!strcmp(sectionsp->name, name)) { - ret = sectionsp->rva; + for (i = 0; !sections[i].last; i++) { + if (!strcmp(sections[i].name, name)) { + ret = sections[i].rva; break; } - - sectionsp++; } free(sections); @@ -274,19 +272,18 @@ u64 r_bin_get_section_rva(struct r_bin_t *bin, char *name) u64 r_bin_get_section_size(struct r_bin_t *bin, char *name) { - struct r_bin_section_t *sections, *sectionsp; + struct r_bin_section_t *sections; u64 ret = -1; + int i; if (!(sections = r_bin_get_sections(bin))) return R_FALSE; - sectionsp = sections; - while (!sectionsp->last) { - if (!strcmp(sectionsp->name, name)) { - ret = sectionsp->size; + for (i = 0; !sections[i].last; i++) { + if (!strcmp(sections[i].name, name)) { + ret = sections[i].size; break; } - sectionsp++; } free(sections); diff --git a/libr/bin/format/elf/elf.c b/libr/bin/format/elf/elf.c index 884ba657f8..83ee0f25a6 100644 --- a/libr/bin/format/elf/elf.c +++ b/libr/bin/format/elf/elf.c @@ -3,714 +3,467 @@ #include #include #include -#include #include #include -#if __UNIX__ -#include -#endif #include +#include #include "elf.h" -/* TODO: move into bin_t */ -static int endian = 0; - -enum { - ENCODING_ASCII = 0, - ENCODING_CP850 = 1 -}; - -static void ELF_(aux_swap_endian)(u8 *value, int size) +static int Elf_(r_bin_elf_init_ehdr)(struct Elf_(r_bin_elf_obj_t) *bin) { - unsigned char buffer[8]; - - if (!endian) - return; - - switch(size) { - case 2: - memcpy(buffer, value, 2); - value[0] = buffer[1]; - value[1] = buffer[0]; - break; - case 4: - memcpy(buffer, value, 4); - value[0] = buffer[3]; - value[1] = buffer[2]; - value[2] = buffer[1]; - value[3] = buffer[0]; - break; - case 8: - memcpy(buffer, value, 8); - value[0] = buffer[7]; - value[1] = buffer[6]; - value[2] = buffer[5]; - value[3] = buffer[4]; - value[4] = buffer[3]; - value[5] = buffer[2]; - value[6] = buffer[1]; - value[7] = buffer[0]; - break; - default: - printf("Invalid size: %d\n", size); - } -} - -static int ELF_(aux_is_encoded)(int encoding, unsigned char c) -{ - switch(encoding) { - case ENCODING_ASCII: - break; - case ENCODING_CP850: - switch(c) { - // CP850 - case 128: // cedilla - case 133: // a grave - case 135: // minicedilla - case 160: // a acute - case 161: // i acute - case 129: // u dieresi - case 130: // e acute - case 139: // i dieresi - case 162: // o acute - case 163: // u acute - case 164: // enye - case 165: // enyemay - case 181: // A acute - case 144: // E acute - case 214: // I acute - case 224: // O acute - case 233: // U acute - return 1; - } - break; - } - return 0; -} - -static int ELF_(aux_stripstr_from_file)(const char *filename, int min, int encoding, u64 seek, u64 limit, const char *filter, int str_limit, r_bin_elf_string *strings) -{ - r_bin_elf_string *stringsp; - unsigned char *buf; - u64 i = seek; - u64 len, string_len; - int unicode = 0, matches = 0; - static int ctr = 0; - char str[ELF_STRING_LENGTH]; - - int fd = open(filename, O_RDONLY); - if (fd == -1) { - ERR("Cannot open target file.\n"); - return 1; - } - - len = lseek(fd, 0, SEEK_END); - - /* TODO: do not use mmap (is faster..but not portable) */ -#if __UNIX__ - buf = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0); // XXX SHARED? - if (((long)buf) == -1) { - perror("mmap"); - return 1; - } - if (min <1) - min = 5; - - if (limit && limit < len) - len = limit; - - stringsp = strings; - for(i = seek; i < len && ctr < str_limit; i++) { - if (IS_PRINTABLE(buf[i]) || (ELF_(aux_is_encoded)(encoding, buf[i]))) { - str[matches] = buf[i]; - if (matches < sizeof(str)) - matches++; - } else { - /* wide char check \x??\x00\x??\x00 */ - if (matches && buf[i+2]=='\0' && buf[i]=='\0' && buf[i+1]!='\0') - unicode = 1; - /* check if the length fits on our request */ - if (matches >= min) { - str[matches] = '\0'; - string_len = strlen(str); - if (string_len>2) { - if (!filter || strstr(str, filter)) { - stringsp->offset = i-matches; - stringsp->type = (unicode?'U':'A'); - stringsp->size = string_len; - memcpy(stringsp->string, str, ELF_STRING_LENGTH); - stringsp->string[ELF_STRING_LENGTH-1] = '\0'; - ctr++; stringsp++; - } - } - } - matches = 0; - unicode = 0; - } - } - - munmap(buf, len); -#elif __WINDOWS__ - ERR("Not yet implemented\n"); -#endif - return ctr; -} - -static int ELF_(do_elf_checks)(ELF_(r_bin_elf_obj) *bin) -{ - ELF_(Ehdr) *ehdr = &bin->ehdr; - - if (strncmp((char *)ehdr->e_ident, ELFMAG, SELFMAG)) { - ERR("File not ELF\n"); - return -1; - } - - if (ehdr->e_version != EV_CURRENT) { - ERR("ELF version not current\n"); - return -1; - } - - return 0; -} - -static int ELF_(load_section)(char **section, int fd, ELF_(Shdr) *shdr) -{ - if (lseek(fd, shdr->sh_offset, SEEK_SET) < 0) { - perror("lseek"); - return -1; - } - - *section = (char *)malloc(shdr->sh_size); - if (*section == NULL) { - perror("malloc"); - return -1; - } - - if (read(fd, *section, shdr->sh_size) != shdr->sh_size) { - perror("read"); - return -1; - } - - return 0; -} - -static int ELF_(r_bin_elf_init)(ELF_(r_bin_elf_obj) *bin) -{ - ELF_(Ehdr) *ehdr; - ELF_(Shdr) *shdr; - ELF_(Shdr) *strtabhdr; - ELF_(Phdr) *phdr; - char **sectionp; - int i, slen; - - bin->base_addr = 0; - ehdr = &bin->ehdr; - if (lseek(bin->fd, 0, SEEK_SET) < 0) { - perror("lseek"); - return -1; + perror("lseek (ehdr)"); + return R_FALSE; } - if (read(bin->fd, ehdr, sizeof(ELF_(Ehdr))) != sizeof(ELF_(Ehdr))) { - perror("read"); - return -1; + if (read(bin->fd, &bin->ehdr, sizeof(Elf_(Ehdr))) != sizeof(Elf_(Ehdr))) { + perror("read (ehdr)"); + return R_FALSE; } - if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) - endian = LIL_ENDIAN; - else endian = !LIL_ENDIAN; + if (bin->ehdr.e_ident[EI_DATA] == ELFDATA2MSB) + bin->endian = LIL_ENDIAN; + else bin->endian = !LIL_ENDIAN; - ELF_(aux_swap_endian)((u8*)&(ehdr->e_type), sizeof(ELF_(Half))); - ELF_(aux_swap_endian)((u8*)&(ehdr->e_machine), sizeof(ELF_(Half))); - ELF_(aux_swap_endian)((u8*)&(ehdr->e_version), sizeof(ELF_(Word))); - ELF_(aux_swap_endian)((u8*)&(ehdr->e_entry), sizeof(ELF_(Addr))); - ELF_(aux_swap_endian)((u8*)&(ehdr->e_phoff), sizeof(ELF_(Off))); - ELF_(aux_swap_endian)((u8*)&(ehdr->e_shoff), sizeof(ELF_(Off))); - ELF_(aux_swap_endian)((u8*)&(ehdr->e_flags), sizeof(ELF_(Word))); - ELF_(aux_swap_endian)((u8*)&(ehdr->e_ehsize), sizeof(ELF_(Half))); - ELF_(aux_swap_endian)((u8*)&(ehdr->e_phentsize), sizeof(ELF_(Half))); - ELF_(aux_swap_endian)((u8*)&(ehdr->e_phnum), sizeof(ELF_(Half))); - ELF_(aux_swap_endian)((u8*)&(ehdr->e_shentsize), sizeof(ELF_(Half))); - ELF_(aux_swap_endian)((u8*)&(ehdr->e_shnum), sizeof(ELF_(Half))); - ELF_(aux_swap_endian)((u8*)&(ehdr->e_shstrndx), sizeof(ELF_(Half))); + r_mem_copyendian((u8*)&(bin->ehdr.e_type), (u8*)&(bin->ehdr.e_type), sizeof(Elf_(Half)), !bin->endian); + r_mem_copyendian((u8*)&(bin->ehdr.e_machine), (u8*)&(bin->ehdr.e_machine), sizeof(Elf_(Half)), !bin->endian); + r_mem_copyendian((u8*)&(bin->ehdr.e_version), (u8*)&(bin->ehdr.e_version), sizeof(Elf_(Word)), !bin->endian); + r_mem_copyendian((u8*)&(bin->ehdr.e_entry), (u8*)&(bin->ehdr.e_entry), sizeof(Elf_(Addr)), !bin->endian); + r_mem_copyendian((u8*)&(bin->ehdr.e_phoff), (u8*)&(bin->ehdr.e_phoff), sizeof(Elf_(Off)), !bin->endian); + r_mem_copyendian((u8*)&(bin->ehdr.e_shoff), (u8*)&(bin->ehdr.e_shoff), sizeof(Elf_(Off)), !bin->endian); + r_mem_copyendian((u8*)&(bin->ehdr.e_flags), (u8*)&(bin->ehdr.e_flags), sizeof(Elf_(Word)), !bin->endian); + r_mem_copyendian((u8*)&(bin->ehdr.e_ehsize), (u8*)&(bin->ehdr.e_ehsize), sizeof(Elf_(Half)), !bin->endian); + r_mem_copyendian((u8*)&(bin->ehdr.e_phentsize), (u8*)&(bin->ehdr.e_phentsize), sizeof(Elf_(Half)), !bin->endian); + r_mem_copyendian((u8*)&(bin->ehdr.e_phnum), (u8*)&(bin->ehdr.e_phnum), sizeof(Elf_(Half)), !bin->endian); + r_mem_copyendian((u8*)&(bin->ehdr.e_shentsize), (u8*)&(bin->ehdr.e_shentsize), sizeof(Elf_(Half)), !bin->endian); + r_mem_copyendian((u8*)&(bin->ehdr.e_shnum), (u8*)&(bin->ehdr.e_shnum), sizeof(Elf_(Half)), !bin->endian); + r_mem_copyendian((u8*)&(bin->ehdr.e_shstrndx), (u8*)&(bin->ehdr.e_shstrndx), sizeof(Elf_(Half)), !bin->endian); -//printf("E_SHOFF: %x\n", ehdr->e_shoff); - if (ELF_(do_elf_checks)(bin) == -1) - return -1; + if (strncmp((char *)bin->ehdr.e_ident, ELFMAG, SELFMAG)) + return R_FALSE; - bin->phdr = (ELF_(Phdr) *)malloc(bin->plen = sizeof(ELF_(Phdr))*ehdr->e_phnum); - if (bin->phdr == NULL) { - perror("malloc"); - return -1; - } - - if (lseek(bin->fd, ehdr->e_phoff, SEEK_SET) < 0) { - perror("lseek"); - return -1; - } - - if (read(bin->fd, bin->phdr, bin->plen) != bin->plen) { - ERR("Warning: Cannot read program headers (0x%08x->0x%08x)\n", - (unsigned int)ehdr->e_phoff, (unsigned int)((long)&ehdr->e_phoff-(long)&ehdr->e_ident)); - perror("read"); - //return -1; - } - - for (i = 0, phdr = bin->phdr; i < ehdr->e_phnum; i++) { - ELF_(aux_swap_endian)((u8*)&(phdr[i].p_type), sizeof(ELF_(Word))); - ELF_(aux_swap_endian)((u8*)&(phdr[i].p_offset), sizeof(ELF_(Off))); - ELF_(aux_swap_endian)((u8*)&(phdr[i].p_vaddr), sizeof(ELF_(Addr))); - ELF_(aux_swap_endian)((u8*)&(phdr[i].p_paddr), sizeof(ELF_(Addr))); - ELF_(aux_swap_endian)((u8*)&(phdr[i].p_filesz), sizeof(ELF_Vword)); - ELF_(aux_swap_endian)((u8*)&(phdr[i].p_memsz), sizeof(ELF_Vword)); - ELF_(aux_swap_endian)((u8*)&(phdr[i].p_flags), sizeof(ELF_(Word))); - ELF_(aux_swap_endian)((u8*)&(phdr[i].p_align), sizeof(ELF_Vword)); - } - - bin->shdr = (ELF_(Shdr) *)malloc(slen = sizeof(ELF_(Shdr))*ehdr->e_shnum); - if (bin->shdr == NULL) { - perror("malloc"); - return -1; - } - - bin->section = (char **)malloc(sizeof(char **)*ehdr->e_shnum); - if (bin->section == NULL) { - perror("malloc"); - return -1; - } - - //printf("shtoff = %d\n", ehdr->e_shoff); - if (lseek(bin->fd, ehdr->e_shoff, SEEK_SET) < 0) { - perror("lseek"); - //return -1; - } - - //printf("shtlen = %d\n", slen); - if (read(bin->fd, bin->shdr, slen) != slen) { - ERR("Warning: Cannot read section headers (0x%08x->0x%08x)\n", - (unsigned int)ehdr->e_shoff, (unsigned int)((long)&ehdr->e_shoff-(long)&ehdr->e_ident)); - perror("read"); - ERR("Warning: Cannot read %d sections.\n", ehdr->e_shnum); - ehdr->e_shnum=0; - //return -1; - } - - for (i = 0, shdr = bin->shdr; i < ehdr->e_shnum; i++) { - ELF_(aux_swap_endian)((u8*)&(shdr[i].sh_name), sizeof(ELF_(Word))); - ELF_(aux_swap_endian)((u8*)&(shdr[i].sh_type), sizeof(ELF_(Word))); - ELF_(aux_swap_endian)((u8*)&(shdr[i].sh_flags), sizeof(ELF_Vword)); - ELF_(aux_swap_endian)((u8*)&(shdr[i].sh_addr), sizeof(ELF_(Addr))); - ELF_(aux_swap_endian)((u8*)&(shdr[i].sh_offset), sizeof(ELF_(Off))); - ELF_(aux_swap_endian)((u8*)&(shdr[i].sh_size), sizeof(ELF_Vword)); - ELF_(aux_swap_endian)((u8*)&(shdr[i].sh_link), sizeof(ELF_(Word))); - ELF_(aux_swap_endian)((u8*)&(shdr[i].sh_info), sizeof(ELF_(Word))); - ELF_(aux_swap_endian)((u8*)&(shdr[i].sh_addralign), sizeof(ELF_Vword)); - ELF_(aux_swap_endian)((u8*)&(shdr[i].sh_entsize), sizeof(ELF_Vword)); - } - - strtabhdr = &bin->shdr[ehdr->e_shstrndx]; - - bin->string = (char *)malloc(strtabhdr->sh_size); - if (bin->string == NULL) { - perror("malloc"); - return -1; - } - - if (lseek(bin->fd, strtabhdr->sh_offset, SEEK_SET) != strtabhdr->sh_offset) { - perror("lseek"); - //return -1; - } - - if (read(bin->fd, bin->string, strtabhdr->sh_size) != strtabhdr->sh_size) { - perror("read"); - ERR("Warning: Cannot read strtabhdr.\n"); - //return -1; - } - - bin->bss = -1; - - for (i = 0, sectionp = bin->section, shdr = bin->shdr; i < ehdr->e_shnum; i++, sectionp++) { - if (shdr[i].sh_type == SHT_NOBITS) { - bin->bss = i; - } else { - if (ELF_(load_section)(sectionp, bin->fd, &shdr[i]) == -1) - return -1; - } - } - - bin->base_addr = ELF_(r_bin_elf_get_base_addr)(bin); - - return 0; + return R_TRUE; } -static u64 ELF_(get_import_addr)(ELF_(r_bin_elf_obj) *bin, int sym) +static int Elf_(r_bin_elf_init_phdr)(struct Elf_(r_bin_elf_obj_t) *bin) { - ELF_(Ehdr) *ehdr = &bin->ehdr; - ELF_(Shdr) *shdr = bin->shdr, *shdrp; - ELF_(Addr) plt_sym_addr, got_addr = 0; - const char *string = bin->string; - int i, j; - u64 got_offset; + int phdr_size, i; + + phdr_size = bin->ehdr.e_phnum * sizeof(Elf_(Phdr)); + if ((bin->phdr = (Elf_(Phdr) *)malloc(phdr_size)) == NULL) { + perror("malloc (phdr)"); + return R_FALSE; + } + if (lseek(bin->fd, bin->ehdr.e_phoff, SEEK_SET) < 0) { + perror("lseek (phdr)"); + return R_FALSE; + } + if (read(bin->fd, bin->phdr, phdr_size) != phdr_size) { + perror("read (phdr)"); + return R_FALSE; + } + + for (i = 0; i < bin->ehdr.e_phnum; i++) { + r_mem_copyendian((u8*)&(bin->phdr[i].p_type), (u8*)&(bin->phdr[i].p_type), sizeof(Elf_(Word)), !bin->endian); + r_mem_copyendian((u8*)&(bin->phdr[i].p_offset), (u8*)&(bin->phdr[i].p_offset), sizeof(Elf_(Off)), !bin->endian); + r_mem_copyendian((u8*)&(bin->phdr[i].p_vaddr), (u8*)&(bin->phdr[i].p_vaddr), sizeof(Elf_(Addr)), !bin->endian); + r_mem_copyendian((u8*)&(bin->phdr[i].p_paddr), (u8*)&(bin->phdr[i].p_paddr), sizeof(Elf_(Addr)), !bin->endian); + r_mem_copyendian((u8*)&(bin->phdr[i].p_filesz), (u8*)&(bin->phdr[i].p_filesz), sizeof(Elf_Vword), !bin->endian); + r_mem_copyendian((u8*)&(bin->phdr[i].p_memsz), (u8*)&(bin->phdr[i].p_memsz), sizeof(Elf_Vword), !bin->endian); + r_mem_copyendian((u8*)&(bin->phdr[i].p_flags), (u8*)&(bin->phdr[i].p_flags), sizeof(Elf_(Word)), !bin->endian); + r_mem_copyendian((u8*)&(bin->phdr[i].p_align), (u8*)&(bin->phdr[i].p_align), sizeof(Elf_Vword), !bin->endian); + } + + return R_TRUE; +} + +static int Elf_(r_bin_elf_init_shdr)(struct Elf_(r_bin_elf_obj_t) *bin) +{ + int shdr_size, i; - shdrp = shdr; - for (i = 0; i < ehdr->e_shnum; i++, shdrp++) { - if (!strcmp(&string[shdrp->sh_name], ".got")) - got_addr = shdrp->sh_offset; + shdr_size = bin->ehdr.e_shnum * sizeof(Elf_(Shdr)); + if ((bin->shdr = (Elf_(Shdr) *)malloc(shdr_size)) == NULL) { + perror("malloc (shdr)"); + return R_FALSE; } - if (got_addr == 0) { - /* TODO: Unknown GOT address */ + if (lseek(bin->fd, bin->ehdr.e_shoff, SEEK_SET) < 0) { + perror("lseek (shdr)"); + return R_FALSE; + } + if (read(bin->fd, bin->shdr, shdr_size) != shdr_size) { + perror("read (shdr)"); + return R_FALSE; } - shdrp = shdr; - for (i = 0; i < ehdr->e_shnum; i++, shdrp++) { - if (!strcmp(&string[shdrp->sh_name], ".rel.plt")) { - ELF_(Rel) *rel, *relp; - rel = (ELF_(Rel) *)malloc(shdrp->sh_size); - if (rel == NULL) { - perror("malloc"); - return 0; - } - - if (lseek(bin->fd, shdrp->sh_offset, SEEK_SET) != shdrp->sh_offset) { - perror("lseek"); - return 0; - } - - if (read(bin->fd, rel, shdrp->sh_size) != shdrp->sh_size) { - perror("read"); - return 0; - } - - relp = rel; - for (j = 0; j < shdrp->sh_size; j += sizeof(ELF_(Rel)), relp++) { - ELF_(aux_swap_endian)((u8*)&(relp->r_offset), sizeof(ELF_(Addr))); - ELF_(aux_swap_endian)((u8*)&(relp->r_info), sizeof(ELF_Vword)); - } - - got_offset = (rel->r_offset - bin->base_addr - got_addr) & ELF_GOTOFF_MASK; - relp = rel; - for (j = 0; j < shdrp->sh_size; j += sizeof(ELF_(Rel)), relp++) { - if (ELF_R_SYM(relp->r_info) == sym) { - if (lseek(bin->fd, relp->r_offset-bin->base_addr-got_offset, SEEK_SET) - != relp->r_offset-bin->base_addr-got_offset) { - perror("lseek"); - return 0; - } - - if (read(bin->fd, &plt_sym_addr, sizeof(ELF_(Addr))) != sizeof(ELF_(Addr))) { - perror("read"); - return 0; - } - - return plt_sym_addr-6; - } - } - } else if (!strcmp(&string[shdrp->sh_name], ".rela.plt")) { - ELF_(Rela) *rel, *relp; - rel = (ELF_(Rela) *)malloc(shdrp->sh_size); - if (rel == NULL) { - perror("malloc"); - return -1; - } - - if (lseek(bin->fd, shdrp->sh_offset, SEEK_SET) != shdrp->sh_offset) { - perror("lseek"); - return -1; - } - - if (read(bin->fd, rel, shdrp->sh_size) != shdrp->sh_size) { - perror("read"); - return -1; - } - - relp = rel; - for (j = 0; j < shdrp->sh_size; j += sizeof(ELF_(Rela)), relp++) { - ELF_(aux_swap_endian)((u8*)&(relp->r_offset), sizeof(ELF_(Addr))); - ELF_(aux_swap_endian)((u8*)&(relp->r_info), sizeof(ELF_Vword)); - } - - got_offset = (rel->r_offset - bin->base_addr - got_addr) & ELF_GOTOFF_MASK; - relp = rel; - for (j = 0; j < shdrp->sh_size; j += sizeof(ELF_(Rela)), relp++) { - if (ELF_R_SYM(relp->r_info) == sym) { - if (lseek(bin->fd, relp->r_offset-bin->base_addr-got_offset, SEEK_SET) - != relp->r_offset-bin->base_addr-got_offset) { - perror("lseek"); - return 0; - } - - if (read(bin->fd, &plt_sym_addr, sizeof(ELF_(Addr))) != sizeof(ELF_(Addr))) { - perror("read"); - return 0; - } - - return plt_sym_addr-6; - } - } - } + for (i = 0; i < bin->ehdr.e_shnum; i++) { + r_mem_copyendian((u8*)&(bin->shdr[i].sh_name), (u8*)&(bin->shdr[i].sh_name), sizeof(Elf_(Word)), !bin->endian); + r_mem_copyendian((u8*)&(bin->shdr[i].sh_type), (u8*)&(bin->shdr[i].sh_type), sizeof(Elf_(Word)), !bin->endian); + r_mem_copyendian((u8*)&(bin->shdr[i].sh_flags), (u8*)&(bin->shdr[i].sh_flags), sizeof(Elf_Vword), !bin->endian); + r_mem_copyendian((u8*)&(bin->shdr[i].sh_addr), (u8*)&(bin->shdr[i].sh_addr), sizeof(Elf_(Addr)), !bin->endian); + r_mem_copyendian((u8*)&(bin->shdr[i].sh_offset), (u8*)&(bin->shdr[i].sh_offset), sizeof(Elf_(Off)), !bin->endian); + r_mem_copyendian((u8*)&(bin->shdr[i].sh_size), (u8*)&(bin->shdr[i].sh_size), sizeof(Elf_Vword), !bin->endian); + r_mem_copyendian((u8*)&(bin->shdr[i].sh_link), (u8*)&(bin->shdr[i].sh_link), sizeof(Elf_(Word)), !bin->endian); + r_mem_copyendian((u8*)&(bin->shdr[i].sh_info), (u8*)&(bin->shdr[i].sh_info), sizeof(Elf_(Word)), !bin->endian); + r_mem_copyendian((u8*)&(bin->shdr[i].sh_addralign), (u8*)&(bin->shdr[i].sh_addralign), sizeof(Elf_Vword), !bin->endian); + r_mem_copyendian((u8*)&(bin->shdr[i].sh_entsize), (u8*)&(bin->shdr[i].sh_entsize), sizeof(Elf_Vword), !bin->endian); } - return 0; + return R_TRUE; } -static u64 ELF_(r_bin_elf_get_section_offset)(ELF_(r_bin_elf_obj) *bin, const char *section_name) +static int Elf_(r_bin_elf_init_strtab)(struct Elf_(r_bin_elf_obj_t) *bin) { - ELF_(Ehdr) *ehdr = &bin->ehdr; - ELF_(Shdr) *shdr = bin->shdr, *shdrp; - const char *string = bin->string; + Elf_(Shdr) *strtab_section; + + strtab_section = &bin->shdr[bin->ehdr.e_shstrndx]; + if ((bin->strtab = (char *)malloc(strtab_section->sh_size)) == NULL) { + perror("malloc"); + return R_FALSE; + } + if (lseek(bin->fd, strtab_section->sh_offset, SEEK_SET) != strtab_section->sh_offset) { + perror("lseek"); + return R_FALSE; + } + if (read(bin->fd, bin->strtab, strtab_section->sh_size) != strtab_section->sh_size) { + perror("read"); + return R_FALSE; + } + + return R_TRUE; +} + +static int Elf_(r_bin_elf_init)(struct Elf_(r_bin_elf_obj_t) *bin) +{ + if (!Elf_(r_bin_elf_init_ehdr)(bin)) { + ERR("Warning: File is not ELF\n"); + return R_FALSE; + } + if (!Elf_(r_bin_elf_init_phdr)(bin)) + ERR("Warning: Cannot initialize program headers\n"); + if (!Elf_(r_bin_elf_init_shdr)(bin)) + ERR("Warning: Cannot initialize section headers\n"); + if (!Elf_(r_bin_elf_init_strtab)(bin)) + ERR("Warning: Cannot initialize strings table\n"); + bin->baddr = Elf_(r_bin_elf_get_baddr)(bin); + + return R_TRUE; +} + +static u64 Elf_(r_bin_elf_get_section_offset)(struct Elf_(r_bin_elf_obj_t) *bin, const char *section_name) +{ + const char *strtab = bin->strtab; int i; - for (shdrp=shdr, i = 0; i < ehdr->e_shnum; i++, shdrp++) { - if (!strcmp(&string[shdrp->sh_name], section_name)) - return shdrp->sh_offset; + for (i = 0; i < bin->ehdr.e_shnum; i++) + if (!strcmp(&strtab[bin->shdr[i].sh_name], section_name)) + return (u64)bin->shdr[i].sh_offset; + + return -1; +} + +/*XXX*/ +static u64 Elf_(get_import_addr)(struct Elf_(r_bin_elf_obj_t) *bin, int sym) +{ + u64 got_addr, got_offset; + Elf_(Addr) plt_sym_addr; + int i, j, k; + + if ((got_addr = Elf_(r_bin_elf_get_section_offset)(bin, ".got")) == -1) + return -1; + + for (i = 0; i < bin->ehdr.e_shnum; i++) { + if (!strcmp(&bin->strtab[bin->shdr[i].sh_name], ".rel.plt")) { + Elf_(Rel) *rel; + if ((rel = (Elf_(Rel) *)malloc(bin->shdr[i].sh_size)) == NULL) { + perror("malloc (rel)"); + return -1; + } + if (lseek(bin->fd, bin->shdr[i].sh_offset, SEEK_SET) != bin->shdr[i].sh_offset) { + perror("lseek (rel)"); + return -1; + } + if (read(bin->fd, rel, bin->shdr[i].sh_size) != bin->shdr[i].sh_size) { + perror("read (rel)"); + return -1; + } + + for (j = 0; j < bin->shdr[i].sh_size; j += sizeof(Elf_(Rel))) { + r_mem_copyendian((u8*)&(rel[j].r_offset), (u8*)&(rel[j].r_offset), sizeof(Elf_(Addr)), !bin->endian); + r_mem_copyendian((u8*)&(rel[j].r_info), (u8*)&(rel[j].r_info), sizeof(Elf_Vword), !bin->endian); + } + + got_offset = (rel->r_offset - bin->baddr - got_addr) & ELF_GOTOFF_MASK; + + for (j = k = 0; j < bin->shdr[i].sh_size; j += sizeof(Elf_(Rel)), k++) { + if (ELF_R_SYM(rel[k].r_info) == sym) { + if (lseek(bin->fd, rel[k].r_offset-bin->baddr-got_offset, SEEK_SET) + != rel[k].r_offset-bin->baddr-got_offset) { + perror("lseek (got)"); + return -1; + } + if (read(bin->fd, &plt_sym_addr, sizeof(Elf_(Addr))) != sizeof(Elf_(Addr))) { + perror("read (got)"); + return -1; + } + + return (u64)(plt_sym_addr - 6); + } + } + break; + } else if (!strcmp(&bin->strtab[bin->shdr[i].sh_name], ".rela.plt")) { + Elf_(Rela) *rel; + if ((rel = (Elf_(Rela) *)malloc(bin->shdr[i].sh_size)) == NULL) { + perror("malloc (rel)"); + return -1; + } + if (lseek(bin->fd, bin->shdr[i].sh_offset, SEEK_SET) != bin->shdr[i].sh_offset) { + perror("lseek (rel)"); + return -1; + } + if (read(bin->fd, rel, bin->shdr[i].sh_size) != bin->shdr[i].sh_size) { + perror("read (rel)"); + return -1; + } + + for (j = 0; j < bin->shdr[i].sh_size; j += sizeof(Elf_(Rela))) { + r_mem_copyendian((u8*)&(rel[j].r_offset), (u8*)&(rel[j].r_offset), sizeof(Elf_(Addr)), !bin->endian); + r_mem_copyendian((u8*)&(rel[j].r_info), (u8*)&(rel[j].r_info), sizeof(Elf_Vword), !bin->endian); + } + + got_offset = (rel->r_offset - bin->baddr - got_addr) & ELF_GOTOFF_MASK; + + for (j = k = 0; j < bin->shdr[i].sh_size; j += sizeof(Elf_(Rela)), k++) { + if (ELF_R_SYM(rel[k].r_info) == sym) { + if (lseek(bin->fd, rel[k].r_offset-bin->baddr-got_offset, SEEK_SET) + != rel[k].r_offset-bin->baddr-got_offset) { + perror("lseek (got)"); + return -1; + } + if (read(bin->fd, &plt_sym_addr, sizeof(Elf_(Addr))) != sizeof(Elf_(Addr))) { + perror("read (got)"); + return -1; + } + + return (u64)(plt_sym_addr - 6); + } + } + break; + } } return -1; } -int ELF_(r_bin_elf_close)(ELF_(r_bin_elf_obj) *bin) -{ - return close(bin->fd); -} - -const char* ELF_(r_bin_elf_get_arch)(ELF_(r_bin_elf_obj) *bin) -{ - u16 machine = bin->ehdr.e_machine; - - switch (machine) { - case EM_MIPS: - case EM_MIPS_RS3_LE: - case EM_MIPS_X: - return "mips"; - case EM_ARM: - return "arm"; - case EM_SPARC: - case EM_SPARC32PLUS: - case EM_SPARCV9: - return "sparc"; - case EM_PPC: - case EM_PPC64: - return "ppc"; // "powerpc" ? - case EM_68K: - return "m68k"; - case EM_IA_64: - case EM_X86_64: - return "intel64"; - default: return "intel"; - } -} - -u64 ELF_(r_bin_elf_get_base_addr)(ELF_(r_bin_elf_obj) *bin) +u64 Elf_(r_bin_elf_get_baddr)(struct Elf_(r_bin_elf_obj_t) *bin) { return bin->phdr->p_vaddr & ELF_ADDR_MASK; } -u64 ELF_(r_bin_elf_get_entry_offset)(ELF_(r_bin_elf_obj) *bin) +u64 Elf_(r_bin_elf_get_entry_offset)(struct Elf_(r_bin_elf_obj_t) *bin) { - return bin->ehdr.e_entry - bin->base_addr; + return bin->ehdr.e_entry - bin->baddr; } -int ELF_(r_bin_elf_get_stripped)(ELF_(r_bin_elf_obj) *bin) +int Elf_(r_bin_elf_get_stripped)(struct Elf_(r_bin_elf_obj_t) *bin) { int i; - ELF_(Ehdr) *ehdr = &bin->ehdr; - ELF_(Shdr) *shdr = bin->shdr, *shdrp; - - shdrp = shdr; - for (i = 0; i < ehdr->e_shnum; i++, shdrp++) - if (shdrp->sh_type == SHT_SYMTAB) - return 0; - return 1; + + for (i = 0; i < bin->ehdr.e_shnum; i++) + if (bin->shdr[i].sh_type == SHT_SYMTAB) + return R_FALSE; + return R_TRUE; } -int ELF_(r_bin_elf_get_static)(ELF_(r_bin_elf_obj) *bin) +int Elf_(r_bin_elf_get_static)(struct Elf_(r_bin_elf_obj_t) *bin) { - ELF_(Ehdr) *ehdr = &bin->ehdr; - ELF_(Phdr) *phdr = bin->phdr, *phdrp; int i; - for (phdrp=phdr, i = 0; i < ehdr->e_phnum; i++, phdrp++) - if (phdrp->p_type == PT_INTERP) - return 0; - return 1; + for (i = 0; i < bin->ehdr.e_phnum; i++) + if (bin->phdr[i].p_type == PT_INTERP) + return R_FALSE; + return R_TRUE; } -const char* ELF_(r_bin_elf_get_data_encoding)(ELF_(r_bin_elf_obj) *bin) +char* Elf_(r_bin_elf_get_data_encoding)(struct Elf_(r_bin_elf_obj_t) *bin) { - unsigned int encoding = bin->ehdr.e_ident[EI_DATA]; - static char buf[32]; - - switch (encoding) { - case ELFDATANONE: return "none"; - case ELFDATA2LSB: return "2's complement, little endian"; - case ELFDATA2MSB: return "2's complement, big endian"; + switch (bin->ehdr.e_ident[EI_DATA]) { + case ELFDATANONE: return r_str_dup_printf("none"); + case ELFDATA2LSB: return r_str_dup_printf("2's complement, little endian"); + case ELFDATA2MSB: return r_str_dup_printf("2's complement, big endian"); + default: return r_str_dup_printf("", bin->ehdr.e_ident[EI_DATA]); } - snprintf (buf, sizeof (buf), "", encoding); - return buf; } -const char* ELF_(r_bin_elf_get_machine_name)(ELF_(r_bin_elf_obj) *bin) +char* Elf_(r_bin_elf_get_arch)(struct Elf_(r_bin_elf_obj_t) *bin) { - unsigned int e_machine = bin->ehdr.e_machine; - static char buf[64]; - - switch (e_machine) { - case EM_NONE: return "No machine"; - case EM_M32: return "AT&T WE 32100"; - case EM_SPARC: return "SUN SPARC"; - case EM_386: return "Intel 80386"; - case EM_68K: return "Motorola m68k family"; - case EM_88K: return "Motorola m88k family"; - case EM_860: return "Intel 80860"; - case EM_MIPS: return "MIPS R3000 big-endian"; - case EM_S370: return "IBM System/370"; - case EM_MIPS_RS3_LE: return "MIPS R3000 little-endian"; - case EM_PARISC: return "HPPA"; - case EM_VPP500: return "Fujitsu VPP500"; - case EM_SPARC32PLUS: return "Sun's \"v8plus\""; - case EM_960: return "Intel 80960"; - case EM_PPC: return "PowerPC"; - case EM_PPC64: return "PowerPC 64-bit"; - case EM_S390: return "IBM S390"; - case EM_V800: return "NEC V800 series"; - case EM_FR20: return "Fujitsu FR20"; - case EM_RH32: return "TRW RH-32"; - case EM_RCE: return "Motorola RCE"; - case EM_ARM: return "ARM"; - case EM_FAKE_ALPHA: return "Digital Alpha"; - case EM_SH: return "Hitachi SH"; - case EM_SPARCV9: return "SPARC v9 64-bit"; - case EM_TRICORE: return "Siemens Tricore"; - case EM_ARC: return "Argonaut RISC Core"; - case EM_H8_300: return "Hitachi H8/300"; - case EM_H8_300H: return "Hitachi H8/300H"; - case EM_H8S: return "Hitachi H8S"; - case EM_H8_500: return "Hitachi H8/500"; - case EM_IA_64: return "Intel Merced"; - case EM_MIPS_X: return "Stanford MIPS-X"; - case EM_COLDFIRE: return "Motorola Coldfire"; - case EM_68HC12: return "Motorola M68HC12"; - case EM_MMA: return "Fujitsu MMA Multimedia Accelerator"; - case EM_PCP: return "Siemens PCP"; - case EM_NCPU: return "Sony nCPU embeeded RISC"; - case EM_NDR1: return "Denso NDR1 microprocessor"; - case EM_STARCORE: return "Motorola Start*Core processor"; - case EM_ME16: return "Toyota ME16 processor"; - case EM_ST100: return "STMicroelectronic ST100 processor"; - case EM_TINYJ: return "Advanced Logic Corp. Tinyj emb.fam"; - case EM_X86_64: return "AMD x86-64 architecture"; - case EM_PDSP: return "Sony DSP Processor"; - case EM_FX66: return "Siemens FX66 microcontroller"; - case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 mc"; - case EM_ST7: return "STmicroelectronics ST7 8 bit mc"; - case EM_68HC16: return "Motorola MC68HC16 microcontroller"; - case EM_68HC11: return "Motorola MC68HC11 microcontroller"; - case EM_68HC08: return "Motorola MC68HC08 microcontroller"; - case EM_68HC05: return "Motorola MC68HC05 microcontroller"; - case EM_SVX: return "Silicon Graphics SVx"; - case EM_ST19: return "STMicroelectronics ST19 8 bit mc"; - case EM_VAX: return "Digital VAX"; - case EM_CRIS: return "Axis Communications 32-bit embedded processor"; - case EM_JAVELIN: return "Infineon Technologies 32-bit embedded processor"; - case EM_FIREPATH: return "Element 14 64-bit DSP Processor"; - case EM_ZSP: return "LSI Logic 16-bit DSP Processor"; - case EM_MMIX: return "Donald Knuth's educational 64-bit processor"; - case EM_HUANY: return "Harvard University machine-independent object files"; - case EM_PRISM: return "SiTera Prism"; - case EM_AVR: return "Atmel AVR 8-bit microcontroller"; - case EM_FR30: return "Fujitsu FR30"; - case EM_D10V: return "Mitsubishi D10V"; - case EM_D30V: return "Mitsubishi D30V"; - case EM_V850: return "NEC v850"; - case EM_M32R: return "Mitsubishi M32R"; - case EM_MN10300: return "Matsushita MN10300"; - case EM_MN10200: return "Matsushita MN10200"; - case EM_PJ: return "picoJava"; - case EM_OPENRISC: return "OpenRISC 32-bit embedded processor"; - case EM_ARC_A5: return "ARC Cores Tangent-A5"; - case EM_XTENSA: return "Tensilica Xtensa Architecture"; + switch (bin->ehdr.e_machine) { + case EM_MIPS: + case EM_MIPS_RS3_LE: + case EM_MIPS_X: + return r_str_dup_printf("mips"); + case EM_ARM: + return r_str_dup_printf("arm"); + case EM_SPARC: + case EM_SPARC32PLUS: + case EM_SPARCV9: + return r_str_dup_printf("sparc"); + case EM_PPC: + case EM_PPC64: + return r_str_dup_printf("powerpc"); + case EM_68K: + return r_str_dup_printf("m68k"); + case EM_IA_64: + case EM_X86_64: + return r_str_dup_printf("intel64"); + default: + return r_str_dup_printf("intel"); + } +} +char* Elf_(r_bin_elf_get_machine_name)(struct Elf_(r_bin_elf_obj_t) *bin) +{ + switch (bin->ehdr.e_machine) { + case EM_NONE: return r_str_dup_printf("No machine"); + case EM_M32: return r_str_dup_printf("AT&T WE 32100"); + case EM_SPARC: return r_str_dup_printf("SUN SPARC"); + case EM_386: return r_str_dup_printf("Intel 80386"); + case EM_68K: return r_str_dup_printf("Motorola m68k family"); + case EM_88K: return r_str_dup_printf("Motorola m88k family"); + case EM_860: return r_str_dup_printf("Intel 80860"); + case EM_MIPS: return r_str_dup_printf("MIPS R3000 big-endian"); + case EM_S370: return r_str_dup_printf("IBM System/370"); + case EM_MIPS_RS3_LE: return r_str_dup_printf("MIPS R3000 little-endian"); + case EM_PARISC: return r_str_dup_printf("HPPA"); + case EM_VPP500: return r_str_dup_printf("Fujitsu VPP500"); + case EM_SPARC32PLUS: return r_str_dup_printf("Sun's \"v8plus\""); + case EM_960: return r_str_dup_printf("Intel 80960"); + case EM_PPC: return r_str_dup_printf("PowerPC"); + case EM_PPC64: return r_str_dup_printf("PowerPC 64-bit"); + case EM_S390: return r_str_dup_printf("IBM S390"); + case EM_V800: return r_str_dup_printf("NEC V800 series"); + case EM_FR20: return r_str_dup_printf("Fujitsu FR20"); + case EM_RH32: return r_str_dup_printf("TRW RH-32"); + case EM_RCE: return r_str_dup_printf("Motorola RCE"); + case EM_ARM: return r_str_dup_printf("ARM"); + case EM_FAKE_ALPHA: return r_str_dup_printf("Digital Alpha"); + case EM_SH: return r_str_dup_printf("Hitachi SH"); + case EM_SPARCV9: return r_str_dup_printf("SPARC v9 64-bit"); + case EM_TRICORE: return r_str_dup_printf("Siemens Tricore"); + case EM_ARC: return r_str_dup_printf("Argonaut RISC Core"); + case EM_H8_300: return r_str_dup_printf("Hitachi H8/300"); + case EM_H8_300H: return r_str_dup_printf("Hitachi H8/300H"); + case EM_H8S: return r_str_dup_printf("Hitachi H8S"); + case EM_H8_500: return r_str_dup_printf("Hitachi H8/500"); + case EM_IA_64: return r_str_dup_printf("Intel Merced"); + case EM_MIPS_X: return r_str_dup_printf("Stanford MIPS-X"); + case EM_COLDFIRE: return r_str_dup_printf("Motorola Coldfire"); + case EM_68HC12: return r_str_dup_printf("Motorola M68HC12"); + case EM_MMA: return r_str_dup_printf("Fujitsu MMA Multimedia Accelerator"); + case EM_PCP: return r_str_dup_printf("Siemens PCP"); + case EM_NCPU: return r_str_dup_printf("Sony nCPU embeeded RISC"); + case EM_NDR1: return r_str_dup_printf("Denso NDR1 microprocessor"); + case EM_STARCORE: return r_str_dup_printf("Motorola Start*Core processor"); + case EM_ME16: return r_str_dup_printf("Toyota ME16 processor"); + case EM_ST100: return r_str_dup_printf("STMicroelectronic ST100 processor"); + case EM_TINYJ: return r_str_dup_printf("Advanced Logic Corp. Tinyj emb.fam"); + case EM_X86_64: return r_str_dup_printf("AMD x86-64 architecture"); + case EM_PDSP: return r_str_dup_printf("Sony DSP Processor"); + case EM_FX66: return r_str_dup_printf("Siemens FX66 microcontroller"); + case EM_ST9PLUS: return r_str_dup_printf("STMicroelectronics ST9+ 8/16 mc"); + case EM_ST7: return r_str_dup_printf("STmicroelectronics ST7 8 bit mc"); + case EM_68HC16: return r_str_dup_printf("Motorola MC68HC16 microcontroller"); + case EM_68HC11: return r_str_dup_printf("Motorola MC68HC11 microcontroller"); + case EM_68HC08: return r_str_dup_printf("Motorola MC68HC08 microcontroller"); + case EM_68HC05: return r_str_dup_printf("Motorola MC68HC05 microcontroller"); + case EM_SVX: return r_str_dup_printf("Silicon Graphics SVx"); + case EM_ST19: return r_str_dup_printf("STMicroelectronics ST19 8 bit mc"); + case EM_VAX: return r_str_dup_printf("Digital VAX"); + case EM_CRIS: return r_str_dup_printf("Axis Communications 32-bit embedded processor"); + case EM_JAVELIN: return r_str_dup_printf("Infineon Technologies 32-bit embedded processor"); + case EM_FIREPATH: return r_str_dup_printf("Element 14 64-bit DSP Processor"); + case EM_ZSP: return r_str_dup_printf("LSI Logic 16-bit DSP Processor"); + case EM_MMIX: return r_str_dup_printf("Donald Knuth's educational 64-bit processor"); + case EM_HUANY: return r_str_dup_printf("Harvard University machine-independent object files"); + case EM_PRISM: return r_str_dup_printf("SiTera Prism"); + case EM_AVR: return r_str_dup_printf("Atmel AVR 8-bit microcontroller"); + case EM_FR30: return r_str_dup_printf("Fujitsu FR30"); + case EM_D10V: return r_str_dup_printf("Mitsubishi D10V"); + case EM_D30V: return r_str_dup_printf("Mitsubishi D30V"); + case EM_V850: return r_str_dup_printf("NEC v850"); + case EM_M32R: return r_str_dup_printf("Mitsubishi M32R"); + case EM_MN10300: return r_str_dup_printf("Matsushita MN10300"); + case EM_MN10200: return r_str_dup_printf("Matsushita MN10200"); + case EM_PJ: return r_str_dup_printf("picoJava"); + case EM_OPENRISC: return r_str_dup_printf("OpenRISC 32-bit embedded processor"); + case EM_ARC_A5: return r_str_dup_printf("ARC Cores Tangent-A5"); + case EM_XTENSA: return r_str_dup_printf("Tensilica Xtensa Architecture"); + default: return r_str_dup_printf(": 0x%x", bin->ehdr.e_machine); } - snprintf (buf, sizeof(buf), ": 0x%x", e_machine); - return buf; } -const char* ELF_(r_bin_elf_get_file_type)(ELF_(r_bin_elf_obj) *bin) +char* Elf_(r_bin_elf_get_file_type)(struct Elf_(r_bin_elf_obj_t) *bin) { - unsigned int e_type = bin->ehdr.e_type; - static char buf[32]; - - switch (e_type) { - case ET_NONE: return "NONE (None)"; - case ET_REL: return "REL (Relocatable file)"; - case ET_EXEC: return "EXEC (Executable file)"; - case ET_DYN: return "DYN (Shared object file)"; - case ET_CORE: return "CORE (Core file)"; + switch (bin->ehdr.e_type) { + case ET_NONE: return r_str_dup_printf("NONE (None)"); + case ET_REL: return r_str_dup_printf("REL (Relocatable file)"); + case ET_EXEC: return r_str_dup_printf("EXEC (Executable file)"); + case ET_DYN: return r_str_dup_printf("DYN (Shared object file)"); + case ET_CORE: return r_str_dup_printf("CORE (Core file)"); } - if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC)) - snprintf (buf, sizeof (buf), "Processor Specific: (%x)", e_type); - else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS)) - snprintf (buf, sizeof (buf), "OS Specific: (%x)", e_type); - else snprintf (buf, sizeof (buf), ": %x", e_type); - - return buf; + if ((bin->ehdr.e_type >= ET_LOPROC) && (bin->ehdr.e_type <= ET_HIPROC)) + return r_str_dup_printf("Processor Specific: %x", bin->ehdr.e_type); + else if ((bin->ehdr.e_type >= ET_LOOS) && (bin->ehdr.e_type <= ET_HIOS)) + return r_str_dup_printf("OS Specific: %x", bin->ehdr.e_type); + else return r_str_dup_printf(": %x", bin->ehdr.e_type); } -const char* ELF_(r_bin_elf_get_elf_class)(ELF_(r_bin_elf_obj) *bin) +char* Elf_(r_bin_elf_get_elf_class)(struct Elf_(r_bin_elf_obj_t) *bin) { - unsigned int elf_class = bin->ehdr.e_ident[EI_CLASS]; - static char buf[32]; - - switch (elf_class) { - case ELFCLASSNONE: return "none"; - case ELFCLASS32: return "ELF32"; - case ELFCLASS64: return "ELF64"; + switch (bin->ehdr.e_ident[EI_CLASS]) { + case ELFCLASSNONE: return r_str_dup_printf("none"); + case ELFCLASS32: return r_str_dup_printf("ELF32"); + case ELFCLASS64: return r_str_dup_printf("ELF64"); + default: return r_str_dup_printf("", bin->ehdr.e_ident[EI_CLASS]); } - snprintf (buf, sizeof (buf), "", elf_class); - return buf; } -const char* ELF_(r_bin_elf_get_osabi_name)(ELF_(r_bin_elf_obj) *bin) +char* Elf_(r_bin_elf_get_osabi_name)(struct Elf_(r_bin_elf_obj_t) *bin) { - unsigned int osabi = bin->ehdr.e_ident[EI_OSABI]; - static char buf[32]; - - switch (osabi) { - case ELFOSABI_NONE: return "linux"; // sysv - case ELFOSABI_HPUX: return "hpux"; - case ELFOSABI_NETBSD: return "netbsd"; - case ELFOSABI_LINUX: return "linux"; - case ELFOSABI_SOLARIS: return "solaris"; - case ELFOSABI_AIX: return "aix"; - case ELFOSABI_IRIX: return "irix"; - case ELFOSABI_FREEBSD: return "freebsd"; - case ELFOSABI_TRU64: return "tru64"; - case ELFOSABI_MODESTO: return "modesto"; - case ELFOSABI_OPENBSD: return "openbsd"; - case ELFOSABI_STANDALONE: return "standalone"; - case ELFOSABI_ARM: return "arm"; + switch (bin->ehdr.e_ident[EI_OSABI]) { + case ELFOSABI_NONE: return r_str_dup_printf("linux"); // sysv + case ELFOSABI_HPUX: return r_str_dup_printf("hpux"); + case ELFOSABI_NETBSD: return r_str_dup_printf("netbsd"); + case ELFOSABI_LINUX: return r_str_dup_printf("linux"); + case ELFOSABI_SOLARIS: return r_str_dup_printf("solaris"); + case ELFOSABI_AIX: return r_str_dup_printf("aix"); + case ELFOSABI_IRIX: return r_str_dup_printf("irix"); + case ELFOSABI_FREEBSD: return r_str_dup_printf("freebsd"); + case ELFOSABI_TRU64: return r_str_dup_printf("tru64"); + case ELFOSABI_MODESTO: return r_str_dup_printf("modesto"); + case ELFOSABI_OPENBSD: return r_str_dup_printf("openbsd"); + case ELFOSABI_STANDALONE: return r_str_dup_printf("standalone"); + case ELFOSABI_ARM: return r_str_dup_printf("arm"); + default: return r_str_dup_printf("", bin->ehdr.e_ident[EI_OSABI]); } - snprintf (buf, sizeof (buf), "", osabi); - return buf; } -int ELF_(r_bin_elf_is_big_endian)(ELF_(r_bin_elf_obj) *bin) +int Elf_(r_bin_elf_is_big_endian)(struct Elf_(r_bin_elf_obj_t) *bin) { - ELF_(Ehdr) *ehdr = &bin->ehdr; - - return (ehdr->e_ident[EI_DATA] == ELFDATA2MSB); + return (bin->ehdr.e_ident[EI_DATA] == ELFDATA2MSB); } +/* XXX Section resize here? */ +#if 0 /* TODO: Take care of endianess */ /* TODO: Real error handling */ /* TODO: Resize sections before .init */ -u64 ELF_(r_bin_elf_resize_section)(ELF_(r_bin_elf_obj) *bin, const char *name, u64 size) +u64 Elf_(r_bin_elf_resize_section)(struct Elf_(r_bin_elf_obj_t) *bin, const char *name, u64 size) { - ELF_(Ehdr) *ehdr = &bin->ehdr; - ELF_(Phdr) *phdr = bin->phdr, *phdrp; - ELF_(Shdr) *shdr = bin->shdr, *shdrp; - const char *string = bin->string; + 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; @@ -724,7 +477,7 @@ u64 ELF_(r_bin_elf_resize_section)(ELF_(r_bin_elf_obj) *bin, const char *name, u /* calculate delta */ for (i = 0, shdrp = shdr; i < ehdr->e_shnum; i++, shdrp++) - if (!strncmp(name, &string[shdrp->sh_name], ELF_NAME_LENGTH)) { + 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; @@ -739,7 +492,7 @@ u64 ELF_(r_bin_elf_resize_section)(ELF_(r_bin_elf_obj) *bin, const char *name, u /* rewrite rel's (imports) */ for (i = 0, shdrp = shdr; i < ehdr->e_shnum; i++, shdrp++) { - if (!strcmp(&string[shdrp->sh_name], ".got")) + if (!strcmp(&strtab[shdrp->sh_name], ".got")) got_addr = (u64)shdrp->sh_offset; } if (got_addr == 0) { @@ -747,9 +500,9 @@ u64 ELF_(r_bin_elf_resize_section)(ELF_(r_bin_elf_obj) *bin, const char *name, u } for (i = 0, shdrp = shdr; i < ehdr->e_shnum; i++, shdrp++) { - if (!strcmp(&string[shdrp->sh_name], ".rel.plt")) { - ELF_(Rel) *rel, *relp; - rel = (ELF_(Rel) *)malloc(shdrp->sh_size); + if (!strcmp(&strtab[shdrp->sh_name], ".rel.plt")) { + Elf_(Rel) *rel, *relp; + rel = (Elf_(Rel) *)malloc(shdrp->sh_size); if (rel == NULL) { perror("malloc"); return -1; @@ -760,25 +513,25 @@ u64 ELF_(r_bin_elf_resize_section)(ELF_(r_bin_elf_obj) *bin, const char *name, u if (read(bin->fd, rel, shdrp->sh_size) != shdrp->sh_size) perror("read"); - got_offset = (rel->r_offset - bin->base_addr - got_addr) & ELF_GOTOFF_MASK; - for (j = 0, relp = rel; j < shdrp->sh_size; j += sizeof(ELF_(Rel)), relp++) { - ELF_(aux_swap_endian)((u8*)&(relp->r_offset), sizeof(ELF_(Addr))); + 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); /* rewrite relp->r_offset */ - if (relp->r_offset - bin->base_addr - got_offset >= rsz_offset + rsz_osize) { + 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 (write(bin->fd, &relp, sizeof(Elf_(Rel))) != sizeof(Elf_(Rel))) perror("write (imports)"); } } free(rel); break; - } else if (!strcmp(&string[shdrp->sh_name], ".rela.plt")) { - ELF_(Rela) *rel, *relp; - rel = (ELF_(Rela) *)malloc(shdrp->sh_size); + } else if (!strcmp(&strtab[shdrp->sh_name], ".rela.plt")) { + Elf_(Rela) *rel, *relp; + rel = (Elf_(Rela) *)malloc(shdrp->sh_size); if (rel == NULL) { perror("malloc"); return -1; @@ -789,17 +542,17 @@ u64 ELF_(r_bin_elf_resize_section)(ELF_(r_bin_elf_obj) *bin, const char *name, u if (read(bin->fd, rel, shdrp->sh_size) != shdrp->sh_size) perror("read"); - got_offset = (rel->r_offset - bin->base_addr - got_addr) & ELF_GOTOFF_MASK; - for (j = 0, relp = rel; j < shdrp->sh_size; j += sizeof(ELF_(Rela)), relp++) { - ELF_(aux_swap_endian)((u8*)&(relp->r_offset), sizeof(ELF_(Addr))); + 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); /* rewrite relp->r_offset */ - if (relp->r_offset - bin->base_addr - got_offset >= rsz_offset + rsz_osize) { + 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 (write(bin->fd, &relp, sizeof(Elf_(Rela))) != sizeof(Elf_(Rela))) perror("write (imports)"); } } @@ -810,7 +563,7 @@ u64 ELF_(r_bin_elf_resize_section)(ELF_(r_bin_elf_obj) *bin, const char *name, u /* rewrite section headers */ for (i = 0, shdrp = shdr; i < ehdr->e_shnum; i++, shdrp++) { - if (!done && !strncmp(name, &string[shdrp->sh_name], ELF_NAME_LENGTH)) { + if (!done && !strncmp(name, &strtab[shdrp->sh_name], ELF_STRING_LENGTH)) { shdrp->sh_size = rsz_size; done = 1; } else if (shdrp->sh_offset >= rsz_offset + rsz_osize) { @@ -818,12 +571,12 @@ u64 ELF_(r_bin_elf_resize_section)(ELF_(r_bin_elf_obj) *bin, const char *name, u if (shdrp->sh_addr) shdrp->sh_addr += delta; } - off = ehdr->e_shoff + i * sizeof(ELF_(Shdr)); + 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 (write(bin->fd, shdrp, sizeof(Elf_(Shdr))) != sizeof(Elf_(Shdr))) perror("write (shdr)"); - printf("-> elf section (%s)\n", &string[shdrp->sh_name]); + printf("-> elf section (%s)\n", &strtab[shdrp->sh_name]); } /* rewrite program headers */ @@ -839,16 +592,16 @@ u64 ELF_(r_bin_elf_resize_section)(ELF_(r_bin_elf_obj) *bin, const char *name, u if (phdrp->p_vaddr) phdrp->p_vaddr += delta; if (phdrp->p_paddr) phdrp->p_paddr += delta; } - off = ehdr->e_phoff + i * sizeof(ELF_(Phdr)); + 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 (write(bin->fd, phdrp, sizeof(Elf_(Phdr))) != sizeof(Elf_(Phdr))) perror("write (phdr)"); printf("-> program header (%08llx)\n", (u64) phdrp->p_offset); } /* rewrite other elf pointers (entrypoint, phoff, shoff) */ - if (ehdr->e_entry - bin->base_addr >= rsz_offset + rsz_osize) + if (ehdr->e_entry - bin->baddr >= rsz_offset + rsz_osize) ehdr->e_entry += delta; if (ehdr->e_phoff >= rsz_offset + rsz_osize) ehdr->e_phoff += delta; @@ -856,7 +609,7 @@ u64 ELF_(r_bin_elf_resize_section)(ELF_(r_bin_elf_obj) *bin, const char *name, u 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 (write(bin->fd, ehdr, sizeof(Elf_(Ehdr))) != sizeof(Elf_(Ehdr))) perror("write (ehdr)"); /* inverse order to write bodies .. avoid overlapping here */ @@ -874,406 +627,266 @@ u64 ELF_(r_bin_elf_resize_section)(ELF_(r_bin_elf_obj) *bin, const char *name, u free(buf); /* Reinit structs*/ - ELF_(r_bin_elf_init)(bin); + Elf_(r_bin_elf_init)(bin); return delta; } +#endif -int ELF_(r_bin_elf_get_sections)(ELF_(r_bin_elf_obj) *bin, r_bin_elf_section *section) +struct r_bin_elf_section_t* Elf_(r_bin_elf_get_sections)(struct Elf_(r_bin_elf_obj_t) *bin) { - ELF_(Ehdr) *ehdr = &bin->ehdr; - ELF_(Shdr) *shdr = bin->shdr, *shdrp; - r_bin_elf_section *sectionp; - const char *string = bin->string; + struct r_bin_elf_section_t *ret = NULL; + const char *strtab = bin->strtab; int i; - - shdrp = shdr; - sectionp = section; - for (i = 0; i < ehdr->e_shnum; i++, shdrp++, sectionp++) { - sectionp->offset = shdrp->sh_offset; - sectionp->size = shdrp->sh_size; - sectionp->align = shdrp->sh_addralign; - sectionp->flags = shdrp->sh_flags; - strncpy(sectionp->name, &string[shdrp->sh_name], ELF_NAME_LENGTH); - } - - return i; -} - -int ELF_(r_bin_elf_get_sections_count)(ELF_(r_bin_elf_obj) *bin) -{ - ELF_(Ehdr) *ehdr = &bin->ehdr; - return ehdr->e_shnum; -} - -int ELF_(r_bin_elf_get_imports)(ELF_(r_bin_elf_obj) *bin, r_bin_elf_import *import) -{ - ELF_(Ehdr) *ehdr = &bin->ehdr; - ELF_(Shdr) *shdr = bin->shdr, *shdrp; - ELF_(Sym) *sym, *symp; - ELF_(Shdr) *strtabhdr; - r_bin_elf_import *importp; - char *string; - int i, j, k; - - shdrp = shdr; - for (i = 0; i < ehdr->e_shnum; i++, shdrp++) { - if (shdrp->sh_type == (bin->ehdr.e_type == ET_REL?SHT_SYMTAB:SHT_DYNSYM)) { - strtabhdr = &shdr[shdrp->sh_link]; - - string = (char *)malloc(strtabhdr->sh_size); - if (string == NULL) { - perror("malloc"); - return -1; - } - - if (lseek(bin->fd, strtabhdr->sh_offset, SEEK_SET) != strtabhdr->sh_offset) { - perror("lseek"); - return -1; - } - - if (read(bin->fd, string, strtabhdr->sh_size) != strtabhdr->sh_size) { - perror("read"); - return -1; - } - - sym = (ELF_(Sym) *)malloc(shdrp->sh_size); - if (sym == NULL) { - perror("malloc"); - return -1; - } - - if (lseek(bin->fd, shdrp->sh_offset, SEEK_SET) != shdrp->sh_offset) { - perror("lseek"); - return -1; - } - - if (read(bin->fd, sym, shdrp->sh_size) != shdrp->sh_size) { - perror("read"); - return -1; - } - - symp = sym; - for (j = 0; j < shdrp->sh_size; j += sizeof(ELF_(Sym)), symp++) { - ELF_(aux_swap_endian)((u8*)&(symp->st_name), sizeof(ELF_(Word))); - ELF_(aux_swap_endian)((u8*)&(symp->st_value), sizeof(ELF_(Addr))); - ELF_(aux_swap_endian)((u8*)&(symp->st_size), sizeof(ELF_Vword)); - ELF_(aux_swap_endian)((u8*)&(symp->st_shndx), sizeof(ELF_(Section))); - } - - importp = import; - symp = sym; - for (j = 0, k = 0; j < shdrp->sh_size; j += sizeof(ELF_(Sym)), k++, symp++) { - if (k == 0) - continue; - if (symp->st_shndx == STN_UNDEF) { - memcpy(importp->name, &string[symp->st_name], ELF_NAME_LENGTH); - importp->name[ELF_NAME_LENGTH-1] = '\0'; - if (symp->st_value) - importp->offset = symp->st_value; - else - importp->offset = ELF_(get_import_addr)(bin, k); - if (importp->offset >= bin->base_addr) - importp->offset -= bin->base_addr; - - switch (ELF_ST_BIND(symp->st_info)) { - case STB_LOCAL: snprintf(importp->bind, ELF_NAME_LENGTH, "LOCAL"); break; - case STB_GLOBAL: snprintf(importp->bind, ELF_NAME_LENGTH, "GLOBAL"); break; - case STB_NUM: snprintf(importp->bind, ELF_NAME_LENGTH, "NUM"); break; - case STB_LOOS: snprintf(importp->bind, ELF_NAME_LENGTH, "LOOS"); break; - case STB_HIOS: snprintf(importp->bind, ELF_NAME_LENGTH, "HIOS"); break; - case STB_LOPROC: snprintf(importp->bind, ELF_NAME_LENGTH, "LOPROC"); break; - case STB_HIPROC: snprintf(importp->bind, ELF_NAME_LENGTH, "HIPROC"); break; - default: snprintf(importp->bind, ELF_NAME_LENGTH, "UNKNOWN"); - } - switch (ELF_ST_TYPE(symp->st_info)) { - case STT_NOTYPE: snprintf(importp->type, ELF_NAME_LENGTH, "NOTYPE"); break; - case STT_OBJECT: snprintf(importp->type, ELF_NAME_LENGTH, "OBJECT"); break; - case STT_FUNC: snprintf(importp->type, ELF_NAME_LENGTH, "FUNC"); break; - case STT_SECTION: snprintf(importp->type, ELF_NAME_LENGTH, "SECTION"); break; - case STT_FILE: snprintf(importp->type, ELF_NAME_LENGTH, "FILE"); break; - case STT_COMMON: snprintf(importp->type, ELF_NAME_LENGTH, "COMMON"); break; - case STT_TLS: snprintf(importp->type, ELF_NAME_LENGTH, "TLS"); break; - case STT_NUM: snprintf(importp->type, ELF_NAME_LENGTH, "NUM"); break; - case STT_LOOS: snprintf(importp->type, ELF_NAME_LENGTH, "LOOS"); break; - case STT_HIOS: snprintf(importp->type, ELF_NAME_LENGTH, "HIOS"); break; - case STT_LOPROC: snprintf(importp->type, ELF_NAME_LENGTH, "LOPROC"); break; - case STT_HIPROC: snprintf(importp->type, ELF_NAME_LENGTH, "HIPROC"); break; - default: snprintf(importp->type, ELF_NAME_LENGTH, "UNKNOWN"); - } - importp++; - } - } - } - } - return 0; -} + if ((ret = malloc((bin->ehdr.e_shnum + 1) * sizeof(struct r_bin_elf_section_t))) == NULL) + return NULL; -int ELF_(r_bin_elf_get_imports_count)(ELF_(r_bin_elf_obj) *bin) -{ - ELF_(Ehdr) *ehdr = &bin->ehdr; - ELF_(Shdr) *shdr = bin->shdr, *shdrp; - ELF_(Sym) *sym, *symp; - int i, j, k, ctr = 0; - - shdrp = shdr; - for (i = 0; i < ehdr->e_shnum; i++, shdrp++) { - if (shdrp->sh_type == (bin->ehdr.e_type == ET_REL?SHT_SYMTAB:SHT_DYNSYM)) { - sym = (ELF_(Sym) *)malloc(shdrp->sh_size); - if (sym == NULL) { - perror("malloc"); - return -1; - } - - if (lseek(bin->fd, shdrp->sh_offset, SEEK_SET) != shdrp->sh_offset) { - perror("lseek"); - return -1; - } - - if (read(bin->fd, sym, shdrp->sh_size) != shdrp->sh_size) { - perror("read"); - return -1; - } - - symp = sym; - for (j = 0, k = 0; j < shdrp->sh_size; j += sizeof(ELF_(Sym)), k++, symp++) { - if (k == 0) - continue; - if (symp->st_shndx == STN_UNDEF) { - ctr++; - } - } - } + for (i = 0; i < bin->ehdr.e_shnum; i++) { + ret[i].offset = bin->shdr[i].sh_offset; + ret[i].size = bin->shdr[i].sh_size; + ret[i].align = bin->shdr[i].sh_addralign; + ret[i].flags = bin->shdr[i].sh_flags; + strncpy(ret[i].name, &strtab[bin->shdr[i].sh_name], ELF_STRING_LENGTH); + ret[i].last = 0; } + ret[i].last = 1; - return ctr; + return ret; } -int ELF_(r_bin_elf_get_symbols)(ELF_(r_bin_elf_obj) *bin, r_bin_elf_symbol *symbol) +/*XXX*/ +struct r_bin_elf_import_t* Elf_(r_bin_elf_get_imports)(struct Elf_(r_bin_elf_obj_t) *bin) { - ELF_(Ehdr) *ehdr = &bin->ehdr; - ELF_(Shdr) *shdr = bin->shdr, *shdrp; - ELF_(Sym) *sym, *symp; - ELF_(Shdr) *strtabhdr; - r_bin_elf_symbol *symbolp; + Elf_(Shdr) *strtab_section; + Elf_(Sym) *sym; + struct r_bin_elf_import_t *ret = NULL; + char *strtab; u64 sym_offset; - char *string; - int i, j, k; + int ret_ctr, i, j, k; - sym_offset = (bin->ehdr.e_type == ET_REL ? ELF_(r_bin_elf_get_section_offset)(bin, ".text") : 0); + sym_offset = (bin->ehdr.e_type == ET_REL ? Elf_(r_bin_elf_get_section_offset)(bin, ".text") : 0); - shdrp = shdr; + if (bin->ehdr.e_shnum == 0) + return NULL; - /* No section headers found */ - if (ehdr->e_shnum == 0) { - } else - for (i = 0; i < ehdr->e_shnum; i++, shdrp++) { - if (shdrp->sh_type == (ELF_(r_bin_elf_get_stripped)(bin)?SHT_DYNSYM:SHT_SYMTAB)) { - strtabhdr = &shdr[shdrp->sh_link]; - - string = (char *)malloc(strtabhdr->sh_size); - if (string == NULL) { - perror("malloc"); - return -1; + for (i = 0; i < bin->ehdr.e_shnum; i++) + if (bin->shdr[i].sh_type == (Elf_(r_bin_elf_get_stripped)(bin)?SHT_DYNSYM:SHT_SYMTAB)) { + strtab_section = &bin->shdr[bin->shdr[i].sh_link]; + if ((strtab = (char *)malloc(strtab_section->sh_size)) == NULL) { + perror("malloc (syms strtab)"); + return NULL; + } + if (lseek(bin->fd, strtab_section->sh_offset, SEEK_SET) != strtab_section->sh_offset) { + perror("lseek (syms strtab)"); + return NULL; + } + if (read(bin->fd, strtab, strtab_section->sh_size) != strtab_section->sh_size) { + perror("read (syms strtab)"); + return NULL; } - if (lseek(bin->fd, strtabhdr->sh_offset, SEEK_SET) != strtabhdr->sh_offset) { - perror("lseek"); - return -1; + if ((sym = (Elf_(Sym) *)malloc(bin->shdr[i].sh_size)) == NULL) { + perror("malloc (syms)"); + return NULL; + } + if (lseek(bin->fd, bin->shdr[i].sh_offset, SEEK_SET) != bin->shdr[i].sh_offset) { + perror("lseek (syms)"); + return NULL; + } + if (read(bin->fd, sym, bin->shdr[i].sh_size) != bin->shdr[i].sh_size) { + perror("read (syms)"); + return NULL; } - if (read(bin->fd, string, strtabhdr->sh_size) != strtabhdr->sh_size) { - perror("read"); - return -1; + for (j = 0; j < bin->shdr[i].sh_size; j += sizeof(Elf_(Sym))) { + r_mem_copyendian((u8*)&(sym[i].st_name), (u8*)&(sym[i].st_name), sizeof(Elf_(Word)), !bin->endian); + r_mem_copyendian((u8*)&(sym[i].st_value), (u8*)&(sym[i].st_value), sizeof(Elf_(Addr)), !bin->endian); + r_mem_copyendian((u8*)&(sym[i].st_size), (u8*)&(sym[i].st_size), sizeof(Elf_Vword), !bin->endian); + r_mem_copyendian((u8*)&(sym[i].st_shndx), (u8*)&(sym[i].st_shndx), sizeof(Elf_(Section)), !bin->endian); } - sym = (ELF_(Sym) *)malloc(shdrp->sh_size); - if (sym == NULL) { - perror("malloc"); - return -1; - } - - if (lseek(bin->fd, shdrp->sh_offset, SEEK_SET) != shdrp->sh_offset) { - perror("lseek"); - return -1; - } - - if (read(bin->fd, sym, shdrp->sh_size) != shdrp->sh_size) { - perror("read"); - return -1; - } - - symp = sym; - for (j = 0; j < shdrp->sh_size; j += sizeof(ELF_(Sym)), symp++) { - ELF_(aux_swap_endian)((u8*)&(symp->st_name), sizeof(ELF_(Word))); - ELF_(aux_swap_endian)((u8*)&(symp->st_value), sizeof(ELF_(Addr))); - ELF_(aux_swap_endian)((u8*)&(symp->st_size), sizeof(ELF_Vword)); - ELF_(aux_swap_endian)((u8*)&(symp->st_shndx), sizeof(ELF_(Section))); - } - - symbolp = symbol; - symp = sym; - for (j = 0, k = 0; j < shdrp->sh_size; j += sizeof(ELF_(Sym)), k++, symp++) { + for (j = k = ret_ctr = 0; j < bin->shdr[i].sh_size; j += sizeof(Elf_(Sym)), k++) { if (k == 0) continue; - if (symp->st_shndx != STN_UNDEF && ELF_ST_TYPE(symp->st_info) != STT_SECTION && ELF_ST_TYPE(symp->st_info) != STT_FILE) { - symbolp->size = (u64)symp->st_size; - memcpy(symbolp->name, &string[symp->st_name], ELF_NAME_LENGTH); - symbolp->name[ELF_NAME_LENGTH-1] = '\0'; - symbolp->offset = (u64)symp->st_value + sym_offset; - if (symbolp->offset >= bin->base_addr) - symbolp->offset -= bin->base_addr; - switch (ELF_ST_BIND(symp->st_info)) { - case STB_LOCAL: snprintf(symbolp->bind, ELF_NAME_LENGTH, "LOCAL"); break; - case STB_GLOBAL: snprintf(symbolp->bind, ELF_NAME_LENGTH, "GLOBAL"); break; - case STB_NUM: snprintf(symbolp->bind, ELF_NAME_LENGTH, "NUM"); break; - case STB_LOOS: snprintf(symbolp->bind, ELF_NAME_LENGTH, "LOOS"); break; - case STB_HIOS: snprintf(symbolp->bind, ELF_NAME_LENGTH, "HIOS"); break; - case STB_LOPROC: snprintf(symbolp->bind, ELF_NAME_LENGTH, "LOPROC"); break; - case STB_HIPROC: snprintf(symbolp->bind, ELF_NAME_LENGTH, "HIPROC"); break; - default: snprintf(symbolp->bind, ELF_NAME_LENGTH, "UNKNOWN"); + if (sym[k].st_shndx == STN_UNDEF) { + if ((ret = realloc(ret, (ret_ctr + 1) * sizeof(struct r_bin_elf_symbol_t))) == NULL) { + perror("realloc (imports)"); + return NULL; } - switch (ELF_ST_TYPE(symp->st_info)) { - case STT_NOTYPE: snprintf(symbolp->type, ELF_NAME_LENGTH, "NOTYPE"); break; - case STT_OBJECT: snprintf(symbolp->type, ELF_NAME_LENGTH, "OBJECT"); break; - case STT_FUNC: snprintf(symbolp->type, ELF_NAME_LENGTH, "FUNC"); break; - case STT_SECTION: snprintf(symbolp->type, ELF_NAME_LENGTH, "SECTION"); break; - case STT_FILE: snprintf(symbolp->type, ELF_NAME_LENGTH, "FILE"); break; - case STT_COMMON: snprintf(symbolp->type, ELF_NAME_LENGTH, "COMMON"); break; - case STT_TLS: snprintf(symbolp->type, ELF_NAME_LENGTH, "TLS"); break; - case STT_NUM: snprintf(symbolp->type, ELF_NAME_LENGTH, "NUM"); break; - case STT_LOOS: snprintf(symbolp->type, ELF_NAME_LENGTH, "LOOS"); break; - case STT_HIOS: snprintf(symbolp->type, ELF_NAME_LENGTH, "HIOS"); break; - case STT_LOPROC: snprintf(symbolp->type, ELF_NAME_LENGTH, "LOPROC"); break; - case STT_HIPROC: snprintf(symbolp->type, ELF_NAME_LENGTH, "HIPROC"); break; - default: snprintf(symbolp->type, ELF_NAME_LENGTH, "UNKNOWN"); + memcpy(ret[ret_ctr].name, &strtab[sym[k].st_name], ELF_STRING_LENGTH); + if (sym[k].st_value) + ret[ret_ctr].offset = sym[k].st_value; + else if ((ret[ret_ctr].offset = Elf_(get_import_addr)(bin, k)) == -1) + ret[ret_ctr].offset = 0; + if (ret[ret_ctr].offset >= bin->baddr) + ret[ret_ctr].offset -= bin->baddr; + switch (ELF_ST_BIND(sym[k].st_info)) { + case STB_LOCAL: snprintf(ret[ret_ctr].bind, ELF_STRING_LENGTH, "LOCAL"); break; + case STB_GLOBAL: snprintf(ret[ret_ctr].bind, ELF_STRING_LENGTH, "GLOBAL"); break; + case STB_NUM: snprintf(ret[ret_ctr].bind, ELF_STRING_LENGTH, "NUM"); break; + case STB_LOOS: snprintf(ret[ret_ctr].bind, ELF_STRING_LENGTH, "LOOS"); break; + case STB_HIOS: snprintf(ret[ret_ctr].bind, ELF_STRING_LENGTH, "HIOS"); break; + case STB_LOPROC: snprintf(ret[ret_ctr].bind, ELF_STRING_LENGTH, "LOPROC"); break; + case STB_HIPROC: snprintf(ret[ret_ctr].bind, ELF_STRING_LENGTH, "HIPROC"); break; + default: snprintf(ret[ret_ctr].bind, ELF_STRING_LENGTH, "UNKNOWN"); } - - symbolp++; + switch (ELF_ST_TYPE(sym[k].st_info)) { + case STT_NOTYPE: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "NOTYPE"); break; + case STT_OBJECT: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "OBJECT"); break; + case STT_FUNC: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "FUNC"); break; + case STT_SECTION: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "SECTION"); break; + case STT_FILE: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "FILE"); break; + case STT_COMMON: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "COMMON"); break; + case STT_TLS: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "TLS"); break; + case STT_NUM: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "NUM"); break; + case STT_LOOS: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "LOOS"); break; + case STT_HIOS: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "HIOS"); break; + case STT_LOPROC: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "LOPROC"); break; + case STT_HIPROC: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "HIPROC"); break; + default: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "UNKNOWN"); + } + ret[ret_ctr].last = 0; + ret_ctr++; } } + if ((sym = realloc(sym, (ret_ctr + 1) * sizeof(struct r_bin_elf_symbol_t))) == NULL) + return NULL; + ret[ret_ctr].last = 1; + break; } - } - return 0; + return ret; } -int ELF_(r_bin_elf_get_symbols_count)(ELF_(r_bin_elf_obj) *bin) +/*XXX*/ +struct r_bin_elf_symbol_t* Elf_(r_bin_elf_get_symbols)(struct Elf_(r_bin_elf_obj_t) *bin) { - ELF_(Ehdr) *ehdr = &bin->ehdr; - ELF_(Shdr) *shdr = bin->shdr, *shdrp; - ELF_(Sym) *sym, *symp; - int i, j, k, ctr=0; + Elf_(Shdr) *strtab_section; + Elf_(Sym) *sym; + struct r_bin_elf_symbol_t *ret = NULL; + char *strtab; + u64 sym_offset; + int ret_ctr, i, j, k; - shdrp = shdr; - for (i = 0; i < ehdr->e_shnum; i++, shdrp++) { - if (shdrp->sh_type == (ELF_(r_bin_elf_get_stripped)(bin)?SHT_DYNSYM:SHT_SYMTAB)) { - sym = (ELF_(Sym) *)malloc(shdrp->sh_size); - if (sym == NULL) { - perror("malloc"); - return -1; + sym_offset = (bin->ehdr.e_type == ET_REL ? Elf_(r_bin_elf_get_section_offset)(bin, ".text") : 0); + + if (bin->ehdr.e_shnum == 0) + return NULL; + + for (i = 0; i < bin->ehdr.e_shnum; i++) + if (bin->shdr[i].sh_type == (Elf_(r_bin_elf_get_stripped)(bin)?SHT_DYNSYM:SHT_SYMTAB)) { + strtab_section = &bin->shdr[bin->shdr[i].sh_link]; + if ((strtab = (char *)malloc(strtab_section->sh_size)) == NULL) { + perror("malloc (syms strtab)"); + return NULL; + } + if (lseek(bin->fd, strtab_section->sh_offset, SEEK_SET) != strtab_section->sh_offset) { + perror("lseek (syms strtab)"); + return NULL; + } + if (read(bin->fd, strtab, strtab_section->sh_size) != strtab_section->sh_size) { + perror("read (syms strtab)"); + return NULL; } - if (lseek(bin->fd, shdrp->sh_offset, SEEK_SET) != shdrp->sh_offset) { - perror("lseek"); - return -1; + if ((sym = (Elf_(Sym) *)malloc(bin->shdr[i].sh_size)) == NULL) { + perror("malloc (syms)"); + return NULL; + } + if (lseek(bin->fd, bin->shdr[i].sh_offset, SEEK_SET) != bin->shdr[i].sh_offset) { + perror("lseek (syms)"); + return NULL; + } + if (read(bin->fd, sym, bin->shdr[i].sh_size) != bin->shdr[i].sh_size) { + perror("read (syms)"); + return NULL; } - if (read(bin->fd, sym, shdrp->sh_size) != shdrp->sh_size) { - perror("read"); - return -1; + for (j = 0; j < bin->shdr[i].sh_size; j += sizeof(Elf_(Sym))) { + r_mem_copyendian((u8*)&(sym[i].st_name), (u8*)&(sym[i].st_name), sizeof(Elf_(Word)), !bin->endian); + r_mem_copyendian((u8*)&(sym[i].st_value), (u8*)&(sym[i].st_value), sizeof(Elf_(Addr)), !bin->endian); + r_mem_copyendian((u8*)&(sym[i].st_size), (u8*)&(sym[i].st_size), sizeof(Elf_Vword), !bin->endian); + r_mem_copyendian((u8*)&(sym[i].st_shndx), (u8*)&(sym[i].st_shndx), sizeof(Elf_(Section)), !bin->endian); } - symp = sym; - for (j = 0, k = 0; j < shdrp->sh_size; j += sizeof(ELF_(Sym)), k++, symp++) { + for (j = k = ret_ctr = 0; j < bin->shdr[i].sh_size; j += sizeof(Elf_(Sym)), k++) { if (k == 0) continue; - if (symp->st_shndx != STN_UNDEF && ELF_ST_TYPE(symp->st_info) != STT_SECTION && ELF_ST_TYPE(symp->st_info) != STT_FILE) - ctr++; + if (sym[k].st_shndx != STN_UNDEF && ELF_ST_TYPE(sym[k].st_info) != STT_SECTION && ELF_ST_TYPE(sym[k].st_info) != STT_FILE) { + if ((ret = realloc(ret, (ret_ctr + 1) * sizeof(struct r_bin_elf_symbol_t))) == NULL) { + perror("realloc (symbols)"); + return NULL; + } + ret[ret_ctr].size = (u64)sym[k].st_size; + memcpy(ret[ret_ctr].name, &strtab[sym[k].st_name], ELF_STRING_LENGTH); + ret[ret_ctr].name[ELF_STRING_LENGTH-1] = '\0'; + ret[ret_ctr].offset = (u64)sym[k].st_value + sym_offset; + if (ret[ret_ctr].offset >= bin->baddr) + ret[ret_ctr].offset -= bin->baddr; + switch (ELF_ST_BIND(sym[k].st_info)) { + case STB_LOCAL: snprintf(ret[ret_ctr].bind, ELF_STRING_LENGTH, "LOCAL"); break; + case STB_GLOBAL: snprintf(ret[ret_ctr].bind, ELF_STRING_LENGTH, "GLOBAL"); break; + case STB_NUM: snprintf(ret[ret_ctr].bind, ELF_STRING_LENGTH, "NUM"); break; + case STB_LOOS: snprintf(ret[ret_ctr].bind, ELF_STRING_LENGTH, "LOOS"); break; + case STB_HIOS: snprintf(ret[ret_ctr].bind, ELF_STRING_LENGTH, "HIOS"); break; + case STB_LOPROC: snprintf(ret[ret_ctr].bind, ELF_STRING_LENGTH, "LOPROC"); break; + case STB_HIPROC: snprintf(ret[ret_ctr].bind, ELF_STRING_LENGTH, "HIPROC"); break; + default: snprintf(ret[ret_ctr].bind, ELF_STRING_LENGTH, "UNKNOWN"); + } + switch (ELF_ST_TYPE(sym[k].st_info)) { + case STT_NOTYPE: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "NOTYPE"); break; + case STT_OBJECT: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "OBJECT"); break; + case STT_FUNC: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "FUNC"); break; + case STT_SECTION: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "SECTION"); break; + case STT_FILE: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "FILE"); break; + case STT_COMMON: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "COMMON"); break; + case STT_TLS: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "TLS"); break; + case STT_NUM: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "NUM"); break; + case STT_LOOS: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "LOOS"); break; + case STT_HIOS: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "HIOS"); break; + case STT_LOPROC: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "LOPROC"); break; + case STT_HIPROC: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "HIPROC"); break; + default: snprintf(ret[ret_ctr].type, ELF_STRING_LENGTH, "UNKNOWN"); + } + ret[ret_ctr].last = 0; + ret_ctr++; + } } + if ((ret = realloc(ret, (ret_ctr + 1) * sizeof(struct r_bin_elf_symbol_t))) == NULL) + return NULL; + ret[ret_ctr].last = 1; + break; } - } - return ctr; + return ret; } -int ELF_(r_bin_elf_get_fields)(ELF_(r_bin_elf_obj) *bin, r_bin_elf_field *field) +struct r_bin_elf_field_t* Elf_(r_bin_elf_get_fields)(struct Elf_(r_bin_elf_obj_t) *bin) { - ELF_(Ehdr) *ehdr = &bin->ehdr; - ELF_(Phdr) *phdr = bin->phdr; - char string[ELF_NAME_LENGTH]; - int i = 0, j = 0; + struct r_bin_elf_field_t *ret = NULL; + int i = 0, j; - strncpy(field[i].name, "ehdr", ELF_NAME_LENGTH); - field[i++].offset = 0; - strncpy(field[i].name, "shoff", ELF_NAME_LENGTH); - field[i++].offset = ehdr->e_shoff; - strncpy(field[i].name, "phoff", ELF_NAME_LENGTH); - field[i++].offset = ehdr->e_phoff; + if ((ret = malloc((bin->ehdr.e_phnum+3 + 1) * sizeof(struct r_bin_elf_field_t))) == NULL) + return NULL; - for (j = 0; j < ehdr->e_phnum; i++, j++) { - snprintf(string, ELF_NAME_LENGTH, "phdr_%i", j); - strncpy(field[i].name, string, ELF_NAME_LENGTH); - field[i].offset = phdr[i].p_offset; + strncpy(ret[i].name, "ehdr", ELF_STRING_LENGTH); + ret[i++].offset = 0; + strncpy(ret[i].name, "shoff", ELF_STRING_LENGTH); + ret[i++].offset = bin->ehdr.e_shoff; + strncpy(ret[i].name, "phoff", ELF_STRING_LENGTH); + ret[i++].offset = bin->ehdr.e_phoff; + for (j = 0; j < bin->ehdr.e_phnum; i++, j++) { + snprintf(ret[i].name, ELF_STRING_LENGTH, "phdr_%i", j); + ret[i].offset = bin->phdr[j].p_offset; + ret[i].last = 0; } + ret[i].last = 1; - return 0; + return ret; } -int ELF_(r_bin_elf_get_fields_count)(ELF_(r_bin_elf_obj) *bin) -{ - ELF_(Ehdr) *ehdr = &bin->ehdr; - int ctr=0; - - ctr = 3; - ctr += ehdr->e_phnum; - - return ctr; -} - -int ELF_(r_bin_elf_get_strings)(ELF_(r_bin_elf_obj) *bin, int verbose, int str_limit, r_bin_elf_string *strings) -{ - ELF_(Ehdr) *ehdr = &bin->ehdr; - ELF_(Shdr) *shdr = bin->shdr, *shdrp; - const char *string = bin->string; - int i, ctr = 0; - - shdrp = shdr; - for (i = 0; i < ehdr->e_shnum; i++, shdrp++) { - if (verbose < 2 && i != 0 && !strcmp(&string[shdrp->sh_name], ".rodata")) - ctr = ELF_(aux_stripstr_from_file)(bin->file, 3, ENCODING_ASCII, - shdrp->sh_offset, shdrp->sh_offset+shdrp->sh_size, NULL, str_limit-ctr, strings+ctr); - if (verbose == 2 && i != 0 && !(shdrp->sh_flags & SHF_EXECINSTR)) { - ctr = ELF_(aux_stripstr_from_file)(bin->file, 3, ENCODING_ASCII, - shdrp->sh_offset, shdrp->sh_offset+shdrp->sh_size, NULL, str_limit-ctr, strings+ctr); - } - } - - return ctr; -} - -int ELF_(r_bin_elf_get_libs)(ELF_(r_bin_elf_obj) *bin, int str_limit, r_bin_elf_string *strings) -{ - ELF_(Ehdr) *ehdr = &bin->ehdr; - ELF_(Shdr) *shdr = bin->shdr, *shdrp; - const char *string = bin->string; - int i, ctr = 0; - - // TODO: use system() hack..read rabin code! - // LD_TRACE_LOADED_OBJECTS=1 ./vim - shdrp = shdr; - for (i = 0; i < ehdr->e_shnum; i++, shdrp++) { - if (!strcmp(&string[shdrp->sh_name], ".dynstr")) { - ctr = ELF_(aux_stripstr_from_file)(bin->file, 3, ENCODING_ASCII, - shdrp->sh_offset, shdrp->sh_offset+shdrp->sh_size, ".so.", str_limit, strings+ctr); - } - } - - return ctr; -} - -int ELF_(r_bin_elf_open)(ELF_(r_bin_elf_obj) *bin, const char *file, int rw) +int Elf_(r_bin_elf_open)(struct Elf_(r_bin_elf_obj_t) *bin, const char *file, int rw) { if ((bin->fd=open(file, rw?O_RDWR:O_RDONLY)) == -1) { ERR("Error: Cannot open \"%s\"\n", file); @@ -1282,10 +895,15 @@ int ELF_(r_bin_elf_open)(ELF_(r_bin_elf_obj) *bin, const char *file, int rw) bin->file = file; - if (ELF_(r_bin_elf_init)(bin) == -1) { + if (!Elf_(r_bin_elf_init)(bin)) { close(bin->fd); return -1; } return bin->fd; } + +int Elf_(r_bin_elf_close)(struct Elf_(r_bin_elf_obj_t) *bin) +{ + return close(bin->fd); +} diff --git a/libr/bin/format/elf/elf.h b/libr/bin/format/elf/elf.h index 9355f8cc3a..070452f577 100644 --- a/libr/bin/format/elf/elf.h +++ b/libr/bin/format/elf/elf.h @@ -11,77 +11,75 @@ #define R_BIN_ELF_SCN_IS_READABLE(x) x & SHF_ALLOC #define R_BIN_ELF_SCN_IS_WRITABLE(x) x & SHF_WRITE -typedef struct { +struct r_bin_elf_section_t { u64 offset; u64 size; u64 align; u32 flags; - char name[ELF_NAME_LENGTH]; -} r_bin_elf_section; + char name[ELF_STRING_LENGTH]; + int last; +}; -typedef struct { +struct r_bin_elf_import_t { u64 offset; - char bind[ELF_NAME_LENGTH]; - char type[ELF_NAME_LENGTH]; - char name[ELF_NAME_LENGTH]; -} r_bin_elf_import; + char bind[ELF_STRING_LENGTH]; + char type[ELF_STRING_LENGTH]; + char name[ELF_STRING_LENGTH]; + int last; +}; -typedef struct { +struct r_bin_elf_symbol_t { u64 offset; u64 size; - char bind[ELF_NAME_LENGTH]; - char type[ELF_NAME_LENGTH]; - char name[ELF_NAME_LENGTH]; -} r_bin_elf_symbol; + char bind[ELF_STRING_LENGTH]; + char type[ELF_STRING_LENGTH]; + char name[ELF_STRING_LENGTH]; + int last; +}; -typedef struct { +struct r_bin_elf_field_t { u64 offset; - char name[ELF_NAME_LENGTH]; -} r_bin_elf_field; + char name[ELF_STRING_LENGTH]; + int last; +}; -typedef struct { +struct r_bin_elf_string_t { u64 offset; u64 size; char type; char string[ELF_STRING_LENGTH]; -} r_bin_elf_string; + int last; +}; #endif -typedef struct { - ELF_(Ehdr) ehdr; - ELF_(Phdr)* phdr; - ELF_(Shdr)* shdr; - int plen; - char** section; - char* string; +struct Elf_(r_bin_elf_obj_t) { + Elf_(Ehdr) ehdr; + Elf_(Phdr)* phdr; + Elf_(Shdr)* shdr; + char* strtab; int bss; - u64 base_addr; + u64 baddr; + int endian; const char* file; int fd; -} ELF_(r_bin_elf_obj); +}; -int ELF_(r_bin_elf_close)(ELF_(r_bin_elf_obj)*); -const char* ELF_(r_bin_elf_get_arch)(ELF_(r_bin_elf_obj)*); -u64 ELF_(r_bin_elf_get_base_addr)(ELF_(r_bin_elf_obj)*); -const char* ELF_(r_bin_elf_get_data_encoding)(ELF_(r_bin_elf_obj)*); -const char* ELF_(r_bin_elf_get_elf_class)(ELF_(r_bin_elf_obj)*); -u64 ELF_(r_bin_elf_get_entry_offset)(ELF_(r_bin_elf_obj)*); -const char* ELF_(r_bin_elf_get_file_type)(ELF_(r_bin_elf_obj)*); -int ELF_(r_bin_elf_get_imports)(ELF_(r_bin_elf_obj)*, r_bin_elf_import*); -int ELF_(r_bin_elf_get_imports_count)(ELF_(r_bin_elf_obj)*); -int ELF_(r_bin_elf_get_libs)(ELF_(r_bin_elf_obj)*, int, r_bin_elf_string*); -const char* ELF_(r_bin_elf_get_machine_name)(ELF_(r_bin_elf_obj)*); -const char* ELF_(r_bin_elf_get_osabi_name)(ELF_(r_bin_elf_obj)*); -int ELF_(r_bin_elf_get_sections)(ELF_(r_bin_elf_obj)*, r_bin_elf_section*); -int ELF_(r_bin_elf_get_sections_count)(ELF_(r_bin_elf_obj)*); -int ELF_(r_bin_elf_get_static)(ELF_(r_bin_elf_obj)*); -int ELF_(r_bin_elf_get_strings)(ELF_(r_bin_elf_obj)*, int, int, r_bin_elf_string*); -int ELF_(r_bin_elf_get_stripped)(ELF_(r_bin_elf_obj)*); -int ELF_(r_bin_elf_get_symbols)(ELF_(r_bin_elf_obj)*, r_bin_elf_symbol*); -int ELF_(r_bin_elf_get_symbols_count)(ELF_(r_bin_elf_obj)*); -int ELF_(r_bin_elf_get_fields)(ELF_(r_bin_elf_obj)*, r_bin_elf_field*); -int ELF_(r_bin_elf_get_fields_count)(ELF_(r_bin_elf_obj)*); -int ELF_(r_bin_elf_is_big_endian)(ELF_(r_bin_elf_obj)*); -int ELF_(r_bin_elf_open)(ELF_(r_bin_elf_obj)*, const char*, int); -u64 ELF_(r_bin_elf_resize_section)(ELF_(r_bin_elf_obj)*, const char*, u64); +u64 Elf_(r_bin_elf_get_baddr)(struct Elf_(r_bin_elf_obj_t) *bin); +u64 Elf_(r_bin_elf_get_entry_offset)(struct Elf_(r_bin_elf_obj_t) *bin); +int Elf_(r_bin_elf_get_stripped)(struct Elf_(r_bin_elf_obj_t) *bin); +int Elf_(r_bin_elf_get_static)(struct Elf_(r_bin_elf_obj_t) *bin); +char* Elf_(r_bin_elf_get_data_encoding)(struct Elf_(r_bin_elf_obj_t) *bin); +char* Elf_(r_bin_elf_get_arch)(struct Elf_(r_bin_elf_obj_t) *bin); +char* Elf_(r_bin_elf_get_machine_name)(struct Elf_(r_bin_elf_obj_t) *bin); +char* Elf_(r_bin_elf_get_file_type)(struct Elf_(r_bin_elf_obj_t) *bin); +char* Elf_(r_bin_elf_get_elf_class)(struct Elf_(r_bin_elf_obj_t) *bin); +char* Elf_(r_bin_elf_get_osabi_name)(struct Elf_(r_bin_elf_obj_t) *bin); +int Elf_(r_bin_elf_is_big_endian)(struct Elf_(r_bin_elf_obj_t) *bin); +/*XXX Section resize? */ +struct r_bin_elf_section_t* Elf_(r_bin_elf_get_sections)(struct Elf_(r_bin_elf_obj_t) *bin); +struct r_bin_elf_import_t* Elf_(r_bin_elf_get_imports)(struct Elf_(r_bin_elf_obj_t) *bin); +struct r_bin_elf_symbol_t* Elf_(r_bin_elf_get_symbols)(struct Elf_(r_bin_elf_obj_t) *bin); +struct r_bin_elf_field_t* Elf_(r_bin_elf_get_fields)(struct Elf_(r_bin_elf_obj_t) *bin); +int Elf_(r_bin_elf_open)(struct Elf_(r_bin_elf_obj_t) *bin, const char *file, int rw); +int Elf_(r_bin_elf_close)(struct Elf_(r_bin_elf_obj_t) *bin); diff --git a/libr/bin/format/elf/elf_specs.h b/libr/bin/format/elf/elf_specs.h index 747a2c1c2e..3d796cf234 100644 --- a/libr/bin/format/elf/elf_specs.h +++ b/libr/bin/format/elf/elf_specs.h @@ -17,7 +17,8 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#undef ELF_ +#undef Elf_ +#undef Elf_Vword #undef ELF_ST_BIND #undef ELF_ST_TYPE #undef ELF_ST_INFO @@ -28,39 +29,42 @@ #undef ELF_M_SYM #undef ELF_M_SIZE #undef ELF_M_INFO -#undef ELF_Vword #ifdef R_BIN_ELF64 - #define ELF_(name) Elf64_##name - #define ELF_ST_BIND ELF64_ST_BIND - #define ELF_ST_TYPE ELF64_ST_TYPE - #define ELF_ST_INFO ELF64_ST_INFO - #define ELF_ST_VISIBILITY ELF64_ST_VISIBILITY - #define ELF_R_SYM ELF64_R_SYM - #define ELF_R_TYPE ELF64_R_TYPE - #define ELF_R_INFO ELF64_R_INFO - #define ELF_M_SYM ELF64_M_SYM - #define ELF_M_SIZE ELF64_M_SIZE - #define ELF_M_INFO ELF64_M_INFO - #define ELF_Vword Elf64_Xword +# define Elf_(name) Elf64_##name +# define Elf_Vword Elf64_Xword +# define ELF_ST_BIND ELF64_ST_BIND +# define ELF_ST_TYPE ELF64_ST_TYPE +# define ELF_ST_INFO ELF64_ST_INFO +# define ELF_ST_VISIBILITY ELF64_ST_VISIBILITY +# define ELF_R_SYM ELF64_R_SYM +# define ELF_R_TYPE ELF64_R_TYPE +# define ELF_R_INFO ELF64_R_INFO +# define ELF_M_SYM ELF64_M_SYM +# define ELF_M_SIZE ELF64_M_SIZE +# define ELF_M_INFO ELF64_M_INFO #else - #define ELF_(name) Elf32_##name - #define ELF_ST_BIND ELF32_ST_BIND - #define ELF_ST_TYPE ELF32_ST_TYPE - #define ELF_ST_INFO ELF32_ST_INFO - #define ELF_ST_VISIBILITY ELF32_ST_VISIBILITY - #define ELF_R_SYM ELF32_R_SYM - #define ELF_R_TYPE ELF32_R_TYPE - #define ELF_R_INFO ELF32_R_INFO - #define ELF_M_SYM ELF32_M_SYM - #define ELF_M_SIZE ELF32_M_SIZE - #define ELF_M_INFO ELF32_M_INFO - #define ELF_Vword Elf32_Word +# define Elf_(name) Elf32_##name +# define Elf_Vword Elf32_Word +# define ELF_ST_BIND ELF32_ST_BIND +# define ELF_ST_TYPE ELF32_ST_TYPE +# define ELF_ST_INFO ELF32_ST_INFO +# define ELF_ST_VISIBILITY ELF32_ST_VISIBILITY +# define ELF_R_SYM ELF32_R_SYM +# define ELF_R_TYPE ELF32_R_TYPE +# define ELF_R_INFO ELF32_R_INFO +# define ELF_M_SYM ELF32_M_SYM +# define ELF_M_SIZE ELF32_M_SIZE +# define ELF_M_INFO ELF32_M_INFO #endif #ifndef _INCLUDE_ELF_SPECS_H #define _INCLUDE_ELF_SPECS_H +#define ELF_STRING_LENGTH 256 +#define ELF_ADDR_MASK 0xFFFFFFFFFFFF8000LL +#define ELF_GOTOFF_MASK 0xFFFFFFFFFFFFF000LL + /* Type for a 16-bit quantity. */ typedef unsigned short Elf32_Half; typedef unsigned short Elf64_Half; @@ -93,12 +97,6 @@ typedef unsigned short Elf64_Section; typedef Elf32_Half Elf32_Versym; typedef Elf64_Half Elf64_Versym; - -#define ELF_NAME_LENGTH 256 -#define ELF_STRING_LENGTH 256 -#define ELF_ADDR_MASK 0xffffffffffff8000LL -#define ELF_GOTOFF_MASK 0xfffffffffffff000LL - /* The ELF file header. This appears at the start of every ELF file. */ #define EI_NIDENT (16) diff --git a/libr/bin/p/bin_elf.c b/libr/bin/p/bin_elf.c index 4f429aa023..63613fd2b6 100644 --- a/libr/bin/p/bin_elf.c +++ b/libr/bin/p/bin_elf.c @@ -7,10 +7,10 @@ static int bopen(struct r_bin_t *bin) { - if((bin->bin_obj = MALLOC_STRUCT(ELF_(r_bin_elf_obj))) == NULL) + if((bin->bin_obj = MALLOC_STRUCT(struct Elf_(r_bin_elf_obj_t))) == NULL) return R_FALSE; - if ((bin->fd = ELF_(r_bin_elf_open)(bin->bin_obj,bin->file,bin->rw)) == -1) { + if ((bin->fd = Elf_(r_bin_elf_open)(bin->bin_obj,bin->file,bin->rw)) == -1) { free(bin->bin_obj); return R_FALSE; } @@ -20,12 +20,12 @@ static int bopen(struct r_bin_t *bin) static int bclose(struct r_bin_t *bin) { - return ELF_(r_bin_elf_close)(bin->bin_obj); + return Elf_(r_bin_elf_close)(bin->bin_obj); } static u64 baddr(struct r_bin_t *bin) { - return ELF_(r_bin_elf_get_base_addr)(bin->bin_obj); + return Elf_(r_bin_elf_get_baddr)(bin->bin_obj); } static struct r_bin_entry_t* entry(struct r_bin_t *bin) @@ -36,28 +36,24 @@ static struct r_bin_entry_t* entry(struct r_bin_t *bin) return NULL; memset(ret, '\0', sizeof(struct r_bin_entry_t)); - ret->offset = ret->rva = ELF_(r_bin_elf_get_entry_offset)(bin->bin_obj); + ret->offset = ret->rva = Elf_(r_bin_elf_get_entry_offset)(bin->bin_obj); return ret; } static struct r_bin_section_t* sections(struct r_bin_t *bin) { - int sections_count, i; struct r_bin_section_t *ret = NULL; - r_bin_elf_section *section = NULL; + struct r_bin_elf_section_t *section = NULL; + int i, sections_count; - sections_count = ELF_(r_bin_elf_get_sections_count)(bin->bin_obj); - - if((section = malloc(sections_count * sizeof(r_bin_elf_section))) == NULL) + if ((section = Elf_(r_bin_elf_get_sections)(bin->bin_obj)) == NULL) return NULL; - if((ret = malloc((sections_count + 1) * sizeof(struct r_bin_section_t))) == NULL) + for (sections_count = 0; !section[sections_count].last; sections_count++); + if ((ret = malloc((sections_count + 1) * sizeof(struct r_bin_section_t))) == NULL) return NULL; - memset(ret, '\0', (sections_count + 1) * sizeof(struct r_bin_section_t)); - - ELF_(r_bin_elf_get_sections)(bin->bin_obj,section); for (i = 0; i < sections_count; i++) { - strncpy(ret[i].name, (char*)section[i].name, R_BIN_SIZEOF_NAMES); + strncpy(ret[i].name, (char*)section[i].name, R_BIN_SIZEOF_STRINGS); ret[i].size = section[i].size; ret[i].vsize = section[i].size; ret[i].offset = section[i].offset; @@ -82,23 +78,18 @@ static struct r_bin_symbol_t* symbols(struct r_bin_t *bin) { int symbols_count, i; struct r_bin_symbol_t *ret = NULL; - r_bin_elf_symbol *symbol = NULL; + struct r_bin_elf_symbol_t *symbol = NULL; - symbols_count = ELF_(r_bin_elf_get_symbols_count)(bin->bin_obj); - - if ((symbol = malloc(symbols_count * sizeof(r_bin_elf_symbol))) == NULL) - return NULL; + symbol = Elf_(r_bin_elf_get_symbols)(bin->bin_obj); + for (symbols_count = 0; !symbol[symbols_count].last; symbols_count++); if ((ret = malloc((symbols_count + 1) * sizeof(struct r_bin_symbol_t))) == NULL) return NULL; - memset(ret, '\0', (symbols_count + 1) * sizeof(struct r_bin_symbol_t)); - - ELF_(r_bin_elf_get_symbols)(bin->bin_obj, symbol); for (i = 0; i < symbols_count; i++) { - strncpy(ret[i].name, symbol[i].name, R_BIN_SIZEOF_NAMES); - strncpy(ret[i].forwarder, "NONE", R_BIN_SIZEOF_NAMES); - strncpy(ret[i].bind, symbol[i].bind, R_BIN_SIZEOF_NAMES); - strncpy(ret[i].type, symbol[i].type, R_BIN_SIZEOF_NAMES); + strncpy(ret[i].name, symbol[i].name, R_BIN_SIZEOF_STRINGS); + strncpy(ret[i].forwarder, "NONE", R_BIN_SIZEOF_STRINGS); + strncpy(ret[i].bind, symbol[i].bind, R_BIN_SIZEOF_STRINGS); + strncpy(ret[i].type, symbol[i].type, R_BIN_SIZEOF_STRINGS); ret[i].rva = symbol[i].offset; ret[i].offset = symbol[i].offset; ret[i].size = symbol[i].size; @@ -116,22 +107,17 @@ static struct r_bin_import_t* imports(struct r_bin_t *bin) { int imports_count, i; struct r_bin_import_t *ret = NULL; - r_bin_elf_import *import = NULL; + struct r_bin_elf_import_t *import = NULL; - imports_count = ELF_(r_bin_elf_get_imports_count)(bin->bin_obj); - - if ((import = malloc(imports_count * sizeof(r_bin_elf_import))) == NULL) - return NULL; + import = Elf_(r_bin_elf_get_imports)(bin->bin_obj); + for (imports_count = 0; !import[imports_count].last; imports_count++); if ((ret = malloc((imports_count + 1) * sizeof(struct r_bin_import_t))) == NULL) return NULL; - memset(ret, '\0', (imports_count + 1) * sizeof(struct r_bin_import_t)); - - ELF_(r_bin_elf_get_imports)(bin->bin_obj,import); for (i = 0; i < imports_count; i++) { - strncpy(ret[i].name, import[i].name, R_BIN_SIZEOF_NAMES); - strncpy(ret[i].bind, import[i].bind, R_BIN_SIZEOF_NAMES); - strncpy(ret[i].type, import[i].type, R_BIN_SIZEOF_NAMES); + strncpy(ret[i].name, import[i].name, R_BIN_SIZEOF_STRINGS); + strncpy(ret[i].bind, import[i].bind, R_BIN_SIZEOF_STRINGS); + strncpy(ret[i].type, import[i].type, R_BIN_SIZEOF_STRINGS); ret[i].rva = import[i].offset; ret[i].offset = import[i].offset; ret[i].ordinal = 0; @@ -139,35 +125,63 @@ static struct r_bin_import_t* imports(struct r_bin_t *bin) ret[i].last = 0; } ret[i].last = 1; + free(import); + return ret; } static struct r_bin_info_t* info(struct r_bin_t *bin) { struct r_bin_info_t *ret = NULL; + char *string; if((ret = malloc(sizeof(struct r_bin_info_t))) == NULL) return NULL; memset(ret, '\0', sizeof(struct r_bin_info_t)); - strncpy(ret->type, ELF_(r_bin_elf_get_file_type)(bin->bin_obj), R_BIN_SIZEOF_NAMES); - strncpy(ret->class, ELF_(r_bin_elf_get_elf_class)(bin->bin_obj), R_BIN_SIZEOF_NAMES); - strncpy(ret->rclass, "elf", R_BIN_SIZEOF_NAMES); - strncpy(ret->os, ELF_(r_bin_elf_get_osabi_name)(bin->bin_obj), R_BIN_SIZEOF_NAMES); - strncpy(ret->subsystem, ELF_(r_bin_elf_get_osabi_name)(bin->bin_obj), R_BIN_SIZEOF_NAMES); - strncpy(ret->machine, ELF_(r_bin_elf_get_machine_name)(bin->bin_obj), R_BIN_SIZEOF_NAMES); - strncpy(ret->arch, ELF_(r_bin_elf_get_arch)(bin->bin_obj), R_BIN_SIZEOF_NAMES); - ret->big_endian=ELF_(r_bin_elf_is_big_endian)(bin->bin_obj); + + if ((string = Elf_(r_bin_elf_get_file_type)(bin->bin_obj)) == NULL) + return NULL; + strncpy(ret->type, string, R_BIN_SIZEOF_STRINGS); + free(string); + + if ((string = Elf_(r_bin_elf_get_elf_class)(bin->bin_obj)) == NULL) + return NULL; + strncpy(ret->class, string, R_BIN_SIZEOF_STRINGS); + free(string); + + if ((string = Elf_(r_bin_elf_get_osabi_name)(bin->bin_obj)) == NULL) + return NULL; + strncpy(ret->os, string, R_BIN_SIZEOF_STRINGS); + free(string); + + if ((string = Elf_(r_bin_elf_get_osabi_name)(bin->bin_obj)) == NULL) + return NULL; + strncpy(ret->subsystem, string, R_BIN_SIZEOF_STRINGS); + free(string); + + if ((string = Elf_(r_bin_elf_get_machine_name)(bin->bin_obj)) == NULL) + return NULL; + strncpy(ret->machine, string, R_BIN_SIZEOF_STRINGS); + free(string); + + if ((string = Elf_(r_bin_elf_get_arch)(bin->bin_obj)) == NULL) + return NULL; + strncpy(ret->arch, string, R_BIN_SIZEOF_STRINGS); + free(string); + + strncpy(ret->rclass, "elf", R_BIN_SIZEOF_STRINGS); + ret->big_endian=Elf_(r_bin_elf_is_big_endian)(bin->bin_obj); ret->dbg_info = 0; - if (ELF_(r_bin_elf_get_stripped)(bin->bin_obj)) { + if (Elf_(r_bin_elf_get_stripped)(bin->bin_obj)) { ret->dbg_info |= 0x01; } else { ret->dbg_info |= 0x04; ret->dbg_info |= 0x08; ret->dbg_info |= 0x10; } - if (ELF_(r_bin_elf_get_static)(bin->bin_obj)) + if (Elf_(r_bin_elf_get_static)(bin->bin_obj)) ret->dbg_info |= 0x02; return ret; } @@ -175,21 +189,15 @@ static struct r_bin_info_t* info(struct r_bin_t *bin) static struct r_bin_field_t* fields(struct r_bin_t *bin) { struct r_bin_field_t *ret = NULL; - r_bin_elf_field *field = NULL; + struct r_bin_elf_field_t *field = NULL; int i, fields_count; - fields_count = ELF_(r_bin_elf_get_fields_count)(bin->bin_obj); - - if ((field = malloc(fields_count * sizeof(r_bin_elf_field))) == NULL) - return NULL; + field = Elf_(r_bin_elf_get_fields)(bin->bin_obj); + for (fields_count = 0; !field[fields_count].last; fields_count++); if ((ret = malloc((fields_count + 1) * sizeof(struct r_bin_field_t))) == NULL) return NULL; - memset(ret, '\0', (fields_count + 1) * sizeof(struct r_bin_field_t)); - - ELF_(r_bin_elf_get_fields)(bin->bin_obj,field); - for (i = 0; i < fields_count; i++) { - strncpy(ret[i].name, field[i].name, R_BIN_SIZEOF_NAMES); + strncpy(ret[i].name, field[i].name, R_BIN_SIZEOF_STRINGS); ret[i].rva = field[i].offset; ret[i].offset = field[i].offset; ret[i].last = 0; @@ -201,10 +209,13 @@ static struct r_bin_field_t* fields(struct r_bin_t *bin) return ret; } +/*XXX*/ +#if 0 static u64 resize_section(struct r_bin_t *bin, char *name, u64 size) { - return ELF_(r_bin_elf_resize_section)(bin->bin_obj, name, size); + return Elf_(r_bin_elf_resize_section)(bin->bin_obj, name, size); } +#endif #if !R_BIN_ELF64 static int check(struct r_bin_t *bin) @@ -239,7 +250,8 @@ struct r_bin_handle_t r_bin_plugin_elf = { .strings = NULL, .info = &info, .fields = &fields, - .resize_section = &resize_section + .resize_section = NULL + /*XXX .resize_section = &resize_section */ }; #ifndef CORELIB diff --git a/libr/bin/p/bin_elf64.c b/libr/bin/p/bin_elf64.c index 70b5027e84..19fcf58a3b 100644 --- a/libr/bin/p/bin_elf64.c +++ b/libr/bin/p/bin_elf64.c @@ -36,7 +36,8 @@ struct r_bin_handle_t r_bin_plugin_elf64 = { .strings = NULL, .info = &info, .fields = &fields, - .resize_section = &resize_section + .resize_section = NULL + /*XXX .resize_section = &resize_section */ }; #ifndef CORELIB diff --git a/libr/bin/p/bin_java.c b/libr/bin/p/bin_java.c index 41b8cd74dc..6897144d19 100644 --- a/libr/bin/p/bin_java.c +++ b/libr/bin/p/bin_java.c @@ -57,10 +57,10 @@ static struct r_bin_symbol_t* symbols(struct r_bin_t *bin) r_bin_java_get_symbols(bin->bin_obj,symbol); for (i = 0; i < symbols_count; i++) { - strncpy(ret[i].name, symbol[i].name, R_BIN_SIZEOF_NAMES); - strncpy(ret[i].forwarder, "NONE", R_BIN_SIZEOF_NAMES); - strncpy(ret[i].bind, "NONE", R_BIN_SIZEOF_NAMES); - strncpy(ret[i].type, "FUNC", R_BIN_SIZEOF_NAMES); + strncpy(ret[i].name, symbol[i].name, R_BIN_SIZEOF_STRINGS); + strncpy(ret[i].forwarder, "NONE", R_BIN_SIZEOF_STRINGS); + strncpy(ret[i].bind, "NONE", R_BIN_SIZEOF_STRINGS); + strncpy(ret[i].type, "FUNC", R_BIN_SIZEOF_STRINGS); ret[i].rva = ret[i].offset = symbol[i].offset; ret[i].size = symbol[i].size; ret[i].ordinal = 0; @@ -90,7 +90,7 @@ static struct r_bin_string_t* strings(struct r_bin_t *bin) r_bin_java_get_strings(bin->bin_obj,string); for (i = 0; i < strings_count; i++) { - strncpy(ret[i].string, string[i].str, R_BIN_SIZEOF_NAMES); + strncpy(ret[i].string, string[i].str, R_BIN_SIZEOF_STRINGS); ret[i].rva = ret[i].offset = string[i].offset; ret[i].size = string[i].size; ret[i].ordinal = string[i].ordinal; @@ -115,13 +115,13 @@ static struct r_bin_info_t* info(struct r_bin_t *bin) version[0] = '\0'; r_bin_java_get_version(bin->bin_obj, version); - strncpy(ret->type, "JAVA CLASS", R_BIN_SIZEOF_NAMES); - strncpy(ret->class, version, R_BIN_SIZEOF_NAMES); - strncpy(ret->rclass, "class", R_BIN_SIZEOF_NAMES); - strncpy(ret->os, "any", R_BIN_SIZEOF_NAMES); - strncpy(ret->subsystem, "any", R_BIN_SIZEOF_NAMES); - strncpy(ret->machine, "Java VM", R_BIN_SIZEOF_NAMES); - strncpy(ret->arch, "javavm", R_BIN_SIZEOF_NAMES); + strncpy(ret->type, "JAVA CLASS", R_BIN_SIZEOF_STRINGS); + strncpy(ret->class, version, R_BIN_SIZEOF_STRINGS); + strncpy(ret->rclass, "class", R_BIN_SIZEOF_STRINGS); + strncpy(ret->os, "any", R_BIN_SIZEOF_STRINGS); + strncpy(ret->subsystem, "any", R_BIN_SIZEOF_STRINGS); + strncpy(ret->machine, "Java VM", R_BIN_SIZEOF_STRINGS); + strncpy(ret->arch, "javavm", R_BIN_SIZEOF_STRINGS); ret->big_endian= 0; ret->dbg_info = 0x04 | 0x08; /* LineNums | Syms */ diff --git a/libr/bin/p/bin_pe.c b/libr/bin/p/bin_pe.c index 7d4947c23f..62dde0a53e 100644 --- a/libr/bin/p/bin_pe.c +++ b/libr/bin/p/bin_pe.c @@ -61,7 +61,7 @@ static struct r_bin_section_t* sections(struct r_bin_t *bin) PE_(r_bin_pe_get_sections)(bin->bin_obj, section); for (i = 0; i < sections_count; i++) { - strncpy(ret[i].name, (char*)section[i].name, R_BIN_SIZEOF_NAMES); + strncpy(ret[i].name, (char*)section[i].name, R_BIN_SIZEOF_STRINGS); ret[i].size = section[i].size; ret[i].vsize = section->vsize; ret[i].offset = section[i].offset; @@ -101,10 +101,10 @@ static struct r_bin_symbol_t* symbols(struct r_bin_t *bin) PE_(r_bin_pe_get_exports)(bin->bin_obj, symbol); for (i = 0; i < symbols_count; i++) { - strncpy(ret[i].name, (char*)symbol[i].name, R_BIN_SIZEOF_NAMES); - strncpy(ret[i].forwarder, (char*)symbol[i].forwarder, R_BIN_SIZEOF_NAMES); - strncpy(ret[i].bind, "NONE", R_BIN_SIZEOF_NAMES); - strncpy(ret[i].type, "NONE", R_BIN_SIZEOF_NAMES); + strncpy(ret[i].name, (char*)symbol[i].name, R_BIN_SIZEOF_STRINGS); + strncpy(ret[i].forwarder, (char*)symbol[i].forwarder, R_BIN_SIZEOF_STRINGS); + strncpy(ret[i].bind, "NONE", R_BIN_SIZEOF_STRINGS); + strncpy(ret[i].type, "NONE", R_BIN_SIZEOF_STRINGS); ret[i].rva = symbol[i].rva; ret[i].offset = symbol[i].offset; ret[i].size = 0; @@ -136,9 +136,9 @@ static struct r_bin_import_t* imports(struct r_bin_t *bin) PE_(r_bin_pe_get_imports)(bin->bin_obj, import); for (i = 0; i < imports_count; i++) { - strncpy(ret[i].name, (char*)import[i].name, R_BIN_SIZEOF_NAMES); - strncpy(ret[i].bind, "NONE", R_BIN_SIZEOF_NAMES); - strncpy(ret[i].type, "NONE", R_BIN_SIZEOF_NAMES); + strncpy(ret[i].name, (char*)import[i].name, R_BIN_SIZEOF_STRINGS); + strncpy(ret[i].bind, "NONE", R_BIN_SIZEOF_STRINGS); + strncpy(ret[i].type, "NONE", R_BIN_SIZEOF_STRINGS); ret[i].rva = import[i].rva; ret[i].offset = import[i].offset; ret[i].ordinal = import[i].ordinal; @@ -161,20 +161,20 @@ static struct r_bin_info_t* info(struct r_bin_t *bin) memset(ret, '\0', sizeof(struct r_bin_info_t)); if (PE_(r_bin_pe_get_class)(bin->bin_obj, pe_class_str)) - strncpy(ret->class, pe_class_str, R_BIN_SIZEOF_NAMES); - strncpy(ret->rclass, "pe", R_BIN_SIZEOF_NAMES); + strncpy(ret->class, pe_class_str, R_BIN_SIZEOF_STRINGS); + strncpy(ret->rclass, "pe", R_BIN_SIZEOF_STRINGS); if (PE_(r_bin_pe_get_os)(bin->bin_obj, pe_os_str)) - strncpy(ret->os, pe_os_str, R_BIN_SIZEOF_NAMES); + strncpy(ret->os, pe_os_str, R_BIN_SIZEOF_STRINGS); if (PE_(r_bin_pe_get_arch)(bin->bin_obj, pe_arch_str)) - strncpy(ret->arch, pe_arch_str, R_BIN_SIZEOF_NAMES); + strncpy(ret->arch, pe_arch_str, R_BIN_SIZEOF_STRINGS); if (PE_(r_bin_pe_get_machine)(bin->bin_obj, pe_machine_str)) - strncpy(ret->machine, pe_machine_str, R_BIN_SIZEOF_NAMES); + strncpy(ret->machine, pe_machine_str, R_BIN_SIZEOF_STRINGS); if (PE_(r_bin_pe_get_subsystem)(bin->bin_obj, pe_subsystem_str)) - strncpy(ret->subsystem, pe_subsystem_str, R_BIN_SIZEOF_NAMES); + strncpy(ret->subsystem, pe_subsystem_str, R_BIN_SIZEOF_STRINGS); if (PE_(r_bin_pe_is_dll)(bin->bin_obj)) - strncpy(ret->type, "DLL (Dynamic Link Library)", R_BIN_SIZEOF_NAMES); + strncpy(ret->type, "DLL (Dynamic Link Library)", R_BIN_SIZEOF_STRINGS); else - strncpy(ret->type, "EXEC (Executable file)", R_BIN_SIZEOF_NAMES); + strncpy(ret->type, "EXEC (Executable file)", R_BIN_SIZEOF_STRINGS); ret->big_endian = PE_(r_bin_pe_is_big_endian)(bin->bin_obj); ret->dbg_info = 0; diff --git a/libr/bin/t/rabin2.c b/libr/bin/t/rabin2.c index b2dbec1ce5..a137c815bb 100644 --- a/libr/bin/t/rabin2.c +++ b/libr/bin/t/rabin2.c @@ -82,9 +82,9 @@ static int rabin_show_entrypoint() static int rabin_show_imports() { - int ctr = 0; + struct r_bin_import_t *imports; u64 baddr; - struct r_bin_import_t *imports, *importsp; + int i; baddr = r_bin_get_baddr(&bin); @@ -95,21 +95,19 @@ static int rabin_show_imports() printf("fs imports\n"); else printf("[Imports]\n"); - importsp = imports; - while (!importsp->last) { + for (i = 0; !imports[i].last; i++) { if (rad) { - r_flag_name_filter(importsp->name); + r_flag_name_filter(imports[i].name); printf("f imp.%s @ 0x%08llx\n", - importsp->name, baddr+importsp->rva); + imports[i].name, baddr+imports[i].rva); } else printf("address=0x%08llx offset=0x%08llx ordinal=%03lli " "hint=%03lli bind=%s type=%s name=%s\n", - baddr+importsp->rva, importsp->offset, - importsp->ordinal, importsp->hint, importsp->bind, - importsp->type, importsp->name); - importsp++; ctr++; + baddr+imports[i].rva, imports[i].offset, + imports[i].ordinal, imports[i].hint, imports[i].bind, + imports[i].type, imports[i].name); } - if (!rad) printf("\n%i imports\n", ctr); + if (!rad) printf("\n%i imports\n", i); free(imports); @@ -118,9 +116,9 @@ static int rabin_show_imports() static int rabin_show_symbols() { - int ctr = 0; + struct r_bin_symbol_t *symbols; u64 baddr; - struct r_bin_symbol_t *symbols, *symbolsp; + int i; baddr = r_bin_get_baddr(&bin); @@ -130,33 +128,31 @@ static int rabin_show_symbols() if (rad) printf("fs symbols\n"); else printf("[Symbols]\n"); - symbolsp = symbols; - while (!symbolsp->last) { + for (i = 0; !symbols[i].last; i++) { if (rad) { - r_flag_name_filter(symbolsp->name); - if (symbolsp->size) { - if (!strncmp(symbolsp->type,"FUNC", 4)) + r_flag_name_filter(symbols[i].name); + if (symbols[i].size) { + if (!strncmp(symbols[i].type,"FUNC", 4)) printf("CF %lli @ 0x%08llx\n", - symbolsp->size, baddr+symbolsp->rva); + symbols[i].size, baddr+symbols[i].rva); else - if (!strncmp(symbolsp->type,"OBJECT", 6)) + if (!strncmp(symbols[i].type,"OBJECT", 6)) printf("Cd %lli @ 0x%08llx\n", - symbolsp->size, baddr+symbolsp->rva); + symbols[i].size, baddr+symbols[i].rva); printf("f sym.%s %lli @ 0x%08llx\n", - symbolsp->name, symbolsp->size, - baddr+symbolsp->rva); + symbols[i].name, symbols[i].size, + baddr+symbols[i].rva); } else printf("f sym.%s @ 0x%08llx\n", - symbolsp->name, baddr+symbolsp->rva); + symbols[i].name, baddr+symbols[i].rva); } else printf("address=0x%08llx offset=0x%08llx ordinal=%03lli " "forwarder=%s size=%08lli bind=%s type=%s name=%s\n", - baddr+symbolsp->rva, symbolsp->offset, - symbolsp->ordinal, symbolsp->forwarder, - symbolsp->size, symbolsp->bind, symbolsp->type, - symbolsp->name); - symbolsp++; ctr++; + baddr+symbols[i].rva, symbols[i].offset, + symbols[i].ordinal, symbols[i].forwarder, + symbols[i].size, symbols[i].bind, symbols[i].type, + symbols[i].name); } - if (!rad) printf("\n%i symbols\n", ctr); + if (!rad) printf("\n%i symbols\n", i); free(symbols); @@ -165,9 +161,9 @@ static int rabin_show_symbols() static int rabin_show_strings() { - int ctr = 0; + struct r_bin_string_t *strings; u64 baddr; - struct r_bin_string_t *strings, *stringsp; + int i; baddr = r_bin_get_baddr(&bin); @@ -178,22 +174,20 @@ static int rabin_show_strings() printf("fs strings\n"); else printf("[strings]\n"); - stringsp = strings; - while (!stringsp->last) { + for (i = 0; !strings[i].last; i++) { if (rad) { - r_flag_name_filter(stringsp->string); + r_flag_name_filter(strings[i].string); printf( "f str.%s %lli @ 0x%08llx\n" "Cs %lli @ 0x%08llx\n", - stringsp->string, stringsp->size, baddr+stringsp->rva, - stringsp->size, baddr+stringsp->rva); + strings[i].string, strings[i].size, baddr+strings[i].rva, + strings[i].size, baddr+strings[i].rva); } else printf("address=0x%08llx offset=0x%08llx ordinal=%03lli " "size=%08lli string=%s\n", - baddr+stringsp->rva, stringsp->offset, - stringsp->ordinal, stringsp->size, stringsp->string); - stringsp++; ctr++; + baddr+strings[i].rva, strings[i].offset, + strings[i].ordinal, strings[i].size, strings[i].string); } - if (!rad) printf("\n%i strings\n", ctr); + if (!rad) printf("\n%i strings\n", i); free(strings); @@ -202,9 +196,9 @@ static int rabin_show_strings() static int rabin_show_sections() { - int ctr = 0; + struct r_bin_section_t *sections; u64 baddr; - struct r_bin_section_t *sections, *sectionsp; + int i; baddr = r_bin_get_baddr(&bin); @@ -214,34 +208,32 @@ static int rabin_show_sections() if (rad) printf("fs sections\n"); else printf("[Sections]\n"); - sectionsp = sections; - while (!sectionsp->last) { + for (i = 0; !sections[i].last; i++) { if (rad) { - r_flag_name_filter(sectionsp->name); + r_flag_name_filter(sections[i].name); printf("f section.%s @ 0x%08llx\n", - sectionsp->name, baddr+sectionsp->rva); + sections[i].name, baddr+sections[i].rva); printf("f section.%s_end @ 0x%08llx\n", - sectionsp->name, baddr+sectionsp->rva+sectionsp->size); + sections[i].name, baddr+sections[i].rva+sections[i].size); printf("[%02i] address=0x%08llx offset=0x%08llx size=%08lli " "privileges=%c%c%c%c name=%s\n", - ctr, baddr+sectionsp->rva, sectionsp->offset, sectionsp->size, - R_BIN_SCN_SHAREABLE(sectionsp->characteristics)?'s':'-', - R_BIN_SCN_READABLE(sectionsp->characteristics)?'r':'-', - R_BIN_SCN_WRITABLE(sectionsp->characteristics)?'w':'-', - R_BIN_SCN_EXECUTABLE(sectionsp->characteristics)?'x':'-', - sectionsp->name); + i, baddr+sections[i].rva, sections[i].offset, sections[i].size, + R_BIN_SCN_SHAREABLE(sections[i].characteristics)?'s':'-', + R_BIN_SCN_READABLE(sections[i].characteristics)?'r':'-', + R_BIN_SCN_WRITABLE(sections[i].characteristics)?'w':'-', + R_BIN_SCN_EXECUTABLE(sections[i].characteristics)?'x':'-', + sections[i].name); } else printf("idx=%02i address=0x%08llx offset=0x%08llx size=%08lli " "privileges=%c%c%c%c name=%s\n", - ctr, baddr+sectionsp->rva, sectionsp->offset, sectionsp->size, - R_BIN_SCN_SHAREABLE(sectionsp->characteristics)?'s':'-', - R_BIN_SCN_READABLE(sectionsp->characteristics)?'r':'-', - R_BIN_SCN_WRITABLE(sectionsp->characteristics)?'w':'-', - R_BIN_SCN_EXECUTABLE(sectionsp->characteristics)?'x':'-', - sectionsp->name); - sectionsp++; ctr++; + i, baddr+sections[i].rva, sections[i].offset, sections[i].size, + R_BIN_SCN_SHAREABLE(sections[i].characteristics)?'s':'-', + R_BIN_SCN_READABLE(sections[i].characteristics)?'r':'-', + R_BIN_SCN_WRITABLE(sections[i].characteristics)?'w':'-', + R_BIN_SCN_EXECUTABLE(sections[i].characteristics)?'x':'-', + sections[i].name); } - if (!rad) printf("\n%i sections\n", ctr); + if (!rad) printf("\n%i sections\n", i); free(sections); @@ -292,9 +284,9 @@ static int rabin_show_info() static int rabin_show_fields() { - int ctr = 0; + struct r_bin_field_t *fields; u64 baddr; - struct r_bin_field_t *fields, *fieldsp; + int i; baddr = r_bin_get_baddr(&bin); @@ -304,20 +296,18 @@ static int rabin_show_fields() if (rad) printf("fs header\n"); else printf("[Header fields]\n"); - fieldsp = fields; - while (!fieldsp->last) { + for (i = 0; !fields[i].last; i++) { if (rad) { - r_flag_name_filter(fieldsp->name); + r_flag_name_filter(fields[i].name); printf("f header.%s @ 0x%08llx\n", - fieldsp->name, baddr+fieldsp->rva); + fields[i].name, baddr+fields[i].rva); printf("[%02i] address=0x%08llx offset=0x%08llx name=%s\n", - ctr, baddr+fieldsp->rva, fieldsp->offset, fieldsp->name); + i, baddr+fields[i].rva, fields[i].offset, fields[i].name); } else printf("idx=%02i address=0x%08llx offset=0x%08llx name=%s\n", - ctr, baddr+fieldsp->rva, fieldsp->offset, fieldsp->name); - fieldsp++; ctr++; + i, baddr+fields[i].rva, fields[i].offset, fields[i].name); } - if (!rad) printf("\n%i fields\n", ctr); + if (!rad) printf("\n%i fields\n", i); free(fields); @@ -327,33 +317,30 @@ static int rabin_show_fields() static int rabin_dump_symbols(int len) { - struct r_bin_symbol_t *symbols, *symbolsp; - int olen = len; + struct r_bin_symbol_t *symbols; u8 *buf; char *ret; + int olen = len, i; if ((symbols = r_bin_get_symbols(&bin)) == NULL) return R_FALSE; - symbolsp = symbols; - while (!symbolsp->last) { - if (symbolsp->size != 0 && (olen > symbolsp->size || olen == 0)) - len = symbolsp->size; - else if (symbolsp->size == 0 && olen == 0) + for (i = 0; !symbols[i].last; i++) { + if (symbols[i].size != 0 && (olen > symbols[i].size || olen == 0)) + len = symbols[i].size; + else if (symbols[i].size == 0 && olen == 0) len = 32; else len = olen; if (!(buf = malloc(len)) || !(ret = malloc(len*2+1))) return R_FALSE; - lseek(bin.fd, symbolsp->offset, SEEK_SET); + lseek(bin.fd, symbols[i].offset, SEEK_SET); read(bin.fd, buf, len); r_hex_bin2str(buf, len, ret); - printf("%s %s\n", symbolsp->name, ret); + printf("%s %s\n", symbols[i].name, ret); free(buf); free(ret); - - symbolsp++; } free(symbols); @@ -363,29 +350,27 @@ static int rabin_dump_symbols(int len) static int rabin_dump_sections(char *name) { - struct r_bin_section_t *sections, *sectionsp; + struct r_bin_section_t *sections; u8 *buf; char *ret; + int i; if ((sections = r_bin_get_sections(&bin)) == NULL) return R_FALSE; - sectionsp = sections; - while (!sectionsp->last) { - if (!strcmp(name, sectionsp->name)) { - if (!(buf = malloc(sectionsp->size)) || - !(ret = malloc(sectionsp->size*2+1))) + for (i = 0; !sections[i].last; i++) + if (!strcmp(name, sections[i].name)) { + if (!(buf = malloc(sections[i].size)) || + !(ret = malloc(sections[i].size*2+1))) return R_FALSE; - lseek(bin.fd, sectionsp->offset, SEEK_SET); - read(bin.fd, buf, sectionsp->size); - r_hex_bin2str(buf, sectionsp->size, ret); + lseek(bin.fd, sections[i].offset, SEEK_SET); + read(bin.fd, buf, sections[i].size); + r_hex_bin2str(buf, sections[i].size, ret); printf("%s\n", ret); free(buf); free(ret); break; } - sectionsp++; - } free(sections); @@ -399,8 +384,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" - " Resize section: r/.data/1024\n"); + " Dump section: d/S/.text\n"); + //" Resize section: r/.data/1024\n"); return R_FALSE; } arg = alloca(strlen(op)+1); @@ -416,6 +401,8 @@ static int rabin_do_operation(const char *op) } switch(arg[0]) { +/*XXX*/ +#if 0 case 'r': if (!rw) { printf("File must be opened in rw mode\n"); @@ -428,6 +415,7 @@ static int rabin_do_operation(const char *op) return R_FALSE; } break; +#endif case 'd': if (!ptr) goto _rabin_do_operation_error; diff --git a/libr/include/r_bin.h b/libr/include/r_bin.h index bf494e7d06..c06fbf9b0a 100644 --- a/libr/include/r_bin.h +++ b/libr/include/r_bin.h @@ -17,7 +17,7 @@ #define R_BIN_DBG_SYMS(x) x & 0x08 #define R_BIN_DBG_RELOCS(x) x & 0x10 -#define R_BIN_SIZEOF_NAMES 256 +#define R_BIN_SIZEOF_STRINGS 256 /* types */ struct r_bin_t { @@ -56,7 +56,7 @@ struct r_bin_entry_t { }; struct r_bin_section_t { - char name[R_BIN_SIZEOF_NAMES]; + char name[R_BIN_SIZEOF_STRINGS]; u64 size; u64 vsize; u64 rva; @@ -66,10 +66,10 @@ struct r_bin_section_t { }; struct r_bin_symbol_t { - char name[R_BIN_SIZEOF_NAMES]; - char forwarder[R_BIN_SIZEOF_NAMES]; - char bind[R_BIN_SIZEOF_NAMES]; - char type[R_BIN_SIZEOF_NAMES]; + char name[R_BIN_SIZEOF_STRINGS]; + char forwarder[R_BIN_SIZEOF_STRINGS]; + char bind[R_BIN_SIZEOF_STRINGS]; + char type[R_BIN_SIZEOF_STRINGS]; u64 rva; u64 offset; u64 size; @@ -78,9 +78,9 @@ struct r_bin_symbol_t { }; struct r_bin_import_t { - char name[R_BIN_SIZEOF_NAMES]; - char bind[R_BIN_SIZEOF_NAMES]; - char type[R_BIN_SIZEOF_NAMES]; + char name[R_BIN_SIZEOF_STRINGS]; + char bind[R_BIN_SIZEOF_STRINGS]; + char type[R_BIN_SIZEOF_STRINGS]; u64 rva; u64 offset; u64 ordinal; @@ -89,7 +89,7 @@ struct r_bin_import_t { }; struct r_bin_string_t { - char string[R_BIN_SIZEOF_NAMES]; + char string[R_BIN_SIZEOF_STRINGS]; u64 rva; u64 offset; u64 ordinal; @@ -98,19 +98,19 @@ struct r_bin_string_t { }; struct r_bin_info_t { - char type[R_BIN_SIZEOF_NAMES]; - char class[R_BIN_SIZEOF_NAMES]; - char rclass[R_BIN_SIZEOF_NAMES]; - char arch[R_BIN_SIZEOF_NAMES]; - char machine[R_BIN_SIZEOF_NAMES]; - char os[R_BIN_SIZEOF_NAMES]; - char subsystem[R_BIN_SIZEOF_NAMES]; + char type[R_BIN_SIZEOF_STRINGS]; + char class[R_BIN_SIZEOF_STRINGS]; + char rclass[R_BIN_SIZEOF_STRINGS]; + char arch[R_BIN_SIZEOF_STRINGS]; + char machine[R_BIN_SIZEOF_STRINGS]; + char os[R_BIN_SIZEOF_STRINGS]; + char subsystem[R_BIN_SIZEOF_STRINGS]; int big_endian; u64 dbg_info; }; struct r_bin_field_t { - char name[R_BIN_SIZEOF_NAMES]; + char name[R_BIN_SIZEOF_STRINGS]; u64 rva; u64 offset; int last; @@ -133,7 +133,7 @@ struct r_bin_import_t* r_bin_get_imports(struct r_bin_t *bin); struct r_bin_string_t* r_bin_get_strings(struct r_bin_t *bin); struct r_bin_info_t* r_bin_get_info(struct r_bin_t *bin); struct r_bin_field_t* r_bin_get_fields(struct r_bin_t *bin); -u64 r_bin_resize_section(struct r_bin_t *bin, char *name, u64 size); +/*XXX u64 r_bin_resize_section(struct r_bin_t *bin, char *name, u64 size); */ u64 r_bin_get_section_offset(struct r_bin_t *bin, char *name); u64 r_bin_get_section_rva(struct r_bin_t *bin, char *name); u64 r_bin_get_section_size(struct r_bin_t *bin, char *name); diff --git a/libr/include/r_util.h b/libr/include/r_util.h index 03b474534c..72042c45ff 100644 --- a/libr/include/r_util.h +++ b/libr/include/r_util.h @@ -86,6 +86,7 @@ R_API int r_str_cmp(const char *dst, const char *orig, int len); R_API int r_str_ccpy(char *dst, char *orig, int ch); R_API const char *r_str_get(const char *str); R_API char *r_str_dup(char *ptr, const char *string); +R_API char *r_str_dup_printf(const char *fmt, ...); R_API void *r_str_free(void *ptr); R_API int r_str_inject(char *begin, char *end, char *str, int maxlen); R_API int r_str_delta(char *p, char a, char b); diff --git a/libr/util/mem.c b/libr/util/mem.c index cee5cbb032..235bd543ed 100644 --- a/libr/util/mem.c +++ b/libr/util/mem.c @@ -23,6 +23,7 @@ int r_mem_cmp_mask(const u8 *dest, const u8 *orig, const u8 *mask, int len) void r_mem_copyendian (u8 *dest, const u8 *orig, int size, int endian) { if (endian) { + if (dest != orig) memcpy(dest, orig, size); } else { unsigned char buffer[8]; diff --git a/libr/util/str.c b/libr/util/str.c index 95382bdd71..32b4261dc6 100644 --- a/libr/util/str.c +++ b/libr/util/str.c @@ -245,6 +245,18 @@ char *r_str_dup(char *ptr, const char *string) return ptr; } +char *r_str_dup_printf(const char *fmt, ...) +{ + char *ret; + va_list ap; + va_start(ap, fmt); + if ((ret = malloc(1024)) == NULL) + return NULL; + vsnprintf(ret, 1023, fmt, ap); + va_end(ap); + return ret; +} + char *r_str_concat(char *ptr, const char *string) { if (!ptr)