2010-03-08 18:40:21 +00:00
|
|
|
/* radare - LGPL - Copyright 2009-2010 nibble<.ds@gmail.com> */
|
2009-02-05 21:08:46 +00:00
|
|
|
|
|
|
|
/* TODO:
|
|
|
|
* dlopen library and show address
|
|
|
|
*/
|
|
|
|
|
2009-03-08 15:49:15 +00:00
|
|
|
#include <r_types.h>
|
2010-01-24 11:40:48 +00:00
|
|
|
#include <r_util.h>
|
2009-03-08 15:49:15 +00:00
|
|
|
#include <r_lib.h>
|
2010-03-10 10:01:38 +00:00
|
|
|
#include <r_list.h>
|
2009-03-08 15:49:15 +00:00
|
|
|
#include <r_bin.h>
|
2010-03-10 10:01:38 +00:00
|
|
|
#include <list.h>
|
2009-03-09 12:03:42 +00:00
|
|
|
#include "../config.h"
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2009-09-24 10:29:05 +00:00
|
|
|
/* plugin pointers */
|
2010-02-07 12:17:51 +00:00
|
|
|
extern RBinHandle r_bin_plugin_elf;
|
|
|
|
extern RBinHandle r_bin_plugin_elf64;
|
|
|
|
extern RBinHandle r_bin_plugin_pe;
|
|
|
|
extern RBinHandle r_bin_plugin_pe64;
|
|
|
|
extern RBinHandle r_bin_plugin_mach0;
|
2010-02-22 16:13:40 +00:00
|
|
|
extern RBinHandle r_bin_plugin_mach064;
|
2010-02-07 12:17:51 +00:00
|
|
|
extern RBinHandle r_bin_plugin_java;
|
|
|
|
extern RBinHandle r_bin_plugin_dummy;
|
|
|
|
|
|
|
|
static RBinHandle *bin_static_plugins[] = { R_BIN_STATIC_PLUGINS };
|
|
|
|
|
2010-03-10 10:01:38 +00:00
|
|
|
static RList* get_strings(RBin *bin, int min) {
|
|
|
|
RList *ret;
|
2010-02-07 14:43:42 +00:00
|
|
|
RBinString *ptr = NULL;
|
2009-07-05 14:49:47 +00:00
|
|
|
char str[R_BIN_SIZEOF_STRINGS];
|
2010-03-10 10:01:38 +00:00
|
|
|
int i, matches = 0, ctr = 0;
|
2009-03-16 23:34:45 +00:00
|
|
|
|
2010-03-10 10:01:38 +00:00
|
|
|
if (!(ret = r_list_new ())) {
|
2010-02-22 13:10:44 +00:00
|
|
|
eprintf ("Error allocating array\n");
|
2009-07-16 12:17:32 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2010-03-10 10:01:38 +00:00
|
|
|
ret->free = free;
|
|
|
|
for(i = 0; i < bin->size; i++) {
|
2010-02-07 14:43:42 +00:00
|
|
|
if ((IS_PRINTABLE (bin->buf->buf[i])) && matches < R_BIN_SIZEOF_STRINGS-1) {
|
|
|
|
str[matches] = bin->buf->buf[i];
|
2009-03-16 23:34:45 +00:00
|
|
|
matches++;
|
|
|
|
} else {
|
|
|
|
/* check if the length fits on our request */
|
|
|
|
if (matches >= min) {
|
2010-03-12 12:35:10 +00:00
|
|
|
if (!(ptr = R_NEW (RBinString))) {
|
2010-02-07 12:17:51 +00:00
|
|
|
fprintf(stderr, "Error allocating string\n");
|
|
|
|
break;
|
|
|
|
}
|
2009-03-16 23:34:45 +00:00
|
|
|
str[matches] = '\0';
|
2010-02-07 14:43:42 +00:00
|
|
|
ptr->rva = ptr->offset = i-matches;
|
|
|
|
ptr->size = matches;
|
|
|
|
ptr->ordinal = ctr;
|
|
|
|
memcpy (ptr->string, str, R_BIN_SIZEOF_STRINGS);
|
|
|
|
ptr->string[R_BIN_SIZEOF_STRINGS-1] = '\0';
|
2010-03-10 10:01:38 +00:00
|
|
|
r_list_append (ret, ptr);
|
2009-03-16 23:34:45 +00:00
|
|
|
ctr++;
|
|
|
|
}
|
|
|
|
matches = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
2009-03-16 20:07:31 +00:00
|
|
|
}
|
|
|
|
|
2010-02-07 12:17:51 +00:00
|
|
|
static void r_bin_init_items(RBin *bin) {
|
|
|
|
if (!bin->cur)
|
|
|
|
return;
|
|
|
|
if (bin->cur->baddr)
|
|
|
|
bin->baddr = bin->cur->baddr (bin);
|
|
|
|
if (bin->cur->entries)
|
|
|
|
bin->entries = bin->cur->entries (bin);
|
|
|
|
if (bin->cur->fields)
|
|
|
|
bin->fields = bin->cur->fields (bin);
|
|
|
|
if (bin->cur->imports)
|
|
|
|
bin->imports = bin->cur->imports (bin);
|
|
|
|
if (bin->cur->info)
|
|
|
|
bin->info = bin->cur->info (bin);
|
2010-02-23 17:04:39 +00:00
|
|
|
if (bin->cur->libs)
|
|
|
|
bin->libs = bin->cur->libs (bin);
|
2010-02-07 12:17:51 +00:00
|
|
|
if (bin->cur->sections)
|
|
|
|
bin->sections = bin->cur->sections (bin);
|
|
|
|
if (bin->cur->strings)
|
|
|
|
bin->strings = bin->cur->strings (bin);
|
|
|
|
else bin->strings = get_strings (bin, 5);
|
|
|
|
if (bin->cur->symbols)
|
|
|
|
bin->symbols = bin->cur->symbols (bin);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void r_bin_free_items(RBin *bin) {
|
|
|
|
if (bin->entries)
|
2010-03-10 10:01:38 +00:00
|
|
|
r_list_free (bin->entries);
|
2010-02-07 12:17:51 +00:00
|
|
|
if (bin->fields)
|
2010-03-10 10:01:38 +00:00
|
|
|
r_list_free (bin->fields);
|
2010-02-07 12:17:51 +00:00
|
|
|
if (bin->imports)
|
2010-03-10 10:01:38 +00:00
|
|
|
r_list_free (bin->imports);
|
2010-02-07 12:17:51 +00:00
|
|
|
if (bin->info)
|
2010-02-07 13:11:05 +00:00
|
|
|
free (bin->info);
|
2010-02-23 17:04:39 +00:00
|
|
|
if (bin->libs)
|
2010-03-10 10:01:38 +00:00
|
|
|
r_list_free (bin->libs);
|
2010-02-07 12:17:51 +00:00
|
|
|
if (bin->sections)
|
2010-03-10 10:01:38 +00:00
|
|
|
r_list_free (bin->sections);
|
2010-02-07 12:17:51 +00:00
|
|
|
if (bin->strings)
|
2010-03-10 10:01:38 +00:00
|
|
|
r_list_free (bin->strings);
|
2010-02-07 12:17:51 +00:00
|
|
|
if (bin->symbols)
|
2010-03-10 10:01:38 +00:00
|
|
|
r_list_free (bin->symbols);
|
2010-02-07 12:17:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_bin_add(RBin *bin, RBinHandle *foo) {
|
2009-03-09 01:14:50 +00:00
|
|
|
struct list_head *pos;
|
2009-03-08 15:49:15 +00:00
|
|
|
if (foo->init)
|
2010-02-07 12:17:51 +00:00
|
|
|
foo->init (bin->user);
|
|
|
|
list_for_each_prev (pos, &bin->bins) {
|
|
|
|
RBinHandle *h = list_entry (pos, RBinHandle, list);
|
|
|
|
if (!strcmp (h->name, foo->name))
|
2009-03-08 23:49:15 +00:00
|
|
|
return R_FALSE;
|
|
|
|
}
|
2010-02-07 12:17:51 +00:00
|
|
|
list_add_tail (&(foo->list), &(bin->bins));
|
2009-03-08 15:49:15 +00:00
|
|
|
return R_TRUE;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2010-02-07 12:17:51 +00:00
|
|
|
R_API void* r_bin_free(RBin *bin) {
|
2010-01-24 11:40:48 +00:00
|
|
|
if (!bin)
|
2010-01-08 12:25:03 +00:00
|
|
|
return NULL;
|
2010-02-07 12:17:51 +00:00
|
|
|
r_bin_free_items (bin);
|
|
|
|
if (bin->cur && bin->cur->destroy)
|
|
|
|
bin->cur->destroy (bin);
|
2010-03-04 00:46:25 +00:00
|
|
|
free (bin);
|
2010-01-08 12:25:03 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-02-07 12:17:51 +00:00
|
|
|
R_API int r_bin_init(RBin *bin) {
|
2010-01-25 16:54:32 +00:00
|
|
|
int i;
|
2010-02-07 13:11:05 +00:00
|
|
|
memset (bin, 0, sizeof(RBin));
|
2010-02-07 12:17:51 +00:00
|
|
|
INIT_LIST_HEAD (&bin->bins);
|
2010-03-04 00:46:25 +00:00
|
|
|
for (i=0;bin_static_plugins[i];i++)
|
2010-02-07 12:17:51 +00:00
|
|
|
r_bin_add (bin, bin_static_plugins[i]);
|
2010-01-25 16:54:32 +00:00
|
|
|
return R_TRUE;
|
|
|
|
}
|
|
|
|
|
2010-02-07 12:17:51 +00:00
|
|
|
R_API int r_bin_list(RBin *bin) {
|
2009-09-24 10:29:05 +00:00
|
|
|
struct list_head *pos;
|
2009-07-16 12:17:32 +00:00
|
|
|
|
2009-03-08 15:49:15 +00:00
|
|
|
list_for_each_prev(pos, &bin->bins) {
|
2010-02-07 12:17:51 +00:00
|
|
|
RBinHandle *h = list_entry (pos, RBinHandle, list);
|
|
|
|
printf ("bin %-10s %s\n", h->name, h->desc);
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
2010-01-24 11:40:48 +00:00
|
|
|
return R_FALSE;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2010-02-07 12:17:51 +00:00
|
|
|
R_API int r_bin_load(RBin *bin, const char *file, const char *plugin_name) {
|
2010-01-24 14:35:28 +00:00
|
|
|
struct list_head *pos;
|
|
|
|
|
|
|
|
if (!bin || !file)
|
2010-02-07 12:17:51 +00:00
|
|
|
return R_FALSE;
|
2010-02-20 05:40:02 +00:00
|
|
|
bin->file = r_file_abspath (file);
|
2010-02-07 12:17:51 +00:00
|
|
|
list_for_each_prev (pos, &bin->bins) {
|
|
|
|
RBinHandle *h = list_entry (pos, RBinHandle, list);
|
|
|
|
if ((plugin_name && !strcmp (h->name, plugin_name)) ||
|
|
|
|
(h->check && h->check (bin)))
|
2010-01-24 14:35:28 +00:00
|
|
|
bin->cur = h;
|
|
|
|
}
|
2010-02-07 14:49:23 +00:00
|
|
|
if (bin->cur && bin->cur->load && bin->cur->load (bin))
|
|
|
|
r_bin_init_items (bin);
|
2010-02-07 12:17:51 +00:00
|
|
|
else return R_FALSE;
|
|
|
|
return R_TRUE;
|
2009-03-08 15:49:15 +00:00
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2010-01-24 11:40:48 +00:00
|
|
|
|
2010-02-07 12:17:51 +00:00
|
|
|
R_API ut64 r_bin_get_baddr(RBin *bin) {
|
|
|
|
return bin->baddr;
|
2009-03-08 15:49:15 +00:00
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2010-03-10 10:01:38 +00:00
|
|
|
R_API RList* r_bin_get_entries(RBin *bin) {
|
2010-02-07 12:17:51 +00:00
|
|
|
return bin->entries;
|
2009-03-08 15:49:15 +00:00
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2010-03-10 10:01:38 +00:00
|
|
|
R_API RList* r_bin_get_fields(RBin *bin) {
|
2010-02-07 12:17:51 +00:00
|
|
|
return bin->fields;
|
2009-03-08 15:49:15 +00:00
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2010-03-10 10:01:38 +00:00
|
|
|
R_API RList* r_bin_get_imports(RBin *bin) {
|
2010-02-07 12:17:51 +00:00
|
|
|
return bin->imports;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2010-02-07 12:17:51 +00:00
|
|
|
R_API RBinInfo* r_bin_get_info(RBin *bin) {
|
|
|
|
return bin->info;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2010-03-10 10:01:38 +00:00
|
|
|
R_API RList* r_bin_get_libs(RBin *bin) {
|
2010-02-07 12:17:51 +00:00
|
|
|
return bin->libs;
|
2009-04-24 10:12:15 +00:00
|
|
|
}
|
|
|
|
|
2010-03-10 10:01:38 +00:00
|
|
|
R_API RList* r_bin_get_sections(RBin *bin) {
|
2010-02-07 12:17:51 +00:00
|
|
|
return bin->sections;
|
2010-01-24 11:40:48 +00:00
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2010-02-23 17:26:02 +00:00
|
|
|
R_API RBinSection* r_bin_get_section_at(RBin *bin, ut64 off, int va) {
|
|
|
|
RBinSection *section;
|
2010-03-10 10:01:38 +00:00
|
|
|
RListIter *iter;
|
2010-02-23 17:26:02 +00:00
|
|
|
ut64 from, to;
|
|
|
|
|
2010-04-08 12:04:34 +00:00
|
|
|
if (bin->sections)
|
2010-03-10 10:01:38 +00:00
|
|
|
r_list_foreach (bin->sections, iter, section) {
|
2010-02-23 17:26:02 +00:00
|
|
|
from = va ? bin->baddr+section->rva : section->offset;
|
|
|
|
to = va ? bin->baddr+section->rva+section->vsize :
|
|
|
|
section->offset + section->size;
|
|
|
|
if (off >= from && off < to)
|
|
|
|
return section;
|
|
|
|
}
|
|
|
|
return NULL;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2010-03-10 10:01:38 +00:00
|
|
|
R_API RList* r_bin_get_strings(RBin *bin) {
|
2010-02-07 12:17:51 +00:00
|
|
|
return bin->strings;
|
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2010-03-10 10:01:38 +00:00
|
|
|
R_API RList* r_bin_get_symbols(RBin *bin) {
|
2010-02-07 12:17:51 +00:00
|
|
|
return bin->symbols;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2010-03-13 19:25:03 +00:00
|
|
|
R_API int r_bin_is_big_endian (RBin *bin) {
|
|
|
|
return bin->info->big_endian;
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_bin_is_stripped (RBin *bin) {
|
|
|
|
return R_BIN_DBG_STRIPPED (bin->info->dbg_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_bin_is_static (RBin *bin) {
|
|
|
|
return R_BIN_DBG_STATIC (bin->info->dbg_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX Implement in r_bin_meta and deprecate? */
|
|
|
|
R_API int r_bin_has_dbg_linenums (RBin *bin) {
|
|
|
|
return R_BIN_DBG_LINENUMS (bin->info->dbg_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_bin_has_dbg_syms (RBin *bin) {
|
|
|
|
return R_BIN_DBG_SYMS (bin->info->dbg_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_bin_has_dbg_relocs (RBin *bin) {
|
|
|
|
return R_BIN_DBG_RELOCS (bin->info->dbg_info);
|
|
|
|
}
|
|
|
|
|
2010-02-07 12:17:51 +00:00
|
|
|
R_API RBin* r_bin_new() {
|
|
|
|
RBin *bin;
|
2010-03-04 00:46:25 +00:00
|
|
|
if (!(bin = R_NEW (RBin)))
|
2010-01-24 11:40:48 +00:00
|
|
|
return NULL;
|
2010-02-07 12:17:51 +00:00
|
|
|
r_bin_init (bin);
|
2010-01-24 11:40:48 +00:00
|
|
|
return bin;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2010-02-07 12:17:51 +00:00
|
|
|
R_API void r_bin_set_user_ptr(RBin *bin, void *user) {
|
2010-01-24 11:40:48 +00:00
|
|
|
bin->user = user;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|