- Add r_buf_fread for "format read" (needs a better name)
  - Fix segfault in set_bytes
  - Fix r_buf_read
* r_bin
  - Refactoring of r_bin_mach0 using r_buf and r_file
This commit is contained in:
Nibble 2010-01-19 22:41:45 +01:00
parent 41ba5c0104
commit 5795654c51
7 changed files with 148 additions and 190 deletions

View File

@ -23,3 +23,5 @@ These refactoring bugs should be discussed and reviewed. Feedback is welcome
* Finish and import the spp's getopt owns implementation in r_util (like in p9)
* Rename __UNIX__ as __POSIX__
* Find a better name for r_buf_fread

View File

@ -16,70 +16,60 @@
static int r_bin_mach0_init_hdr(struct r_bin_mach0_obj_t* bin)
{
lseek(bin->fd, 0, SEEK_SET);
if (read(bin->fd, &bin->hdr, sizeof(struct mach_header)) != sizeof(struct mach_header)) {
perror("read (hdr)");
int len, magic;
if (r_buf_read_at(bin->b, 0, (ut8*)&magic, 4) == -1) {
ERR("Error: read (magic)\n");
return R_FALSE;
}
if (bin->hdr.magic == MH_MAGIC)
if (magic == MH_MAGIC)
bin->endian = !LIL_ENDIAN;
else if (bin->hdr.magic == MH_CIGAM)
else if (magic == MH_CIGAM)
bin->endian = LIL_ENDIAN;
else return R_FALSE;
r_mem_copyendian((ut8*)&(bin->hdr.cputype), (ut8*)&(bin->hdr.cputype), sizeof(cpu_type_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->hdr.cpusubtype), (ut8*)&(bin->hdr.cpusubtype), sizeof(cpu_subtype_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->hdr.ncmds), (ut8*)&(bin->hdr.ncmds), sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->hdr.sizeofcmds, (ut8*)&bin->hdr.sizeofcmds, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->hdr.flags), (ut8*)&(bin->hdr.flags), sizeof(uint32_t), !bin->endian);
if (bin->endian)
len = r_buf_fread_at(bin->b, 0, (ut8*)&bin->hdr, "7I", 1);
else
len = r_buf_fread_at(bin->b, 0, (ut8*)&bin->hdr, "7i", 1);
if (len == -1) {
ERR("Error: read (hdr)\n");
return R_FALSE;
}
return R_TRUE;
}
static int r_bin_mach0_parse_seg(struct r_bin_mach0_obj_t* bin, ut64 off)
{
int seg, i;
int seg, sect, len;
seg = bin->nsegs - 1;
if (!(bin->segs = realloc(bin->segs, bin->nsegs * sizeof(struct segment_command)))) {
perror("realloc (seg)");
return R_FALSE;
}
lseek(bin->fd, off, SEEK_SET);
if (read(bin->fd, &bin->segs[seg], sizeof(struct segment_command))
!= sizeof(struct segment_command)) {
perror("read (seg)");
if (bin->endian)
len = r_buf_fread_at(bin->b, off, (ut8*)&bin->segs[seg], "2I16c8I", 1);
else
len = r_buf_fread_at(bin->b, off, (ut8*)&bin->segs[seg], "2i16c8i", 1);
if (len == -1) {
ERR("Error: read (seg)\n");
return R_FALSE;
}
r_mem_copyendian((ut8*)&(bin->segs[seg].cmd), (ut8*)&(bin->segs[seg].cmd), sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->segs[seg].cmdsize), (ut8*)&(bin->segs[seg].cmdsize), sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->segs[seg].vmaddr), (ut8*)&(bin->segs[seg].vmaddr), sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->segs[seg].vmsize), (ut8*)&(bin->segs[seg].vmsize), sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->segs[seg].fileoff), (ut8*)&(bin->segs[seg].fileoff), sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->segs[seg].filesize), (ut8*)&(bin->segs[seg].filesize), sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->segs[seg].maxprot), (ut8*)&(bin->segs[seg].maxprot), sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->segs[seg].initprot), (ut8*)&(bin->segs[seg].initprot), sizeof(vm_prot_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->segs[seg].nsects), (ut8*)&(bin->segs[seg].nsects), sizeof(vm_prot_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->segs[seg].flags), (ut8*)&(bin->segs[seg].flags), sizeof(uint32_t), !bin->endian);
if (bin->segs[seg].nsects > 0) {
sect = bin->nsects;
bin->nsects += bin->segs[seg].nsects;
if (!(bin->sects = realloc(bin->sects, bin->nsects * sizeof(struct section)))) {
perror("realloc (sects)");
return R_FALSE;
}
for (i = bin->nsects - bin->segs[seg].nsects; i < bin->nsects; i++) {
if (read(bin->fd, &bin->sects[i], sizeof(struct section))
!= sizeof(struct section)) {
perror("read (sects)");
return R_FALSE;
}
r_mem_copyendian((ut8*)&(bin->sects[i].addr), (ut8*)&(bin->sects[i].addr), sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->sects[i].size), (ut8*)&(bin->sects[i].size), sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->sects[i].offset), (ut8*)&(bin->sects[i].offset), sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->sects[i].align), (ut8*)&(bin->sects[i].align), sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->sects[i].reloff), (ut8*)&(bin->sects[i].reloff), sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->sects[i].nreloc), (ut8*)&(bin->sects[i].nreloc), sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->sects[i].flags), (ut8*)&(bin->sects[i].flags), sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->sects[i].reserved1), (ut8*)&(bin->sects[i].reserved1), sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&(bin->sects[i].reserved2), (ut8*)&(bin->sects[i].reserved2), sizeof(uint32_t), !bin->endian);
if (bin->endian)
len = r_buf_fread_at(bin->b, off + sizeof(struct segment_command),
(ut8*)&bin->sects[sect], "16c16c9I", bin->nsects - sect);
else
len = r_buf_fread_at(bin->b, off + sizeof(struct segment_command),
(ut8*)&bin->sects[sect], "16c16c9i", bin->nsects - sect);
if (len == -1) {
ERR("Error: read (sects)\n");
return R_FALSE;
}
}
return R_TRUE;
@ -88,45 +78,37 @@ static int r_bin_mach0_parse_seg(struct r_bin_mach0_obj_t* bin, ut64 off)
static int r_bin_mach0_parse_symtab(struct r_bin_mach0_obj_t* bin, ut64 off)
{
struct symtab_command st;
int i;
int len;
lseek(bin->fd, off, SEEK_SET);
if (read(bin->fd, &st, sizeof(struct symtab_command)) != sizeof(struct symtab_command)) {
perror("read (symtab)");
if (bin->endian)
len = r_buf_fread_at(bin->b, off, (ut8*)&st, "6I", 1);
else
len = r_buf_fread_at(bin->b, off, (ut8*)&st, "6i", 1);
if (len == -1) {
ERR("Error: read (symtab)\n");
return R_FALSE;
}
r_mem_copyendian((ut8*)&st.cmd, (ut8*)&st.cmd, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&st.cmdsize, (ut8*)&st.cmdsize, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&st.symoff, (ut8*)&st.symoff, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&st.nsyms, (ut8*)&st.nsyms, sizeof(uint32_t), !bin->endian);
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->nsymtab = st.nsyms;
if (!(bin->symstr = malloc(st.strsize))) {
perror("malloc (symstr)");
return R_FALSE;
}
lseek(bin->fd, st.stroff, SEEK_SET);
if (read(bin->fd, bin->symstr, st.strsize) != st.strsize) {
perror("read (symstr)");
if (r_buf_read_at(bin->b, st.stroff, (ut8*)bin->symstr, st.strsize) == -1) {
ERR("Error: read (symstr)\n");
return R_FALSE;
}
if (!(bin->symtab = malloc(st.nsyms * sizeof(struct nlist)))) {
if (!(bin->symtab = malloc(bin->nsymtab * sizeof(struct nlist)))) {
perror("malloc (symtab)");
return R_FALSE;
}
lseek(bin->fd, st.symoff, SEEK_SET);
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;
}
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 -> %08x (sect: %08x)\n",
bin->symstr+bin->symtab[i].n_un.n_strx, bin->symtab[i].n_value, bin->symtab[i].n_sect);
if (bin->endian)
len = r_buf_fread_at(bin->b, st.symoff, (ut8*)bin->symtab, "I2cSI", bin->nsymtab);
else
len = r_buf_fread_at(bin->b, st.symoff, (ut8*)bin->symtab, "i2csi", bin->nsymtab);
if (len == -1) {
ERR("Error: read (nlist)\n");
return R_FALSE;
}
}
return R_TRUE;
@ -134,74 +116,46 @@ static int r_bin_mach0_parse_symtab(struct r_bin_mach0_obj_t* bin, ut64 off)
static int r_bin_mach0_parse_dysymtab(struct r_bin_mach0_obj_t* bin, ut64 off)
{
int i;
int len;
lseek(bin->fd, off, SEEK_SET);
if (read(bin->fd, &bin->dysymtab, sizeof(struct dysymtab_command)) != sizeof(struct dysymtab_command)) {
perror("read (dysymtab)");
if (bin->endian)
len = r_buf_fread_at(bin->b, off, (ut8*)&bin->dysymtab, "20I", 1);
else
len = r_buf_fread_at(bin->b, off, (ut8*)&bin->dysymtab, "20i", 1);
if (len == -1) {
ERR("Error: read (dysymtab)\n");
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->ntoc > 0) {
if (!(bin->toc = malloc(bin->dysymtab.ntoc * sizeof(struct dylib_table_of_contents)))) {
if (!(bin->toc = malloc(bin->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)");
if (bin->endian)
len = r_buf_fread_at(bin->b, bin->dysymtab.tocoff, (ut8*)bin->toc, "2I", bin->ntoc);
else
len = r_buf_fread_at(bin->b, bin->dysymtab.tocoff, (ut8*)bin->toc, "2i", bin->ntoc);
if (len == -1) {
ERR("Error: read (toc)\n");
return R_FALSE;
}
for (i = 0; i < bin->ntoc; i++) {
r_mem_copyendian((ut8*)&bin->toc[i].symbol_index, (ut8*)&bin->toc[i].symbol_index, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->toc[i].module_index, (ut8*)&bin->toc[i].module_index, sizeof(uint32_t), !bin->endian);
}
}
bin->nmodtab = bin->dysymtab.nmodtab;
if (bin->nmodtab > 0) {
if (!(bin->modtab = malloc(bin->dysymtab.nmodtab * sizeof(struct dylib_module)))) {
perror("malloc (toc)");
if (!(bin->modtab = malloc(bin->nmodtab * sizeof(struct dylib_module)))) {
perror("malloc (modtab)");
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)");
printf("AAAAAAAAA: %i\n", bin->nmodtab);
if (bin->endian)
len = r_buf_fread_at(bin->b, bin->dysymtab.modtaboff, (ut8*)bin->modtab, "13I", bin->nmodtab);
else
len = r_buf_fread_at(bin->b, bin->dysymtab.modtaboff, (ut8*)bin->modtab, "13i", bin->nmodtab);
if (len == -1) {
ERR("Error: read (modtab)\n");
return R_FALSE;
}
for (i = 0; i < bin->nmodtab; i++) {
r_mem_copyendian((ut8*)&bin->modtab[i].module_name, (ut8*)&bin->modtab[i].module_name, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->modtab[i].iextdefsym, (ut8*)&bin->modtab[i].module_name, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->modtab[i].nextdefsym, (ut8*)&bin->modtab[i].module_name, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->modtab[i].irefsym, (ut8*)&bin->modtab[i].irefsym, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->modtab[i].nrefsym, (ut8*)&bin->modtab[i].nrefsym, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->modtab[i].ilocalsym, (ut8*)&bin->modtab[i].ilocalsym, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->modtab[i].nlocalsym, (ut8*)&bin->modtab[i].nlocalsym, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->modtab[i].iextrel, (ut8*)&bin->modtab[i].iextrel, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->modtab[i].nextrel, (ut8*)&bin->modtab[i].nextrel, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->modtab[i].iinit_iterm, (ut8*)&bin->modtab[i].iinit_iterm, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->modtab[i].ninit_nterm, (ut8*)&bin->modtab[i].ninit_nterm, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->modtab[i].objc_module_info_addr, (ut8*)&bin->modtab[i].objc_module_info_addr, sizeof(uint32_t), !bin->endian);
r_mem_copyendian((ut8*)&bin->modtab[i].objc_module_info_size, (ut8*)&bin->modtab[i].objc_module_info_size, sizeof(uint32_t), !bin->endian);
}
}
return R_TRUE;
}
@ -210,16 +164,17 @@ static int r_bin_mach0_init_items(struct r_bin_mach0_obj_t* bin)
{
struct load_command lc = {0, 0};
ut64 off;
int i;
int i, len;
for (i = 0, off = sizeof(struct mach_header); i < bin->hdr.ncmds; i++, off += lc.cmdsize) {
lseek(bin->fd, off, SEEK_SET);
if (read(bin->fd, &lc, sizeof(struct load_command)) != sizeof(struct load_command)) {
perror("read (lc)");
if (bin->endian)
len = r_buf_fread_at(bin->b, off, (ut8*)&lc, "2I", 1);
else
len = r_buf_fread_at(bin->b, off, (ut8*)&lc, "2i", 1);
if (len == -1) {
ERR("Error: read (lc)\n");
return R_FALSE;
}
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 printf("cmd: 0x%02x cmdsize= %i\n", lc.cmd, lc.cmdsize);
switch (lc.cmd) {
case LC_SEGMENT:
@ -254,7 +209,6 @@ static int r_bin_mach0_init(struct r_bin_mach0_obj_t* bin)
bin->modtab = NULL;
bin->nmodtab = 0;
bin->baddr = 0;
bin->size = lseek(bin->fd, 0, SEEK_END);
if (!r_bin_mach0_init_hdr(bin)) {
ERR("Warning: File is not MACH0\n");
return R_FALSE;
@ -280,7 +234,8 @@ void* r_bin_mach0_free(struct r_bin_mach0_obj_t* bin)
free(bin->toc);
if (bin->modtab)
free(bin->modtab);
close(bin->fd);
if (bin->b)
r_buf_free(bin->b);
free(bin);
return NULL;
}
@ -288,11 +243,16 @@ void* r_bin_mach0_free(struct r_bin_mach0_obj_t* bin)
struct r_bin_mach0_obj_t* r_bin_mach0_new(const char* file)
{
struct r_bin_mach0_obj_t *bin;
ut8 *buf;
if (!(bin = malloc(sizeof(struct r_bin_mach0_obj_t))))
return NULL;
if ((bin->fd = open(file, O_RDONLY)) == -1)
return r_bin_mach0_free(bin);
bin->file = file;
if (!(buf = (ut8*)r_file_slurp(file, &bin->size)))
return r_bin_mach0_free(bin);
bin->b = r_buf_new();
if (!r_buf_set_bytes(bin->b, buf, bin->size))
return r_bin_mach0_free(bin);
free (buf);
if (!r_bin_mach0_init(bin))
return r_bin_mach0_free(bin);
return bin;
@ -303,6 +263,9 @@ 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 (!bin->sects)
return NULL;
if (!(sections = malloc((bin->nsects + 1) * sizeof(struct r_bin_mach0_section_t))))
return NULL;
for (i = 0; i < bin->nsects; i++) {
@ -325,6 +288,9 @@ struct r_bin_mach0_symbol_t* r_bin_mach0_get_symbols(struct r_bin_mach0_obj_t* b
{
struct r_bin_mach0_symbol_t *symbols;
int i, j;
if (!bin->symtab || !bin->symstr)
return NULL;
if (!(symbols = malloc((bin->dysymtab.nextdefsym + 1) * sizeof(struct r_bin_mach0_symbol_t))))
return NULL;
/* XXX: only extdefsym? */
@ -332,7 +298,7 @@ struct r_bin_mach0_symbol_t* r_bin_mach0_get_symbols(struct r_bin_mach0_obj_t* b
symbols[j].offset = bin->symtab[i].n_value;
symbols[j].addr = bin->symtab[i].n_value; /* TODO: baddr? */
symbols[j].size = 0; /* TODO: Is it anywhere? */
memcpy(symbols[j].name, bin->symstr+bin->symtab[i].n_un.n_strx, R_BIN_MACH0_STRING_LENGTH);
strncpy(symbols[j].name, (char*)bin->symstr+bin->symtab[i].n_un.n_strx, R_BIN_MACH0_STRING_LENGTH);
symbols[j].last = 0;
}
symbols[j].last = 1;
@ -343,13 +309,16 @@ struct r_bin_mach0_import_t* r_bin_mach0_get_imports(struct r_bin_mach0_obj_t* b
{
struct r_bin_mach0_import_t *imports;
int i, j;
if (!bin->symtab || !bin->symstr)
return NULL;
if (!(imports = malloc((bin->dysymtab.nundefsym + 1) * sizeof(struct r_bin_mach0_import_t))))
return NULL;
/* XXX: only iundefsym? */
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);
strncpy(imports[j].name, (char*)bin->symstr+bin->symtab[i].n_un.n_strx, R_BIN_MACH0_STRING_LENGTH);
imports[j].last = 0;
}
imports[j].last = 1;
@ -365,53 +334,3 @@ ut64 r_bin_mach0_get_baddr(struct r_bin_mach0_obj_t* bin)
{
return UT64_MIN;
}
#ifdef MAIN
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;
struct r_bin_mach0_entrypoint_t *entrypoints;
int i;
if (argc != 2) {
ERR("Usage: %s <mach0 file>\n", argv[0]);
return 1;
}
if(!(bin = r_bin_mach0_new(argv[1]))) {
ERR("Cannot open '%s'\n", argv[1]);
return 1;
}
entrypoints = r_bin_mach0_get_entrypoints(bin);
printf("-> ENTRYPOINTS\n");
for (i = 0; entrypoints && !entrypoints[i].last; i++)
printf( "offset=0x%08llx address=0x%08llx\n",
entrypoints[i].offset, entrypoints[i].addr);
if (entrypoints) free(entrypoints);
sections = r_bin_mach0_get_sections(bin);
printf("-> SECTIONS\n");
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 && !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;
}
#endif

View File

@ -60,11 +60,11 @@ struct r_bin_mach0_obj_t {
int ntoc;
struct dylib_module* modtab;
int nmodtab;
ut32 size;
ut64 baddr;
int endian;
int size;
ut64 baddr;
int endian;
const char* file;
int fd;
struct r_buf_t* b;
};
struct r_bin_mach0_obj_t* r_bin_mach0_new(const char* file);

View File

@ -11,7 +11,7 @@ static int bopen(struct r_bin_t *bin)
if(!(bin->bin_obj = r_bin_mach0_new(bin->file)))
return -1;
mach0_obj = (struct r_bin_mach0_obj_t*)bin->bin_obj;
bin->fd = mach0_obj->fd;
bin->fd = 1;
return bin->fd;
}

View File

@ -60,6 +60,7 @@ R_API struct r_buf_t *r_buf_new();
R_API int r_buf_set_bits(struct r_buf_t *b, int bitoff, int bitsize, ut64 value);
R_API int r_buf_set_bytes(struct r_buf_t *b, ut8 *buf, int length);
R_API int r_buf_read_at(struct r_buf_t *b, ut64 addr, ut8 *buf, int len);
R_API int r_buf_fread_at(struct r_buf_t *b, ut64 addr, ut8 *buf, const char *fmt, int n);
R_API int r_buf_write_at(struct r_buf_t *b, ut64 addr, const ut8 *buf, int len);
R_API void r_buf_free(struct r_buf_t *b);

View File

@ -39,16 +39,17 @@ R_API int r_buf_set_bits(struct r_buf_t *b, int bitoff, int bitsize, ut64 value)
R_API int r_buf_set_bytes(struct r_buf_t *b, ut8 *buf, int length)
{
free(b->buf);
b->buf = malloc(length);
if (b->buf == NULL)
if (b->buf)
free(b->buf);
if (!(b->buf = malloc(length)))
return R_FALSE;
memcpy(b->buf, buf, length);
b->length = length;
return R_TRUE;
}
static int r_buf_memcpy(struct r_buf_t *b, ut64 addr, ut8 *dst, ut8 *src, int len) {
static int r_buf_memcpy(struct r_buf_t *b, ut64 addr, ut8 *dst, const ut8 *src, int len)
{
int end;
addr -= b->base;
if (addr > b->length)
@ -56,7 +57,7 @@ static int r_buf_memcpy(struct r_buf_t *b, ut64 addr, ut8 *dst, ut8 *src, int le
end = (int)(addr+len);
if (end > b->length)
len -= end-b->length;
memcpy(dst, src, len);
memcpy(dst, src+addr, len);
return len;
}
@ -65,6 +66,38 @@ R_API int r_buf_read_at(struct r_buf_t *b, ut64 addr, ut8 *buf, int len)
return r_buf_memcpy(b, addr, buf, b->buf, len);
}
R_API int r_buf_fread_at(struct r_buf_t *b, ut64 addr, ut8 *buf, const char *fmt, int n)
{
int i, j, k, len, tsize, endian, m = 1;
addr -= b->base;
if (addr < 0 || addr > b->length)
return -1;
for (i = len = 0; i < n; i++)
for (j = 0; fmt[j]; j++) {
if (len > b->length)
return -1;
switch (fmt[j]) {
case '0'...'9':
if (m == 1)
m = r_num_get(NULL, &fmt[j]);
continue;
case 's': tsize = 2; endian = 1; break;
case 'S': tsize = 2; endian = 0; break;
case 'i': tsize = 4; endian = 1; break;
case 'I': tsize = 4; endian = 0; break;
case 'l': tsize = 8; endian = 1; break;
case 'L': tsize = 8; endian = 0; break;
case 'c': tsize = 1; endian = 1; break;
default: return -1;
}
for (k = 0; k < m; k++)
r_mem_copyendian((ut8*)&buf[len+k*tsize], (ut8*)&b->buf[addr+len+k*tsize], tsize, endian);
len += m*tsize; m = 1;
}
return len;
}
R_API int r_buf_write_at(struct r_buf_t *b, ut64 addr, const ut8 *buf, int len)
{
return r_buf_memcpy(b, addr, b->buf, buf, len);

View File

@ -97,11 +97,14 @@ src |__________|_________|
R_API void r_mem_copyendian (ut8 *dest, const ut8 *orig, int size, int endian)
{
if (endian) {
if (dest != orig)
memcpy(dest, orig, size);
if (dest != orig)
memcpy(dest, orig, size);
} else {
unsigned char buffer[8];
switch(size) {
case 1:
dest[0] = orig[0];
break;
case 2:
buffer[0] = orig[0];
dest[0] = orig[1];