* 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
This commit is contained in:
pancake 2010-04-09 00:52:38 +02:00
parent f499ca67e7
commit f5bf177c60
5 changed files with 118 additions and 33 deletions

View File

@ -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;
}

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>
#include <string.h>
@ -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,
};

View File

@ -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] [<file] [<<EOF] [@addr]\n"
" w foobar write string 'foobar'\n"
" ww foobar write wide string 'f\\x00o\\x00o\\x00b\\x00a\\x00r\\x00'\n"
" wa push ebp write opcode, separated by ';' (use '\"' around the command)\n"
" wA r 0 alter/modify opcode at current seek (see wA?)\n"
" wb 010203 fill current block with cyclic hexpairs\n"
" wc[ir*?] write cache commit/reset/list\n"
" wx 9090 write two intel nops\n"
" wv eip+34 write 32-64 bit value\n"
" wo[] hex write in block with operation. 'wo?' fmi\n"
" wm f0ff cyclic write mask\n"
" wm f0ff set binary mask hexpair to be used as cyclic write mask\n"
" wf file write contents of file at current offset\n"
" wF file write contents of hexpairs file here\n"
" wt file write current block to file\n");
@ -1697,6 +1725,8 @@ static int cmd_search(void *data, const char *input) {
case 'v':
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"));
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);

View File

@ -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);

View File

@ -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();