static int haret__read(RIO *io, RIODesc *fd, ut8 *buf, int count) { char tmp[1024]; int i = 0; ut64 off; st64 j; RSocket *s = HARET_FD (fd); off = io->off & -4; sprintf (tmp, "pdump 0x%"PFMT64x" %i\r\n", off, count+4); r_socket_write (s, tmp, strlen (tmp)); r_socket_read_block (s, (unsigned char *) tmp, strlen (tmp)+1); j = (io->off - off)*2; while (i<count && j >= 0) { r_socket_read_block (s, (ut8*) tmp, 11); r_socket_read_block (s, (ut8*) tmp, 35); if (i+16 < count || (io->off-off) == 0) { tmp[35] = 0; i += r_hex_str2bin (tmp+j, buf+i); r_socket_read_block (s, (unsigned char *) tmp, 21); } else { tmp[(io->off - off)*2] = 0; i += r_hex_str2bin (tmp+j, buf+i); } j = 0; } haret_wait_until_prompt (s); return i; }
static bool encrypt_or_decrypt_block(RCore *core, const char *algo, const char *key, int direction, const char *iv) { //TODO: generalise no_key_mode for all non key encoding/decoding. int keylen = 0; bool no_key_mode = !strcmp ("base64", algo) || !strcmp ("base91", algo) || !strcmp ("punycode", algo); ut8 *binkey = NULL; if (!strncmp (key, "s:", 2)) { binkey = (ut8*)strdup (key + 2); keylen = strlen (key + 2); } else { binkey = (ut8 *)strdup (key); keylen = r_hex_str2bin (key, binkey); } if (!no_key_mode && keylen < 1) { eprintf ("%s key not defined. Use -S [key]\n", ((!direction) ? "Encryption" : "Decryption")); return false; } RCrypto *cry = r_crypto_new (); if (r_crypto_use (cry, algo)) { if (!binkey) { eprintf ("Cannot allocate %d byte(s)\n", keylen); r_crypto_free (cry); return false; } if (r_crypto_set_key (cry, binkey, keylen, 0, direction)) { if (iv) { ut8 *biniv = malloc (strlen (iv) + 1); int ivlen = r_hex_str2bin (iv, biniv); if (ivlen < 1) { ivlen = strlen(iv); strcpy ((char *)biniv, iv); } if (!r_crypto_set_iv (cry, biniv, ivlen)) { eprintf ("Invalid IV.\n"); return 0; } } r_crypto_update (cry, (const ut8*)core->block, core->blocksize); r_crypto_final (cry, NULL, 0); int result_size = 0; ut8 *result = r_crypto_get_output (cry, &result_size); if (result) { r_io_write_at (core->io, core->offset, result, result_size); eprintf ("Written %d byte(s)\n", result_size); free (result); } } else { eprintf ("Invalid key\n"); } free (binkey); r_crypto_free (cry); return 0; } else { eprintf ("Unknown %s algorithm '%s'\n", ((!direction) ? "encryption" : "decryption") ,algo); } r_crypto_free (cry); return 1; }
// TODO: integrate in '/' command with search.inblock ? static void visual_search (RCore *core) { const ut8 *p; int len, d = cursor; char str[128], buf[258]; r_line_set_prompt ("search byte/string in block: "); r_cons_fgets (str, sizeof (str), 0, NULL); len = r_hex_str2bin (str, (ut8*)buf); if (*str=='"') { char *e = strncpy (buf, str+1, sizeof (buf)-1); if (e) { --e; if (*e=='"') *e=0; } len = strlen (buf); } else if (len<1) { strncpy (buf, str, sizeof (buf)-1); len = strlen (str); } p = r_mem_mem (core->block+d, core->blocksize-d, (const ut8*)buf, len); if (p) { cursor = (int)(size_t)(p-core->block); if (len>1) { ocursor = cursor+len-1; } else ocursor = -1; showcursor (core, true); eprintf ("FOUND IN %d\n", cursor); r_cons_any_key (NULL); } else { eprintf ("Cannot find bytes\n"); r_cons_any_key (NULL); r_cons_clear00 (); } }
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) { if (__plugin_open (io, pathname,0)) { RIOMalloc *mal = R_NEW (RIOMalloc); mal->fd = -2; /* causes r_io_desc_new() to set the correct fd */ if (!strncmp (pathname, "hex://", 6)) { mal->size = strlen (pathname); mal->buf = malloc (mal->size+1); mal->offset = 0; memset (mal->buf, 0, mal->size); mal->size = r_hex_str2bin (pathname+6, mal->buf); if ((int)mal->size<1) { free (mal->buf); mal->buf = NULL; } } else { mal->size = r_num_math (NULL, pathname+9); if (((int)mal->size) <= 0) { free (mal); eprintf ("Cannot allocate (%s) 0 bytes\n", pathname+9); return NULL; } mal->offset = 0; mal->buf = calloc (1, mal->size+1); } if (mal->buf != NULL) { RETURN_IO_DESC_NEW (&r_io_plugin_malloc, mal->fd, pathname, rw, mode,mal); } eprintf ("Cannot allocate (%s) %d bytes\n", pathname+9, mal->size); free (mal); } return NULL; }
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) { if (__plugin_open (io, pathname, 0)) { const char *hostport = pathname + 6; RIOKdp *mal = R_NEW (RIOKdp); mal->fd = -2; /* causes r_io_desc_new() to set the correct fd */ eprintf ("HOST:PORT = %s", hostport); //mal->sock = r_socket_new(); mal->size = strlen (pathname); mal->buf = malloc (mal->size+1); mal->offset = 0; memset (mal->buf, 0, mal->size); mal->size = r_hex_str2bin (hostport, mal->buf); if ((int)mal->size<1) { free (mal->buf); mal->buf = NULL; } if (mal->buf != NULL) { RETURN_IO_DESC_NEW (&r_io_plugin_kdp, mal->fd, pathname, rw, mode,mal); } eprintf ("Cannot connect to %s\n", hostport); free (mal); } return NULL; }
static RIODesc *__open(struct r_io_t *io, const char *pathname, int rw, int mode) { if (__plugin_open (io, pathname)) { RIOMalloc *mal = R_NEW (RIOMalloc); mal->fd = -2; /* causes r_io_desc_new() to set the correct fd */ if (!memcmp (pathname, "hex://", 6)) { mal->size = strlen (pathname); mal->buf = malloc (mal->size); memset (mal->buf, 0, mal->size); mal->size = r_hex_str2bin (pathname+6, mal->buf); } else { mal->size = r_num_math (NULL, pathname+9); if ((mal->size)>0) { mal->buf = malloc (mal->size); memset (mal->buf, '\0', mal->size); } else { eprintf ("Cannot allocate (%s) 0 bytes\n", pathname+9); return NULL; } } if (mal->buf != NULL) { RETURN_IO_DESC_NEW(&r_io_plugin_malloc, mal->fd, pathname, rw, mode,mal); //return r_io_desc_new (&r_io_plugin_malloc, mal->fd, pathname, rw, mode, mal); } eprintf ("Cannot allocate (%s) %d bytes\n", pathname+9, mal->size); free (mal); } return NULL; }
static void do_hash_seed(const char *seed) { const char *sptr = seed; if (!seed) { _s = NULL; return; } _s = &s; s.buf = (ut8*)malloc (strlen (seed)+128); if (!s.buf) { _s = NULL; return; } if (*seed=='^') { s.prefix = 1; sptr++; } else s.prefix = 0; if (!strncmp (sptr, "s:", 2)) { strcpy ((char*)s.buf, sptr+2); s.len = strlen (sptr+2); } else { s.len = r_hex_str2bin (sptr, s.buf); if (s.len<1) { strcpy ((char*)s.buf, sptr); s.len = strlen (sptr); } } }
R_API int r_hex_str2binmask(const char *in, ut8 *out, ut8 *mask) { ut8 *ptr; int len, ilen = strlen (in)+1; int has_nibble = 0; memcpy (out, in, ilen); for (ptr=out; *ptr; ptr++) if (*ptr=='.') *ptr = '0'; len = r_hex_str2bin ((char*)out, out); if (len<0) { has_nibble = 1; len = -len; } if (len != -1) { memcpy (mask, in, ilen); if (has_nibble) memcpy (mask+ilen, "f0", 3); for (ptr=mask; *ptr; ptr++) *ptr = (*ptr=='.')?'0':'f'; len = r_hex_str2bin ((char*)mask, mask); } return len; }
R_API RSearchKeyword* r_search_keyword_new_hex(const char *kwstr, const char *bmstr, const char *data) { RSearchKeyword *ks = NULL; ut8 *kw, *bm; int bmlen, kwlen; if (kwstr != NULL) { kw = malloc (strlen (kwstr)+1); bm = malloc (strlen (bmstr)+1); if (kw != NULL && bm != NULL) { bmlen = r_hex_str2bin (bmstr, (ut8*)bm); kwlen = r_hex_str2bin (kwstr, (ut8*)kw); if (bmlen>=0 && kwlen>0) ks = r_search_keyword_new (kw, kwlen, bm, bmlen, data); } free (kw); free (bm); } return ks; }
static int __read(RIO *io, RIODesc *fd, ut8 *buf, int count) { memset (buf, 0xff, count); if (RIOGDB_IS_VALID (fd)) { char *ptr = gdbwrap_readmem (RIOGDB_DESC (fd), (la32)io->off, count); if (ptr == NULL) return -1; return r_hex_str2bin (ptr, buf); } return -1; }
R_API int r_core_write_op(RCore *core, const char *arg, char op) { char *str; ut8 *buf; int i, j, ret, len; // XXX we can work with config.block instead of dupping it buf = (ut8 *)malloc (core->blocksize); str = (char *)malloc (strlen(arg)); if (buf == NULL || str == NULL) { free (buf); free (str); return R_FALSE; } memcpy (buf, core->block, core->blocksize); len = r_hex_str2bin (arg, (ut8 *)str); if (len==-1) { eprintf ("Invalid hexpair string\n"); return R_FALSE; } if (op=='2' || op=='4') { op -= '0'; for (i=0; i<core->blocksize; i+=op) { /* endian swap */ ut8 tmp = buf[i]; buf[i] = buf[i+3]; buf[i+3] = tmp; if (op==4) { tmp = buf[i+1]; buf[i+1] = buf[i+2]; buf[i+2] = tmp; } } } else { for (i=j=0; i<core->blocksize; i++) { switch (op) { case 'x': buf[i] ^= str[j]; break; case 'a': buf[i] += str[j]; break; case 's': buf[i] -= str[j]; break; case 'm': buf[i] *= str[j]; break; case 'd': if (str[j]) buf[i] /= str[j]; else buf[i] = 0; break; case 'r': buf[i] >>= str[j]; break; case 'l': buf[i] <<= str[j]; break; case 'o': buf[i] |= str[j]; break; case 'A': buf[i] &= str[j]; break; } j++; if (j>=len) j=0; /* cyclic key */ } } ret = r_core_write_at (core, core->offset, buf, core->blocksize); free (buf); return ret; }
static int rax (char *str, int len, int last) { float f; char *p, *buf, out_mode = '0'; int i; if (!len) len = strlen (str); if (*str=='-') { switch (str[1]) { case 's': flags ^= 1; break; case 'e': flags ^= 2; break; case 'S': flags ^= 4; break; case 'b': flags ^= 8; break; case 'x': flags ^= 16; break; case 'k': flags ^= 32; break; case 'v': printf ("rax2 v"R2_VERSION"\n"); break; case '\0': return use_stdin (); default: printf ("Usage: rax2 [options] [expression]\n"); return help (); } if (last) return use_stdin (); return R_TRUE; } else if (*str=='q') return R_FALSE; else if (*str=='h' || *str=='?') return help (); if (flags & 1) { ut64 n = ((strlen (str))>>1)+1; buf = malloc (sizeof (char) * n); memset (buf, '\0', n); n = r_hex_str2bin (str, (ut8*)buf); write (1, buf, n); free (buf); return R_TRUE; }
R_API bool r_core_yank_hexpair(RCore *core, const char *input) { if (!input || !*input) { return false; } char *out = strdup (input); int len = r_hex_str2bin (input, (ut8 *)out); if (len > 0) { r_core_yank_set (core, 0, (ut8 *)out, len); } free (out); return true; }
static char *getstr(const char *src) { int len; char *ret = NULL; switch (*src) { case '\'': ret = strdup (src+1); if (ret) { len = strlen (ret); if (len>0) { len--; if (ret[len]=='\'') { ret[len] = 0; return ret; } else eprintf ("Missing \"\n"); } free (ret); } return NULL; case '"': ret = strdup (src+1); if (ret) { len = strlen (ret); if (len>0) { len--; if (ret[len]=='"') { ret[len] = 0; r_str_unescape (ret); return ret; } else eprintf ("Missing \"\n"); } free (ret); } return NULL; case '@': // slurp file return r_file_slurp (src+1, NULL); case ':': // hexpairs ret = strdup (src); len = r_hex_str2bin (src+1, (ut8*)ret); if (len>0) { ret[len] = 0; return ret; } else { eprintf ("Invalid hexpair string\n"); free (ret); return NULL; } } r_str_unescape ((ret = strdup (src))); return ret; }
R_API int r_asm_op_set_hex(RAsmOp *op, const char *str) { r_strbuf_set (&op->buf_hex, str); ut8 *bin = (ut8*)strdup (str); if (bin) { int len = r_hex_str2bin (str, bin); if (len > 0) { r_strbuf_setbin (&op->buf, bin, len); } free (bin); return len; } return 0; }
R_API RSearchKeyword* r_search_keyword_new_hex(const char *kwstr, const char *bmstr, const char *data) { RSearchKeyword *kw; ut8 *kwbuf, *bmbuf; int kwlen, bmlen = 0; if (!kwstr) return NULL; kwbuf = malloc (strlen (kwstr)+1); if (!kwbuf) return NULL; kwlen = r_hex_str2bin (kwstr, kwbuf); if (kwlen < 1) { free (kwbuf); return NULL; } bmbuf = NULL; if (bmstr) { bmbuf = malloc (strlen (bmstr)+1); if (!bmbuf) { free (kwbuf); return NULL; } bmlen = r_hex_str2bin (bmstr, bmbuf); if (bmlen < 1) { bmlen = -bmlen; free (bmbuf); free (kwbuf); return NULL; } } kw = r_search_keyword_new (kwbuf, kwlen, bmbuf, bmlen, data); free (kwbuf); free (bmbuf); return kw; }
R_API int cmd_write_hexpair(RCore* core, const char* pairs) { ut8 *buf = malloc (strlen (pairs)); int len = r_hex_str2bin (pairs, buf); if (len != 0) { if (len < 0) len = -len + 1; if (len<core->blocksize) buf[len] = (core->block[len] & 0xf) | (buf[len] & 0xf0); r_core_write_at (core, core->offset, buf, len); if (r_config_get_i (core->config, "cfg.wseek")) r_core_seek_delta (core, len); r_core_block_read (core, 0); } else eprintf ("Error: invalid hexpair string\n"); free (buf); return !!!len; }
static bool encrypt_or_decrypt_block(RCore *core, const char *algo, const char *key, int direction) { //TODO: generalise no_key_mode for all non key encoding/decoding. int keylen = key ? strlen (key): 0; bool no_key_mode = !strcmp ("base64", algo) || !strcmp ("base91", algo); if (no_key_mode || keylen > 0) { RCrypto *cry = r_crypto_new (); if (r_crypto_use (cry, algo)) { ut8 *binkey = malloc (keylen + 1); if (binkey) { int len = no_key_mode ? 1 : r_hex_str2bin (key, binkey); if (len < 1) { len = keylen; strcpy ((char *)binkey, key); } else { keylen = len; } if (r_crypto_set_key (cry, binkey, keylen, 0, direction)) { r_crypto_update (cry, (const ut8*)core->block, core->blocksize); r_crypto_final (cry, NULL, 0); int result_size = 0; ut8 *result = r_crypto_get_output (cry, &result_size); if (result) { r_io_write_at (core->io, core->offset, result, result_size); eprintf ("Written %d bytes\n", result_size); free (result); } } else { eprintf ("Invalid key\n"); } free (binkey); return 0; } else { eprintf ("Cannot allocate %d bytes\n", keylen); } } else { eprintf ("Unknown %s algorithm '%s'\n", ((!direction) ? "encryption" : "decryption") ,algo); } r_crypto_free (cry); } else { eprintf ("%s key not defined. Use -S [key]\n", ((!direction) ? "Encryption" : "Decryption")); } return 1; }
static int __read(RIO *io, RIODesc *fd, ut8 *buf, int count) { int code, rlen; char *out, *url; int ret = 0; if (fd == NULL || fd->data == NULL) return -1; url = r_str_newf ("%s/p8%%20%d@%"PFMT64d, rURL(fd), count, io->off); out = r_socket_http_get (url, &code, &rlen); if (out && rlen>0) { ut8 *tmp = malloc (rlen+1); ret = r_hex_str2bin (out, tmp); memcpy (buf, tmp, R_MIN (count, rlen)); free (tmp); if (ret<0) ret = -ret; } free (out); free (url); return ret; }
R_API int cmd_write_hexpair(RCore* core, const char* pairs) { ut8 *buf = malloc (strlen (pairs) + 1); int len = r_hex_str2bin (pairs, buf); if (len != 0) { if (len < 0) { len = -len; if (len < core->blocksize) { buf[len-1] |= core->block[len-1] & 0xf; } } r_core_write_at (core, core->offset, buf, len); if (r_config_get_i (core->config, "cfg.wseek")) { r_core_seek_delta (core, len); } r_core_block_read (core); } else { eprintf ("Error: invalid hexpair string\n"); } free (buf); return len; }
// "dr8" read register state static int __io_read(RDebug *dbg, int type, ut8 *buf, int size) { dbg->iob.system (dbg->iob.io, "dr8"); char *regs = strdup (r_cons_get_buffer ()); ut8 *bregs = calloc (1, strlen (regs)); if (!bregs) { free (regs); return -1; } r_cons_reset (); int sz = r_hex_str2bin (regs, bregs); if (sz > 0) { memcpy (buf, bregs, R_MIN (size, sz)); free (bregs); free (regs); return size; } else { eprintf ("SIZE %d (%s)\n", sz, regs); } free (bregs); free (regs); return -1; }
static int __system(RIO *io, RIODesc *fd, const char *cmd) { /* XXX: test only for x86-32 */ if(!strcmp(cmd,"regs")){ int i; gdbwrap_readgenreg (RIOGDB_DESC (fd)); for (i=0; i<NUM_REGS; i++){ ut32 v = gdbwrap_getreg (RIOGDB_DESC (fd), i) & 0xFFFFFFFF; printf ("Reg #%d - %#x\n", i, v); } } else if (!strcmp (cmd, "stepi")) { gdbwrap_stepi (RIOGDB_DESC (fd)); } else if (!strcmp (cmd, "cont")) { gdbwrap_continue (RIOGDB_DESC (fd)); } else if (!strncmp (cmd, "bp", 2) && r_str_word_count (cmd)==2) { char *saddr = strrchr (cmd, ' '); //Assuming only spaces as separator, get last space if (saddr) { int addr; r_hex_str2bin (saddr, (ut8*)&addr); //TODO handle endianness local machine gdbwrap_simplesetbp (RIOGDB_DESC (fd), addr); } } return -1; }
R_API RSearchKeyword* r_search_keyword_new_str(const char *kw, const char *bmhex, const char *data, int icase) { RSearchKeyword *ks = NULL; int bmlen = 0; ut8 *bm = NULL; if (!kw) return NULL; if (bmhex != NULL) { bm = malloc (strlen (bmhex)+1); if (bm != NULL) { bmlen = r_hex_str2bin (bmhex, (ut8*)bm); if (bmlen<1) { free (bm); bm = NULL; } } } ks = r_search_keyword_new ((ut8 *)kw, strlen (kw), bm, bmlen, data); if (ks) { ks->icase = icase; ks->type = R_SEARCH_KEYWORD_TYPE_STRING; } free (bm); return ks; }
R_API RSearchKeyword* r_search_keyword_new_str(const char *kwbuf, const char *bmstr, const char *data, int ignore_case) { RSearchKeyword *kw; ut8 *bmbuf = NULL; int bmlen = 0; if (bmstr) { bmbuf = malloc (strlen (bmstr)+1); if (!bmbuf) return NULL; bmlen = r_hex_str2bin (bmstr, bmbuf); if (bmlen < 1) { free (bmbuf); bmbuf = NULL; } } kw = r_search_keyword_new ((ut8 *)kwbuf, strlen (kwbuf), bmbuf, bmlen, data); if (kw) { kw->icase = ignore_case; kw->type = R_SEARCH_KEYWORD_TYPE_STRING; } free (bmbuf); return kw; }
static void r2tox_addfriend(const char *addr) { if (!tox) { eprintf ("[tox] Not connected\n"); return; } char *a = strdup (addr); if (!a) { return; } char *b = strchr (a, ' '); uint8_t fa[128] = {0}; if (b) { *b++ = 0; } b = NULL; int len = r_hex_str2bin (a, &fa); printf ("LEN %d (%s)\n", len, a); // int friendid = tox_friend_add_norequest(tox, fa, NULL); int friendid = b ? tox_friend_add (tox, fa, b, strlen(b), NULL) : tox_friend_add (tox, fa, "hi there", 8, NULL); printf ("friendid %d\n", friendid); free (a); }
R_API RSearchKeyword* r_search_keyword_new_wide(const char *kwbuf, const char *bmstr, const char *data, int ignore_case) { RSearchKeyword *kw; int len; const char *p2; char *p, *str; ut8 *bmbuf = NULL; int bmlen = 0; if (bmstr) { bmbuf = malloc (strlen (bmstr)+1); if (!bmbuf) return NULL; bmlen = r_hex_str2bin (bmstr, bmbuf); if (bmlen < 1) { free(bmbuf); bmbuf = NULL; } } len = strlen(kwbuf); str = malloc((len+1)*2); for (p2=kwbuf, p=str; *p2; p+=2, p2++) { if (ignore_case) p[0] = tolower((const unsigned char)*p2); else p[0] = *p2; p[1] = 0; } kw = r_search_keyword_new ((ut8 *)str, len*2, bmbuf, bmlen, data); free(str); if (kw) { kw->icase = ignore_case; } free(bmbuf); return kw; }
static char *getstr(const char *src) { int len; char *ret = NULL; switch (*src) { case '\'': ret = strdup (src+1); if (ret) { len = strlen (ret); if (len>0) { len--; if (ret[len]=='\'') { ret[len] = 0; return ret; } else eprintf ("Missing \"\n"); } free (ret); } return NULL; case '"': ret = strdup (src+1); if (ret) { len = strlen (ret); if (len>0) { len--; if (ret[len]=='"') { ret[len] = 0; r_str_unescape (ret); return ret; } else eprintf ("Missing \"\n"); } free (ret); } return NULL; case '@': { char *pat = strchr (src+1, '@'); if (pat) { *pat++ = 0; int i, rep = atoi (src+1); int len = strlen (pat); if (rep>0) { char *buf = malloc (rep); for(i=0;i<rep;i++) { buf[i] = pat[i%len]; } return buf; } } // slurp file return r_file_slurp (src+1, NULL); } case '!': return r_str_trim_tail (r_sys_cmd_str (src+1, NULL, NULL)); case ':': if (src[1]=='!') { ret = r_str_trim_tail (r_sys_cmd_str (src+1, NULL, NULL)); } else { ret = strdup (src); } len = r_hex_str2bin (src+1, (ut8*)ret); if (len>0) { ret[len] = 0; return ret; } else { eprintf ("Invalid hexpair string\n"); free (ret); return NULL; } } r_str_unescape ((ret = strdup (src))); return ret; }
int main(int argc, char **argv) { const char *query = NULL; int c, bits = 0, actions_done = 0, actions = 0, action = ACTION_UNK; char *homeplugindir = r_str_home (R2_HOMEDIR"/plugins"); char *ptr, *arch = NULL, *arch_name = NULL; const char *op = NULL; RCoreBinFilter filter; RCore core; RCoreFile *cf = NULL; int xtr_idx = 0; // load all files if extraction is necessary. int fd = -1; int rawstr = 0; r_core_init (&core); bin = core.bin; l = r_lib_new ("radare_plugin"); r_lib_add_handler (l, R_LIB_TYPE_BIN, "bin plugins", &__lib_bin_cb, &__lib_bin_dt, NULL); r_lib_add_handler (l, R_LIB_TYPE_BIN_XTR, "bin xtr plugins", &__lib_bin_xtr_cb, &__lib_bin_xtr_dt, NULL); /* load plugins everywhere */ r_lib_opendir (l, getenv ("LIBR_PLUGINS")); r_lib_opendir (l, homeplugindir); r_lib_opendir (l, LIBDIR"/radare2/"R2_VERSION); #define is_active(x) (action&x) #define set_action(x) actions++; action |=x while ((c = getopt (argc, argv, "jgqAf:a:B:b:c:Ck:dMm:n:N:@:isSIHelRwO:o:rvLhxzZ")) != -1) { switch (c) { case 'g': set_action (ACTION_CLASSES); set_action (ACTION_IMPORTS); set_action (ACTION_SYMBOLS); set_action (ACTION_SECTIONS); set_action (ACTION_STRINGS); set_action (ACTION_SIZE); set_action (ACTION_INFO); set_action (ACTION_FIELDS); set_action (ACTION_DWARF); set_action (ACTION_ENTRIES); set_action (ACTION_MAIN); set_action (ACTION_LIBS); set_action (ACTION_RELOCS); set_action (ACTION_EXTRACT); break; case 'q': rad = R_CORE_BIN_SIMPLE; break; case 'j': rad = R_CORE_BIN_JSON; break; case 'A': set_action (ACTION_LISTARCHS); break; case 'a': if (optarg) arch = optarg; break; case 'c': if (!optarg) { eprintf ("Missing argument for -c"); return 1; } set_action (ACTION_CREATE); create = strdup (optarg); break; case 'k': query = optarg; break; case 'C': set_action (ACTION_CLASSES); break; case 'f': if (optarg) arch_name = strdup (optarg); break; case 'b': bits = r_num_math (NULL, optarg); break; case 'm': at = r_num_math (NULL, optarg); set_action (ACTION_SRCLINE); break; case 'i': set_action (ACTION_IMPORTS); break; case 's': set_action (ACTION_SYMBOLS); break; case 'S': set_action (ACTION_SECTIONS); break; case 'z': if (is_active (ACTION_STRINGS)) { rawstr = R_TRUE; } else set_action (ACTION_STRINGS); break; case 'Z': set_action (ACTION_SIZE); break; case 'I': set_action (ACTION_INFO); break; case 'H': set_action (ACTION_FIELDS); break; case 'd': set_action (ACTION_DWARF); break; case 'e': set_action (ACTION_ENTRIES); break; case 'M': set_action (ACTION_MAIN); break; case 'l': set_action (ACTION_LIBS); break; case 'R': set_action (ACTION_RELOCS); break; case 'x': set_action (ACTION_EXTRACT); break; case 'w': rw = R_TRUE; break; case 'O': op = optarg; set_action (ACTION_OPERATION); if (op && !strcmp (op, "help")) { printf ("Operation string:\n" " Dump symbols: d/s/1024\n" " Dump section: d/S/.text\n" " Resize section: r/.data/1024\n"); return 0; } if (optind==argc) { eprintf ("Missing filename\n"); return 1; } break; case 'o': output = optarg; break; case 'r': rad = R_TRUE; break; case 'v': va = R_TRUE; break; case 'L': r_bin_list (bin); return 1; case 'B': baddr = r_num_math (NULL, optarg); break; case '@': at = r_num_math (NULL, optarg); break; case 'n': name = optarg; break; case 'N': bin->minstrlen = r_num_math (NULL, optarg); break; //case 'V': return blob_version ("rabin2"); case 'h': return rabin_show_help (1); default: action |= ACTION_HELP; } } file = argv[optind]; if (!query) if (action & ACTION_HELP || action == ACTION_UNK || file == NULL) { if (va) return blob_version ("rabin2"); return rabin_show_help (0); } if (arch) { ptr = strchr (arch, '_'); if (ptr) { *ptr = '\0'; bits = r_num_math (NULL, ptr+1); } } if (action & ACTION_CREATE) { // TODO: move in a function outside RBuffer *b; int datalen, codelen; ut8 *data = NULL, *code = NULL; char *p2, *p = strchr (create, ':'); if (!p) { eprintf ("Invalid format for -c flag. Use 'format:codehexpair:datahexpair'\n"); return 1; } *p++ = 0; p2 = strchr (p, ':'); if (p2) { // has data *p2++ = 0; data = malloc (strlen (p2)+1); datalen = r_hex_str2bin (p2, data); } else { data = NULL; datalen = 0; } code = malloc (strlen (p)+1); if (!code) { return 1; } codelen = r_hex_str2bin (p, code); if (!arch) arch = "x86"; if (!bits) bits = 32; if (!r_bin_use_arch (bin, arch, bits, create)) { eprintf ("Cannot set arch\n"); return 1; } b = r_bin_create (bin, code, codelen, data, datalen); if (b) { if (r_file_dump (file, b->buf, b->length)) { eprintf ("dumped %d bytes in '%s'\n", b->length, file); r_file_chmod (file, "+x", 0); } else eprintf ("error dumping into a.out\n"); r_buf_free (b); } else eprintf ("Cannot create binary for this format '%s'.\n", create); r_bin_free (bin); return 0; } r_config_set_i (core.config, "bin.rawstr", rawstr); cf = r_core_file_open (&core, file, R_IO_READ, 0); fd = cf ? r_core_file_cur_fd (&core) : -1; if (!cf || fd == -1) { eprintf ("r_core: Cannot open file\n"); return 1; } if (!r_bin_load (bin, file, baddr, 0, xtr_idx, fd, rawstr)) { if (!r_bin_load (bin, file, baddr, 0, xtr_idx, fd, rawstr)) { eprintf ("r_bin: Cannot open file\n"); return 1; } } if (query) { if (!strcmp (query, "-")) { __sdb_prompt (bin->cur->sdb); } else sdb_query (bin->cur->sdb, query); return 0; } // XXX: TODO move this to libr/core/bin.c if (action & ACTION_LISTARCHS || ((arch || bits || arch_name) && !r_bin_select (bin, arch, bits, arch_name))) { if (rad == R_CORE_BIN_JSON) { int i; printf ("["); for (i = 0; i < bin->narch; i++) { if (r_bin_select_idx (bin, bin->file, i)) { RBinObject *o = r_bin_cur_object (bin); RBinInfo *info = o ? o->info : NULL; printf ("%s{\"arch\":\"%s\",\"bits\":%d," "\"offset\":%"PFMT64d",\"machine\":\"%s\"}", i?",":"",info->arch, info->bits, bin->cur->offset, info->machine); } } printf ("]"); } else r_bin_list_archs (bin, 1); free (arch_name); } if (baddr != 0LL) { r_bin_set_baddr (bin, baddr); bin->cur->o->baddr = baddr; } core.bin = bin; filter.offset = at; filter.name = name; r_cons_new ()->is_interactive = R_FALSE; #define isradjson (rad==R_CORE_BIN_JSON&&actions>0) #define run_action(n,x,y) {\ if (action&x) {\ if (isradjson) r_cons_printf ("\"%s\":",n);\ if (!r_core_bin_info (&core, y, rad, va, &filter, 0)) {\ if (isradjson) r_cons_printf("false");\ };\ actions_done++;\ if (isradjson) r_cons_printf (actions==actions_done? "":",");\ }\ } if (isradjson) r_cons_printf ("{"); run_action ("sections", ACTION_SECTIONS, R_CORE_BIN_ACC_SECTIONS); run_action ("entries", ACTION_ENTRIES, R_CORE_BIN_ACC_ENTRIES); run_action ("main", ACTION_MAIN, R_CORE_BIN_ACC_MAIN); run_action ("imports", ACTION_IMPORTS, R_CORE_BIN_ACC_IMPORTS); run_action ("classes", ACTION_CLASSES, R_CORE_BIN_ACC_CLASSES); run_action ("symbols", ACTION_SYMBOLS, R_CORE_BIN_ACC_SYMBOLS); run_action ("strings", ACTION_STRINGS, R_CORE_BIN_ACC_STRINGS); run_action ("info", ACTION_INFO, R_CORE_BIN_ACC_INFO); run_action ("fields", ACTION_FIELDS, R_CORE_BIN_ACC_FIELDS); run_action ("libs", ACTION_LIBS, R_CORE_BIN_ACC_LIBS); run_action ("relocs", ACTION_RELOCS, R_CORE_BIN_ACC_RELOCS); run_action ("dwarf", ACTION_DWARF, R_CORE_BIN_ACC_DWARF); run_action ("size", ACTION_SIZE, R_CORE_BIN_ACC_SIZE); if (action&ACTION_SRCLINE) rabin_show_srcline (at); if (action&ACTION_EXTRACT) rabin_extract ((arch==NULL && arch_name==NULL && bits==0)); if (op != NULL && action&ACTION_OPERATION) rabin_do_operation (op); if (isradjson) printf ("}"); r_cons_flush (); r_core_fini (&core); return 0; }
/* TODO: simplify using r_write */ static int cmd_write(void *data, const char *input) { ut64 off; ut8 *buf; const char *arg; int wseek, i, size, len = strlen (input); char *tmp, *str, *ostr; RCore *core = (RCore *)data; #define WSEEK(x,y) if(wseek)r_core_seek_delta(x,y) wseek = r_config_get_i (core->config, "cfg.wseek"); str = ostr = strdup (input+1); switch (*input) { case 'p': if (input[1]==' ' && input[2]) { r_core_patch (core, input+2); } else { eprintf ("Usage: wp [rapatch-file]\n" "TODO: rapatch format documentation here\n"); } break; case 'r': off = r_num_math (core->num, input+1); len = (int)off; if (len>0) { buf = malloc (len); if (buf != NULL) { r_num_irand (); for (i=0; i<len; i++) buf[i] = r_num_rand (256); r_core_write_at (core, core->offset, buf, len); WSEEK (core, len); free (buf); } else eprintf ("Cannot allocate %d bytes\n", len); } break; case 'A': switch (input[1]) { case ' ': if (input[2] && input[3]==' ') { r_asm_set_pc (core->assembler, core->offset); eprintf ("modify (%c)=%s\n", input[2], input+4); len = r_asm_modify (core->assembler, core->block, input[2], r_num_math (core->num, input+4)); eprintf ("len=%d\n", len); if (len>0) { r_core_write_at (core, core->offset, core->block, len); WSEEK (core, len); } else eprintf ("r_asm_modify = %d\n", len); } else eprintf ("Usage: wA [type] [value]\n"); break; case '?': default: r_cons_printf ("Usage: wA [type] [value]\n" "Types:\n" " r raw write value\n" " v set value (taking care of current address)\n" " d destination register\n" " 0 1st src register\n" " 1 2nd src register\n" "Example: wA r 0 # e800000000\n"); break; } break; case 'c': switch (input[1]) { case 'i': r_io_cache_commit (core->io); r_core_block_read (core, 0); break; case 'r': r_io_cache_reset (core->io, R_TRUE); /* Before loading the core block we have to make sure that if * the cache wrote past the original EOF these changes are no * longer displayed. */ memset (core->block, 0xff, core->blocksize); r_core_block_read (core, 0); break; case '-': if (input[2]=='*') { r_io_cache_reset (core->io, R_TRUE); } else if (input[2]==' ') { char *p = strchr (input+3, ' '); ut64 to, from = core->offset; if (p) { *p = 0; from = r_num_math (core->num, input+3); to = r_num_math (core->num, input+3); if (to<from) { eprintf ("Invalid range (from>to)\n"); return 0; } } else { from = r_num_math (core->num, input+3); to = from + core->blocksize; } r_io_cache_invalidate (core->io, from, to); } else { eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset); r_io_cache_invalidate (core->io, core->offset, core->offset+core->blocksize); } /* See 'r' above. */ memset (core->block, 0xff, core->blocksize); r_core_block_read (core, 0); break; case '?': r_cons_printf ( "Usage: wc[ir*?]\n" " wc list all write changes\n" " wc- [a] [b] remove write op at curseek or given addr\n" " wc* \"\" in radare commands\n" " wcr reset all write changes in cache\n" " wci commit write cache\n" "NOTE: Requires 'e io.cache=true'\n"); break; case '*': r_io_cache_list (core->io, R_TRUE); break; case '\0': r_io_cache_list (core->io, R_FALSE); break; } break; case ' ': /* write string */ len = r_str_escape (str); r_core_write_at (core, core->offset, (const ut8*)str, len); #if 0 r_io_set_fd (core->io, core->file->fd); r_io_write_at (core->io, core->offset, (const ut8*)str, len); #endif WSEEK (core, len); r_core_block_read (core, 0); break; case 't': if (*str != ' ') { eprintf ("Usage: wt file [size]\n"); } else { tmp = strchr (str+1, ' '); if (tmp) { st64 sz = (st64) r_num_math (core->num, tmp+1); *tmp = 0; if (sz<1) eprintf ("Invalid length\n"); else r_core_dump (core, str+1, core->offset, (ut64)sz); } else r_file_dump (str+1, core->block, core->blocksize); } break; case 'T': eprintf ("TODO: wT // why?\n"); break; case 'f': arg = (const char *)(input+((input[1]==' ')?2:1)); if ((buf = (ut8*) r_file_slurp (arg, &size))) { r_io_set_fd (core->io, core->file->fd); r_io_write_at (core->io, core->offset, buf, size); WSEEK (core, size); free(buf); r_core_block_read (core, 0); } else eprintf ("Cannot open file '%s'\n", arg); break; case 'F': arg = (const char *)(input+((input[1]==' ')?2:1)); if ((buf = r_file_slurp_hexpairs (arg, &size))) { r_io_set_fd (core->io, core->file->fd); r_io_write_at (core->io, core->offset, buf, size); WSEEK (core, size); free (buf); r_core_block_read (core, 0); } else eprintf ("Cannot open file '%s'\n", arg); break; case 'w': str++; len = (len-1)<<1; if (len>0) tmp = malloc (len+1); else tmp = NULL; if (tmp) { for (i=0; i<len; i++) { if (i%2) tmp[i] = 0; else tmp[i] = str[i>>1]; } str = tmp; r_io_set_fd (core->io, core->file->fd); r_io_write_at (core->io, core->offset, (const ut8*)str, len); WSEEK (core, len); r_core_block_read (core, 0); free (tmp); } else eprintf ("Cannot malloc %d\n", len); break; case 'x': { int b, len = strlen (input); ut8 *buf = malloc (len+1); len = r_hex_str2bin (input+1, buf); if (len != 0) { if (len<0) len = -len+1; b = core->block[len]&0xf; b |= (buf[len]&0xf0); buf[len] = b; r_core_write_at (core, core->offset, buf, len); WSEEK (core, len); r_core_block_read (core, 0); } else eprintf ("Error: invalid hexpair string\n"); free (buf); } break; case 'a': 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); if (acode) { if (input[1]=='*') { 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); } } 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 (hack)\n"); break; } break; case 'b': { int len = strlen (input); ut8 *buf = malloc (len+1); if (buf) { len = r_hex_str2bin (input+1, buf); if (len > 0) { r_mem_copyloop (core->block, buf, core->blocksize, len); r_core_write_at (core, core->offset, core->block, core->blocksize); WSEEK (core, core->blocksize); r_core_block_read (core, 0); } else eprintf ("Wrong argument\n"); } else eprintf ("Cannot malloc %d\n", len+1); } break; case 'm': size = r_hex_str2bin (input+1, (ut8*)str); switch (input[1]) { case '\0': eprintf ("Current write mask: TODO\n"); // TODO break; case '?': break; case '-': r_io_set_write_mask(core->io, 0, 0); eprintf ("Write mask disabled\n"); break; case ' ': if (size>0) { r_io_set_fd (core->io, core->file->fd); r_io_set_write_mask (core->io, (const ut8*)str, size); WSEEK (core, size); eprintf ("Write mask set to '"); for (i=0; i<size; i++) eprintf ("%02x", str[i]); eprintf ("'\n"); } else eprintf ("Invalid string\n"); break; } break; case 'v': { int type = 0; ut8 addr1; ut16 addr2; ut32 addr4, addr4_; ut64 addr8; switch (input[1]) { case '?': r_cons_printf ("Usage: wv[size] [value] # write value of given size\n" " wv1 234 # write one byte with this value\n" " wv 0x834002 # write dword with this value\n" "Supported sizes are: 1, 2, 4, 8\n"); return 0; case '1': type = 1; break; case '2': type = 2; break; case '4': type = 4; break; case '8': type = 8; break; } off = r_num_math (core->num, input+2); r_io_set_fd (core->io, core->file->fd); r_io_seek (core->io, core->offset, R_IO_SEEK_SET); if (type == 0) type = (off&UT64_32U)? 8: 4; switch (type) { case 1: addr1 = (ut8)off; r_io_write (core->io, (const ut8 *)&addr1, 1); WSEEK (core, 1); break; case 2: addr2 = (ut16)off; r_io_write (core->io, (const ut8 *)&addr2, 2); WSEEK (core, 2); break; case 4: addr4_ = (ut32)off; //drop_endian((ut8*)&addr4_, (ut8*)&addr4, 4); /* addr4_ = addr4 */ //endian_memcpy((ut8*)&addr4, (ut8*)&addr4_, 4); /* addr4 = addr4_ */ memcpy ((ut8*)&addr4, (ut8*)&addr4_, 4); // XXX needs endian here too r_io_write (core->io, (const ut8 *)&addr4, 4); WSEEK (core, 4); break; case 8: /* 8 byte addr */ memcpy ((ut8*)&addr8, (ut8*)&off, 8); // XXX needs endian here // endian_memcpy((ut8*)&addr8, (ut8*)&off, 8); r_io_write (core->io, (const ut8 *)&addr8, 8); WSEEK (core, 8); break; } r_core_block_read (core, 0); } break; case 'o': switch (input[1]) { case 'a': case 's': case 'A': case 'x': case 'r': case 'l': case 'm': case 'd': case 'o': case 'w': if (input[2]!=' ') { r_cons_printf ("Usage: 'wo%c 00 11 22'\n", input[1]); return 0; } case '2': case '4': r_core_write_op (core, input+3, input[1]); r_core_block_read (core, 0); break; case 'n': r_core_write_op (core, "ff", 'x'); r_core_block_read (core, 0); break; case '\0': case '?': default: r_cons_printf ( "Usage: wo[asmdxoArl24] [hexpairs] @ addr[:bsize]\n" "Example:\n" " wox 0x90 ; xor cur block with 0x90\n" " wox 90 ; xor cur block with 0x90\n" " wox 0x0203 ; xor cur block with 0203\n" " woa 02 03 ; add [0203][0203][...] to curblk\n" "Supported operations:\n" " wow == write looped value (alias for 'wb')\n" " woa += addition\n" " wos -= substraction\n" " wom *= multiply\n" " wod /= divide\n" " wox ^= xor\n" " woo |= or\n" " woA &= and\n" " wor >>= shift right\n" " wol <<= shift left\n" " wo2 2= 2 byte endian swap\n" " wo4 4= 4 byte endian swap\n" ); break; } break; default: case '?': if (core->oobi) { eprintf ("Writing oobi buffer!\n"); r_io_set_fd (core->io, core->file->fd); r_io_write (core->io, core->oobi, core->oobi_len); WSEEK (core, core->oobi_len); r_core_block_read (core, 0); } else r_cons_printf ( "Usage: w[x] [str] [<file] [<<EOF] [@addr]\n" " w foobar write string 'foobar'\n" " wr 10 write 10 random bytes\n" " ww foobar write wide string 'f\\x00o\\x00o\\x00b\\x00a\\x00r\\x00'\n" " wa push ebp write opcode, separated by ';' (use '\"' around the command)\n" " waf file assemble file and write bytes\n" " wA r 0 alter/modify opcode at current seek (see wA?)\n" " wb 010203 fill current block with cyclic hexpairs\n" " wc[ir*?] write cache commit/reset/list\n" " wx 9090 write two intel nops\n" " wv eip+34 write 32-64 bit value\n" " wo? hex write in block with operation. 'wo?' fmi\n" " wm f0ff set binary mask hexpair to be used as cyclic write mask\n" " wf file write contents of file at current offset\n" " wF file write contents of hexpairs file here\n" " wt file [sz] write to file (from current seek, blocksize or sz bytes)\n" " wp file apply radare patch file. See wp? fmi\n"); //TODO: add support for offset+seek // " wf file o s ; write contents of file from optional offset 'o' and size 's'.\n" break; }
int main(int argc, char **argv) { int i, ret, c, rad = 0, bsize = 0, numblocks = 0, ule = 0, b64mode = 0; const char *algo = "sha256"; /* default hashing algorithm */ const char *seed = NULL; char *hashstr = NULL; int hashstr_len = 0; int hashstr_hex = 0; ut64 algobit; RHash *ctx; RIO *io; while ((c = getopt (argc, argv, "jdDrvea:i:S:s:x:b:nBhf:t:kLq")) != -1) { switch (c) { case 'q': quiet = 1; break; case 'i': iterations = atoi (optarg); if (iterations<0) { eprintf ("error: -i argument must be positive\n"); return 1; } break; case 'j': rad = 'j'; break; case 'S': seed = optarg; break; case 'n': numblocks = 1; break; case 'd': b64mode = 1; break; case 'D': b64mode = 2; break; case 'L': algolist (); return 0; case 'e': ule = 1; break; case 'r': rad = 1; break; case 'k': rad = 2; break; case 'a': algo = optarg; break; case 'B': incremental = 0; break; case 'b': bsize = (int)r_num_math (NULL, optarg); break; case 'f': from = r_num_math (NULL, optarg); break; case 't': to = 1+r_num_math (NULL, optarg); break; case 'v': return blob_version ("rahash2"); case 'h': return do_help (0); case 's': setHashString (optarg, 0); break; case 'x': setHashString (optarg, 1); break; break; default: eprintf ("rahash2: Unknown flag\n"); return 1; } } if ((st64)from>=0 && (st64)to<0) { to = 0; // end of file } if (from || to) { if (to && from>=to) { eprintf ("Invalid -f or -t offsets\n"); return 1; } } do_hash_seed (seed); if (hashstr) { #define INSIZE 32768 if (!strcmp (hashstr, "-")) { int res = 0; hashstr = malloc (INSIZE); if (!hashstr) return 1; res = fread ((void*)hashstr, 1, INSIZE-1, stdin); if (res<1) res = 0; hashstr[res] = '\0'; hashstr_len = res; } if (hashstr_hex) { ut8 *out = malloc ((strlen (hashstr)+1)*2); hashstr_len = r_hex_str2bin (hashstr, out); if (hashstr_len<1) { eprintf ("Invalid hex string\n"); free (out); } hashstr = (char *)out; /* out memleaks here, hashstr can't be freed */ } else { hashstr_len = strlen (hashstr); } if (from) { if (from>=hashstr_len) { eprintf ("Invalid -f.\n"); return 1; } } if (to) { if (to>hashstr_len) { eprintf ("Invalid -t.\n"); return 1; } } else { to = hashstr_len; } hashstr = hashstr+from; hashstr_len = to-from; hashstr[hashstr_len] = '\0'; hashstr_len = r_str_unescape (hashstr); switch (b64mode) { case 1: // encode { char *out = malloc (((hashstr_len+1)*4)/3); if (out) { r_base64_encode (out, (const ut8*)hashstr, hashstr_len); printf ("%s\n", out); fflush (stdout); free (out); } } break; case 2: // decode { ut8 *out = malloc (INSIZE); if (out) { int outlen = r_base64_decode (out, (const char *)hashstr, hashstr_len); write (1, out, outlen); free (out); } } break; default: { char *str = (char *)hashstr; int strsz = hashstr_len; if (_s) { // alloc/concat/resize str = malloc (strsz + s.len); if (s.prefix) { memcpy (str, s.buf, s.len); memcpy (str+s.len, hashstr, hashstr_len); } else { memcpy (str, hashstr, hashstr_len); memcpy (str+strsz, s.buf, s.len); } strsz += s.len; str[strsz] = 0; } algobit = r_hash_name_to_bits (algo); for (i=1; i<0x800000; i<<=1) { if (algobit & i) { int hashbit = i & algobit; ctx = r_hash_new (R_TRUE, hashbit); from = 0; to = strsz; do_hash_internal (ctx, hashbit, (const ut8*)str, strsz, rad, 1, ule); r_hash_free (ctx); } } if (_s) { free (str); free (s.buf); } } } return 0; } if (optind>=argc) return do_help (1); if (numblocks) { bsize = -bsize; } else if (bsize<0) { eprintf ("rahash2: Invalid block size\n"); return 1; } io = r_io_new (); for (ret=0, i=optind; i<argc; i++) { switch (b64mode) { case 1: // encode { int binlen; char *out; ut8 *bin = (ut8*)r_file_slurp (argv[i], &binlen); if (!bin) { eprintf ("Cannot open file\n"); continue; } out = malloc (((binlen+1)*4)/3); if (out) { r_base64_encode (out, bin, binlen); printf ("%s\n", out); fflush (stdout); free (out); } free (bin); } break; case 2: // decode { int binlen, outlen; ut8 *out, *bin = (ut8*)r_file_slurp (argv[i], &binlen); if (!bin) { eprintf ("Cannot open file\n"); continue; } out = malloc (binlen+1); if (out) { outlen = r_base64_decode (out, (const char*)bin, binlen); write (1, out, outlen); free (out); } free (bin); } break; default: if (r_file_is_directory (argv[i])) { eprintf ("rahash2: Cannot hash directories\n"); return 1; } if (!r_io_open_nomap (io, argv[i], 0, 0)) { eprintf ("rahash2: Cannot open '%s'\n", argv[i]); return 1; } ret |= do_hash (argv[i], algo, io, bsize, rad, ule); } } free (hashstr); r_io_free (io); return ret; }