mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-28 23:50:40 +00:00
Improvements for rabin2 -H and pfo in macho ##bin
This commit is contained in:
parent
40d3f7e822
commit
fd863fce33
@ -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
3
libr/bin/d/fat
Normal 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
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user