2009-02-05 21:08:46 +00:00
|
|
|
/* radare - LGPL - Copyright 2009 nibble<.ds@gmail.com> */
|
|
|
|
|
|
|
|
/* TODO:
|
|
|
|
* Linked libraries
|
|
|
|
* dlopen library and show address
|
|
|
|
* Strings
|
|
|
|
* XRefs
|
|
|
|
* Generic resize
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2009-03-08 15:49:15 +00:00
|
|
|
#include <r_types.h>
|
|
|
|
#include <r_lib.h>
|
|
|
|
#include <r_bin.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 */
|
|
|
|
extern struct r_bin_handle_t r_bin_plugin_elf;
|
|
|
|
extern struct r_bin_handle_t r_bin_plugin_elf64;
|
|
|
|
extern struct r_bin_handle_t r_bin_plugin_pe;
|
|
|
|
extern struct r_bin_handle_t r_bin_plugin_pe64;
|
2010-01-15 01:08:38 +00:00
|
|
|
extern struct r_bin_handle_t r_bin_plugin_mach0;
|
2009-09-24 10:29:05 +00:00
|
|
|
extern struct r_bin_handle_t r_bin_plugin_java;
|
|
|
|
extern struct r_bin_handle_t r_bin_plugin_dummy;
|
|
|
|
|
2009-03-09 12:03:42 +00:00
|
|
|
static struct r_bin_handle_t *bin_static_plugins[] =
|
|
|
|
{ R_BIN_STATIC_PLUGINS };
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2009-03-16 23:34:45 +00:00
|
|
|
static struct r_bin_string_t *get_strings(struct r_bin_t *bin, int min)
|
2009-03-16 20:07:31 +00:00
|
|
|
{
|
2009-03-16 23:34:45 +00:00
|
|
|
struct r_bin_string_t *ret = NULL;
|
2009-07-08 11:49:55 +00:00
|
|
|
ut8 *buf = NULL;
|
|
|
|
ut64 len, max_str = 0;
|
2009-03-16 23:34:45 +00:00
|
|
|
int i, matches = 0, ctr = 0;
|
2009-07-05 14:49:47 +00:00
|
|
|
char str[R_BIN_SIZEOF_STRINGS];
|
2009-03-16 23:34:45 +00:00
|
|
|
|
|
|
|
len = lseek(bin->fd, 0, SEEK_END);
|
2009-07-08 11:49:55 +00:00
|
|
|
max_str = (ut64)(len/min);
|
2009-03-16 23:34:45 +00:00
|
|
|
|
|
|
|
ret = malloc(max_str*sizeof(struct r_bin_string_t));
|
2009-07-16 12:17:32 +00:00
|
|
|
if (ret == NULL) {
|
|
|
|
fprintf(stderr, "Error allocating file\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-03-16 23:34:45 +00:00
|
|
|
|
|
|
|
buf = malloc(len);
|
|
|
|
if (buf == NULL) {
|
|
|
|
fprintf(stderr, "Error allocating file\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
lseek(bin->fd, 0, SEEK_SET);
|
|
|
|
read(bin->fd, buf, len);
|
|
|
|
|
|
|
|
for(i = 0; i < len && ctr < max_str; i++) {
|
|
|
|
if ((IS_PRINTABLE(buf[i]))) {
|
|
|
|
str[matches] = buf[i];
|
|
|
|
if (matches < sizeof(str))
|
|
|
|
matches++;
|
|
|
|
} else {
|
|
|
|
/* check if the length fits on our request */
|
|
|
|
if (matches >= min) {
|
|
|
|
str[matches] = '\0';
|
2009-04-19 18:09:07 +00:00
|
|
|
ret[ctr].rva = ret[ctr].offset = i-matches;
|
2009-03-16 23:34:45 +00:00
|
|
|
ret[ctr].size = matches;
|
2009-05-17 10:01:02 +00:00
|
|
|
ret[ctr].ordinal = ctr;
|
2009-07-05 14:49:47 +00:00
|
|
|
memcpy(ret[ctr].string, str, R_BIN_SIZEOF_STRINGS);
|
|
|
|
ret[ctr].string[R_BIN_SIZEOF_STRINGS-1] = '\0';
|
2009-03-16 23:34:45 +00:00
|
|
|
ret[ctr].last = 0;
|
|
|
|
ctr++;
|
|
|
|
}
|
|
|
|
matches = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret[ctr].last = 1;
|
|
|
|
free(buf);
|
|
|
|
|
|
|
|
return ret;
|
2009-03-16 20:07:31 +00:00
|
|
|
}
|
|
|
|
|
2009-09-10 20:51:34 +00:00
|
|
|
R_API struct r_bin_t *r_bin_new()
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
2009-03-08 15:49:15 +00:00
|
|
|
struct r_bin_t *bin = MALLOC_STRUCT(struct r_bin_t);
|
2009-09-10 20:51:34 +00:00
|
|
|
if (bin != NULL)
|
|
|
|
r_bin_init(bin);
|
2009-02-05 21:08:46 +00:00
|
|
|
return bin;
|
|
|
|
}
|
|
|
|
|
2009-09-10 20:51:34 +00:00
|
|
|
R_API struct r_bin_t *r_bin_free(struct r_bin_t *bin)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
|
|
|
free(bin);
|
2009-07-16 12:17:32 +00:00
|
|
|
return NULL;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2009-09-10 20:51:34 +00:00
|
|
|
static int r_bin_io_read_at(struct r_io_t *io, ut64 addr, ut8 *buf, int size)
|
|
|
|
{
|
2009-09-22 11:27:33 +00:00
|
|
|
// TODO: Implement this
|
|
|
|
return size;
|
2009-09-10 20:51:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int r_bin_io_write_at(struct r_io_bind_t *io, ut64 addr, const ut8 *buf, int size)
|
|
|
|
{
|
2009-09-22 11:27:33 +00:00
|
|
|
// TODO: Implement this
|
|
|
|
return size;
|
2009-09-10 20:51:34 +00:00
|
|
|
}
|
2009-09-20 00:16:14 +00:00
|
|
|
static void r_bin_io_init(struct r_bin_t *bin)
|
2009-09-10 20:51:34 +00:00
|
|
|
{
|
|
|
|
bin->iob.init = R_TRUE;
|
|
|
|
bin->iob.io = NULL;
|
|
|
|
bin->iob.read_at = r_bin_io_read_at;
|
2009-09-22 11:27:33 +00:00
|
|
|
bin->iob.write_at = (void*)r_bin_io_write_at;
|
2009-09-10 20:51:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_bin_init(struct r_bin_t *bin)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
2009-03-09 12:03:42 +00:00
|
|
|
int i;
|
2009-03-25 14:52:17 +00:00
|
|
|
bin->rw = 0;
|
2009-09-22 11:27:33 +00:00
|
|
|
bin->cur = bin->user = NULL;
|
|
|
|
bin->file = NULL;
|
2009-03-08 15:49:15 +00:00
|
|
|
INIT_LIST_HEAD(&bin->bins);
|
2009-03-09 12:03:42 +00:00
|
|
|
for(i=0;bin_static_plugins[i];i++)
|
|
|
|
r_bin_add(bin, bin_static_plugins[i]);
|
2009-09-10 20:51:34 +00:00
|
|
|
r_bin_io_init(bin);
|
2009-03-08 15:49:15 +00:00
|
|
|
return R_TRUE;
|
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2009-09-10 20:51:34 +00:00
|
|
|
// TODO: why the hell do we need user ptr here??
|
|
|
|
R_API void r_bin_set_user_ptr(struct r_bin_t *bin, void *user)
|
2009-03-08 15:49:15 +00:00
|
|
|
{
|
|
|
|
bin->user = user;
|
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2009-09-10 20:51:34 +00:00
|
|
|
R_API int r_bin_add(struct r_bin_t *bin, struct r_bin_handle_t *foo)
|
2009-03-08 15:49:15 +00:00
|
|
|
{
|
2009-03-09 01:14:50 +00:00
|
|
|
struct list_head *pos;
|
2009-03-08 15:49:15 +00:00
|
|
|
if (foo->init)
|
|
|
|
foo->init(bin->user);
|
2009-03-08 23:49:15 +00:00
|
|
|
/* avoid dupped plugins */
|
2009-03-09 01:14:50 +00:00
|
|
|
list_for_each_prev(pos, &bin->bins) {
|
|
|
|
struct r_bin_handle_t *h = list_entry(pos, struct r_bin_handle_t, list);
|
2009-03-08 23:49:15 +00:00
|
|
|
if (!strcmp(h->name, foo->name))
|
|
|
|
return R_FALSE;
|
|
|
|
}
|
2009-03-08 15:49:15 +00:00
|
|
|
list_add_tail(&(foo->list), &(bin->bins));
|
|
|
|
return R_TRUE;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2009-09-24 10:29:05 +00:00
|
|
|
R_API int r_bin_list(struct r_bin_t *bin)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
2009-03-08 15:49:15 +00:00
|
|
|
struct list_head *pos;
|
|
|
|
list_for_each_prev(pos, &bin->bins) {
|
|
|
|
struct r_bin_handle_t *h = list_entry(pos, struct r_bin_handle_t, list);
|
2009-09-24 10:29:05 +00:00
|
|
|
printf("bin %s\t%s\n", h->name, h->desc);
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
2009-03-08 15:49:15 +00:00
|
|
|
return R_FALSE;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2010-01-08 12:25:03 +00:00
|
|
|
R_API struct r_bin_object_t *r_bin_load(struct r_bin_t *bin, const char *file, const char *plugin_name)
|
|
|
|
{
|
|
|
|
int fd = r_bin_open (bin, file, R_FALSE, plugin_name);
|
|
|
|
if (fd == -1)
|
|
|
|
return NULL;
|
|
|
|
/* TODO: allocate and fill r_bin_object */
|
|
|
|
r_bin_close (bin);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-09-25 02:04:51 +00:00
|
|
|
R_API int r_bin_open(struct r_bin_t *bin, const char *file, int rw, const char *plugin_name)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
2009-09-24 10:29:05 +00:00
|
|
|
struct list_head *pos;
|
2009-07-16 12:17:32 +00:00
|
|
|
|
2009-09-24 10:29:05 +00:00
|
|
|
if (bin == NULL || file == NULL)
|
|
|
|
return -1;
|
2009-07-16 12:17:32 +00:00
|
|
|
bin->file = file;
|
2009-03-25 14:52:17 +00:00
|
|
|
bin->rw = rw;
|
2009-03-08 15:49:15 +00:00
|
|
|
list_for_each_prev(pos, &bin->bins) {
|
|
|
|
struct r_bin_handle_t *h = list_entry(pos, struct r_bin_handle_t, list);
|
2009-03-25 19:51:26 +00:00
|
|
|
if ((plugin_name && !strcmp(h->name, plugin_name)) ||
|
|
|
|
(h->check && h->check(bin)))
|
2009-03-08 15:49:15 +00:00
|
|
|
bin->cur = h;
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
2009-03-08 15:49:15 +00:00
|
|
|
if (bin->cur && bin->cur->open)
|
|
|
|
return bin->cur->open(bin);
|
2009-09-24 10:29:05 +00:00
|
|
|
if (plugin_name && !strcmp(plugin_name, "dummy"))
|
2009-07-05 14:49:47 +00:00
|
|
|
return -1;
|
2009-09-24 10:29:05 +00:00
|
|
|
return r_bin_open(bin, file, rw, "dummy");
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2009-09-24 10:29:05 +00:00
|
|
|
R_API int r_bin_close(struct r_bin_t *bin)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
2009-03-08 15:49:15 +00:00
|
|
|
if (bin->cur && bin->cur->close)
|
|
|
|
return bin->cur->close(bin);
|
2009-07-05 14:49:47 +00:00
|
|
|
return -1;
|
2009-03-08 15:49:15 +00:00
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2009-07-16 12:17:32 +00:00
|
|
|
R_API ut64 r_bin_get_baddr(struct r_bin_t *bin)
|
2009-03-08 15:49:15 +00:00
|
|
|
{
|
|
|
|
if (bin->cur && bin->cur->baddr)
|
|
|
|
return bin->cur->baddr(bin);
|
2009-07-16 12:17:32 +00:00
|
|
|
return UT64_MAX;
|
2009-03-08 15:49:15 +00:00
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2010-01-08 12:25:03 +00:00
|
|
|
/* XXX : a binary can contain more than one entrypoint */
|
2009-07-16 12:17:32 +00:00
|
|
|
R_API struct r_bin_entry_t* r_bin_get_entry(struct r_bin_t *bin)
|
2009-03-08 15:49:15 +00:00
|
|
|
{
|
|
|
|
if (bin->cur && bin->cur->entry)
|
|
|
|
return bin->cur->entry(bin);
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2009-07-16 12:17:32 +00:00
|
|
|
R_API struct r_bin_section_t* r_bin_get_sections(struct r_bin_t *bin)
|
2009-03-08 15:49:15 +00:00
|
|
|
{
|
|
|
|
if (bin->cur && bin->cur->sections)
|
|
|
|
return bin->cur->sections(bin);
|
2009-02-05 21:08:46 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-07-16 12:17:32 +00:00
|
|
|
R_API struct r_bin_symbol_t* r_bin_get_symbols(struct r_bin_t *bin)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
2009-03-08 15:49:15 +00:00
|
|
|
if (bin->cur && bin->cur->symbols)
|
|
|
|
return bin->cur->symbols(bin);
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2009-07-16 12:17:32 +00:00
|
|
|
R_API struct r_bin_import_t* r_bin_get_imports(struct r_bin_t *bin)
|
2009-03-08 15:49:15 +00:00
|
|
|
{
|
|
|
|
if (bin->cur && bin->cur->imports)
|
|
|
|
return bin->cur->imports(bin);
|
2009-02-05 21:08:46 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-07-16 12:17:32 +00:00
|
|
|
R_API struct r_bin_string_t* r_bin_get_strings(struct r_bin_t *bin)
|
2009-03-16 20:07:31 +00:00
|
|
|
{
|
|
|
|
if (bin->cur && bin->cur->strings)
|
|
|
|
return bin->cur->strings(bin);
|
2009-07-16 12:17:32 +00:00
|
|
|
return get_strings(bin, 5);
|
2009-03-16 20:07:31 +00:00
|
|
|
}
|
|
|
|
|
2009-07-16 12:17:32 +00:00
|
|
|
R_API struct r_bin_info_t* r_bin_get_info(struct r_bin_t *bin)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
2009-03-08 15:49:15 +00:00
|
|
|
if (bin->cur && bin->cur->info)
|
|
|
|
return bin->cur->info(bin);
|
2009-02-05 21:08:46 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-07-16 12:17:32 +00:00
|
|
|
R_API struct r_bin_field_t* r_bin_get_fields(struct r_bin_t *bin)
|
2009-04-24 10:12:15 +00:00
|
|
|
{
|
|
|
|
if (bin->cur && bin->cur->fields)
|
|
|
|
return bin->cur->fields(bin);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-09-24 10:29:05 +00:00
|
|
|
// why not just return a single instance of the Section struct?
|
|
|
|
R_API ut64 r_bin_get_section_offset(struct r_bin_t *bin, const char *name)
|
2009-03-08 15:49:15 +00:00
|
|
|
{
|
2009-07-05 14:49:47 +00:00
|
|
|
struct r_bin_section_t *sections;
|
2009-07-16 12:17:32 +00:00
|
|
|
ut64 ret = UT64_MAX;
|
2009-07-05 14:49:47 +00:00
|
|
|
int i;
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2009-07-16 12:17:32 +00:00
|
|
|
sections = r_bin_get_sections(bin);
|
|
|
|
if (sections) {
|
|
|
|
for (i = 0; !sections[i].last; i++)
|
|
|
|
if (!strcmp(sections[i].name, name)) {
|
|
|
|
ret = sections[i].offset;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
free(sections);
|
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-09-24 10:29:05 +00:00
|
|
|
R_API ut64 r_bin_get_section_rva(struct r_bin_t *bin, const char *name)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
2009-07-05 14:49:47 +00:00
|
|
|
struct r_bin_section_t *sections;
|
2009-07-16 12:17:32 +00:00
|
|
|
ut64 ret = UT64_MAX;
|
2009-07-05 14:49:47 +00:00
|
|
|
int i;
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2009-07-16 12:17:32 +00:00
|
|
|
sections = r_bin_get_sections(bin);
|
|
|
|
if (sections) {
|
|
|
|
for (i=0; !sections[i].last; i++) {
|
|
|
|
if (!strcmp(sections[i].name, name)) {
|
|
|
|
ret = sections[i].rva;
|
|
|
|
break;
|
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
2009-07-16 12:17:32 +00:00
|
|
|
free(sections);
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-09-24 10:29:05 +00:00
|
|
|
R_API ut64 r_bin_get_section_size(struct r_bin_t *bin, const char *name)
|
2009-02-05 21:08:46 +00:00
|
|
|
{
|
2009-07-05 14:49:47 +00:00
|
|
|
struct r_bin_section_t *sections;
|
2009-07-16 12:17:32 +00:00
|
|
|
ut64 ret = UT64_MAX;
|
2009-07-05 14:49:47 +00:00
|
|
|
int i;
|
2009-02-05 21:08:46 +00:00
|
|
|
|
2009-07-16 12:17:32 +00:00
|
|
|
sections = r_bin_get_sections(bin);
|
|
|
|
if (sections) {
|
|
|
|
for (i=0; !sections[i].last; i++) {
|
|
|
|
if (!strcmp(sections[i].name, name)) {
|
|
|
|
ret = sections[i].size;
|
|
|
|
break;
|
|
|
|
}
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
2009-07-16 12:17:32 +00:00
|
|
|
free(sections);
|
2009-02-05 21:08:46 +00:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
int r_bin_get_libs()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|