* Initial dummy implementation of r_bp

- Managing breakpoints for the core
  - Initial work on the support for breakpoints
    for the r_debug plugins
* Adding some dummy work for context support in r_anal
* Make asm_set_bits check per-plugin supported bit sizes
  - Now asm plugins have 'arch' and 'bits' attributes
  - Used to setup default callbacks for undefined 'assemble' callback
  - Also used to avoid setting asm.bits eval variable to invalid values
  - We need a way to display all this data
* Added DEFAULT_ARCH in config.h to setup default arch to asm and anal
* Added r_config_set_i_cb()
  - Make r_config_set restore value when callback is called and fails
  - asm.bits now has a config callback
* Added _LAST in some r_anal enums
This commit is contained in:
pancake 2009-04-11 21:22:20 +00:00
parent 44ecdbb636
commit cdd80105cb
32 changed files with 238 additions and 42 deletions

View file

@ -43,3 +43,12 @@ Before any release we have to:
the code for testing parts of libraries and be able to go back or find bugs
while refactoring code or re-doing-it from scratch. This code, should be
reviewed and removed if necessary.
$ grep -r -e TODO -e XXX -e FIX libr
- Graph per symbol-module dependency graph to identify unused/dupped/-
simplificable use cases of the API for every module.
FUTURE
- Commands should be handled in a structural way, not by a bunch of switch/cases

View file

@ -35,6 +35,7 @@ coding style guidelines ;) Here'r some rules:
the algorithm, only external-copy-pasted-not-going-to-be-maintained code
can be accepted in this way (gnu code, external disassemblers, etc..)
VIM syntax configuration:
-------------------------
TODO:

View file

@ -5,7 +5,7 @@ PFX=${DESTDIR}${PREFIX}
#PREFIX=${PFX}
# Libraries
LIBLIST=io util lib meta lang flags bin bininfo macro hash line cons print config syscall range socket cmd asm anal parse search diff debug reg core var sign trace vm
LIBLIST=io util lib meta lang flags bin bininfo macro hash line cons print config syscall range socket cmd asm anal parse search diff bp debug reg core var sign trace vm
# Under development
#LIBLIST+=print

View file

@ -1,5 +1,5 @@
NAME=r_anal
DEPS=r_util r_lib
OBJ=anal.o
OBJ=anal.o ctx.o
include ../rules.mk

View file

@ -5,34 +5,35 @@
#include <r_anal.h>
#include <r_util.h>
struct r_anal_t *r_anal_new()
R_API struct r_anal_t *r_anal_new()
{
struct r_anal_t *r = MALLOC_STRUCT(struct r_anal_t);
r_anal_init(r);
return r;
}
struct r_anal_t *r_anal_free(struct r_anal_t *r)
R_API struct r_anal_t *r_anal_free(struct r_anal_t *r)
{
free(r);
return NULL;
}
int r_anal_init(struct r_anal_t *anal)
R_API int r_anal_init(struct r_anal_t *anal)
{
anal->user = NULL;
anal->ctx = NULL;
r_anal_set_bits(anal, 32);
r_anal_set_big_endian(anal, R_FALSE);
INIT_LIST_HEAD(&anal->anals);
return R_TRUE;
}
void r_anal_set_user_ptr(struct r_anal_t *anal, void *user)
R_API void r_anal_set_user_ptr(struct r_anal_t *anal, void *user)
{
anal->user = user;
}
int r_anal_add(struct r_anal_t *anal, struct r_anal_handle_t *foo)
R_API int r_anal_add(struct r_anal_t *anal, struct r_anal_handle_t *foo)
{
if (foo->init)
foo->init(anal->user);
@ -40,7 +41,7 @@ int r_anal_add(struct r_anal_t *anal, struct r_anal_handle_t *foo)
return R_TRUE;
}
int r_anal_list(struct r_anal_t *anal)
R_API int r_anal_list(struct r_anal_t *anal)
{
struct list_head *pos;
list_for_each_prev(pos, &anal->anals) {
@ -50,7 +51,7 @@ int r_anal_list(struct r_anal_t *anal)
return R_FALSE;
}
int r_anal_set(struct r_anal_t *anal, const char *name)
R_API int r_anal_set(struct r_anal_t *anal, const char *name)
{
struct list_head *pos;
list_for_each_prev(pos, &anal->anals) {
@ -63,7 +64,7 @@ int r_anal_set(struct r_anal_t *anal, const char *name)
return R_FALSE;
}
int r_anal_set_bits(struct r_anal_t *anal, int bits)
R_API int r_anal_set_bits(struct r_anal_t *anal, int bits)
{
switch (bits) {
case 16:

33
libr/anal/ctx.c Normal file
View file

@ -0,0 +1,33 @@
/* radare - LGPL - Copyright 2009 */
/* nibble<.ds@gmail.com> */
/* pancake<nopcode.org> */
#include <r_anal.h>
R_API void r_anal_ctx_init(struct r_anal_ctx_t *ctx)
{
}
R_API struct r_anal_ctx_t *r_anal_ctx_new()
{
struct r_anal_ctx_t *ctx = MALLOC_STRUCT(struct r_anal_ctx_t);
r_anal_ctx_init(ctx);
return ctx;
}
R_API void r_anal_ctx_reset(struct r_anal_t *anal)
{
}
#if 0
/* getter/setter */
R_API struct r_anal_ctx_t *r_anal_ctx_get(struct r_anal_t *anal)
{
return anal->ctx;
}
R_API void r_anal_ctx_set(struct r_anal_t *anal, struct r_anal_ctx_t *ctx)
{
anal->ctx = ctx;
}
#endif

View file

@ -96,17 +96,26 @@ R_API int r_asm_set(struct r_asm_t *a, const char *name)
return R_FALSE;
}
static int has_bits(struct r_asm_handle_t *h, int bits)
{
int i;
if (h && h->bits) {
for(i=0; h->bits[i]; i++) {
if (bits == h->bits[i])
return R_TRUE;
}
}
return R_FALSE;
}
R_API int r_asm_set_bits(struct r_asm_t *a, int bits)
{
switch (bits) {
case 16:
case 32:
case 64:
if ( has_bits(a->cur, bits) ) {
a->bits = bits;
return R_TRUE;
default:
return R_FALSE;
}
return R_FALSE;
}
R_API int r_asm_set_big_endian(struct r_asm_t *a, int boolean)
@ -137,15 +146,22 @@ R_API int r_asm_disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, u8 *buf,
{
if (a->cur && a->cur->disassemble)
return a->cur->disassemble(a, aop, buf, len);
return R_FALSE;
}
R_API int r_asm_assemble(struct r_asm_t *a, struct r_asm_aop_t *aop, const char *buf)
{
if (a->cur && a->cur->assemble)
return a->cur->assemble(a, aop, buf);
struct list_head *pos;
if (a->cur) {
if (a->cur->assemble)
return a->cur->assemble(a, aop, buf);
/* find callback if no assembler support in current plugin */
list_for_each_prev(pos, &a->asms) {
struct r_asm_handle_t *h = list_entry(pos, struct r_asm_handle_t, list);
if (h->arch && h->assemble && has_bits(h, a->bits) && !strcmp(a->cur->arch, h->arch))
return h->assemble(a, aop, buf);
}
}
return R_FALSE;
}

View file

@ -93,6 +93,8 @@ static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, u8 *buf, u64
struct r_asm_handle_t r_asm_plugin_arm = {
.name = "asm_arm",
.arch = "arm",
.bits = (int[]){ 16, 32, 0 },
.desc = "ARM disassembly plugin",
.init = NULL,
.fini = NULL,

View file

@ -68,6 +68,8 @@ static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, u8 *buf, u64
struct r_asm_handle_t r_asm_plugin_bf = {
.name = "asm_bf",
.arch = "brainfuck",
.bits = (int[]){ 8, 0 },
.desc = "BF disassembly plugin",
.init = NULL,
.fini = NULL,

View file

@ -23,6 +23,8 @@ static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, u8 *buf, u64
struct r_asm_handle_t r_asm_plugin_csr = {
.name = "asm_csr",
.arch = "csr",
.bits = (int[]){ 16, 0 },
.desc = "CSR disassembly plugin",
.init = NULL,
.fini = NULL,

View file

@ -14,6 +14,8 @@ static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, u8 *buf, u64
struct r_asm_handle_t r_asm_plugin_dummy = {
.name = "asm_dummy",
.arch = "none",
.bits = (int[]){ 0 },
.desc = "dummy disassembly plugin",
.init = NULL,
.fini = NULL,

View file

@ -39,6 +39,8 @@ static int assemble(struct r_asm_t *a, struct r_asm_aop_t *aop, char *buf)
struct r_asm_handle_t r_asm_plugin_java = {
.name = "asm_java",
.arch = "java",
.bits = (int[]){ 8, 0 },
.desc = "java disassembly plugin",
.init = NULL,
.fini = NULL,

View file

@ -37,6 +37,8 @@ static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, u8 *buf, u64
struct r_asm_handle_t r_asm_plugin_m68k = {
.name = "asm_m68k",
.arch = "m68k",
.bits = (int[]){ 32, 0 },
.desc = "M68K disassembly plugin",
.init = NULL,
.fini = NULL,

View file

@ -97,6 +97,8 @@ static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, u8 *buf, u64
struct r_asm_handle_t r_asm_plugin_mips = {
.name = "asm_mips",
.arch = "mips",
.bits = (int[]){ 32, 0 },
.desc = "MIPS disassembly plugin",
.init = NULL,
.fini = NULL,

View file

@ -37,6 +37,8 @@ static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, u8 *buf, u64
struct r_asm_handle_t r_asm_plugin_ppc = {
.name = "asm_ppc",
.arch = "powepc",
.bits = (int[]){ 32, 0 },
.desc = "PPC disassembly plugin",
.init = NULL,
.fini = NULL,

View file

@ -92,6 +92,8 @@ static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, u8 *buf, u64
struct r_asm_handle_t r_asm_plugin_sparc = {
.name = "asm_sparc",
.arch = "sparc",
.bits = (int[]){ 32, 0 },
.desc = "SPARC disassembly plugin",
.init = NULL,
.fini = NULL,

View file

@ -38,6 +38,8 @@ static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, u8 *buf, u64
struct r_asm_handle_t r_asm_plugin_x86 = {
.name = "asm_x86",
.desc = "X86 disassembly plugin",
.arch = "x86",
.bits = (int[]){ 16, 32, 64, 0 },
.init = NULL,
.fini = NULL,
.disassemble = &disassemble,

View file

@ -41,6 +41,8 @@ static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, u8 *buf, u64
struct r_asm_handle_t r_asm_plugin_x86_bea = {
.name = "asm_x86_bea",
.desc = "X86 disassembly plugin (bea engine)",
.arch = "x86",
.bits = (int[]){ 32, 64, 0 }, /* also 16 ? */
.init = NULL,
.fini = NULL,
.disassemble = &disassemble,

View file

@ -52,6 +52,8 @@ static int assemble(struct r_asm_t *a, struct r_asm_aop_t *aop, const char *buf)
struct r_asm_handle_t r_asm_plugin_x86_olly = {
.name = "asm_x86_olly",
.desc = "X86 disassembly plugin (olly engine)",
.arch = "x86",
.bits = (int[]){ 32, 0 },
.init = NULL,
.fini = NULL,
.disassemble = &disassemble,

View file

@ -2,24 +2,30 @@
#include <r_bp.h>
int r_bp_init(struct r_bp_t *bp)
R_API int r_bp_init(struct r_bp_t *bp)
{
return R_TRUE;
}
struct r_bp_t *r_bp_new()
R_API struct r_bp_t *r_bp_new()
{
struct r_bp_t *bp = MALLOC_STRUCT(struct r_bpt);
struct r_bp_t *bp = MALLOC_STRUCT(struct r_bp_t);
r_bp_init(bp);
return bp;
}
struct r_bp_t *r_bp_free(struct r_bp_t *bp)
R_API struct r_bp_t *r_bp_free(struct r_bp_t *bp)
{
free(bp);
return NULL;
}
int r_bp_add(struct r_bp_t *bp, u64 addr, int type)
R_API int r_bp_add(struct r_bp_t *bp, u64 addr, int hw, int type)
{
return R_TRUE;
}
R_API int r_bp_list(struct r_bp_t *bp, int rad)
{
return 0;
}

View file

@ -7,6 +7,8 @@
/* inlined APIs */
#define R_INLINE 0
#define DEFAULT_ARCH "x86"
#define R_ASM_STATIC_PLUGINS \
&r_asm_plugin_java, \
&r_asm_plugin_x86_olly, \

View file

@ -107,9 +107,22 @@ R_API struct r_config_node_t *r_config_set_cb(struct r_config_t *cfg, const char
return node;
}
/* TODO: _cb can be a macro */
R_API struct r_config_node_t *r_config_set_i_cb(struct r_config_t *cfg, const char *name, int ivalue, int (*callback)(void *user, void *data))
{
struct r_config_node_t *node = r_config_set_i(cfg, name, ivalue);
node->callback = callback;
if (node->callback)
node->callback(cfg->user, node);
return node;
}
/* TODO: reduce number of strdups here */
R_API struct r_config_node_t *r_config_set(struct r_config_t *cfg, const char *name, const char *value)
{
struct r_config_node_t *node;
char *ov = NULL;
u64 oi;
if (name[0] == '\0')
return NULL;
@ -122,6 +135,10 @@ R_API struct r_config_node_t *r_config_set(struct r_config_t *cfg, const char *n
eprintf("(read only)\n");
return node;
}
oi = node->i_value;
if (node->value)
ov = strdup(node->value);
else node->value = strdup("");
free(node->value);
if (node->flags & CN_BOOL) {
int b = (!strcmp(value,"true")||!strcmp(value,"1"));
@ -153,8 +170,15 @@ R_API struct r_config_node_t *r_config_set(struct r_config_t *cfg, const char *n
}
}
if (node && node->callback)
node->callback(cfg->user, node);
if (node && node->callback) {
int ret = node->callback(cfg->user, node);
if (ret == R_FALSE) {
node->i_value = oi;
free(node->value);
node->value = strdup(ov);
}
}
free(ov);
return node;
}
@ -201,8 +225,13 @@ R_API struct r_config_node_t *r_config_set_i(struct r_config_t *cfg, const char
}
}
if (node && node->callback)
node->callback(cfg->user, node);
if (node && node->callback) {
u64 oi = node->i_value;
int ret = node->callback(cfg->user, node);
if (ret == R_FALSE) {
node->i_value = oi;
}
}
return node;
}

View file

@ -1,5 +1,5 @@
NAME=r_core
DEPS=r_config r_cons r_line r_io r_cmd r_util r_print r_flags r_asm r_lib r_macro r_debug r_hash r_bin r_lang r_io r_asm r_anal r_parse r_config r_macro r_print r_bininfo
DEPS=r_config r_cons r_line r_io r_cmd r_util r_print r_flags r_asm r_lib r_macro r_debug r_hash r_bin r_lang r_io r_asm r_anal r_parse r_config r_macro r_print r_bininfo r_bp
OBJ=core.o cmd.o file.o config.o visual.o io.o yank.o libs.o

View file

@ -24,6 +24,24 @@ static int config_asm_parser_callback(void *user, void *data)
return R_TRUE;
}
static int config_asm_bits_callback(void *user, void *data)
{
struct r_core_t *core = (struct r_core_t *) user;
struct r_config_node_t *node = (struct r_config_node_t *) data;
int ret = r_asm_set_bits(&core->assembler, node->i_value);
if (ret == R_FALSE) {
struct r_asm_handle_t *h = core->assembler.cur;
if (h) {
eprintf("Cannot set bits %d to '%s'\n",
node->i_value, h->name);
} else {
eprintf("No plugins defined yet\n");
ret = R_TRUE;
}
}
return ret;
}
static int config_color_callback(void *user, void *data)
{
struct r_core_t *core = (struct r_core_t *) user;
@ -48,14 +66,13 @@ R_API int r_core_config_init(struct r_core_t *core)
r_config_set_cb(cfg, "asm.arch", "x86",
&config_asm_arch_callback);
r_parse_set(&core->parser, "parse_x86_pseudo");
r_config_set_cb(cfg, "asm.parser", "x86_pseudo",
&config_asm_parser_callback);
r_config_set(cfg, "dir.plugins", LIBDIR"/radare/");
r_config_set(cfg, "asm.syntax", "intel");
r_config_set_i(cfg, "asm.bits", 32);
r_config_set_i_cb(cfg, "asm.bits", 32,
&config_asm_bits_callback);
r_config_set(cfg, "asm.pseudo", "false"); // DEPRECATED ???
r_config_set(cfg, "asm.bytes", "true");
r_config_set(cfg, "asm.offset", "true");

View file

@ -1,6 +1,7 @@
/* radare - LGPL - Copyright 2009 pancake<nopcode.org> */
#include "r_core.h"
#include "../config.h"
static u64 num_callback(void *userptr, const char *str, int *ok)
{
@ -106,8 +107,11 @@ R_API int r_core_init(struct r_core_t *core)
/* load plugins */
r_core_loadlibs(core);
r_asm_set(&core->assembler, "asm_x86"); // XXX WHERE?
r_anal_set(&core->anal, "anal_x86");
/* UH? */
r_asm_set(&core->assembler, "asm_"DEFAULT_ARCH);
r_anal_set(&core->anal, "anal_"DEFAULT_ARCH);
r_config_set(&core->config, "asm.arch", "x86");
r_config_set_i(&core->config, "asm.bits", 32);
return 0;
}

View file

@ -48,6 +48,16 @@ static int r_debug_ptrace_wait(int pid)
return status;
}
static int r_debug_ptrace_bp_write(int pid, u64 addr, int hw, int type)
{
return R_TRUE;
}
static int r_debug_ptrace_bp_read(int pid, u64 addr, int hw, int type)
{
return R_TRUE;
}
#if 0
static int r_debug_ptrace_import(struct r_debug_handle_t *from)
{
@ -64,6 +74,8 @@ static struct r_debug_handle_t r_dbg_plugin_ptrace = {
.attach = &r_debug_ptrace_attach,
.detach = &r_debug_ptrace_detach,
.wait = &r_debug_ptrace_wait,
.bp_write = &r_debug_ptrace_bp_write,
//.bp_read = &r_debug_ptrace_bp_read,
// .import = &r_debug_ptrace_import,
// .export = &r_debug_ptrace_export,
};

View file

@ -1,3 +1,6 @@
include ../../../config-user.mk
include ../../../mk/${COMPILER}.mk
all: test
test:

View file

@ -10,10 +10,11 @@
enum {
R_ANAL_AOP_FAMILY_UNKNOWN = 0,
R_ANAL_AOP_FAMILY_CPU, /* normal cpu insturction */
R_ANAL_AOP_FAMILY_FPU, /* fpu (floating point) */
R_ANAL_AOP_FAMILY_MMX, /* multimedia instruction (packed data) */
R_ANAL_AOP_FAMILY_CPU, /* normal cpu insturction */
R_ANAL_AOP_FAMILY_FPU, /* fpu (floating point) */
R_ANAL_AOP_FAMILY_MMX, /* multimedia instruction (packed data) */
R_ANAL_AOP_FAMILY_PRIV, /* priviledged instruction */
R_ANAL_AOP_FAMILY_LAST
};
enum {
@ -46,7 +47,8 @@ enum {
R_ANAL_AOP_TYPE_XOR,
R_ANAL_AOP_TYPE_NOT,
R_ANAL_AOP_TYPE_STORE, /* store from register to memory */
R_ANAL_AOP_TYPE_LOAD /* load from memory to register */
R_ANAL_AOP_TYPE_LOAD, /* load from memory to register */
R_ANAL_AOP_TYPE_LAST
};
enum {
@ -55,7 +57,8 @@ enum {
R_ANAL_DATA_STR, /* ascii string */
R_ANAL_DATA_CODE, /* plain assembly code */
R_ANAL_DATA_FUN, /* plain assembly code */
R_ANAL_DATA_STRUCT /* memory */
R_ANAL_DATA_STRUCT, /* memory */
R_ANAL_DATA_LAST
};
enum {
@ -77,8 +80,8 @@ enum {
};
enum {
R_ANAL_REFLINE_STYLE = 0x1,
R_ANAL_REFLINE_WIDE = 0x2,
R_ANAL_REFLINE_STYLE = 1,
R_ANAL_REFLINE_WIDE = 2,
};
struct r_anal_refline_t {
@ -102,11 +105,20 @@ struct r_anal_aop_t {
u64 i_dst,i_src1,i_src2; /* inmediate arguments */
};
struct r_anal_ctx_t {
/* TODO: add more info here */
/* per opcode deep level */
/* per opcode stack size */
/* basic blocks */
int stacksize;
};
struct r_anal_t {
int bits;
int big_endian;
u64 pc;
void *user;
struct r_anal_ctx_t *ctx;
struct r_anal_handle_t *cur;
struct list_head anals;
};

View file

@ -36,7 +36,9 @@ struct r_asm_t {
struct r_asm_handle_t {
char *name;
char *arch;
char *desc;
int *bits;
int (*init)(void *user);
int (*fini)(void *user);
int (*disassemble)(struct r_asm_t *a, struct r_asm_aop_t *aop, u8 *buf, u64 len);

20
libr/include/r_bp.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef _INCLUDE_LIBR_BP_H_
#define _INCLUDE_LIBR_BP_H_
#include "r_types.h"
#include "list.h"
struct r_bp_t {
int trace;
int nbps;
struct list_head bps;
};
R_API int r_bp_init(struct r_bp_t *bp);
R_API struct r_bp_t *r_bp_new();
R_API struct r_bp_t *r_bp_free(struct r_bp_t *bp);
R_API int r_bp_add(struct r_bp_t *bp, u64 addr, int hw, int type);
R_API int r_bp_list(struct r_bp_t *bp, int rad);
#endif

View file

@ -43,6 +43,7 @@ R_API void r_config_lock(O, int l);
R_API int r_config_eval(O, const char *str);
R_API struct r_config_node_t *r_config_set_i(O, const char *name, const u64 i);
R_API struct r_config_node_t *r_config_set_cb(struct r_config_t *cfg, const char *name, const char *value, int (*callback)(void *user, void *data));
R_API struct r_config_node_t *r_config_set_i_cb(struct r_config_t *cfg, const char *name, int ivalue, int (*callback)(void *user, void *data));
R_API int r_config_rm(O, const char *name);
R_API struct r_config_node_t *r_config_set(O, const char *name, const char *value);
R_API u64 r_config_get_i(O, const char *name);

View file

@ -4,6 +4,7 @@
#include <r_types.h>
#include <r_util.h>
#include <r_reg.h>
#include <r_bp.h>
#include <r_syscall.h>
#include "list.h"
@ -31,6 +32,8 @@ struct r_debug_handle_t {
int (*cont)(int pid);
int (*wait)(int pid);
int (*contsc)(int pid, int sc);
int (*bp_write)(int pid, u64 addr, int hw, int type);
// XXX bad signature int (*bp_read)(int pid, u64 addr, int hw, int type);
struct list_head list;
};
@ -40,6 +43,7 @@ struct r_debug_t {
int swstep; /* steps with software traps */
int steps; /* counter of steps done */
struct r_reg_t reg;
struct r_bp_t bp;
/* io */
int (*read)(int pid, u64 addr, u8 *buf, int len);
int (*write)(int pid, u64 addr, u8 *buf, int len);