2009-02-05 22:08:46 +01:00
|
|
|
/* radare - LGPL - Copyright 2009 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>
|
2009-02-18 03:47:40 +01:00
|
|
|
#include <r_lib.h>
|
|
|
|
|
|
|
|
|
|
|
|
static struct r_lib_t l;
|
|
|
|
static struct r_asm_t a;
|
2009-02-05 22:08:46 +01:00
|
|
|
|
|
|
|
static int rasm_show_help()
|
|
|
|
{
|
2009-03-08 23:49:15 +00:00
|
|
|
printf ("rasm2 [-e] [-o offset] [-a arch] [-s syntax] -d \"opcode\"|\"hexpairs\"|-\n"
|
|
|
|
" -d Disassemble from hexpair bytes\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"
|
2009-04-05 16:02:17 +02:00
|
|
|
" -B Binary input/output (-l is mandatory for binary input)\n"
|
|
|
|
" -l [int] input/output length\n"
|
2009-04-11 21:24:37 +00:00
|
|
|
" -L list supported asm plugins\n"
|
2009-03-08 23:49:15 +00:00
|
|
|
" -e Use big endian\n"
|
2009-04-05 16:02:17 +02:00
|
|
|
" If '-l' value is greater than output length, output is padded with nops\n"
|
2009-04-12 23:10:22 +00:00
|
|
|
" If the last argument is '-' reads from stdin\n");
|
|
|
|
//r_asm_list(&a);
|
2009-02-05 22:08:46 +01:00
|
|
|
return R_TRUE;
|
|
|
|
}
|
|
|
|
|
2009-04-05 15:23:36 +02:00
|
|
|
static int rasm_disasm(char *buf, u64 offset, u64 len, int ascii, int bin)
|
2009-02-05 22:08:46 +01:00
|
|
|
{
|
2009-02-18 03:47:40 +01:00
|
|
|
struct r_asm_aop_t aop;
|
2009-02-05 22:08:46 +01:00
|
|
|
u8 *data;
|
|
|
|
char *ptr = buf;
|
|
|
|
int ret = 0;
|
2009-04-05 15:23:36 +02:00
|
|
|
u64 idx, word = 0, clen = 0;
|
2009-02-05 22:08:46 +01:00
|
|
|
|
2009-04-05 15:23:36 +02:00
|
|
|
if (bin) {
|
|
|
|
clen = len; //XXX
|
|
|
|
data = (u8*)buf;
|
|
|
|
} else if (ascii) {
|
|
|
|
clen = strlen(buf);
|
|
|
|
data = (u8*)buf;
|
|
|
|
} else {
|
2009-02-18 13:59:57 +01:00
|
|
|
while(ptr[0]) {
|
|
|
|
if (ptr[0]!= ' ')
|
2009-04-05 15:23:36 +02:00
|
|
|
if (0==(++word%2))clen++;
|
2009-02-18 13:59:57 +01:00
|
|
|
ptr += 1;
|
|
|
|
}
|
2009-04-05 15:23:36 +02:00
|
|
|
data = alloca(clen);
|
2009-02-18 13:59:57 +01:00
|
|
|
r_hex_str2bin(buf, data);
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|
|
|
|
|
2009-04-05 15:23:36 +02:00
|
|
|
if (!len || clen <= len)
|
|
|
|
len = clen;
|
|
|
|
|
|
|
|
|
|
|
|
for(idx=ret=0; idx < len; idx+=ret) {
|
2009-02-19 14:24:51 +01:00
|
|
|
r_asm_set_pc(&a, offset + idx);
|
2009-04-05 15:23:36 +02:00
|
|
|
if (!(ret = r_asm_disassemble(&a, &aop, data+idx, len-idx)))
|
|
|
|
return 0;
|
2009-02-18 03:47:40 +01:00
|
|
|
printf("%s\n", aop.buf_asm);
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return (int)idx;
|
|
|
|
}
|
|
|
|
|
2009-04-05 15:23:36 +02:00
|
|
|
static int rasm_asm(char *buf, u64 offset, u64 len, int bin)
|
2009-02-05 22:08:46 +01:00
|
|
|
{
|
2009-02-18 03:47:40 +01:00
|
|
|
struct r_asm_aop_t aop;
|
2009-04-09 01:03:49 +02:00
|
|
|
int ret, idx, i;
|
2009-02-05 22:08:46 +01:00
|
|
|
|
2009-03-05 16:58:13 +01:00
|
|
|
#if 0
|
2009-02-05 22:08:46 +01:00
|
|
|
/* TODO: Arch, syntax... */
|
2009-02-19 18:13:34 +01:00
|
|
|
if (!r_asm_set(&a, "asm_x86_olly")) {
|
|
|
|
fprintf(stderr, "Error: Cannot find asm_x86 plugin\n");
|
|
|
|
return 1;
|
|
|
|
}
|
2009-03-05 16:58:13 +01:00
|
|
|
#endif
|
2009-04-09 01:03:49 +02:00
|
|
|
r_asm_set_pc(&a, offset);
|
|
|
|
idx = r_asm_massemble(&a, &aop, buf);
|
|
|
|
if (bin)
|
|
|
|
for (i = 0; i < idx; i++)
|
|
|
|
printf("%c", aop.buf[i]);
|
|
|
|
else printf("%s\n", aop.buf_hex);
|
2009-04-05 16:02:17 +02:00
|
|
|
|
|
|
|
for (ret = 0; idx < len; idx+=ret) {
|
|
|
|
ret = r_asm_assemble(&a, &aop, "nop");
|
|
|
|
if (ret) {
|
|
|
|
if (bin)
|
2009-04-09 01:03:49 +02:00
|
|
|
for (i = 0; i < ret; i++)
|
|
|
|
printf("%c", aop.buf[i]);
|
2009-04-05 16:02:17 +02:00
|
|
|
else printf("%s", aop.buf_hex);
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "invalid\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!bin && idx == len) printf("\n");
|
2009-04-05 15:23:36 +02:00
|
|
|
|
|
|
|
return idx;
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|
|
|
|
|
2009-02-18 03:47:40 +01:00
|
|
|
/* asm callback */
|
|
|
|
static int __lib_asm_cb(struct r_lib_plugin_t *pl, void *user, void *data)
|
|
|
|
{
|
|
|
|
struct r_asm_handle_t *hand = (struct r_asm_handle_t *)data;
|
|
|
|
//printf(" * Added (dis)assembly handler\n");
|
|
|
|
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; }
|
|
|
|
|
2009-02-05 22:08:46 +01:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
2009-02-19 18:13:34 +01:00
|
|
|
char *arch = NULL;
|
2009-02-19 14:24:51 +01:00
|
|
|
u64 offset = 0x8048000;
|
2009-04-05 15:23:36 +02:00
|
|
|
int dis = 0, ascii = 0, bin = 0, ret = 0, c;
|
|
|
|
u64 len = 0, idx = 0;
|
2009-02-05 22:08:46 +01:00
|
|
|
|
2009-02-18 03:47:40 +01:00
|
|
|
r_asm_init(&a);
|
|
|
|
r_lib_init(&l, "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, getenv("LIBR_PLUGINS"));
|
|
|
|
|
2009-02-18 16:20:14 +01:00
|
|
|
if (argc<2)
|
|
|
|
return rasm_show_help();
|
|
|
|
|
2009-04-13 22:47:02 +00:00
|
|
|
r_asm_set(&a, "asm_x86");
|
2009-04-11 21:24:37 +00:00
|
|
|
while ((c = getopt(argc, argv, "a:b:s:do:Bl:hL")) != -1)
|
2009-02-05 22:08:46 +01:00
|
|
|
{
|
|
|
|
switch( c ) {
|
|
|
|
case 'a':
|
2009-02-19 18:13:34 +01:00
|
|
|
arch = optarg;
|
2009-02-19 14:24:51 +01:00
|
|
|
break;
|
|
|
|
case 'b':
|
2009-04-13 22:47:02 +00:00
|
|
|
ret = r_asm_set_bits(&a, r_num_math(NULL, optarg));
|
|
|
|
if (!ret) fprintf(stderr, "cannot set bits\n");
|
2009-02-05 22:08:46 +01:00
|
|
|
break;
|
|
|
|
case 's':
|
2009-02-19 14:24:51 +01:00
|
|
|
if (!strcmp(optarg, "att"))
|
|
|
|
r_asm_set_syntax(&a, R_ASM_SYN_ATT);
|
|
|
|
else r_asm_set_syntax(&a, R_ASM_SYN_INTEL);
|
2009-02-05 22:08:46 +01:00
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
dis = 1;
|
|
|
|
break;
|
|
|
|
case 'o':
|
|
|
|
offset = r_num_math(NULL, optarg);
|
|
|
|
break;
|
2009-04-05 15:23:36 +02:00
|
|
|
case 'B':
|
|
|
|
bin = 1;
|
|
|
|
break;
|
|
|
|
case 'l':
|
|
|
|
len = r_num_math(NULL, optarg);
|
|
|
|
break;
|
2009-04-11 21:24:37 +00:00
|
|
|
case 'L':
|
|
|
|
r_asm_list(&a);
|
|
|
|
exit(1);
|
2009-02-05 22:08:46 +01:00
|
|
|
case 'e':
|
2009-02-19 14:24:51 +01:00
|
|
|
r_asm_set_big_endian(&a, R_TRUE);
|
2009-02-05 22:08:46 +01:00
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
return rasm_show_help();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-19 18:13:34 +01:00
|
|
|
if (arch) {
|
2009-03-08 23:49:15 +00:00
|
|
|
char *str = malloc(strlen(arch)+10);
|
|
|
|
sprintf(str, "asm_%s", arch);
|
|
|
|
if (!r_asm_set(&a, str)) {
|
2009-02-19 18:13:34 +01:00
|
|
|
fprintf(stderr, "Error: Unknown plugin\n");
|
2009-03-08 23:49:15 +00:00
|
|
|
free (str);
|
2009-02-19 18:13:34 +01:00
|
|
|
return 1;
|
|
|
|
}
|
2009-03-08 23:49:15 +00:00
|
|
|
free (str);
|
2009-04-05 15:23:36 +02:00
|
|
|
if (!strcmp(arch, "bf"))
|
|
|
|
ascii = 1;
|
2009-03-05 16:58:13 +01:00
|
|
|
} else if (!dis) {
|
|
|
|
if (!r_asm_set(&a, "asm_x86_olly")) {
|
|
|
|
fprintf(stderr, "Error: Cannot find asm_x86_olly plugin\n");
|
|
|
|
return 1;
|
|
|
|
}
|
2009-02-19 18:13:34 +01:00
|
|
|
} else if (!r_asm_set(&a, "asm_x86")) {
|
|
|
|
fprintf(stderr, "Error: Cannot find asm_x86 plugin\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-02-05 22:08:46 +01:00
|
|
|
if (argv[optind]) {
|
|
|
|
if (!strcmp(argv[optind], "-")) {
|
|
|
|
char buf[1024];
|
|
|
|
for(;;) {
|
|
|
|
fgets(buf, 1024, stdin);
|
2009-04-05 15:23:36 +02:00
|
|
|
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 || (len && idx >= len))
|
2009-02-05 22:08:46 +01:00
|
|
|
break;
|
|
|
|
}
|
2009-04-05 15:23:36 +02:00
|
|
|
return idx;
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|
2009-04-05 15:23:36 +02:00
|
|
|
if (dis) return rasm_disasm(argv[optind], offset, len, ascii, bin);
|
|
|
|
else return rasm_asm(argv[optind], offset, len, bin);
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|