static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) { if (__plugin_open (io, pathname,0)) { RIOSparse *mal = R_NEW0 (RIOSparse); int size = (int)r_num_math (NULL, pathname + 9); mal->buf = r_buf_new_sparse (io->Oxff); if (!mal->buf) { free (mal); return NULL; } if (size > 0) { ut8 *data = malloc (size); if (!data) { eprintf ("Cannot allocate (%s) %d byte(s)\n", pathname+9, size); mal->offset = 0; } else { memset (data, 0x00, size); r_buf_write_at (mal->buf, 0, data, size); free (data); } } if (mal->buf) { return r_io_desc_new (io, &r_io_plugin_sparse, pathname, rw, mode, mal); } r_buf_free (mal->buf); free (mal); } return NULL; }
static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) { if (__plugin_open (io, pathname,0)) { RIOSparse *mal = R_NEW0 (RIOSparse); mal->fd = -2; /* causes r_io_desc_new() to set the correct fd */ int size = (int)r_num_math (NULL, pathname+9); mal->buf = r_buf_new_sparse (); if (size>0) { ut8 *data = malloc (size); if (!data) { eprintf ("Cannot allocate (%s) %d bytes\n", pathname+9, size); mal->offset = 0; } else { memset (data, 0x00, size); r_buf_write_at (mal->buf, 0, data, size); free (data); } } if (mal->buf) { RETURN_IO_DESC_NEW (&r_io_plugin_sparse, mal->fd, pathname, rw, mode, mal); } r_buf_free (mal->buf); free (mal); } return NULL; }
static void __patch_reloc(RBuffer *buf, ut32 addr_to_patch, ut32 data_offset) { ut8 val[4] = { 0 }; r_write_le32 (val, data_offset); r_buf_write_at (buf, addr_to_patch, (void *) val, sizeof (val)); }
static int __write(RIO *io, RIODesc *fd, const ut8 *buf, int count) { ut64 o; RBuffer *b; if (fd == NULL || fd->data == NULL) return -1; b = RIOSPARSE_BUF(fd); o = RIOSPARSE_OFF(fd); return r_buf_write_at (b, o, buf, count); }
static RBuffer *build (REgg *egg) { RBuffer *buf = r_buf_new (); const ut8 *sc = NULL; int cd = 0; char *port = r_egg_option_get (egg, "port"); //TODO: char *udp = r_egg_option_get (egg, "udp"); switch (egg->os) { case R_EGG_OS_OSX: case R_EGG_OS_DARWIN: switch (egg->arch) { case R_SYS_ARCH_X86: if (suid) { sc = x86_osx_suid_binsh; cd = 7+36; } else { sc = x86_osx_binsh; cd = 36; } case R_SYS_ARCH_ARM: // TODO break; } break; case R_EGG_OS_LINUX: if (suid) eprintf ("no suid for this platform\n"); suid = 0; switch (egg->arch) { case R_SYS_ARCH_X86: switch (egg->bits) { case 32: sc = x86_linux_binsh; break; case 64: sc = x86_64_linux_binsh; break; default: eprintf ("Unsupportted\n"); } break; case R_SYS_ARCH_ARM: sc = arm_linux_binsh; break; } break; default: eprintf ("unsupported os %x\n", egg->os); break; } if (sc) { r_buf_set_bytes (buf, sc, strlen ((const char *)sc)); if (shell && *shell) { if (cd) r_buf_write_at (buf, cd, (const ut8*)shell, strlen (shell)+1); else eprintf ("Cannot set shell\n"); } } free (suid); free (shell); return buf; }
static RBuffer *build (REgg *egg) { RBuffer *buf, *sc; ut8 aux[32], nkey; const char *default_key = DEFAULT_XOR_KEY; char *key = r_egg_option_get (egg, "key"); int i; if (!key || !*key) { free (key); key = strdup (default_key); eprintf ("XOR key not provided. Using (%s) as the key\n", key); } nkey = r_num_math (NULL, key); if (nkey == 0) { eprintf ("Invalid key (%s)\n", key); free (key); return false; } if (nkey != (nkey & 0xff)) { nkey &= 0xff; eprintf ("xor key wrapped to (%d)\n", nkey); } if (r_buf_size (egg->bin) > 240) { // XXX eprintf ("shellcode is too long :(\n"); free (key); return NULL; } sc = egg->bin; // hack if (!r_buf_size (sc)) { eprintf ("No shellcode found!\n"); free (key); return NULL; } for (i = 0; i<r_buf_size (sc); i++) { // eprintf ("%02x -> %02x\n", sc->buf[i], sc->buf[i] ^nkey); if ((r_buf_read8_at (sc, i) ^ nkey)==0) { eprintf ("This xor key generates null bytes. Try again.\n"); free (key); return NULL; } } buf = r_buf_new (); sc = r_buf_new (); // TODO: alphanumeric? :D // This is the x86-32/64 xor encoder r_buf_append_buf (sc, egg->bin); if (egg->arch == R_SYS_ARCH_X86) { #define STUBLEN 18 ut8 stub[STUBLEN] = "\xe8\xff\xff\xff\xff" // call $$+4 "\xc1" // ffc1 = inc ecx "\x5e" // pop esi "\x48\x83\xc6\x0d" // add rsi, xx ... 64bit // loop0: "\x30\x1e" // xor [esi], bl "\x48\xff\xc6" // inc rsi "\xe2\xf9"; // loop loop0 // ecx = length aux[0] = 0x6a; // push length aux[1] = r_buf_size (sc); aux[2] = 0x59; // pop ecx // ebx = key aux[3] = 0x6a; // push key aux[4] = nkey; aux[5] = 0x5b; // pop ebx r_buf_set_bytes (buf, aux, 6); r_buf_append_bytes (buf, stub, STUBLEN); for (i = 0; i<r_buf_size (sc); i++) { ut8 v = r_buf_read8_at (sc, i) ^ nkey; r_buf_write_at (sc, i, &v, sizeof (v)); } r_buf_append_buf (buf, sc); } r_buf_free (sc); free (key); return buf; }
static int r_bin_dyldcache_apply_patch (struct r_buf_t* buf, ut32 data, ut64 offset) { return r_buf_write_at (buf, offset, (ut8*)&data, sizeof (data)); }