* Fix x86im code analysis plugin for 64bits

* 'pm' without arguments load magic files from MAGICPATH
* Add alias r_cons_puts () for r_cons_strcat
* Add 'wao' opcode. like the write hack plugin
  - added help for 'wa?'
  - needs refactoring to add support for !x86 archs
  - current supported commands are:
    nop, jz, jnz, un-cjmp, swap-cjmp
This commit is contained in:
pancake 2011-10-11 01:21:38 +02:00
parent 989fdb3dc8
commit f9fe34a2ea
9 changed files with 133 additions and 41 deletions

3
TODO
View File

@ -5,8 +5,7 @@
------8<-------------------8<--------------------8<-----------------8<----------
* Add command to assemble opcodes and files without writing
- wan? wax? wafx?
* 'ao' must be for bytes count, not bytes
====[[ 0.8.6 ]]====
* asm.pseudo for brainfuck

View File

@ -778,6 +778,7 @@ static int x86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
x86im_instr_object io;
st64 imm, disp;
char mnem[256];
int ret;
if (data == NULL)
return 0;
@ -788,9 +789,13 @@ static int x86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
op->jump = op->fail = -1;
op->ref = op->value = -1;
if ((x86im_dec (&io,
anal->bits == 32 ? X86IM_IO_MODE_32BIT : X86IM_IO_MODE_64BIT,
(ut8*)data)) == X86IM_STATUS_SUCCESS) {
ret = -1;
if (anal->bits==64)
ret = (x86im_dec (&io, X86IM_IO_MODE_64BIT, (ut8*)data));
if (ret != X86IM_STATUS_SUCCESS)
ret = (x86im_dec (&io, X86IM_IO_MODE_32BIT, (ut8*)data));
if (ret == X86IM_STATUS_SUCCESS) {
if (io.len > len)
return 0;
x86im_fmt_format_name (&io, mnem);
@ -876,7 +881,6 @@ static int x86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
op->length = io.len;
op->nopcode = io.opcode_count;
}
return op->length;
}
@ -1038,7 +1042,7 @@ struct r_anal_plugin_t r_anal_plugin_x86 = {
.name = "x86",
.desc = "X86 analysis plugin (x86im backend)",
.arch = R_SYS_ARCH_X86,
.bits = 32,
.bits = 32|64,
.init = NULL,
.fini = NULL,
.op = &x86_op,

View File

@ -4,7 +4,7 @@ DEPS=r_config r_cons r_line r_io r_cmd r_util r_print r_flags r_asm r_lib
DEPS+=r_debug r_hash r_bin r_lang r_io r_anal r_parse r_print r_bp r_egg
DEPS+=r_reg r_search r_syscall r_sign r_diff r_socket r_fs r_magic
OBJ=core.o cmd.o file.o config.o visual.o io.o yank.o libs.o
OBJ=core.o cmd.o file.o config.o visual.o io.o yank.o libs.o hack.o
OBJ+=anal.o project.o gdiff.o asm.o rtr.o vmenus.o disasm.o patch.o
CFLAGS+=-DLIBDIR=\"${LIBDIR}\"

View File

@ -1592,13 +1592,15 @@ static void r_core_magic_at(RCore *core, const char *file, ut64 addr, int depth,
// TODO: Move RMagic into RCore
r_magic_free (ck);
ck = r_magic_new (0);
if ((file && *file) && (r_magic_load (ck, MAGICPATH) == -1))
eprintf ("failed r_magic_load ("MAGICPATH") %s\n", r_magic_error (ck));
}
if (file)
if (r_magic_load (ck, file) == -1) {
eprintf ("failed r_magic_load (\"%s\") %s\n", file, r_magic_error (ck));
return;
if (file) {
if (r_magic_load (ck, file) == -1) {
eprintf ("failed r_magic_load (\"%s\") %s\n", file, r_magic_error (ck));
return;
}
} else {
if (r_magic_load (ck, MAGICPATH) == -1)
eprintf ("failed r_magic_load ("MAGICPATH") %s\n", r_magic_error (ck));
}
//if (v) r_cons_printf (" %d # pm %s @ 0x%"PFMT64x"\n", depth, file? file: "", addr);
str = r_magic_buffer (ck, core->block, core->blocksize);
@ -2411,7 +2413,8 @@ static int cmd_anal(void *data, const char *input) {
ret = r_anal_op (core->anal, &op,
core->offset+idx, buf + idx, (len-idx));
if (ret<1) {
eprintf ("Oops at 0x%08"PFMT64x"\n", core->offset+idx);
eprintf ("Oops at 0x%08"PFMT64x" (%02x %02x %02x ...)\n",
core->offset+idx, buf[idx], buf[idx+1], buf[idx+2]);
break;
}
r_cons_printf ("addr: 0x%08"PFMT64x"\n", core->offset+idx);
@ -3022,8 +3025,15 @@ static int cmd_write(void *data, const char *input) {
}
break;
case 'a':
if (input[1]==' '||input[1]=='*') {
const char *file = input[1]=='*'? input+2: input+1;
switch (input[1]) {
case 'o':
if (input[2] == ' ')
r_core_hack (core, input+3);
else r_core_hack_help (core);
break;
case ' ':
case '*':
{ const char *file = input[1]=='*'? input+2: input+1;
RAsmCode *acode;
r_asm_set_pc (core->assembler, core->offset);
acode = r_asm_massemble (core->assembler, file);
@ -3039,25 +3049,37 @@ static int cmd_write(void *data, const char *input) {
}
r_asm_code_free (acode);
}
} else
if (input[1]=='f' && (input[2]==' '||input[2]=='*')) {
const char *file = input[2]=='*'? input+4: input+3;
RAsmCode *acode;
r_asm_set_pc (core->assembler, core->offset);
acode = r_asm_assemble_file (core->assembler, file);
if (acode) {
if (input[2]=='*') {
r_cons_printf ("wx %s\n", acode->buf_hex);
} else {
if (r_config_get_i (core->config, "scr.prompt"))
eprintf ("Written %d bytes (%s)=wx %s\n", acode->len, input+1, acode->buf_hex);
r_core_write_at (core, core->offset, acode->buf, acode->len);
WSEEK (core, acode->len);
r_core_block_read (core, 0);
}
r_asm_code_free (acode);
} else eprintf ("Cannot assemble file\n");
} else eprintf ("Wrong argument\n");
} break;
case 'f':
if ((input[2]==' '||input[2]=='*')) {
const char *file = input[2]=='*'? input+4: input+3;
RAsmCode *acode;
r_asm_set_pc (core->assembler, core->offset);
acode = r_asm_assemble_file (core->assembler, file);
if (acode) {
if (input[2]=='*') {
r_cons_printf ("wx %s\n", acode->buf_hex);
} else {
if (r_config_get_i (core->config, "scr.prompt"))
eprintf ("Written %d bytes (%s)=wx %s\n", acode->len, input+1, acode->buf_hex);
r_core_write_at (core, core->offset, acode->buf, acode->len);
WSEEK (core, acode->len);
r_core_block_read (core, 0);
}
r_asm_code_free (acode);
} else eprintf ("Cannot assemble file\n");
} else eprintf ("Wrong argument\n");
break;
default:
eprintf ("Usage: wa[of*] [arg]\n"
" wa nop : write nopcode using asm.arch and asm.bits\n"
" wa* mov eax, 33 : show 'wx' op with hexpair bytes of sassembled opcode\n"
" \"wa nop;nop\" : assemble more than one instruction (note the quotes)\n"
" waf foo.asm : assemble file and write bytes\n"
" wao nop : convert current opcode into nops\n"
" wao? : show help for assembler operation on current opcode (aka hack)\n");
break;
}
break;
case 'b':
{

65
libr/core/hack.c Normal file
View File

@ -0,0 +1,65 @@
/* radare - LGPL - Copyright 2011 // pancake<nopcode.org> */
#include <r_core.h>
R_API void r_core_hack_help(RCore *core) {
eprintf ("wao [op] ; performs a modification on current opcode\n"
" nop : replace current opcode with\n"
" jz : make current opcode conditional (zero)\n"
" jnz : make current opcode conditional (not zero)\n"
" un-cjmp : remove conditional operation to branch\n"
" swap-cjmp : swap conditional branch\n"
"NOTE: those operations are only implemented for x86 atm. (TODO)\n");
}
// TODO: needs refactoring to make it cross-architecture
R_API int r_core_hack(RCore *core, const char *op) {
ut8 *b = core->block;
RAnalOp analop;
if (!r_anal_op (core->anal, &analop, core->offset, core->block, core->blocksize)) {
eprintf ("anal op fail\n");
return R_FALSE;
}
if (!strcmp (op, "nop")) {
int nopsize = 1; // XXX x86 only
const char *nopcode = "90"; // XXX x86 only
int len = analop.length;
if (len%nopsize) {
eprintf ("Invalid nopcode length\n");
return R_FALSE;
}
r_cons_puts ("wx ");
do r_cons_puts (nopcode);
while (len-=nopsize);
r_cons_puts ("\n");
return R_TRUE;
} else
if (!strcmp (op, "jz")) {
if (b[0] == 0x75) {
r_cons_puts ("wx 74\n");
return R_TRUE;
} else eprintf ("Current opcode is not conditional\n");
} else
if (!strcmp (op, "jnz")) {
if (b[0] == 0x74) {
r_cons_puts ("wx 75\n");
return R_TRUE;
} else eprintf ("Current opcode is not conditional\n");
return R_TRUE;
} else
if (!strcmp (op, "un-cjmp")) {
if (b[0] >= 0x70 && b[0] <= 0x7f) {
r_cons_puts ("wx eb\n");
return R_TRUE;
} else eprintf ("Current opcode is not conditional\n");
} else
if (!strcmp (op, "swap-cjmp")) {
if (b[0] == 0x74)
r_cons_puts ("wx 75\n");
else
if (b[0] == 0x75)
r_cons_puts ("wx 74\n");
else eprintf ("Invalid opcode\n");
// XXX. add support for jb, jg, jl, ..
} else eprintf ("Invalid operation\n");
return R_FALSE;
}

View File

@ -5,9 +5,7 @@
R_API int r_core_write_op(RCore *core, const char *arg, char op) {
char *str;
ut8 *buf;
int i,j;
int ret;
int len;
int i, j, ret, len;
// XXX we can work with config.block instead of dupping it
buf = (ut8 *)malloc (core->blocksize);

View File

@ -186,6 +186,7 @@ R_API void r_cons_set_raw(int b);
/* output */
R_API void r_cons_printf(const char *format, ...);
R_API void r_cons_strcat(const char *str);
#define r_cons_puts(x) r_cons_strcat(x)
R_API void r_cons_strcat_justify (const char *str, int j, char c);
R_API void r_cons_memcat(const char *str, int len);
R_API void r_cons_newline();

View File

@ -240,6 +240,9 @@ R_API int r_core_search_prelude(RCore *core, ut64 from, ut64 to, const ut8 *buf,
R_API int r_core_patch (RCore *core, const char *patch);
R_API void r_core_hack_help(RCore *core);
R_API int r_core_hack(RCore *core, const char *op);
#endif
#endif

View File

@ -211,7 +211,6 @@ const char *file_getbuffer(RMagic *ms) {
if (ms->haderr)
return NULL;
if (ms->flags & R_MAGIC_RAW)
return ms->o.buf;
@ -233,7 +232,8 @@ const char *file_getbuffer(RMagic *ms) {
}
ms->o.pbuf = pbuf;
#if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
#if 1
//defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
{
mbstate_t state;
wchar_t nextchar;