From f5bf177c6051f40032f581a2a47bdae1cc529b4b Mon Sep 17 00:00:00 2001 From: pancake Date: Fri, 9 Apr 2010 00:52:38 +0200 Subject: [PATCH] * Implement r_asm_modify - wA command is used to Alter opcodes (move to r_anal?) - allows to modify various opcode instructions * Add search.distance config variable --- libr/asm/asm.c | 7 ++++++ libr/asm/p/asm_x86.c | 53 ++++++++++++++++++++++++++++++++++---------- libr/core/cmd.c | 40 +++++++++++++++++++++++++++++++-- libr/core/config.c | 1 + libr/include/r_asm.h | 50 +++++++++++++++++++++++++---------------- 5 files changed, 118 insertions(+), 33 deletions(-) diff --git a/libr/asm/asm.c b/libr/asm/asm.c index 44fd82370a..b4a9022b67 100644 --- a/libr/asm/asm.c +++ b/libr/asm/asm.c @@ -377,3 +377,10 @@ R_API struct r_asm_code_t* r_asm_massemble(struct r_asm_t *a, const char *buf) { } return acode; } + +R_API int r_asm_modify(RAsm *a, ut8 *buf, int field, ut64 val) { + int ret = R_FALSE; + if (a->cur && a->cur->modify) + ret = a->cur->modify (a, buf, field, val); + return ret; +} diff --git a/libr/asm/p/asm_x86.c b/libr/asm/p/asm_x86.c index e65f55a63f..8669da7080 100644 --- a/libr/asm/p/asm_x86.c +++ b/libr/asm/p/asm_x86.c @@ -1,4 +1,4 @@ -/* radare - LGPL - Copyright 2009 nibble<.ds@gmail.com> */ +/* radare - LGPL - Copyright 2009-2010 nibble<.ds@gmail.com> */ #include #include @@ -9,20 +9,48 @@ #include "x86/udis86/types.h" #include "x86/udis86/extern.h" -static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, ut8 *buf, ut64 len) { +// TODO : split into get/set... we need a way to create binary masks from asm buffers +// -- move this shit into r_anal.. ?? +// -- delta, size, mode.. mode is for a->pc-5, register handling and things like this +static int modify(RAsm *a, ut8 *buf, int field, ut64 val) { + ut32 val32 = (ut32)val; + int ret = R_FALSE; + + switch (buf[0]) { + case 0x68: // push dword + if (field == R_ASM_MOD_RAWVALUE || field == R_ASM_MOD_VALUE) { + memcpy (buf+1, &val, sizeof (val32)); + } + return 5; + case 0xe8: // call + if (field == R_ASM_MOD_RAWVALUE) { + memcpy (buf+1, &val32, sizeof (val32)); + } else + if (field == R_ASM_MOD_VALUE) { + val32 = (ut32)(val-a->pc-5); + memcpy (buf+1, &val32, sizeof (val32)); + } + return 5; + case 0x73: // jnz + buf[1] = (char)(val-a->pc); + return 2; + } + return ret; +} + +static int disassemble(RAsm *a, RAsmAop *aop, ut8 *buf, ut64 len) { static ud_t disasm_obj; - ud_init(&disasm_obj); + ud_init (&disasm_obj); if (a->syntax == R_ASM_SYNTAX_ATT) - ud_set_syntax(&disasm_obj, UD_SYN_ATT); - else - ud_set_syntax(&disasm_obj, UD_SYN_INTEL); - ud_set_mode(&disasm_obj, a->bits); - ud_set_pc(&disasm_obj, a->pc); - ud_set_input_buffer(&disasm_obj, buf, len); - ud_disassemble(&disasm_obj); - aop->inst_len = ud_insn_len(&disasm_obj); - snprintf(aop->buf_asm, R_ASM_BUFSIZE, "%s", ud_insn_asm(&disasm_obj)); + ud_set_syntax (&disasm_obj, UD_SYN_ATT); + else ud_set_syntax (&disasm_obj, UD_SYN_INTEL); + ud_set_mode (&disasm_obj, a->bits); + ud_set_pc (&disasm_obj, a->pc); + ud_set_input_buffer (&disasm_obj, buf, len); + ud_disassemble (&disasm_obj); + aop->inst_len = ud_insn_len (&disasm_obj); + snprintf (aop->buf_asm, R_ASM_BUFSIZE, "%s", ud_insn_asm (&disasm_obj)); return aop->inst_len; } @@ -35,6 +63,7 @@ struct r_asm_handle_t r_asm_plugin_x86 = { .init = NULL, .fini = NULL, .disassemble = &disassemble, + .modify = &modify, .assemble = NULL, .fastcall = fastcall, }; diff --git a/libr/core/cmd.c b/libr/core/cmd.c index ff795ba0a9..85506ffb8a 100644 --- a/libr/core/cmd.c +++ b/libr/core/cmd.c @@ -1434,6 +1434,33 @@ static int cmd_write(void *data, const char *input) { RCore *core = (RCore *)data; memcpy (str, input+1, len); switch (input[0]) { + case 'A': + switch (input[1]) { + case ' ': + if (input[2]&&input[3]==' ') { + r_asm_set_pc (&core->assembler, core->offset); + eprintf ("modify (%c)=%s\n", input[2], input+4); + len = r_asm_modify (&core->assembler, core->block, input[2], + r_num_math (&core->num, input+4)); + eprintf ("len=%d\n", len); + if (len>0) + r_core_write_at (core, core->offset, core->block, len); + else eprintf ("r_asm_modify = %d\n", len); + } else eprintf ("Usage: wA [type] [value]\n"); + break; + case '?': + default: + r_cons_printf ("Usage: wA [type] [value]\n" + "Types:\n" + " r raw write value\n" + " v set value (taking care of current address)\n" + " d destination register\n" + " 0 1st src register \n" + " 1 2nd src register\n" + "Example: wA r 0 # e800000000\n"); + break; + } + break; case 'c': switch (input[1]) { case 'i': @@ -1645,17 +1672,18 @@ static int cmd_write(void *data, const char *input) { r_io_set_fd (&core->io, core->file->fd); r_io_write (&core->io, core->oobi, core->oobi_len); } else - r_cons_printf( + r_cons_printf ( "Usage: w[x] [str] [search); core->search = r_search_new (R_SEARCH_KEYWORD); + r_search_set_distance (core->search, (int) + r_config_get_i (&core->config, "search.distance")); n32 = r_num_math (&core->num, input+1); r_search_kw_add (core->search, r_search_keyword_new ((const ut8*)&n32, 4, NULL, 0, NULL)); @@ -1706,6 +1736,8 @@ static int cmd_search(void *data, const char *input) { case ' ': /* search string */ r_search_free(core->search); core->search = r_search_new (R_SEARCH_KEYWORD); + r_search_set_distance (core->search, (int) + r_config_get_i (&core->config, "search.distance")); r_search_kw_add (core->search, r_search_keyword_new_str (input+1, "", NULL)); r_search_begin (core->search); @@ -1722,6 +1754,8 @@ static int cmd_search(void *data, const char *input) { } r_search_free (core->search); core->search = r_search_new (R_SEARCH_REGEXP); + r_search_set_distance (core->search, (int) + r_config_get_i (&core->config, "search.distance")); r_search_kw_add (core->search, r_search_keyword_new_str (inp, opt, NULL)); r_search_begin (core->search); @@ -1733,6 +1767,8 @@ static int cmd_search(void *data, const char *input) { case 'x': /* search hex */ r_search_free (core->search); core->search = r_search_new (R_SEARCH_KEYWORD); + r_search_set_distance (core->search, (int) + r_config_get_i (&core->config, "search.distance")); r_search_kw_add (core->search, r_search_keyword_new_hexmask (input+2, NULL)); r_search_begin (core->search); diff --git a/libr/core/config.c b/libr/core/config.c index fad2bb0083..2eecd5f51f 100644 --- a/libr/core/config.c +++ b/libr/core/config.c @@ -181,6 +181,7 @@ R_API int r_core_config_init(RCore *core) { (core->print.flags&R_PRINT_FLAGS_COLOR)?"true":"false", &config_color_callback); r_config_set (cfg, "scr.seek", ""); + r_config_set_i (cfg, "search.distance", 0); r_config_set_cb (cfg, "scr.html", "false", &config_scrhtml_callback); r_config_set_cb (cfg, "io.ffio", "false", &config_ioffio_callback); r_config_set_cb (cfg, "io.va", "false", &config_iova_callback); diff --git a/libr/include/r_asm.h b/libr/include/r_asm.h index 4089781d95..ac6221848b 100644 --- a/libr/include/r_asm.h +++ b/libr/include/r_asm.h @@ -31,6 +31,14 @@ enum { R_ASM_SYNTAX_ATT }; +enum { + R_ASM_MOD_RAWVALUE = 'r', + R_ASM_MOD_VALUE = 'v', + R_ASM_MOD_DSTREG = 'd', + R_ASM_MOD_SRCREG0 = '0', + R_ASM_MOD_SRCREG1 = '1' +}; + typedef struct r_asm_fastcall_t { const char *arg[16]; } RAsmFastcall; @@ -68,6 +76,8 @@ typedef struct r_asm_t { struct list_head asms; } RAsm; +typedef int (*RAsmModifyCallback)(RAsm *a, ut8 *buf, int field, ut64 val); + // TODO: rename to handler? typedef struct r_asm_handle_t { char *name; @@ -78,33 +88,35 @@ typedef struct r_asm_handle_t { int *bits; int (*init)(void *user); int (*fini)(void *user); - int (*disassemble)(struct r_asm_t *a, struct r_asm_aop_t *aop, ut8 *buf, ut64 len); - int (*assemble)(struct r_asm_t *a, struct r_asm_aop_t *aop, const char *buf); - int (*set_subarch)(struct r_asm_t *a, const char *buf); + int (*disassemble)(RAsm *a, struct r_asm_aop_t *aop, ut8 *buf, ut64 len); + int (*assemble)(RAsm *a, struct r_asm_aop_t *aop, const char *buf); + RAsmModifyCallback modify; + int (*set_subarch)(RAsm *a, const char *buf); struct r_asm_fastcall_t *fastcall[R_ASM_FASTCALL_ARGS]; struct list_head list; } RAsmHandle; #ifdef R_API /* asm.c */ -R_API struct r_asm_t *r_asm_new(); -R_API const char *r_asm_fastcall(struct r_asm_t *a, int idx, int num); +R_API RAsm *r_asm_new(); +R_API const char *r_asm_fastcall(RAsm *a, int idx, int num); -R_API void r_asm_free(struct r_asm_t *a); +R_API void r_asm_free(RAsm *a); R_API void* r_asm_code_free(struct r_asm_code_t *acode); -R_API struct r_asm_t *r_asm_init(struct r_asm_t *a); -R_API void r_asm_set_user_ptr(struct r_asm_t *a, void *user); -R_API int r_asm_add(struct r_asm_t *a, struct r_asm_handle_t *foo); -R_API int r_asm_list(struct r_asm_t *a); -R_API int r_asm_use(struct r_asm_t *a, const char *name); -R_API int r_asm_set_bits(struct r_asm_t *a, int bits); -R_API int r_asm_set_big_endian(struct r_asm_t *a, int boolean); -R_API int r_asm_set_syntax(struct r_asm_t *a, int syntax); -R_API int r_asm_set_pc(struct r_asm_t *a, ut64 pc); -R_API int r_asm_disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, ut8 *buf, ut64 len); -R_API int r_asm_assemble(struct r_asm_t *a, struct r_asm_aop_t *aop, const char *buf); -R_API struct r_asm_code_t* r_asm_mdisassemble(struct r_asm_t *a, ut8 *buf, ut64 len); -R_API struct r_asm_code_t* r_asm_massemble(struct r_asm_t *a, const char *buf); +R_API RAsm *r_asm_init(RAsm *a); +R_API int r_asm_modify(RAsm *a, ut8 *buf, int field, ut64 val); +R_API void r_asm_set_user_ptr(RAsm *a, void *user); +R_API int r_asm_add(RAsm *a, struct r_asm_handle_t *foo); +R_API int r_asm_list(RAsm *a); +R_API int r_asm_use(RAsm *a, const char *name); +R_API int r_asm_set_bits(RAsm *a, int bits); +R_API int r_asm_set_big_endian(RAsm *a, int boolean); +R_API int r_asm_set_syntax(RAsm *a, int syntax); +R_API int r_asm_set_pc(RAsm *a, ut64 pc); +R_API int r_asm_disassemble(RAsm *a, struct r_asm_aop_t *aop, ut8 *buf, ut64 len); +R_API int r_asm_assemble(RAsm *a, struct r_asm_aop_t *aop, const char *buf); +R_API struct r_asm_code_t* r_asm_mdisassemble(RAsm *a, ut8 *buf, ut64 len); +R_API struct r_asm_code_t* r_asm_massemble(RAsm *a, const char *buf); /* code.c */ R_API RAsmCode *r_asm_code_new();