Improvements for rabin2 -H and pfo in macho ##bin

This commit is contained in:
radare 2019-04-18 11:13:59 +02:00 committed by GitHub
parent 40d3f7e822
commit fd863fce33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 95 additions and 81 deletions

View File

@ -1,4 +1,4 @@
/* radare2 - LGPL - Copyright 2009-2018 - pancake, nibble, dso */
/* radare2 - LGPL - Copyright 2009-2019 - pancake, nibble, dso */
#include <r_bin.h>
#include <r_types.h>
@ -255,7 +255,7 @@ R_API int r_bin_reload(RBin *bin, int fd, ut64 baseaddr) {
if (sz == UT64_MAX) {
if (!iob->fd_is_dbg (iob->io, fd)) {
// too big, probably wrong
eprintf ("Too big\n");
eprintf ("Warning: file is too big and not in debugger\n");
res = false;
goto error;
}

3
libr/bin/d/fat Normal file
View File

@ -0,0 +1,3 @@
pf.fat_arch xxxxx cputype cpusubtype offset size align
pf.fat_header xd magic nfat_archs
# not yet supported # pf.fat_header xd[?]? magic nfat_archs nfat_archs (fat_arch)fat_arch

View File

@ -1,2 +1,10 @@
pf.mach0_header xxxxddx magic cputype cpusubtype filetype ncmds sizeofcmds flags
pf.mach0_segment xd[16]zxxxxoodx cmd cmdsize segname vmaddr vmsize fileoff filesize maxprot initprot nsects flags
pf.mach0_symtab_command xdxdxd cmd cmdsize symoff nsyms stroff strsize
pf.mach0_dysymtab_command xdddddddddddxdxdxxxd cmd cmdsize ilocalsym nlocalsym iextdefsym nextdefsym iundefsym nundefsym tocoff ntoc moddtaboff nmodtab extrefsymoff nextrefsyms inddirectsymoff nindirectsyms extreloff nextrel locreloff nlocrel
pf.mach0_section [16]z16[z]xxxxxdxxx sectname segname addr size offset align reloff nreloc flags reserved1 reserved2
pf.mach0_dylib xxxx name timestamp current_version compatibility_version
pf.mach0_dylib_command xx? cmd cmdsize (mach0_dylib)dylib
pf.mach0_uuid_command xx[16]b cmd cmdsize uuid
pf.mach0_rpath_command xxx cmd cmdsize path
pf.mach0_entry_point_command xxqq cmd cmdsize entryoff stacksize

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2010-2018 - nibble, pancake */
/* radare - LGPL - Copyright 2010-2019 - nibble, pancake */
#include <stdio.h>
#include <r_types.h>
@ -6,7 +6,9 @@
#include "mach0.h"
#include <r_hash.h>
// TODO: deprecate bprintf and use Eprintf (bin->self)
#define bprintf if (bin->verbose) eprintf
#define Eprintf if (mo->verbose) eprintf
typedef struct _ulebr {
ut8 *p;
@ -305,83 +307,82 @@ static int parse_segments(struct MACH0_(obj_t) *bin, ut64 off) {
return true;
}
static int parse_symtab(struct MACH0_(obj_t) *bin, ut64 off) {
#define Error(x) errorMessage = x; goto error;
static int parse_symtab(struct MACH0_(obj_t) *mo, ut64 off) {
struct symtab_command st;
ut32 size_sym;
int i;
const char *errorMessage = "";
ut8 symt[sizeof (struct symtab_command)] = {0};
ut8 nlst[sizeof (struct MACH0_(nlist))] = {0};
const bool be = mo->big_endian;
if (off > (ut64)bin->size || off + sizeof (struct symtab_command) > (ut64)bin->size) {
if (off > (ut64)mo->size || off + sizeof (struct symtab_command) > (ut64)mo->size) {
return false;
}
int len = r_buf_read_at (bin->b, off, symt, sizeof (struct symtab_command));
int len = r_buf_read_at (mo->b, off, symt, sizeof (struct symtab_command));
if (len != sizeof (struct symtab_command)) {
bprintf ("Error: read (symtab)\n");
Eprintf ("Error: read (symtab)\n");
return false;
}
st.cmd = r_read_ble32 (&symt[0], bin->big_endian);
st.cmdsize = r_read_ble32 (&symt[4], bin->big_endian);
st.symoff = r_read_ble32 (&symt[8], bin->big_endian);
st.nsyms = r_read_ble32 (&symt[12], bin->big_endian);
st.stroff = r_read_ble32 (&symt[16], bin->big_endian);
st.strsize = r_read_ble32 (&symt[20], bin->big_endian);
st.cmd = r_read_ble32 (&symt[0], be);
st.cmdsize = r_read_ble32 (&symt[4], be);
st.symoff = r_read_ble32 (&symt[8], be);
st.nsyms = r_read_ble32 (&symt[12], be);
st.stroff = r_read_ble32 (&symt[16], be);
st.strsize = r_read_ble32 (&symt[20], be);
bin->symtab = NULL;
bin->nsymtab = 0;
if (st.strsize > 0 && st.strsize < bin->size && st.nsyms > 0) {
bin->nsymtab = st.nsyms;
if (st.stroff > bin->size || st.stroff + st.strsize > bin->size) {
return false;
mo->symtab = NULL;
mo->nsymtab = 0;
if (st.strsize > 0 && st.strsize < mo->size && st.nsyms > 0) {
mo->nsymtab = st.nsyms;
if (st.stroff > mo->size || st.stroff + st.strsize > mo->size) {
Error ("fail");
}
if (!UT32_MUL (&size_sym, bin->nsymtab, sizeof (struct MACH0_(nlist)))) {
bprintf("fail2\n");
return false;
if (!UT32_MUL (&size_sym, mo->nsymtab, sizeof (struct MACH0_(nlist)))) {
Error ("fail2");
}
if (!size_sym) {
bprintf("fail3\n");
return false;
Error ("symbol size is zero");
}
if (st.symoff > bin->size || st.symoff + size_sym > bin->size) {
bprintf("fail4\n");
return false;
if (st.symoff > mo->size || st.symoff + size_sym > mo->size) {
Error ("symoff is out of bounds");
}
if (!(bin->symstr = calloc (1, st.strsize + 2))) {
perror ("calloc (symstr)");
return false;
if (!(mo->symstr = calloc (1, st.strsize + 2))) {
Error ("symoff is out of bounds");
}
bin->symstrlen = st.strsize;
len = r_buf_read_at (bin->b, st.stroff, (ut8*)bin->symstr, st.strsize);
mo->symstrlen = st.strsize;
len = r_buf_read_at (mo->b, st.stroff, (ut8*)mo->symstr, st.strsize);
if (len != st.strsize) {
bprintf ("Error: read (symstr)\n");
R_FREE (bin->symstr);
return false;
Error ("Error: read (symstr)");
}
if (!(bin->symtab = calloc (bin->nsymtab, sizeof (struct MACH0_(nlist))))) {
perror ("calloc (symtab)");
return false;
if (!(mo->symtab = calloc (mo->nsymtab, sizeof (struct MACH0_(nlist))))) {
goto error;
}
for (i = 0; i < bin->nsymtab; i++) {
len = r_buf_read_at (bin->b, st.symoff + (i * sizeof (struct MACH0_(nlist))),
for (i = 0; i < mo->nsymtab; i++) {
len = r_buf_read_at (mo->b, st.symoff + (i * sizeof (struct MACH0_(nlist))),
nlst, sizeof (struct MACH0_(nlist)));
if (len != sizeof (struct MACH0_(nlist))) {
bprintf ("Error: read (nlist)\n");
R_FREE (bin->symtab);
return false;
Error ("read (nlist)");
}
//XXX not very safe what if is n_un.n_name instead?
bin->symtab[i].n_strx = r_read_ble32 (&nlst[0], bin->big_endian);
bin->symtab[i].n_type = r_read_ble8 (&nlst[4]);
bin->symtab[i].n_sect = r_read_ble8 (&nlst[5]);
bin->symtab[i].n_desc = r_read_ble16 (&nlst[6], bin->big_endian);
mo->symtab[i].n_strx = r_read_ble32 (&nlst[0], be);
mo->symtab[i].n_type = r_read_ble8 (&nlst[4]);
mo->symtab[i].n_sect = r_read_ble8 (&nlst[5]);
mo->symtab[i].n_desc = r_read_ble16 (&nlst[6], be);
#if R_BIN_MACH064
bin->symtab[i].n_value = r_read_ble64 (&nlst[8], bin->big_endian);
mo->symtab[i].n_value = r_read_ble64 (&nlst[8], be);
#else
bin->symtab[i].n_value = r_read_ble32 (&nlst[8], bin->big_endian);
mo->symtab[i].n_value = r_read_ble32 (&nlst[8], be);
#endif
}
}
return true;
error:
R_FREE (mo->symstr);
R_FREE (mo->symtab);
Eprintf ("%s\n", errorMessage);
return false;
}
static int parse_dysymtab(struct MACH0_(obj_t) *bin, ut64 off) {
@ -522,7 +523,6 @@ static int parse_dysymtab(struct MACH0_(obj_t) *bin, ut64 off) {
R_FREE (bin->indirectsyms);
return false;
}
for (i = 0; i < bin->nindirectsyms; i++) {
len = r_buf_read_at (bin->b, bin->dysymtab.indirectsymoff + i * sizeof (ut32), idsyms, 4);
if (len == -1) {
@ -1109,8 +1109,6 @@ static const char *cmd_to_string(ut32 cmd) {
return "LC_SYMTAB";
case LC_SYMSEG:
return "LC_SYMSEG";
case LC_ID_DYLIB:
return "LC_ID_DYLIB";
case LC_DYSYMTAB:
return "LC_DYSYMTAB";
case LC_PREBOUND_DYLIB:
@ -1155,6 +1153,10 @@ static const char *cmd_to_string(ut32 cmd) {
return "LC_MAIN";
case LC_UUID:
return "LC_UUID";
case LC_ID_DYLIB:
return "LC_ID_DYLIB";
case LC_ID_DYLINKER:
return "LC_ID_DYLINKER";
case LC_LAZY_LOAD_DYLIB:
return "LC_LAZY_LOAD_DYLIB";
case LC_ENCRYPTION_INFO:
@ -1262,7 +1264,7 @@ static int init_items(struct MACH0_(obj_t) *bin) {
break;
case LC_DYSYMTAB:
sdb_set (bin->kv, sdb_fmt ("mach0_cmd_%d.cmd", i), "dysymtab", 0);
if (!parse_dysymtab(bin, off)) {
if (!parse_dysymtab (bin, off)) {
bprintf ("error parsing dysymtab\n");
return false;
}
@ -1485,15 +1487,15 @@ static int init_items(struct MACH0_(obj_t) *bin) {
return true;
}
static int init(struct MACH0_(obj_t) *bin) {
if (!init_hdr (bin)) {
bprintf ("Warning: File is not MACH0\n");
static int init(struct MACH0_(obj_t) *mo) {
if (!init_hdr (mo)) {
Eprintf ("Warning: File is not MACH0\n");
return false;
}
if (!init_items (bin)) {
bprintf ("Warning: Cannot initialize items\n");
if (!init_items (mo)) {
Eprintf ("Warning: Cannot initialize items\n");
}
bin->baddr = MACH0_(get_baddr)(bin);
mo->baddr = MACH0_(get_baddr)(mo);
return true;
}
@ -2751,6 +2753,17 @@ void MACH0_(mach_headerfields)(RBinFile *file) {
#endif
}
break;
case LC_SYMTAB:
{
char *id = r_buf_get_string (buf, addr + 20);
cb_printf ("0x%08"PFMT64x" id 0x%x\n", addr + 20, id? id: "");
cb_printf ("0x%08"PFMT64x" symooff 0x%x\n", addr + 20, id? id: "");
cb_printf ("0x%08"PFMT64x" nsyms %d\n", addr + 20, id? id: "");
cb_printf ("0x%08"PFMT64x" stroff 0x%x\n", addr + 20, id? id: "");
cb_printf ("0x%08"PFMT64x" strsize 0x%x\n", addr + 20, id? id: "");
free (id);
}
break;
case LC_ID_DYLIB: { // install_name_tool
char *id = r_buf_get_string (buf, addr + 20);
cb_printf ("0x%08"PFMT64x" id %s\n",
@ -2780,7 +2793,7 @@ void MACH0_(mach_headerfields)(RBinFile *file) {
break;
case LC_LOAD_DYLIB:
case LC_LOAD_WEAK_DYLIB: {
char *load_dylib = r_buf_get_string (buf, addr + 16);
char *load_dylib = r_buf_get_string (buf, addr + 8);
cb_printf ("0x%08"PFMT64x" load_dylib %s\n",
addr + 16, load_dylib? load_dylib: "");
free (load_dylib);

View File

@ -3784,11 +3784,12 @@ static int r_core_bin_file_print(RCore *core, RBinFile *binfile, int mode) {
break;
case 'j':
r_cons_printf ("{\"name\":\"%s\",\"fd\":%d,\"id\":%d,\"size\":%d,\"objs\":[",
name, fd, id, bin_sz);
name? name: "", fd, id, bin_sz);
r_list_foreach (binfile->objs, iter, obj) {
RBinInfo *info = obj->info;
ut8 bits = info ? info->bits : 0;
const char *arch = info ? info->arch : "unknown";
const char *asmarch = r_config_get (core->config, "asm.arch");
const char *arch = info ? info->arch ? info->arch: asmarch : "unknown";
r_cons_printf ("{\"objid\":%d,\"arch\":\"%s\",\"bits\":%d,\"binoffset\":%"
PFMT64d",\"objsize\":%"PFMT64d"}",
obj->id, arch, bits, obj->boffset, obj->obj_size);
@ -3802,10 +3803,8 @@ static int r_core_bin_file_print(RCore *core, RBinFile *binfile, int mode) {
r_list_foreach (binfile->objs, iter, obj) {
RBinInfo *info = obj->info;
ut8 bits = info ? info->bits : 0;
const char *arch = info ? info->arch : "unknown";
if (!arch) {
arch = r_config_get (core->config, "asm.arch");
}
const char *asmarch = r_config_get (core->config, "asm.arch");
const char *arch = info ? info->arch ? info->arch: asmarch: "unknown";
r_cons_printf ("%4d %s-%d at:0x%08"PFMT64x" sz:%"PFMT64d" ",
obj->id, arch, bits, obj->boffset, obj->obj_size );
r_cons_printf ("fd:%d %s\n", fd, name);

View File

@ -779,9 +779,10 @@ R_API bool r_buf_append_buf_slice(RBuffer *b, RBuffer *a, ut64 offset, ut64 size
// length depends on the first '\0' found in the buffer.
R_API char *r_buf_get_string(RBuffer *b, ut64 addr) {
const ut8 *needle = NULL;
ut8 tmp[16];
ut8 tmp[128] = {0};
ut64 sz = 0;
int r = r_buf_read_at (b, addr + sz, tmp, sizeof (tmp));
r_buf_read_at (b, addr, tmp, sizeof (tmp) - 1);
int r = strlen ((const char *)tmp);
while (r >= 0) {
needle = r_mem_mem (tmp, r, (ut8 *)"\x00", 1);
if (needle) {
@ -789,23 +790,13 @@ R_API char *r_buf_get_string(RBuffer *b, ut64 addr) {
break;
}
sz += r;
r = r_buf_read_at (b, addr + sz, tmp, sizeof (tmp));
r = r_buf_read_at (b, addr + sz, tmp + sz, sizeof (tmp) - sz);
}
if (r < 0) {
return NULL;
}
char *res = R_NEWS (char, sz + 1);
if (!res) {
return NULL;
}
r = r_buf_read_at (b, addr + 20, (ut8 *)res, sz);
if (r < 0) {
free (res);
return NULL;
}
res[sz] = '\0';
return res;
tmp[sz] = 0;
return strdup ((const char *)tmp);
}
R_API ut8 r_buf_read8_at(RBuffer *b, ut64 addr) {