mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-15 01:10:01 +00:00
098b1ba127
- Experimental.. not yet ready for release - Add rasm2 -F flag to specify input and output filters $ rasm2 -F att2intel * Add new att2intel r_parse plugin - make mrproper required * Initial implementation of RBinClass - Only experimental and Java-specific atm - Add rabin2 -C to display classes * Optimize some r_str functions
266 lines
6.5 KiB
C
266 lines
6.5 KiB
C
/* radare - LGPL - Copyright 2009-2011 nibble<.ds@gmail.com> */
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <getopt.h>
|
|
|
|
#include <r_types.h>
|
|
#include <r_asm.h>
|
|
#include <r_util.h>
|
|
#include <r_lib.h>
|
|
|
|
static struct r_lib_t *l;
|
|
static struct r_asm_t *a;
|
|
static int coutput = R_FALSE;
|
|
|
|
static void r_asm_list(RAsm *a) {
|
|
RAsmPlugin *h;
|
|
RListIter *iter;
|
|
r_list_foreach (a->plugins, iter, h)
|
|
printf ("asm %-10s\t %s\n", h->name, h->desc);
|
|
}
|
|
|
|
static int rasm_show_help() {
|
|
printf ("rasm2 [-e] [-o offset] [-a arch] [-s syntax] -d \"opcode\"|\"hexpairs\"|- [-f file ..]\n"
|
|
" -d Disassemble from hexpair bytes\n"
|
|
" -f Read data from file\n"
|
|
" -F [in:out] Specify input and/or output filters (att2intel, x86.pseudo, ...)\n"
|
|
" -o [offset] Offset where this opcode is suposed to be\n"
|
|
" -a [arch] Set architecture plugin\n"
|
|
" -b [bits] Set architecture bits\n"
|
|
" -s [syntax] Select syntax (intel, att)\n"
|
|
" -B Binary input/output (-l is mandatory for binary input)\n"
|
|
" -l [int] Input/Output length\n"
|
|
" -C Output in C format\n"
|
|
" -L List supported asm plugins\n"
|
|
" -e Use big endian\n"
|
|
" -v Show version information\n"
|
|
" If '-l' value is greater than output length, output is padded with nops\n"
|
|
" If the last argument is '-' reads from stdin\n");
|
|
return 0;
|
|
}
|
|
|
|
static int rasm_disasm(char *buf, ut64 offset, ut64 len, int ascii, int bin) {
|
|
struct r_asm_code_t *acode;
|
|
ut8 *data;
|
|
char *ptr = buf;
|
|
int ret = 0;
|
|
ut64 word = 0, clen = 0;
|
|
|
|
if (bin) {
|
|
clen = len; // XXX
|
|
data = (ut8*)buf;
|
|
} else if (ascii) {
|
|
clen = strlen (buf);
|
|
data = (ut8*)buf;
|
|
} else {
|
|
for (; *ptr; ptr++)
|
|
if (*ptr!=' ' && *ptr!='\n' && *ptr!='\r')
|
|
if (!(++word%2)) clen++;
|
|
data = alloca (clen);
|
|
if (r_hex_str2bin (buf, data)==-1)
|
|
return 0;
|
|
}
|
|
|
|
if (!len || clen <= len)
|
|
len = clen;
|
|
|
|
r_asm_set_pc (a, offset);
|
|
if (!(acode = r_asm_mdisassemble (a, data, len)))
|
|
return 0;
|
|
|
|
printf ("%s\n", acode->buf_asm);
|
|
ret = acode->len;
|
|
r_asm_code_free (acode);
|
|
return ret;
|
|
}
|
|
|
|
static void print_buf(char *str) {
|
|
int i;
|
|
if (coutput) {
|
|
printf ("\"");
|
|
for (i=1; *str; str+=2, i+=2) {
|
|
if (!(i%41)) {
|
|
printf ("\" \\\n\"");
|
|
i=1;
|
|
}
|
|
printf ("\\x%c%c", *str, str[1]);
|
|
}
|
|
printf ("\"\n");
|
|
} else printf ("%s\n", str);
|
|
}
|
|
|
|
static int rasm_asm(char *buf, ut64 offset, ut64 len, int bin) {
|
|
struct r_asm_code_t *acode;
|
|
struct r_asm_op_t op;
|
|
int ret, idx, i;
|
|
|
|
r_asm_set_pc (a, offset);
|
|
if (!(acode = r_asm_massemble (a, buf)))
|
|
return 0;
|
|
if (bin)
|
|
for (i = 0; i < acode->len; i++)
|
|
printf ("%c", acode->buf[i]);
|
|
else print_buf (acode->buf_hex);
|
|
for (ret = 0, idx = acode->len; idx < len; idx+=ret) {
|
|
if (!(ret = r_asm_assemble (a, &op, "nop")))
|
|
return 0;
|
|
if (bin)
|
|
for (i = 0; i < ret; i++)
|
|
printf ("%c", op.buf[i]);
|
|
else print_buf (op.buf_hex);
|
|
}
|
|
if (!bin && len && idx == len) printf ("\n");
|
|
r_asm_code_free (acode);
|
|
return idx;
|
|
}
|
|
|
|
/* asm callback */
|
|
static int __lib_asm_cb(struct r_lib_plugin_t *pl, void *user, void *data) {
|
|
RAsmPlugin *hand = (struct r_asm_plugin_t *)data;
|
|
r_asm_add (a, hand);
|
|
return R_TRUE;
|
|
}
|
|
static int __lib_asm_dt(struct r_lib_plugin_t *pl, void *p, void *u) { return R_TRUE; }
|
|
|
|
int main(int argc, char *argv[]) {
|
|
char *arch = NULL, *file = NULL, *filters = NULL;
|
|
ut64 offset = 0x8048000;
|
|
int dis = 0, ascii = 0, bin = 0, ret = 0, bits = 32, c;
|
|
ut64 len = 0, idx = 0;
|
|
|
|
a = r_asm_new ();
|
|
l = r_lib_new ("radare_plugin");
|
|
r_lib_add_handler (l, R_LIB_TYPE_ASM, "(dis)assembly plugins",
|
|
&__lib_asm_cb, &__lib_asm_dt, NULL);
|
|
r_lib_opendir (l, r_sys_getenv ("LIBR_PLUGINS"));
|
|
|
|
if (argc<2)
|
|
return rasm_show_help ();
|
|
|
|
r_asm_use (a, "x86"); // XXX: do not harcode default arch
|
|
while ((c = getopt (argc, argv, "Ceva:b:s:do:Bl:hLf:F:")) != -1) {
|
|
switch (c) {
|
|
case 'f':
|
|
file = optarg;
|
|
break;
|
|
case 'F':
|
|
filters = optarg;
|
|
break;
|
|
case 'C':
|
|
coutput = R_TRUE;
|
|
break;
|
|
case 'a':
|
|
arch = optarg;
|
|
break;
|
|
case 'b':
|
|
bits = r_num_math (NULL, optarg);
|
|
break;
|
|
case 's':
|
|
if (!strcmp (optarg, "att"))
|
|
r_asm_set_syntax (a, R_ASM_SYNTAX_ATT);
|
|
else r_asm_set_syntax (a, R_ASM_SYNTAX_INTEL);
|
|
break;
|
|
case 'd':
|
|
dis = 1;
|
|
break;
|
|
case 'o':
|
|
offset = r_num_math (NULL, optarg);
|
|
break;
|
|
case 'B':
|
|
bin = 1;
|
|
break;
|
|
case 'l':
|
|
len = r_num_math (NULL, optarg);
|
|
break;
|
|
case 'L':
|
|
r_asm_list (a);
|
|
exit (1);
|
|
case 'e':
|
|
r_asm_set_big_endian (a, R_TRUE);
|
|
break;
|
|
case 'v':
|
|
printf ("rasm2 v"R2_VERSION"\n");
|
|
return 0;
|
|
case 'h':
|
|
return rasm_show_help ();
|
|
}
|
|
}
|
|
|
|
if (arch) {
|
|
if (!r_asm_use (a, arch)) {
|
|
eprintf ("Error: Unknown asm plugin '%s'\n", arch);
|
|
return 0;
|
|
}
|
|
if (!strcmp (arch, "bf"))
|
|
ascii = 1;
|
|
} else if (!r_asm_use (a, "x86")) {
|
|
eprintf ("Error: Cannot find asm.x86 plugin\n");
|
|
return 0;
|
|
}
|
|
if (!r_asm_set_bits (a, bits))
|
|
eprintf ("WARNING: cannot set asm backend to %d bits\n", bits);
|
|
|
|
if (filters) {
|
|
char *p = strchr (filters, ':');
|
|
if (p) {
|
|
*p = 0;
|
|
if (*filters) r_asm_filter_input (a, filters);
|
|
if (p[1]) r_asm_filter_output (a, p+1);
|
|
*p = ':';
|
|
} else {
|
|
if (dis) r_asm_filter_output (a, filters);
|
|
else r_asm_filter_input (a, filters);
|
|
}
|
|
}
|
|
|
|
if (file) {
|
|
char *content;
|
|
int length;
|
|
if (!strcmp (file, "-")) {
|
|
char buf[R_ASM_BUFSIZE]; // TODO: Fix this limitation
|
|
ret = fread (buf, 1, sizeof (buf)-1, stdin);
|
|
if (ret == R_ASM_BUFSIZE)
|
|
eprintf ("WARNING: Cannot slurp more from stdin\n");
|
|
if (ret>=0)
|
|
buf[ret] = '\0';
|
|
if (dis) ret = rasm_disasm (buf, offset, len, ascii, bin);
|
|
else ret = rasm_asm (buf, offset, len, bin);
|
|
} else {
|
|
content = r_file_slurp (file, &length);
|
|
if (content) {
|
|
content[length] = '\0';
|
|
if (dis) ret = rasm_disasm (content, offset, len, ascii, bin);
|
|
else ret = rasm_asm (content, offset, len, bin);
|
|
free (content);
|
|
} else eprintf ("Cannot open file %s\n", file);
|
|
}
|
|
} else if (argv[optind]) {
|
|
if (!strcmp (argv[optind], "-")) {
|
|
char buf[R_ASM_BUFSIZE];
|
|
for (;;) {
|
|
fgets (buf, sizeof (buf)-1, stdin);
|
|
if ((!bin || !dis) && feof (stdin))
|
|
break;
|
|
if (!bin || !dis) buf[strlen (buf)-1]='\0';
|
|
if (dis) ret = rasm_disasm (buf, offset, len, ascii, bin);
|
|
else ret = rasm_asm (buf, offset, len, bin);
|
|
idx += ret;
|
|
offset += ret;
|
|
if (!ret) {
|
|
eprintf ("invalid\n");
|
|
return 0;
|
|
}
|
|
if (len && idx >= len)
|
|
break;
|
|
}
|
|
return idx;
|
|
}
|
|
if (dis) ret = rasm_disasm (argv[optind], offset, len, ascii, bin);
|
|
else ret = rasm_asm (argv[optind], offset, len, bin);
|
|
if (!ret) eprintf ("invalid\n");
|
|
return ret;
|
|
}
|
|
return 0;
|
|
}
|