2011-08-08 00:07:26 +00:00
|
|
|
/* radare - LGPL - Copyright 2011 pancake<@nopcode.org> */
|
|
|
|
#include <r_egg.h>
|
2011-08-08 13:00:42 +00:00
|
|
|
#include <r_bin.h>
|
2011-08-08 00:07:26 +00:00
|
|
|
#include <getopt.h>
|
|
|
|
|
|
|
|
static int usage () {
|
2011-08-10 09:24:15 +00:00
|
|
|
eprintf ("ragg2 [options] [file|-]\n"
|
|
|
|
" -a [x86|arm] select architecture\n"
|
|
|
|
" -b [32|64] register size\n"
|
|
|
|
" -k [linux|osx] operating system's kernel\n"
|
|
|
|
" -f [format] output format (raw, pe, elf, mach0)\n"
|
2011-08-10 13:42:54 +00:00
|
|
|
" -F output native format (osx=mach0, linux=elf, ..)\n"
|
2011-08-10 09:24:15 +00:00
|
|
|
" -o [file] output file\n"
|
|
|
|
" -s show assembler\n"
|
|
|
|
" -x show hexpairs (enabled by default)\n"
|
|
|
|
" -X execute\n"
|
|
|
|
" -h show this help\n");
|
2011-08-08 00:07:26 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-08-08 13:00:42 +00:00
|
|
|
static int create (const char *format, const char *arch, int bits, const ut8 *code, int codelen) {
|
|
|
|
RBin *bin = r_bin_new ();
|
|
|
|
RBuffer *b;
|
|
|
|
if (!r_bin_use_arch (bin, arch, bits, format)) {
|
|
|
|
eprintf ("Cannot set arch\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
b = r_bin_create (bin, code, codelen, NULL, 0); //data, datalen);
|
|
|
|
if (b) {
|
|
|
|
write (1, b->buf, b->length);
|
|
|
|
r_buf_free (b);
|
|
|
|
} else eprintf ("Cannot create binary for this format '%s'.\n", format);
|
|
|
|
r_bin_free (bin);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-08-08 00:07:26 +00:00
|
|
|
int main(int argc, char **argv) {
|
|
|
|
const char *arch = "x86";
|
2011-08-09 00:03:12 +00:00
|
|
|
const char *os = R_EGG_OS_NAME;
|
2011-08-08 13:00:42 +00:00
|
|
|
char *format = "raw";
|
2011-08-08 00:07:26 +00:00
|
|
|
int show_execute = 0;
|
|
|
|
int show_hex = 1;
|
|
|
|
int show_asm = 0;
|
|
|
|
int bits = 32;
|
|
|
|
RBuffer *b;
|
2011-08-14 12:11:15 +00:00
|
|
|
REgg *egg;
|
|
|
|
int c, i;
|
2011-08-08 00:07:26 +00:00
|
|
|
|
2011-08-10 13:42:54 +00:00
|
|
|
while ((c = getopt (argc, argv, "ha:b:f:o:sxXk:F")) != -1) {
|
2011-08-08 00:07:26 +00:00
|
|
|
switch (c) {
|
|
|
|
case 'a':
|
|
|
|
arch = optarg;
|
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
bits = atoi (optarg);
|
|
|
|
break;
|
|
|
|
case 'o':
|
|
|
|
{
|
|
|
|
int fd = open (optarg, O_RDWR|O_CREAT, 0644);
|
|
|
|
if (fd != -1) {
|
2011-09-14 10:37:26 +00:00
|
|
|
#if __UNIX__
|
2011-08-08 13:00:42 +00:00
|
|
|
if (*format != 'r')
|
|
|
|
fchmod (fd, 0755);
|
2011-09-14 10:37:26 +00:00
|
|
|
#endif
|
2011-08-08 00:07:26 +00:00
|
|
|
close (1);
|
|
|
|
dup2 (fd, 1);
|
|
|
|
} else eprintf ("Cannot open '%s'\n", optarg);
|
|
|
|
}
|
|
|
|
break;
|
2011-08-10 13:42:54 +00:00
|
|
|
case 'F':
|
|
|
|
#if __APPLE__
|
|
|
|
format = "mach0";
|
|
|
|
#elif __WINDOWS__
|
|
|
|
format = "pe";
|
|
|
|
#else
|
|
|
|
format = "elf";
|
|
|
|
#endif
|
|
|
|
show_asm = 0;
|
|
|
|
break;
|
2011-08-08 00:07:26 +00:00
|
|
|
case 'f':
|
2011-08-08 13:00:42 +00:00
|
|
|
format = optarg;
|
2011-08-09 00:03:12 +00:00
|
|
|
show_asm = 0;
|
2011-08-08 00:07:26 +00:00
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
show_asm = 1;
|
|
|
|
show_hex = 0;
|
|
|
|
break;
|
2011-08-09 00:03:12 +00:00
|
|
|
case 'k':
|
|
|
|
os = optarg;
|
|
|
|
break;
|
2011-08-08 00:07:26 +00:00
|
|
|
case 'x':
|
|
|
|
show_hex = 1;
|
|
|
|
break;
|
|
|
|
case 'X':
|
|
|
|
// execute
|
|
|
|
show_execute = 1;
|
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
return usage ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (optind == argc)
|
|
|
|
return usage ();
|
|
|
|
|
2011-08-14 12:11:15 +00:00
|
|
|
egg = r_egg_new ();
|
2011-08-09 00:03:12 +00:00
|
|
|
r_egg_setup (egg, arch, bits, 0, os);
|
2011-08-08 00:07:26 +00:00
|
|
|
if (!strcmp (argv[optind], "-")) {
|
|
|
|
char buf[1024];
|
|
|
|
for (;;) {
|
2011-08-08 13:00:42 +00:00
|
|
|
fgets (buf, sizeof (buf)-1, stdin);
|
2011-08-08 00:07:26 +00:00
|
|
|
if (feof (stdin)) break;
|
|
|
|
r_egg_load (egg, buf, 0);
|
|
|
|
}
|
2011-08-08 22:10:12 +00:00
|
|
|
} else {
|
|
|
|
if (!r_egg_include (egg, argv[optind], 0)) {
|
|
|
|
eprintf ("Cannot open '%s'\n", argv[optind]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2011-08-08 00:07:26 +00:00
|
|
|
r_egg_compile (egg);
|
|
|
|
//printf ("src (%s)\n", r_egg_get_source (egg));
|
|
|
|
if (show_asm)
|
|
|
|
printf ("%s\n", r_egg_get_assembly (egg));
|
|
|
|
if (show_hex || show_execute) {
|
2011-08-14 12:11:15 +00:00
|
|
|
if (!r_egg_assemble (egg)) {
|
|
|
|
eprintf ("r_egg_assemble: invalid assembly\n");
|
|
|
|
goto fail;
|
|
|
|
}
|
2011-08-08 00:07:26 +00:00
|
|
|
b = r_egg_get_bin (egg);
|
|
|
|
if (b == NULL) {
|
2011-08-14 12:11:15 +00:00
|
|
|
eprintf ("r_egg_get_bin: invalid egg :(\n");
|
|
|
|
goto fail;
|
2011-08-08 00:07:26 +00:00
|
|
|
} else {
|
|
|
|
if (show_execute) {
|
|
|
|
// TODO
|
|
|
|
eprintf ("TODO: execute\n");
|
|
|
|
}
|
2011-08-08 13:00:42 +00:00
|
|
|
switch (*format) {
|
|
|
|
case 'r':
|
|
|
|
if (show_hex) {
|
|
|
|
for (i=0; i<b->length; i++)
|
|
|
|
printf ("%02x", b->buf[i]);
|
|
|
|
printf ("\n");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'p': // PE
|
|
|
|
case 'e': // ELF
|
|
|
|
case 'm': // MACH0
|
|
|
|
create (format, arch, bits, b->buf, b->length);
|
|
|
|
break;
|
|
|
|
default:
|
2011-08-14 12:11:15 +00:00
|
|
|
eprintf ("unknown executable format (%s)\n", format);
|
|
|
|
goto fail;
|
2011-08-08 13:00:42 +00:00
|
|
|
}
|
2011-08-08 00:07:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
r_egg_free (egg);
|
|
|
|
return 0;
|
2011-08-14 12:11:15 +00:00
|
|
|
fail:
|
|
|
|
r_egg_free (egg);
|
|
|
|
return 1;
|
2011-08-08 00:07:26 +00:00
|
|
|
}
|