mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-04 12:36:30 +00:00
* r_buf
- 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:
parent
41ba5c0104
commit
5795654c51
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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];
|
||||
|
Loading…
x
Reference in New Issue
Block a user