* Add support to ARM for the debugger

- asm.arm plugin is now embedded into r_asm as static plugin
* Added register alias names for r_reg
  - Add register names for x86/32/64/arm
  - pc, sp, bp, a0, a1, a2, a3
* Do not build lua5.1 if no lib found
* Enable cfg.ffio in debug mode
* Some code simplification in r_asm
  - Fix a negative offset bug in elf on ARM binaries
This commit is contained in:
pancake/fluendo 2010-02-03 14:34:00 +01:00
parent f343c4d74f
commit c02ef87ac2
22 changed files with 294 additions and 163 deletions

View File

@ -14,6 +14,7 @@ CHKLIB ewf
ARG_WITHOUT HAVE_EWF ewf disable EWF dependency ;
IF HAVE_EWF { HAVE_LIB_EWF = 0 ; }
CHKLIB lua5.1
CHKLIB tcc
(( rules for the compiler ))

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009 nibble<.ds@gmail.com> */
/* radare - LGPL - Copyright 2009-2010 nibble<.ds@gmail.com> */
#include <stdio.h>
@ -13,16 +13,16 @@ static struct r_asm_handle_t *asm_static_plugins[] =
static int r_asm_pseudo_string(struct r_asm_aop_t *aop, char *input)
{
int len = strlen(input)+1;
r_hex_bin2str((ut8*)input, len, aop->buf_hex);
strncpy((char*)aop->buf, input, R_ASM_BUFSIZE);
int len = strlen (input)+1;
r_hex_bin2str ((ut8*)input, len, aop->buf_hex);
strncpy ((char*)aop->buf, input, R_ASM_BUFSIZE);
return len;
}
static inline int r_asm_pseudo_arch(struct r_asm_t *a, char *input)
{
if (!r_asm_use(a, input)) {
fprintf(stderr, "Error: Unknown plugin\n");
if (!r_asm_use (a, input)) {
eprintf ("Error: Unknown plugin\n");
return -1;
}
return 0;
@ -30,8 +30,8 @@ static inline int r_asm_pseudo_arch(struct r_asm_t *a, char *input)
static inline int r_asm_pseudo_bits(struct r_asm_t *a, char *input)
{
if (!(r_asm_set_bits(a, r_num_math(NULL, input)))) {
fprintf(stderr, "Error: Unsupported bits value\n");
if (!(r_asm_set_bits (a, r_num_math (NULL, input)))) {
eprintf ("Error: Unsupported bits value\n");
return -1;
}
return 0;
@ -39,8 +39,7 @@ static inline int r_asm_pseudo_bits(struct r_asm_t *a, char *input)
static inline int r_asm_pseudo_org(struct r_asm_t *a, char *input)
{
r_asm_set_pc(a, r_num_math(NULL, input));
return 0;
return r_asm_set_pc (a, r_num_math (NULL, input));
}
static inline int r_asm_pseudo_byte(struct r_asm_aop_t *aop, char *input)
@ -52,8 +51,7 @@ static inline int r_asm_pseudo_byte(struct r_asm_aop_t *aop, char *input)
R_API struct r_asm_t *r_asm_new()
{
struct r_asm_t *a = MALLOC_STRUCT(struct r_asm_t);
return r_asm_init(a);
return r_asm_init(MALLOC_STRUCT(struct r_asm_t));
}
R_API void* r_asm_code_free(struct r_asm_code_t *acode)
@ -61,12 +59,12 @@ R_API void* r_asm_code_free(struct r_asm_code_t *acode)
if (!acode)
return NULL;
if (acode->buf)
free(acode->buf);
free (acode->buf);
if (acode->buf_hex)
free(acode->buf_hex);
free (acode->buf_hex);
if (acode->buf_asm)
free(acode->buf_asm);
free(acode);
free (acode->buf_asm);
free (acode);
return NULL;
}
@ -85,7 +83,7 @@ R_API const char *r_asm_fastcall(struct r_asm_t *a, int idx, int num)
if (a && a->cur && a->cur->fastcall)
fastcall = *a->cur->fastcall;
if (fastcall && idx<=num)
for(i=0; 1; i++) {
for (i=0; 1; i++) {
if (i == num) {
ret = fastcall[i].arg[idx];
break;
@ -104,9 +102,9 @@ R_API struct r_asm_t *r_asm_init(struct r_asm_t *a)
a->big_endian = 0;
a->syntax = R_ASM_SYNTAX_INTEL;
a->pc = 0;
INIT_LIST_HEAD(&a->asms);
for(i=0;asm_static_plugins[i];i++)
r_asm_add(a, asm_static_plugins[i]);
INIT_LIST_HEAD (&a->asms);
for (i=0; asm_static_plugins[i]; i++)
r_asm_add (a, asm_static_plugins[i]);
}
return a;
}

View File

@ -180,6 +180,8 @@ ut64 Elf_(r_bin_elf_get_baddr)(struct Elf_(r_bin_elf_obj_t) *bin)
ut64 Elf_(r_bin_elf_get_entry_offset)(struct Elf_(r_bin_elf_obj_t) *bin)
{
if (bin->ehdr.e_entry < bin->baddr)
return bin->ehdr.e_entry;
return bin->ehdr.e_entry - bin->baddr;
}

View File

@ -2,7 +2,7 @@ include ../../config.mk
OBJ=rabin2.o
BIN=rabin2${EXT_EXE}
BINDEPS=r_lib r_bin r_flags r_util
BINDEPS=r_lib r_bin r_flags r_util r_cons
CFLAGS+=-DLIBDIR=\"${PREFIX}/lib\"
LIBS+=${DL_LIBS}

View File

@ -57,22 +57,22 @@ static int rabin_show_help() {
static int rabin_show_entrypoint() {
struct r_bin_entry_t *entry;
char *env;
ut64 baddr = r_bin_get_baddr(bin);
if ((entry = r_bin_get_entry(bin)) == NULL)
ut64 baddr = r_bin_get_baddr (bin);
if ((entry = r_bin_get_entry (bin)) == NULL)
return R_FALSE;
if (rad) {
env = getenv("DEBUG");
if (env == NULL || (env && strncmp(env, "1", 1)))
printf("e io.vaddr=0x%08llx\n", baddr);
printf("fs symbols\n");
printf("f entry @ 0x%08llx\n", baddr+entry->rva);
printf("s entry\n");
env = r_sys_getenv ("DEBUG");
if (env == NULL || (env && strncmp (env, "1", 1)))
printf ("e io.vaddr=0x%08llx\n", baddr);
printf ("fs symbols\n");
printf ("f entry @ 0x%08llx\n", baddr+entry->rva);
printf ("s entry\n");
} else {
printf("[Entrypoint]\n");
printf("address=0x%08llx offset=0x%08llx baddr=0x%08llx\n",
baddr+entry->rva, entry->offset, baddr);
printf ("[Entrypoint]\n");
printf ("address=0x%08llx offset=0x%08llx baddr=0x%08llx\n",
baddr+entry->rva, entry->offset, baddr);
}
free(entry);
free (entry);
return R_TRUE;
}

View File

@ -6,6 +6,3 @@
/* inlined APIs */
#define R_INLINE 0
#define DEFAULT_ARCH "x86"

View File

@ -19,8 +19,11 @@ static int config_cfgffio_callback(void *user, void *data) {
static int config_asm_arch_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;
r_asm_use (&core->assembler, node->value);
// TODO: control error and restore old value (return false?) show errormsg?
int ret = r_asm_use (&core->assembler, node->value);
if (!ret) {
// TODO: control error and restore old value (return false?) show errormsg?
eprintf ("Cannot set this arch (%s)\n", node->value);
}
return R_TRUE;
}

View File

@ -147,6 +147,7 @@ int main(int argc, char **argv)
}
if (debug) {
r_core_cmd (&r, "e cfg.ffio=true", 0);
r_core_cmd (&r, "dh ptrace", 0);
r_core_cmdf (&r, "dp %d", r.file->fd);
r_core_cmd (&r, ".dr*", 0);

View File

@ -4,7 +4,13 @@
#define NPF 6
static int printidx = 0;
#if __arm__
const char *printfmt[] = { "x", "pd", "p8", "pc", "ps", "s sp&&x 64&&dr&&s pc&&pd" };
#elif __x86_64__
const char *printfmt[] = { "x", "pd", "p8", "pc", "ps", "s rsp&&x 64&&dr&&s rip&&pd" };
#else
const char *printfmt[] = { "x", "pd", "p8", "pc", "ps", "s esp&&x 64&&dr&&s eip&&pd" };
#endif
static int curset = 0, cursor = -1, ocursor=-1;
static int color = 1;
@ -593,10 +599,10 @@ R_API int r_core_visual_cmd(struct r_core_t *core, int ch)
r_core_block_size (core, core->blocksize+1);
break;
case '/':
r_core_block_size (core, core->blocksize-=16);
r_core_block_size (core, core->blocksize-16);
break;
case '*':
r_core_block_size (core, core->blocksize+=16);
r_core_block_size (core, core->blocksize+16);
break;
case '>':
r_core_seek_align (core, core->blocksize, 1);

View File

@ -130,7 +130,7 @@ static int r_debug_recoil(struct r_debug_t *dbg) {
int recoil, ret = R_FALSE;
RRegisterItem *ri;
r_debug_reg_sync (dbg, R_REG_TYPE_GPR, R_FALSE);
ri = r_reg_get (dbg->reg, "eip", -1);
ri = r_reg_get (dbg->reg, "eip", -1); // XXX eip is hardcoded here oops
if (ri) {
ut64 addr = r_reg_get_value (dbg->reg, ri);
recoil = r_bp_recoil (dbg->bp, addr);

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009 pancake<nopcode.org> */
/* radare - LGPL - Copyright 2009-2010 pancake<nopcode.org> */
#include <r_userconf.h>
#include <r_debug.h>
@ -16,7 +16,11 @@
#elif __linux__
#include <sys/user.h>
#include <limits.h>
#define R_DEBUG_REG_T struct user_regs_struct
# if __i386__ || __x86_64__
# define R_DEBUG_REG_T struct user_regs_struct
# elif __arm__
# define R_DEBUG_REG_T struct user_regs
# endif
#else
#warning Unsupported debugging platform
#endif
@ -83,6 +87,13 @@ static const char *r_debug_ptrace_reg_profile()
{
#if __i386__
return strdup(
"=pc eip\n"
"=sp esp\n"
"=bp ebp\n"
"=a0 eax\n"
"=a1 ebx\n"
"=a2 ecx\n"
"=a3 edx\n"
"gpr eip .32 48 0\n"
"gpr ip .16 48 0\n"
"gpr oeax .32 44 0\n"
@ -129,17 +140,55 @@ static const char *r_debug_ptrace_reg_profile()
"flg flag_r .1 .457 0\n"
);
#elif __x86_64__
#warning linux-x86-64 register profile is really incomplete
#warning linux-x64 reg profile is incomplete
return strdup (
"=pc rip\n"
"=sp rsp\n"
"=bp rbp\n"
"=a0 rax\n"
"=a1 rbx\n"
"=a2 rcx\n"
"=a3 rdx\n"
"# no profile defined for x86-64\n"
"gpr rbx .32 0 0\n"
"gpr rcx .32 0 8\n"
"gpr rdx .32 0 16\n"
"gpr rsi .32 0 24\n"
"gpr rdi .32 0 32\n"
"gpr rip .32 0 32\n"
"gpr rcx .32 8 0\n"
"gpr rdx .32 16 0\n"
"gpr rsi .32 24 0\n"
"gpr rdi .32 32 0\n"
"gpr rip .32 40 0\n"
);
#elif __arm__
return strdup(
"=pc r15"
"=sp r14" // XXX
"=a0 r0"
"=a1 r1"
"=a2 r2"
"=a3 r3"
"gpr lr .32 56 0\n" // r14
"gpr pc .32 60 0\n" // r15
"gpr r0 .32 0 0\n"
"gpr r1 .32 4 0\n"
"gpr r2 .32 8 0\n"
"gpr r3 .32 12 0\n"
"gpr r4 .32 16 0\n"
"gpr r5 .32 20 0\n"
"gpr r6 .32 24 0\n"
"gpr r7 .32 28 0\n"
"gpr r8 .32 32 0\n"
"gpr r9 .32 36 0\n"
"gpr r10 .32 40 0\n"
"gpr r11 .32 44 0\n"
"gpr r12 .32 48 0\n"
"gpr r13 .32 52 0\n"
"gpr r14 .32 56 0\n"
"gpr r15 .32 60 0\n"
"gpr r16 .32 64 0\n"
"gpr r17 .32 68 0\n"
);
#endif
return NULL;
}
// TODO: what about float and hardware regs here ???
@ -156,21 +205,22 @@ static int r_debug_ptrace_reg_read(struct r_debug_t *dbg, int type, ut8 *buf, in
case R_REG_TYPE_GPR:
{
R_DEBUG_REG_T regs;
memset(&regs, 0, sizeof(regs));
memset(buf, 0, size);
memset (&regs, 0, sizeof (regs));
memset (buf, 0, size);
#if __NetBSD__ || __FreeBSD__ || __OpenBSD__
ret = ptrace (PTRACE_GETREGS, pid, &regs, sizeof (regs));
#elif __linux__ && __powerpc__
ret = ptrace (PTRACE_GETREGS, pid, &regs, NULL);
#else __sun
#else
/* linux/arm/x86/x64 */
ret = ptrace (PTRACE_GETREGS, pid, NULL, &regs);
#endif
if (sizeof(regs) < size)
size = sizeof(regs);
if (ret != 0)
return R_FALSE;
memcpy(buf, &regs, size);
return sizeof(regs);
if (sizeof (regs) < size)
size = sizeof(regs);
memcpy (buf, &regs, size);
return sizeof (regs);
}
break;
//r_reg_set_bytes(reg, &regs, sizeof(struct user_regs));
@ -186,12 +236,10 @@ static int r_debug_ptrace_reg_write(int pid, int type, const ut8* buf, int size)
// XXX use switch or so
if (type == R_REG_TYPE_GPR) {
#if __linux__ || __sun || __NetBSD__ || __FreeBSD__ || __OpenBSD__
ret = ptrace(PTRACE_SETREGS, pid, 0, buf);
if (sizeof(struct user_regs_struct) < size)
size = sizeof(struct user_regs_struct);
if (ret != 0)
return R_FALSE;
return R_TRUE;
ret = ptrace (PTRACE_SETREGS, pid, 0, buf);
if (sizeof (R_DEBUG_REG_T) < size)
size = sizeof (R_DEBUG_REG_T);
return (ret != 0) ? R_FALSE: R_TRUE;
#else
#warning r_debug_ptrace_reg_write not implemented
#endif

View File

@ -6,16 +6,16 @@
int main(int argc, char **argv)
{
int ret;
int ret, i;
int tid, pid;
struct r_io_t *io;
struct r_debug_t *dbg;
io = r_io_new();
printf("Supported IO pluggins:\n");
r_io_handle_list(io);
io = r_io_new ();
printf ("Supported IO pluggins:\n");
r_io_handle_list (io);
ret = r_io_open(io, "dbg:///bin/ls", 0, 0);
ret = r_io_open (io, "dbg:///bin/ls", 0, 0);
// r_io_set_fd(io, ret);
printf("r_io_open dbg:///bin/ls' = %s\n", r_str_bool(ret));
if (!ret) {
@ -26,37 +26,48 @@ int main(int argc, char **argv)
{
/* dump process memory */
ut8 buf[128];
#if __arm__
int ret = r_io_read_at(io, 0x8000, buf, 128);
#else
int ret = r_io_read_at(io, 0x8048000, buf, 128);
printf("%d : %02x\n", ret, buf[0]);
#endif
for (i=0;i<128;i++) {
printf ("%02x ", buf[i]);
if (!((i+1)%16)) printf ("\n");
}
}
dbg = r_debug_new();
dbg = r_debug_new ();
printf("Supported debugger backends:\n");
ret = r_debug_use(dbg, "ptrace");
printf("Using dbg ptrace = %s\n", r_str_bool(ret));
ret = r_debug_use (dbg, "ptrace");
printf ("Using dbg ptrace = %s\n", r_str_bool(ret));
tid = pid = r_io_system(io, "pid");
r_debug_select(dbg, pid, tid);
tid = pid = r_io_system (io, "pid");
eprintf (" My pid is : %d\n", pid);
r_debug_select (dbg, pid, tid);
printf("--> regs pre step\n");
r_io_system(io, "reg");
//printf("--> regs pre step\n");
//r_io_system(io, "reg");
r_debug_reg_sync (dbg, R_REG_TYPE_GPR, 0);
r_debug_reg_list (dbg, R_REG_TYPE_GPR, 32, 0);
printf ("--> perform 2 steps (only 1 probably?)\n");
r_debug_step (dbg, 2);
printf("--> perform 2 steps (only 1 probably?)\n");
r_debug_step(dbg, 2);
// TODO: this is not working :/
r_debug_reg_sync(dbg, R_REG_TYPE_GPR, 0);
r_debug_reg_list(dbg, R_REG_TYPE_GPR, 32, 0);
printf("--> regs post step\n");
r_io_system(io, "reg");
//printf("--> regs post step\n");
//r_io_system(io, "reg");
printf("---\n");
r_debug_continue (dbg);
printf("---\n");
beach:
r_io_free(io);
r_debug_free(dbg);
r_io_free (io);
r_debug_free (dbg);
return 0;
}

View File

@ -17,6 +17,17 @@ enum {
R_REG_TYPE_ALL = -1,
};
enum {
R_REG_NAME_PC,
R_REG_NAME_SP,
R_REG_NAME_BP,
R_REG_NAME_A0,
R_REG_NAME_A1,
R_REG_NAME_A2,
R_REG_NAME_A3,
R_REG_NAME_LAST,
};
typedef struct r_reg_item_t {
char *name;
int type;
@ -40,6 +51,7 @@ typedef struct r_reg_set_t {
typedef struct r_reg_t {
char *profile;
char *name[R_REG_NAME_LAST];
struct r_reg_set_t regset[R_REG_TYPE_LAST];
} RRegister;
@ -52,6 +64,7 @@ R_API struct r_reg_t *r_reg_init(struct r_reg_t *reg);
//R_API struct r_reg_t *r_reg_new();
R_API int r_reg_set_profile_string(struct r_reg_t *reg, const char *profile);
R_API int r_reg_set_profile(struct r_reg_t *reg, const char *profile);
R_API const char *r_reg_get_name(struct r_reg_t *reg, int kind);
R_API struct r_reg_item_t *r_reg_get(struct r_reg_t *reg, const char *name, int type);
R_API struct list_head *r_reg_get_list(struct r_reg_t *reg, int type);
R_API int r_reg_type_by_name(const char *str);

View File

@ -10,6 +10,12 @@
#define IFDBG if (0)
#endif
#if __arm__
#define DEFAULT_ARCH "arm"
#else
#define DEFAULT_ARCH "x86"
#endif
#if R_RTDEBUG
#define IFRTDBG if (getenv("LIBR_DEBUG"))
#else

View File

@ -175,9 +175,6 @@ static int __close(struct r_io_t *io, int pid)
static int __system(struct r_io_t *io, int fd, const char *cmd)
{
//printf("ptrace io command (%s)\n", cmd);
#if __linux__ && ( __i386__ || __x86_64__ )
#include <sys/user.h>
#include <limits.h>
/* XXX ugly hack for testing purposes */
if (!strcmp(cmd, "pid")) {
int pid = atoi(cmd+4);
@ -185,8 +182,12 @@ static int __system(struct r_io_t *io, int fd, const char *cmd)
io->fd = pid;
//printf("PID=%d\n", io->fd);
return io->fd;
#if __linux__ && ( __i386__ || __x86_64__ )
#include <sys/user.h>
#include <limits.h>
} else
if (!strcmp(cmd, "reg")) {
/* this is more deprecated than VAX */
struct user_regs_struct regs;
memset(&regs,0, sizeof(regs));
// TODO: swap 3-4 args in powerpc
@ -217,11 +218,11 @@ static int __system(struct r_io_t *io, int fd, const char *cmd)
io->printf("f eip @ 0x%08x\n", regs.eip);
io->printf("f ebp @ 0x%08x\n", regs.ebp);
io->printf("f esp @ 0x%08x\n", regs.esp);
#endif
#endif
} else {
printf("Try: '|reg' or '|pid'\n");
}
#endif
return R_TRUE;
}

View File

@ -30,9 +30,10 @@ lang_tcc.${EXT_SO}: tcc.o
-${CC} ${CFLAGS} -fPIC -shared -o lang_tcc.${EXT_SO} tcc.c -Wl,-R.. -ldl -ltcc
endif
ifeq ($(HAVE_LIB_LUA5_1),1)
lang_lua.${EXT_SO}: lua.o
-${CC} ${CFLAGS} -fPIC -shared -o lang_lua.${EXT_SO} lua.c -Wl,-R..
@#strip -s lua.so
-${CC} ${CFLAGS} -fPIC -shared -o lang_lua.${EXT_SO} lua.c -Wl,-R.. -llua5.1
endif
lang_ruby.${EXT_SO}:
-env CFLAGS="${CFLAGS}" ruby mkruby.rb

View File

@ -6,6 +6,10 @@
#----------------
# type name size offset packedsize
=pc eip
=sp esp
=bp ebp
gpr eip .32 48 0
gpr oeax .32 44 0
gpr eax .32 24 0

View File

@ -13,15 +13,55 @@ static void r_reg_free_internal(struct r_reg_t *reg) {
struct r_reg_item_t *r;
int i;
for(i=0;i<R_REG_TYPE_LAST;i++) {
list_for_each_safe(pos, n, &reg->regset[i].regs) {
r = list_entry(pos, struct r_reg_item_t, list);
list_del(&r->list);
free(r);
for (i=0;i<R_REG_TYPE_LAST;i++) {
list_for_each_safe (pos, n, &reg->regset[i].regs) {
r = list_entry (pos, struct r_reg_item_t, list);
list_del (&r->list);
free (r);
}
}
}
R_API const char *r_reg_get_name(struct r_reg_t *reg, int role) {
if (role>=0 && role<R_REG_NAME_LAST)
return reg->name[role];
return "";
}
R_API int r_reg_set_name(struct r_reg_t *reg, const char *type, const char *name) {
int ret = R_TRUE;
int role = type[0] + (type[1]<<8);
switch (role) {
case 'p'+('c'<<8):
role = R_REG_NAME_PC;
break;
case 's'+('p'<<8):
role = R_REG_NAME_SP;
break;
case 'b'+('p'<<8):
role = R_REG_NAME_BP;
break;
case 'a'+('0'<<8):
role = R_REG_NAME_A0;
break;
case 'a'+('1'<<8):
role = R_REG_NAME_A1;
break;
case 'a'+('2'<<8):
role = R_REG_NAME_A2;
break;
case 'a'+('3'<<8):
role = R_REG_NAME_A3;
break;
default:
ret = R_FALSE;
break;
}
if (ret)
reg->name[role] = r_str_dup (reg->name[role], name);
return ret;
}
R_API struct r_reg_t *r_reg_free(struct r_reg_t *reg)
{
if (reg) {
@ -36,7 +76,9 @@ R_API struct r_reg_t *r_reg_init(struct r_reg_t *reg)
int i;
if (reg) {
reg->profile = NULL;
for(i=0;i<R_REG_TYPE_LAST;i++) {
for (i=0; i<R_REG_NAME_LAST; i++)
reg->name[i] = NULL;
for (i=0;i<R_REG_TYPE_LAST;i++) {
INIT_LIST_HEAD(&reg->regset[i].arenas);
INIT_LIST_HEAD(&reg->regset[i].regs);
reg->regset[i].arena = MALLOC_STRUCT(struct r_reg_arena_t);
@ -49,9 +91,8 @@ R_API struct r_reg_t *r_reg_init(struct r_reg_t *reg)
}
static struct r_reg_item_t *r_reg_item_new() {
//return MALLOC_STRUCT (rRegisterItem);
struct r_reg_item_t *item = MALLOC_STRUCT(struct r_reg_item_t);
memset(item, 0, sizeof(struct r_reg_item_t));
memset (item, 0, sizeof(struct r_reg_item_t));
return item;
}
@ -73,26 +114,26 @@ static int r_reg_set_word(struct r_reg_item_t *item, int idx, char *word) {
int ret = R_TRUE;
switch(idx) {
case 0:
item->type = r_reg_type_by_name(word);
item->type = r_reg_type_by_name (word);
break;
case 1:
item->name = strdup(word);
item->name = strdup (word);
break;
/* spaguetti ftw!!1 */
case 2:
if (*word=='.') // XXX; this is kinda ugly
item->size = atoi(word+1);
else item->size = atoi(word)*8;
item->size = atoi (word+1);
else item->size = atoi (word)*8;
break;
case 3:
if (*word=='.') // XXX; this is kinda ugly
item->offset = atoi(word+1);
else item->offset = atoi(word)*8;
item->offset = atoi (word+1);
else item->offset = atoi (word)*8;
break;
case 4:
if (*word=='.') // XXX; this is kinda ugly
item->packed_size = atoi(word+1);
else item->packed_size = atoi(word)*8;
item->packed_size = atoi (word+1);
else item->packed_size = atoi (word)*8;
break;
default:
eprintf ("register set fail\n");
@ -105,6 +146,8 @@ static int r_reg_set_word(struct r_reg_item_t *item, int idx, char *word) {
R_API int r_reg_set_profile_string(struct r_reg_t *reg, const char *str)
{
RRegisterItem *item;
int setname = R_FALSE;
char *name = NULL;
int ret = R_FALSE;
int lastchar = 0;
int chidx = 0;
@ -113,42 +156,44 @@ R_API int r_reg_set_profile_string(struct r_reg_t *reg, const char *str)
if (!str)
return R_FALSE;
buf[0]=0;
buf[0] = '\0';
/* format file is: 'type name size offset packedsize' */
r_reg_free_internal(reg);
item = r_reg_item_new();
r_reg_free_internal (reg);
item = r_reg_item_new ();
while(*str) {
while (*str) {
if (*str == '#') {
/* skip until newline */
while(*str && *str != '\n') str++;
while (*str && *str != '\n') str++;
continue;
}
switch(*str) {
switch (*str) {
case ' ':
case '\t':
// UGLY PASTAFARIAN TO PARSE
if (word==0 && *buf=='=') {
setname = R_TRUE;
name = r_str_dup (name, buf+1);
} else
if (lastchar != ' ' && lastchar != '\t') {
r_reg_set_word(item, word, buf);
// printf("WORD %d (%s)\n", word, buf);
chidx = 0;
word++;
r_reg_set_word (item, word, buf);
}
chidx = 0;
word++;
break;
case '\n':
// commit new
//printf("WORD %d (%s)\n", word, buf);
if (setname)
r_reg_set_name (reg, name, buf);
else
if (word>3) {
r_reg_set_word(item, word, buf);
// TODO: add check to ensure that all the fields are defined
// before adding it into the list
r_reg_set_word (item, word, buf);
if (item->name != NULL) {
list_add_tail(&item->list, &reg->regset[item->type].regs);
//printf("ADD REG(%s) type=%d\n", item->name, item->type);
item = r_reg_item_new();
// printf("-----------\n");
}
}
chidx = word = 0;
setname = R_FALSE;
break;
default:
if (chidx > 128) // WTF!!
@ -162,6 +207,7 @@ R_API int r_reg_set_profile_string(struct r_reg_t *reg, const char *str)
}
free (item->name);
free (item);
free (name);
r_reg_fit_arena (reg);
/* do we reach the end ? */
@ -175,7 +221,7 @@ R_API int r_reg_set_profile(struct r_reg_t *reg, const char *profile)
const char *base;
char *str, *file;
/* TODO: append .regs extension to filename */
str = r_file_slurp(profile, NULL);
str = r_file_slurp (profile, NULL);
if (str == NULL) {
// XXX we must define this varname in r_lib.h /compiletime/
base = r_sys_getenv ("LIBR_PLUGINS");
@ -205,7 +251,7 @@ R_API struct r_reg_item_t *r_reg_get(struct r_reg_t *reg, const char *name, int
e = type+1;
}
for(;i<e;i++) {
for (; i<e; i++) {
list_for_each(pos, &reg->regset[i].regs) {
r = list_entry(pos, struct r_reg_item_t, list);
if (!strcmp(r->name, name))
@ -221,15 +267,3 @@ R_API struct list_head *r_reg_get_list(struct r_reg_t *reg, int type)
return NULL;
return &reg->regset[type].regs;
}
/* vala example */
/*
rDebug dbg = new rDebug();
dbg.reg = new rRegister();
foreach (var foo in dbg.reg.get_list(rRegister.Type.GPR)) {
if (foo.size == 32)
stdout.printf("Register %s: 0x%08llx\n",
foo.name, foo.size, dbg.reg.get_value(foo));
}
*/

View File

@ -19,6 +19,8 @@ int main() {
reg = r_reg_new();
r_reg_set_profile(reg, "../p/x86-linux.regs");
printf ("Program counter is named: %s\n", r_reg_get_name (reg, R_REG_NAME_PC));
show_regs(reg, 32);
r_reg_set_value(reg, r_reg_get(reg, "eax", -1), 0x414141);
r_reg_set_value(reg, r_reg_get(reg, "ecx", -1), 666);

View File

@ -50,34 +50,35 @@ R_API int r_reg_set_value(struct r_reg_t *reg, struct r_reg_item_t *item, ut64 v
ut16 v16;
ut8 v8;
ut8 *src;
int ret = R_FALSE;
if (item) {
ret = R_TRUE;
switch(item->size) {
case 64: v64 = (ut64)value; src = (ut8*)&v64; break;
case 32: v32 = (ut32)value; src = (ut8*)&v32; break;
case 16: v16 = (ut16)value; src = (ut8*)&v16; break;
case 8: v8 = (ut8)value; src = (ut8*)&v8; break;
case 1:
if (value) {
ut8 * buf = reg->regset[item->type].arena->bytes + (item->offset/8);
int bit = (item->offset%8);
ut8 mask = (1<<bit);
buf[0] = (buf[0] &(0xff^mask)) | mask;
} else {
ut8 * buf = reg->regset[item->type].arena->bytes + (item->offset/8);
int bit = (item->offset%8);
ut8 mask = 0xff^(1<<bit);
buf[0] = (buf[0] & mask) | 0;
}
break;
default:
printf("set_value : TODO: implement bit level\n");
break;
if (!item)
return R_FALSE;
switch (item->size) {
case 64: v64 = (ut64)value; src = (ut8*)&v64; break;
case 32: v32 = (ut32)value; src = (ut8*)&v32; break;
case 16: v16 = (ut16)value; src = (ut8*)&v16; break;
case 8: v8 = (ut8)value; src = (ut8*)&v8; break;
case 1:
if (value) {
ut8 * buf = reg->regset[item->type].arena->bytes + (item->offset/8);
int bit = (item->offset%8);
ut8 mask = (1<<bit);
buf[0] = (buf[0] &(0xff^mask)) | mask;
} else {
ut8 * buf = reg->regset[item->type].arena->bytes + (item->offset/8);
int bit = (item->offset%8);
ut8 mask = 0xff^(1<<bit);
buf[0] = (buf[0] & mask) | 0;
}
r_mem_copybits(reg->regset[item->type].arena->bytes+BITS2BYTES(item->offset), src, item->size);
break;
default:
eprintf ("set_value : TODO: implement bit level\n");
break;
}
return ret;
r_mem_copybits(reg->regset[item->type].arena->bytes+
BITS2BYTES(item->offset), src, item->size);
return R_TRUE;
}
/* floating point */

View File

@ -28,7 +28,8 @@ R_API const char *r_str_bool(int b)
/* TODO: port to w32 and move outside r_str namespace? */
R_API char *r_str_home(const char *str)
{
const char *dst, *home = r_sys_getenv ("HOME");
char *dst;
const char *home = r_sys_getenv ("HOME");
if (home == NULL)
return NULL;
dst = (char *)malloc (strlen (home) + strlen (str)+2);

View File

@ -1,4 +1,5 @@
STATIC="asm.java
asm.arm
asm.mips
asm.x86_nasm
asm.x86_olly
@ -20,7 +21,7 @@ io.ptrace
parse.dummy
parse.mreplace
parse.x86_pseudo"
SHARED="asm.arm
SHARED="
asm.bf
asm.csr
asm.dummy