/* radare - LGPL - Copyright 2007-2017 - pancake */ #include "../blob/version.c" #include #define STDIN_BUFFER_SIZE 354096 #define R_STATIC_ASSERT(x)\ switch (0) { \ case 0:\ case (x):;\ } static RNum *num; static int help(); static ut64 flags = 0; static int use_stdin(); static int force_mode = 0; static int rax(char *str, int len, int last); static int format_output(char mode, const char *s) { ut64 n = r_num_math (num, s); char strbits[65]; if (force_mode) { mode = force_mode; } if (flags & 2) { ut64 n2 = n; r_mem_swapendian ((ut8 *)&n, (ut8 *)&n2, (n >> 32)? 8: 4); } switch (mode) { case 'I': printf ("%" PFMT64d "\n", n); break; case '0': { int len = strlen (s); if (len > 0 && s[len - 1] == 'f') { R_STATIC_ASSERT (sizeof (float) == 4) float f = (float)num->fvalue; ut8 *p = (ut8 *)&f; printf ("Fx%02x%02x%02x%02x\n", p[3], p[2], p[1], p[0]); } else { printf ("0x%" PFMT64x "\n", n); } } break; case 'F': { float *f = (float *)&n; printf ("%ff\n", *f); } break; case 'f': printf ("%.01lf\n", num->fvalue); break; case 'O': printf ("0%" PFMT64o "\n", n); break; case 'B': if (n) { r_num_to_bits (strbits, n); printf ("%sb\n", strbits); } else printf ("0b\n"); break; case 'T': if (n) { r_num_to_trits (strbits, n); printf ("%st\n", strbits); } else printf ("0t\n"); break; default: eprintf ("Unknown output mode %d\n", mode); break; } return true; } static int help() { printf ( " =[base] ; rax2 =10 0x46 -> output in base 10\n" " int -> hex ; rax2 10\n" " hex -> int ; rax2 0xa\n" " -int -> hex ; rax2 -77\n" " -hex -> int ; rax2 0xffffffb3\n" " int -> bin ; rax2 b30\n" " int -> ternary ; rax2 t42\n" " bin -> int ; rax2 1010d\n" " float -> hex ; rax2 3.33f\n" " hex -> float ; rax2 Fx40551ed8\n" " oct -> hex ; rax2 35o\n" " hex -> oct ; rax2 Ox12 (O is a letter)\n" " bin -> hex ; rax2 1100011b\n" " hex -> bin ; rax2 Bx63\n" " hex -> ternary ; rax2 Tx23\n" " raw -> hex ; rax2 -S < /binfile\n" " hex -> raw ; rax2 -s 414141\n" " -b bin -> str ; rax2 -b 01000101 01110110\n" " -B str -> bin ; rax2 -B hello\n" " -d force integer ; rax2 -d 3 -> 3 instead of 0x3\n" " -e swap endianness ; rax2 -e 0x33\n" " -E base64 encode ;\n" " -f floating point ; rax2 -f 6.3+2.1\n" " -F stdin slurp C hex ; rax2 -F < shellcode.c\n" " -h help ; rax2 -h\n" " -k keep base ; rax2 -k 33+3 -> 36\n" " -K randomart ; rax2 -K 0x34 1020304050\n" " -n binary number ; rax2 -n 0x1234 # 34120000\n" " -N binary number ; rax2 -N 0x1234 # \\x34\\x12\\x00\\x00\n" " -r r2 style output ; rax2 -r 0x1234\n" " -s hexstr -> raw ; rax2 -s 43 4a 50\n" " -S raw -> hexstr ; rax2 -S < /bin/ls > ls.hex\n" " -t tstamp -> str ; rax2 -t 1234567890\n" " -x hash string ; rax2 -x linux osx\n" " -u units ; rax2 -u 389289238 # 317.0M\n" " -w signed word ; rax2 -w 16 0xffff\n" " -v version ; rax2 -v\n"); return true; } static int rax(char *str, int len, int last) { float f; ut8 *buf; char *p, out_mode = (flags & 128)? 'I': '0'; int i; if (!(flags & 4) || !len) len = strlen (str); if ((flags & 4)) goto dotherax; if (*str == '=') { switch (atoi (str + 1)) { case 2: force_mode = 'B'; break; case 3: force_mode = 'T'; break; case 8: force_mode = 'O'; break; case 10: force_mode = 'I'; break; case 16: force_mode = '0'; break; case 0: force_mode = str[1]; break; } return true; } if (*str == '-') { while (str[1] && str[1] != ' ') { switch (str[1]) { case 's': flags ^= 1; break; case 'e': flags ^= 1 << 1; break; case 'S': flags ^= 1 << 2; break; case 'b': flags ^= 1 << 3; break; case 'B': flags ^= 1 << 17; break; case 'x': flags ^= 1 << 4; break; case 'k': flags ^= 1 << 5; break; case 'f': flags ^= 1 << 6; break; case 'd': flags ^= 1 << 7; break; case 'K': flags ^= 1 << 8; break; case 'n': flags ^= 1 << 9; break; case 'u': flags ^= 1 << 10; break; case 't': flags ^= 1 << 11; break; case 'E': flags ^= 1 << 12; break; case 'D': flags ^= 1 << 13; break; case 'F': flags ^= 1 << 14; break; case 'N': flags ^= 1 << 15; break; case 'w': flags ^= 1 << 16; break; case 'r': flags ^= 1 << 18; break; case 'v': blob_version ("rax2"); return 0; case '\0': return !use_stdin (); default: out_mode = (flags ^ 32)? '0': 'I'; if (str[1] >= '0' && str[1] <= '9') { if (str[2] == 'x') out_mode = 'I'; return format_output (out_mode, str); } printf ("Usage: rax2 [options] [expr ...]\n"); return help (); } str++; } if (last) return !use_stdin (); return true; } if (!flags && r_str_nlen (str, 2) == 1) { if (*str == 'q') { return false; } if (*str == 'h' || *str == '?') { help (); return false; } } dotherax: if (flags & 1) { // -s int n = ((strlen (str)) >> 1) + 1; buf = malloc (n); if (buf) { memset (buf, '\0', n); n = r_hex_str2bin (str, (ut8 *)buf); if (n > 0) fwrite (buf, n, 1, stdout); #if __EMSCRIPTEN__ puts (""); #endif fflush (stdout); free (buf); } return true; } if (flags & (1 << 2)) { // -S for (i = 0; i < len; i++) { printf ("%02x", (ut8)str[i]); } printf ("\n"); return true; } else if (flags & (1 << 3)) { // -b int i, len; ut8 buf[4096]; len = r_str_binstr2bin (str, buf, sizeof (buf)); for (i = 0; i < len; i++) { printf ("%c", buf[i]); } return true; } else if (flags & (1 << 4)) { // -x int h = r_str_hash (str); printf ("0x%x\n", h); return true; } else if (flags & (1 << 5)) { // -k out_mode = 'I'; } else if (flags & (1 << 6)) { // -f out_mode = 'f'; } else if (flags & (1 << 8)) { // -K int n = ((strlen (str)) >> 1) + 1; char *s = NULL; ut32 *m; buf = (ut8 *)malloc (n); if (!buf) { return false; } m = (ut32 *)buf; memset (buf, '\0', n); n = r_hex_str2bin (str, (ut8 *)buf); if (n < 1 || !memcmp (str, "0x", 2)) { ut64 q = r_num_math (num, str); s = r_print_randomart ((ut8 *)&q, sizeof (q), q); printf ("%s\n", s); free (s); } else { s = r_print_randomart ((ut8 *)buf, n, *m); printf ("%s\n", s); free (s); } free (m); return true; } else if (flags & (1 << 9)) { // -n ut64 n = r_num_math (num, str); if (n >> 32) { /* is 64 bit value */ ut8 *np = (ut8 *)&n; if (flags & 1) fwrite (&n, sizeof (n), 1, stdout); else printf ("%02x%02x%02x%02x" "%02x%02x%02x%02x\n", np[0], np[1], np[2], np[3], np[4], np[5], np[6], np[7]); } else { /* is 32 bit value */ ut32 n32 = (ut32) (n & UT32_MAX); ut8 *np = (ut8 *)&n32; if (flags & 1) fwrite (&n32, sizeof (n32), 1, stdout); else printf ("%02x%02x%02x%02x\n", np[0], np[1], np[2], np[3]); } fflush (stdout); return true; } else if (flags & (1 << 17)) { // -B (bin -> str) int i = 0; // TODO: move to r_util for (i = 0; i < strlen (str); i++) { ut8 ch = str[i]; printf ("%d%d%d%d" "%d%d%d%d", ch & 128? 1: 0, ch & 64? 1: 0, ch & 32? 1: 0, ch & 16? 1: 0, ch & 8? 1: 0, ch & 4? 1: 0, ch & 2? 1: 0, ch & 1? 1: 0); } return true; } else if (flags & (1 << 16)) { // -w ut64 n = r_num_math (num, str); if (n >> 31) { // is >32bit n = (st64) (st32)n; } else if (n >> 14) { n = (st64) (st16)n; } else if (n >> 7) { n = (st64) (st8)n; } printf ("%" PFMT64d "\n", n); fflush (stdout); return true; } else if (flags & (1 << 15)) { // -N ut64 n = r_num_math (num, str); if (n >> 32) { /* is 64 bit value */ ut8 *np = (ut8 *)&n; if (flags & 1) { fwrite (&n, sizeof (n), 1, stdout); } else { printf ("\\x%02x\\x%02x\\x%02x\\x%02x" "\\x%02x\\x%02x\\x%02x\\x%02x\n", np[0], np[1], np[2], np[3], np[4], np[5], np[6], np[7]); } } else { /* is 32 bit value */ ut32 n32 = (ut32) (n & UT32_MAX); ut8 *np = (ut8 *)&n32; if (flags & 1) { fwrite (&n32, sizeof (n32), 1, stdout); } else { printf ("\\x%02x\\x%02x\\x%02x\\x%02x\n", np[0], np[1], np[2], np[3]); } } fflush (stdout); return true; } else if (flags & (1 << 10)) { // -u char buf[80]; r_num_units (buf, r_num_math (NULL, str)); printf ("%s\n", buf); return true; } else if (flags & (1 << 11)) { // -t ut32 n = r_num_math (num, str); RPrint *p = r_print_new (); r_print_date_unix (p, (const ut8 *)&n, sizeof (ut32)); r_print_free (p); return true; } else if (flags & (1 << 12)) { // -E const int len = strlen (str); char *out = calloc (sizeof (char), ((len + 1) * 4) / 3); if (out) { r_base64_encode (out, (const ut8 *)str, len); printf ("%s\n", out); fflush (stdout); free (out); } return true; } else if (flags & (1 << 13)) { // -D const int len = strlen (str); /* http://stackoverflow.com/questions/4715415/base64-what-is-the-worst-possible-increase-in-space-usage */ ut8 *out = calloc (sizeof (ut8), ((len + 2) / 3) * 4); if (out) { r_base64_decode (out, str, len); printf ("%s\n", out); fflush (stdout); free (out); } return true; } else if (flags & 1 << 14) { // -F char *str = r_stdin_slurp (NULL); if (str) { char *res = r_hex_from_c (str); if (res) { printf ("%s\n", res); fflush (stdout); free (res); } else { eprintf ("Invalid input.\n"); } free (str); } return false; } else if (flags & (1 << 18)) { // -r char *asnum, unit[32]; char out[128]; ut32 n32, s, a; double d; float f; ut64 n = r_num_math (num, str); if (num->dbz) { eprintf ("RNum ERROR: Division by Zero\n"); return false; } n32 = (ut32) (n & UT32_MAX); asnum = r_num_as_string (NULL, n, false); memcpy (&f, &n32, sizeof (f)); memcpy (&d, &n, sizeof (d)); /* decimal, hexa, octal */ s = n >> 16 << 12; a = n & 0x0fff; r_num_units (unit, n); eprintf ("%" PFMT64d " 0x%" PFMT64x " 0%" PFMT64o " %s %04x:%04x ", n, n, n, unit, s, a); if (n >> 32) { eprintf ("%" PFMT64d " ", (st64)n); } else { eprintf ("%d ", (st32)n); } if (asnum) { eprintf ("\"%s\" ", asnum); free (asnum); } /* binary and floating point */ r_str_bits (out, (const ut8 *)&n, sizeof (n), NULL); eprintf ("%s %.01lf %ff %lf\n", out, num->fvalue, f, d); return true; } if (str[0] == '0' && str[1] == 'x') { out_mode = (flags & 32)? '0': 'I'; } else if (str[0] == 'b') { out_mode = 'B'; str++; } else if (str[0] == 't') { out_mode = 'T'; str++; } else if (str[0] == 'F' && str[1] == 'x') { out_mode = 'F'; *str = '0'; } else if (str[0] == 'B' && str[1] == 'x') { out_mode = 'B'; *str = '0'; } else if (str[0] == 'T' && str[1] == 'x') { out_mode = 'T'; *str = '0'; } else if (str[0] == 'O' && str[1] == 'x') { out_mode = 'O'; *str = '0'; } else if (str[strlen (str) - 1] == 'd') { out_mode = 'I'; str[strlen (str) - 1] = 'b'; //TODO: Move print into format_output } else if (str[strlen (str) - 1] == 'f') { ut8 *p = (ut8 *)&f; sscanf (str, "%f", &f); printf ("Fx%02x%02x%02x%02x\n", p[3], p[2], p[1], p[0]); return true; } while ((p = strchr (str, ' '))) { *p = 0; format_output (out_mode, str); str = p + 1; } if (*str) { format_output (out_mode, str); } return true; } static int use_stdin() { char *buf = calloc (1, STDIN_BUFFER_SIZE + 1); int l; //, sflag = (flags & 5); if (!buf) { return 0; } if (!(flags & 16384)) { for (l = 0; l >= 0 && l < STDIN_BUFFER_SIZE; l++) { //make sure we don't read beyond boundaries int n = read (0, buf + l, STDIN_BUFFER_SIZE - l); if (n < 1) break; l += n; if (buf[l - 1] == 0) { l--; continue; } buf[n] = 0; //if (sflag && strlen (buf) < STDIN_BUFFER_SIZE) // -S buf[strlen (buf)] = '\0'; if (!rax (buf, l, 0)) break; l = -1; } } else { l = 1; } if (l > 0) { rax (buf, l, 0); } free (buf); return 0; } int main (int argc, char** argv) { int i; num = r_num_new (NULL, NULL, NULL); if (argc == 1) { use_stdin (); } else { for (i = 1; i < argc; i++) { rax (argv[i], 0, i == argc - 1); } } r_num_free (num); return 0; }