mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-31 02:16:53 +00:00
* 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:
parent
f343c4d74f
commit
c02ef87ac2
@ -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 ))
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,3 @@
|
||||
|
||||
/* inlined APIs */
|
||||
#define R_INLINE 0
|
||||
|
||||
#define DEFAULT_ARCH "x86"
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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(®s, 0, sizeof(regs));
|
||||
memset(buf, 0, size);
|
||||
memset (®s, 0, sizeof (regs));
|
||||
memset (buf, 0, size);
|
||||
#if __NetBSD__ || __FreeBSD__ || __OpenBSD__
|
||||
ret = ptrace (PTRACE_GETREGS, pid, ®s, sizeof (regs));
|
||||
#elif __linux__ && __powerpc__
|
||||
ret = ptrace (PTRACE_GETREGS, pid, ®s, NULL);
|
||||
#else __sun
|
||||
#else
|
||||
/* linux/arm/x86/x64 */
|
||||
ret = ptrace (PTRACE_GETREGS, pid, NULL, ®s);
|
||||
#endif
|
||||
if (sizeof(regs) < size)
|
||||
size = sizeof(regs);
|
||||
if (ret != 0)
|
||||
return R_FALSE;
|
||||
memcpy(buf, ®s, size);
|
||||
return sizeof(regs);
|
||||
if (sizeof (regs) < size)
|
||||
size = sizeof(regs);
|
||||
memcpy (buf, ®s, size);
|
||||
return sizeof (regs);
|
||||
}
|
||||
break;
|
||||
//r_reg_set_bytes(reg, ®s, 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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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(®s,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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
128
libr/reg/reg.c
128
libr/reg/reg.c
@ -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, ®->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, ®->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(®->regset[i].arenas);
|
||||
INIT_LIST_HEAD(®->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, ®->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, ®->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 ®->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));
|
||||
}
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user