* More work in r_bin_mach0

- get_symbols
  - get_imports
This commit is contained in:
Nibble 2010-01-15 00:08:39 +01:00
parent ba848ec5dd
commit 7a2b9fd0f4
2 changed files with 127 additions and 14 deletions

View File

@ -101,7 +101,7 @@ static int r_bin_mach0_parse_symtab(struct r_bin_mach0_obj_t* bin, ut64 off)
r_mem_copyendian((ut8*)&st.stroff, (ut8*)&st.stroff, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&st.strsize, (ut8*)&st.strsize, sizeof(uint32_t), !bin->endian);
if (st.strsize > 0 && st.strsize < bin->size && st.nsyms > 0) {
bin->nsyms = st.nsyms;
bin->nsymtab = st.nsyms;
if (!(bin->symstr = malloc(st.strsize))) {
perror("malloc (symstr)");
return R_FALSE;
@ -116,7 +116,7 @@ static int r_bin_mach0_parse_symtab(struct r_bin_mach0_obj_t* bin, ut64 off)
return R_FALSE;
}
lseek(bin->fd, st.symoff, SEEK_SET);
for (i = 0; i < bin->nsyms; i++) {
for (i = 0; i < bin->nsymtab; i++) {
if (read(bin->fd, &bin->symtab[i], sizeof(struct nlist)) != sizeof(struct nlist)) {
perror("read (nlist)");
return R_FALSE;
@ -124,12 +124,62 @@ static int r_bin_mach0_parse_symtab(struct r_bin_mach0_obj_t* bin, ut64 off)
r_mem_copyendian((ut8*)&bin->symtab[i].n_un, (ut8*)&bin->symtab[i].n_un, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->symtab[i].n_desc, (ut8*)&bin->symtab[i].n_desc, sizeof(uint16_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->symtab[i].n_value, (ut8*)&bin->symtab[i].n_value, sizeof(uint32_t), !bin->endian);
IFDBG printf("sym: %s\n", bin->symstr+bin->symtab[i].n_un.n_strx);
IFDBG printf("sym: %s -> %08x (sect: %08x)\n",
bin->symstr+bin->symtab[i].n_un.n_strx, bin->symtab[i].n_value, bin->symtab[i].n_sect);
}
}
return R_TRUE;
}
static int r_bin_mach0_parse_dysymtab(struct r_bin_mach0_obj_t* bin, ut64 off)
{
lseek(bin->fd, off, SEEK_SET);
if (read(bin->fd, &bin->dysymtab, sizeof(struct dysymtab_command)) != sizeof(struct dysymtab_command)) {
perror("read (dysymtab)");
return R_FALSE;
}
r_mem_copyendian((ut8*)&bin->dysymtab.cmd, (ut8*)&bin->dysymtab.cmd, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.cmdsize, (ut8*)&bin->dysymtab.cmdsize, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.ilocalsym, (ut8*)&bin->dysymtab.ilocalsym, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.nlocalsym, (ut8*)&bin->dysymtab.nlocalsym, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.iextdefsym, (ut8*)&bin->dysymtab.iextdefsym, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.nextdefsym, (ut8*)&bin->dysymtab.nextdefsym, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.iundefsym, (ut8*)&bin->dysymtab.iundefsym, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.nundefsym, (ut8*)&bin->dysymtab.nundefsym, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.tocoff, (ut8*)&bin->dysymtab.tocoff, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.ntoc, (ut8*)&bin->dysymtab.ntoc, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.modtaboff, (ut8*)&bin->dysymtab.modtaboff, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.nmodtab, (ut8*)&bin->dysymtab.nmodtab, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.extrefsymoff, (ut8*)&bin->dysymtab.extrefsymoff, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.nextrefsyms, (ut8*)&bin->dysymtab.nextrefsyms, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.indirectsymoff, (ut8*)&bin->dysymtab.indirectsymoff, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.nindirectsyms, (ut8*)&bin->dysymtab.nindirectsyms, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.extreloff, (ut8*)&bin->dysymtab.extreloff, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.locreloff, (ut8*)&bin->dysymtab.locreloff, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->dysymtab.nlocrel, (ut8*)&bin->dysymtab.nlocrel, sizeof(uint32_t), !bin->endian);
bin->ntoc = bin->dysymtab.ntoc;
if (!(bin->toc = malloc(bin->dysymtab.ntoc * sizeof(struct dylib_table_of_contents)))) {
perror("malloc (toc)");
return R_FALSE;
}
lseek(bin->fd, bin->dysymtab.tocoff, SEEK_SET);
if (read(bin->fd, bin->toc, bin->dysymtab.ntoc * sizeof(struct dylib_table_of_contents)) != bin->dysymtab.ntoc * sizeof(struct dylib_table_of_contents)) {
perror("read (toc)");
return R_FALSE;
}
bin->nmodtab = bin->dysymtab.nmodtab;
if (!(bin->modtab = malloc(bin->dysymtab.nmodtab * sizeof(struct dylib_module)))) {
perror("malloc (toc)");
return R_FALSE;
}
lseek(bin->fd, bin->dysymtab.modtaboff, SEEK_SET);
if (read(bin->fd, bin->modtab, bin->dysymtab.nmodtab * sizeof(struct dylib_module)) != bin->dysymtab.nmodtab * sizeof(struct dylib_module)) {
perror("read (toc)");
return R_FALSE;
}
return R_TRUE;
}
static int r_bin_mach0_init_items(struct r_bin_mach0_obj_t* bin)
{
struct load_command lc = {0, 0};
@ -144,7 +194,7 @@ static int r_bin_mach0_init_items(struct r_bin_mach0_obj_t* bin)
}
r_mem_copyendian((ut8*)&lc.cmd, (ut8*)&lc.cmd, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&lc.cmdsize, (ut8*)&lc.cmdsize, sizeof(uint32_t), !bin->endian);
IFDBG eprintf("cmd: 0x%02x cmdsize= %i\n", lc.cmd, lc.cmdsize);
//IFDBG eprintf("cmd: 0x%02x cmdsize= %i\n", lc.cmd, lc.cmdsize);
switch (lc.cmd) {
case LC_SEGMENT:
bin->nsegs++;
@ -155,6 +205,10 @@ static int r_bin_mach0_init_items(struct r_bin_mach0_obj_t* bin)
if (!r_bin_mach0_parse_symtab(bin, off))
return R_FALSE;
break;
case LC_DYSYMTAB:
if (!r_bin_mach0_parse_dysymtab(bin, off))
return R_FALSE;
break;
}
}
return R_TRUE;
@ -168,7 +222,11 @@ static int r_bin_mach0_init(struct r_bin_mach0_obj_t* bin)
bin->nsects = 0;
bin->symtab = NULL;
bin->symstr = NULL;
bin->nsyms = 0;
bin->nsymtab = 0;
bin->toc = NULL;
bin->ntoc = 0;
bin->modtab = NULL;
bin->nmodtab = 0;
bin->size = lseek(bin->fd, 0, SEEK_END);
if (!r_bin_mach0_init_hdr(bin)) {
ERR("Warning: File is not MACH0\n");
@ -191,6 +249,10 @@ void* r_bin_mach0_free(struct r_bin_mach0_obj_t* bin)
free(bin->symtab);
if (bin->symstr)
free(bin->symstr);
if (bin->toc)
free(bin->toc);
if (bin->modtab)
free(bin->modtab);
close(bin->fd);
free(bin);
return NULL;
@ -214,7 +276,7 @@ struct r_bin_mach0_section_t* r_bin_mach0_get_sections(struct r_bin_mach0_obj_t*
struct r_bin_mach0_section_t *sections;
char segname[17], sectname[17];
int i;
if (!(sections = malloc(bin->nsects * sizeof(struct r_bin_mach0_section_t))))
if (!(sections = malloc((bin->nsects + 1) * sizeof(struct r_bin_mach0_section_t))))
return NULL;
for (i = 0; i < bin->nsects; i++) {
sections[i].offset = (ut64)bin->sects[i].offset;
@ -225,14 +287,44 @@ struct r_bin_mach0_section_t* r_bin_mach0_get_sections(struct r_bin_mach0_obj_t*
segname[16] = sectname[16] = '\0';
memcpy(segname, bin->sects[i].segname, 16);
memcpy(sectname, bin->sects[i].sectname, 16);
snprintf(sections[i].name, MACH0_STRING_LENGTH, "%s:%s", segname, sectname);
snprintf(sections[i].name, R_BIN_MACH0_STRING_LENGTH, "%s:%s", segname, sectname);
sections[i].last = 0;
}
sections[i].last = 1;
return sections;
}
struct r_bin_mach0_symbol_t* r_bin_mach0_get_symbols(struct r_bin_mach0_obj_t* bin)
{
return NULL;
struct r_bin_mach0_symbol_t *symbols;
int i, j;
if (!(symbols = malloc((bin->dysymtab.nextdefsym + 1) * sizeof(struct r_bin_mach0_symbol_t))))
return NULL;
for (i = bin->dysymtab.iextdefsym, j = 0; j < bin->dysymtab.nextdefsym; i++, j++) {
symbols[j].offset = bin->symtab[i].n_value;
symbols[j].addr = bin->symtab[i].n_value;
symbols[j].size = 0;
memcpy(symbols[j].name, bin->symstr+bin->symtab[i].n_un.n_strx, R_BIN_MACH0_STRING_LENGTH);
symbols[j].last = 0;
}
symbols[j].last = 1;
return symbols;
}
struct r_bin_mach0_import_t* r_bin_mach0_get_imports(struct r_bin_mach0_obj_t* bin)
{
struct r_bin_mach0_import_t *imports;
int i, j;
if (!(imports = malloc((bin->dysymtab.nundefsym + 1) * sizeof(struct r_bin_mach0_import_t))))
return NULL;
for (i = bin->dysymtab.iundefsym, j = 0; j < bin->dysymtab.nundefsym; i++, j++) {
imports[j].offset = bin->symtab[i].n_value;
imports[j].addr = bin->symtab[i].n_value;
memcpy(imports[j].name, bin->symstr+bin->symtab[i].n_un.n_strx, R_BIN_MACH0_STRING_LENGTH);
imports[j].last = 0;
}
imports[j].last = 1;
return imports;
}
#ifdef MAIN
@ -241,6 +333,7 @@ int main(int argc, char *argv[])
struct r_bin_mach0_obj_t *bin;
struct r_bin_mach0_section_t *sections;
struct r_bin_mach0_symbol_t *symbols;
struct r_bin_mach0_import_t *imports;
int i;
if (argc != 2) {
@ -253,18 +346,24 @@ int main(int argc, char *argv[])
}
sections = r_bin_mach0_get_sections(bin);
printf("-> SECTIONS\n");
for (i = 0; sections && i < bin->nsects; i++)
for (i = 0; sections && !sections[i].last; i++)
printf( "offset=0x%08llx address=0x%08llx size=%05lli name=%s\n",
sections[i].offset, sections[i].addr, sections[i].size,
sections[i].name);
if (sections) free(sections);
symbols = r_bin_mach0_get_symbols(bin);
printf("-> SYMBOLS\n");
for (i = 0; symbols && i < bin->nsyms; i++)
for (i = 0; symbols && !symbols[i].last; i++)
printf( "offset=0x%08llx address=0x%08llx size=%05lli name=%s\n",
symbols[i].offset, symbols[i].addr, symbols[i].size,
symbols[i].name);
if (symbols) free(symbols);
imports = r_bin_mach0_get_imports(bin);
printf("-> IMPORTS\n");
for (i = 0; imports && !imports[i].last; i++)
printf( "offset=0x%08llx address=0x%08llx name=%s\n",
imports[i].offset, imports[i].addr, imports[i].name);
if (imports) free(imports);
r_bin_mach0_free(bin);
return 0;

View File

@ -6,7 +6,7 @@
#include <r_types.h>
#include "mach0_specs.h"
#define MACH0_STRING_LENGTH 256
#define R_BIN_MACH0_STRING_LENGTH 256
#if 0
#define R_BIN_MACH0_SECT_IS_SHAREABLE(x) x
@ -21,14 +21,23 @@ struct r_bin_mach0_section_t {
ut64 size;
ut32 align;
ut32 flags;
char name[MACH0_STRING_LENGTH];
char name[R_BIN_MACH0_STRING_LENGTH];
int last;
};
struct r_bin_mach0_symbol_t {
ut64 offset;
ut64 addr;
ut64 size;
char name[MACH0_STRING_LENGTH];
char name[R_BIN_MACH0_STRING_LENGTH];
int last;
};
struct r_bin_mach0_import_t {
ut64 offset;
ut64 addr;
char name[R_BIN_MACH0_STRING_LENGTH];
int last;
};
struct r_bin_mach0_obj_t {
@ -39,7 +48,12 @@ struct r_bin_mach0_obj_t {
int nsects;
struct nlist* symtab;
ut8* symstr;
int nsyms;
int nsymtab;
struct dysymtab_command dysymtab;
struct dylib_table_of_contents* toc;
int ntoc;
struct dylib_module* modtab;
int nmodtab;
ut32 size;
ut64 baddr;
int endian;