mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-27 23:20:40 +00:00
* 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:
parent
f499ca67e7
commit
f5bf177c60
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user