Add anal.cpp.abi

This commit is contained in:
Florian Märkl 2018-03-12 21:48:44 +01:00 committed by radare
parent f95432fceb
commit 086c3a144e
6 changed files with 49 additions and 31 deletions

View File

@ -70,6 +70,7 @@ R_API RAnal *r_anal_new() {
anal->decode = true; // slow slow if not used
anal->gp = 0LL;
anal->sdb = sdb_new0 ();
anal->cpp_abi = R_ANAL_CPP_ABI_ITANIUM;
anal->opt.depth = 32;
anal->opt.noncode = false; // do not analyze data by default
r_space_new (&anal->meta_spaces, "CS", meta_unset_for, meta_count_for, NULL, anal);

View File

@ -5,5 +5,9 @@
R_API void r_anal_print_rtti (RAnal *anal) {
RVTableContext context;
r_anal_vtable_begin (anal, &context);
r_anal_rtti_msvc_parse (&context);
if (context.abi == R_ANAL_CPP_ABI_MSVC) {
r_anal_rtti_msvc_print_all (&context);
} else {
eprint ("RTTI not supported yet for Itanium.\n");
}
}

View File

@ -1,16 +1,10 @@
/* radare - LGPL - Copyright 2009-2018 - pancake, maijin, thestr4ng3r */
#include <r_anal.h>
#include "r_anal.h"
#define NAME_BUF_SIZE 64
typedef struct run_time_type_information_t {
ut64 vtable_start_addr;
ut64 rtti_addr;
} rtti_struct;
typedef struct rtti_complete_object_locator_t {
ut32 signature;
ut32 vtable_offset; // offset of the vtable within class
@ -43,12 +37,12 @@ typedef struct rtti_type_descriptor_t {
char *name;
} rtti_type_descriptor;
static void rtti_type_descriptor_fini(rtti_type_descriptor *td) {
free (td->name);
}
static bool rtti_msvc_read_complete_object_locator(RVTableContext *context, ut64 addr, rtti_complete_object_locator *col) {
ut8 buf[3*sizeof (ut32) + 2*sizeof (ut64)];
int colSize = 3*sizeof (ut32) + 2*context->word_size;
@ -259,17 +253,17 @@ static void rtti_msvc_print_base_class_descriptor (rtti_base_class_descriptor *b
prefix, bcd->attributes);
}
static rtti_struct *get_rtti_data(RVTableContext *context, ut64 atAddress) {
static void rtti_msvc_print_complete_object_locator_recurse(RVTableContext *context, ut64 atAddress) {
ut64 colRefAddr = atAddress - context->word_size;
ut64 colAddr;
if (!context->read_addr (context->anal, colRefAddr, &colAddr)) {
return NULL;
return;
}
rtti_complete_object_locator col;
if (!rtti_msvc_read_complete_object_locator (context, colAddr, &col)) {
eprintf ("Failed to parse Complete Object Locator at 0x%08"PFMT64x" (referenced from 0x%08"PFMT64x")\n", colAddr, colRefAddr);
return NULL;
return;
}
rtti_msvc_print_complete_object_locator (&col, colAddr, "");
@ -306,26 +300,18 @@ static rtti_struct *get_rtti_data(RVTableContext *context, ut64 atAddress) {
} else {
eprintf ("Failed to parse Class Hierarchy Descriptor at 0x%08"PFMT64x"\n", col.class_descriptor_addr);
}
return NULL;
}
R_API RList *r_anal_rtti_msvc_parse(RVTableContext *context) {
R_API void r_anal_rtti_msvc_print_all(RVTableContext *context) {
RList *vtables = r_anal_vtable_search (context);
RListIter *vtableIter;
RList *rtti_structures = r_list_new ();
RVTableInfo *table;
if (vtables) {
r_list_foreach (vtables, vtableIter, table) {
rtti_struct* current_rtti = get_rtti_data (context, table->saddr);
if (current_rtti) {
current_rtti->vtable_start_addr = table->saddr;
r_list_append (rtti_structures, current_rtti);
}
rtti_msvc_print_complete_object_locator_recurse (context, table->saddr);
r_cons_print ("\n");
}
}
r_list_free (vtables);
return rtti_structures;
}

View File

@ -41,7 +41,7 @@ R_API ut64 r_anal_vtable_info_get_size(RVTableContext *context, RVTableInfo *vta
R_API bool r_anal_vtable_begin(RAnal *anal, RVTableContext *context) {
context->anal = anal;
context->compiler = VTABLE_COMPILER_ITANIUM;
context->abi = anal->cpp_abi;
context->word_size = (ut8)(anal->bits / 8);
switch (anal->bits) {
case 8:

View File

@ -2123,6 +2123,28 @@ static int cb_anal_bb_max_size(void *user, void *data) {
return true;
}
static int cb_anal_cpp_abi(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
if (*node->value == '?') {
print_node_options (node);
return false;
}
if (*node->value) {
if (strcmp (node->value, "itanium") == 0) {
core->anal->cpp_abi = R_ANAL_CPP_ABI_ITANIUM;
return true;
} else if (strcmp (node->value, "msvc") == 0) {
core->anal->cpp_abi = R_ANAL_CPP_ABI_MSVC;
return true;
}
eprintf ("anal.cpp.abi: cannot find '%s'\n", node->value);
}
return false;
}
static int cb_linesto(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
@ -2305,6 +2327,10 @@ R_API int r_core_config_init(RCore *core) {
SETCB ("anal.bb.maxsize", "1024", &cb_anal_bb_max_size, "Maximum basic block size");
SETCB ("anal.pushret", "false", &cb_anal_pushret, "Analyze push+ret as jmp");
n = NODECB ("anal.cpp.abi", "itanium", &cb_anal_cpp_abi);
SETDESC (n, "Select C++ ABI (Compiler)");
SETOPTIONS (n, "itanium", "msvc", NULL);
#if __linux__ && __GNU_LIBRARY__ && __GLIBC__ && __GLIBC_MINOR__
SETCB("dbg.malloc", "glibc", &cb_malloc, "Choose malloc structure parser");
#else

View File

@ -604,6 +604,11 @@ typedef struct r_anal_options_t {
bool armthumb; //
} RAnalOptions;
typedef enum {
R_ANAL_CPP_ABI_ITANIUM = 0,
R_ANAL_CPP_ABI_MSVC
} RAnalCPPABI;
typedef struct r_anal_t {
char *cpu;
char *os;
@ -612,6 +617,7 @@ typedef struct r_anal_t {
int big_endian;
int split; // used only from core
int sleep; // sleep some usecs before analyzing more (avoid 100% cpu usages)
RAnalCPPABI cpp_abi;
void *user;
ut64 gp; // global pointer. used for mips. but can be used by other arches too in the future
RList *fcns;
@ -1662,14 +1668,9 @@ R_API void r_sign_space_unset_for(RAnal *a, int idx);
R_API void r_sign_space_rename_for(RAnal *a, int idx, const char *oname, const char *nname);
/* vtables */
typedef enum {
VTABLE_COMPILER_ITANIUM,
VTABLE_COMPILER_MSVC
} RVTableCompilerType;
typedef struct {
RAnal *anal;
RVTableCompilerType compiler;
RAnalCPPABI abi;
ut8 word_size;
bool (*read_addr) (RAnal *anal, ut64 addr, ut64 *buf);
} RVTableContext;
@ -1693,7 +1694,7 @@ R_API RList *r_anal_vtable_get_methods(RVTableContext *context, RVTableInfo *tab
R_API void r_anal_list_vtables(RAnal *anal, int rad);
/* rtti */
R_API RList *r_anal_rtti_msvc_parse(RVTableContext *context);
R_API void r_anal_rtti_msvc_print_all(RVTableContext *context);
R_API void r_anal_print_rtti(RAnal *anal);
/* plugin pointers */