static int load(RBinFile *arch) { const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL; ut64 sz = arch ? r_buf_size (arch->buf): 0; if (!arch || !arch->o) return false; arch->o->bin_obj = load_bytes (arch, bytes, sz, arch->o->loadaddr, arch->sdb); return arch->o->bin_obj ? true: false; }
static int load(RBinFile *arch) { const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL; ut64 sz = arch ? r_buf_size (arch->buf): 0; if (!arch || !arch->o) return R_FALSE; arch->o->bin_obj = load_bytes (bytes, sz, arch->o->loadaddr, arch->sdb); return arch->o->bin_obj ? R_TRUE: R_FALSE; }
static bool load(RBinFile *arch) { if (arch && arch->buf) { const ut8 *bytes = r_buf_buffer (arch->buf); ut64 sz = r_buf_size (arch->buf); return load_bytes (arch, bytes, sz, arch->o->loadaddr, arch->sdb) != NULL; } return false; }
R_API RIODesc *r_io_open_buffer(RIO *io, RBuffer *b, int flags, int mode) { const int bufSize = r_buf_size (b); char *uri = r_str_newf ("malloc://%d", bufSize); RIODesc *desc = r_io_open_nomap (io, uri, flags, mode); if (desc) { r_io_desc_write (desc, r_buf_get_at(b, 0, NULL), bufSize); } return desc; }
static bool load(RBinFile *arch) { const ut8 *bytes = arch? r_buf_buffer (arch->buf): NULL; ut64 sz = arch? r_buf_size (arch->buf): 0; if (!arch || !arch->o) { return false; } arch->rbin->maxstrbuf = 0x20000000; return check_bytes (bytes, sz); }
static bool load(RBinFile *bf) { const ut8 *bytes = bf? r_buf_buffer (bf->buf): NULL; ut64 sz = bf? r_buf_size (bf->buf): 0; if (!bf || !bf->o) { return false; } bf->o->bin_obj = load_bytes (bf, bytes, sz, bf->o->loadaddr, bf->sdb); return check_bytes (bytes, sz); }
static int check(RBinFile *arch) { const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL; const ut64 size = arch ? r_buf_size (arch->buf) : 0; if (!arch || !arch->o || !bytes) return false; return check_bytes(bytes, size); }
static bool load(RBinFile *bf) { if (!bf || !bf->buf || !bf->o) { return false; } const ut64 sz = r_buf_size (bf->buf); const ut64 la = bf->o->loadaddr; const ut8 *bytes = r_buf_buffer (bf->buf); bf->o->bin_obj = load_bytes (bf, bytes, sz, la, bf->sdb); return bf->o->bin_obj != NULL; }
static bool load(RBinFile *bf) { if (!bf || !bf->o) { return false; } const ut8 *bytes = r_buf_buffer (bf->buf); ut64 sz = r_buf_size (bf->buf); const void *res = load_bytes (bf, bytes, sz, bf->o->loadaddr, bf->sdb); bf->o->bin_obj = (void *)res; return res != NULL; }
struct r_bin_zimg_obj_t* r_bin_zimg_new_buf(RBuffer *buf) { struct r_bin_zimg_obj_t *bin = R_NEW0 (struct r_bin_zimg_obj_t); if (!bin) { goto fail; } bin->size = r_buf_size (buf); bin->b = r_buf_ref (buf); if (r_buf_size (bin->b) < sizeof (struct zimg_header_t)) { goto fail; } r_buf_read_at (bin->b, 0, (ut8 *)&bin->header, sizeof (bin->header)); return bin; fail: if (bin) { r_buf_free (bin->b); free (bin); } return NULL; }
static int load(RBinFile *arch) { const ut8 *byte = arch ? r_buf_buffer(arch->buf) : NULL; ut64 size = arch ? r_buf_size(arch->buf) : 0; if (!arch || !arch->o) { return false; } if (!(arch->o->bin_obj = load_bytes(arch, byte, \ size, arch->o->loadaddr, arch->sdb))) return false; return true; }
static int load(RBinFile *arch) { const void *res; const ut8 *bytes; ut64 sz; if (!arch || !arch->o) return false; bytes = r_buf_buffer (arch->buf); sz = r_buf_size (arch->buf); res = load_bytes (arch, bytes, sz, arch->o->loadaddr, arch->sdb); arch->o->bin_obj = (void *)res; return res != NULL; }
static RList* entries(RBinFile *arch) { RList* ret = r_list_new ();; RBinAddr *ptr = NULL; RRarBinObj *bin_obj = arch && arch->o ? arch->o->bin_obj : NULL; const ut8 *buf = bin_obj ? r_buf_buffer (bin_obj->buf) : NULL; ut64 sz = arch && bin_obj ? r_buf_size (bin_obj->buf) : 0; if (!ret) return NULL; ret->free = free; if (bin_obj && sz > 0x30 && !memcmp (buf+0x30, RAR_CONST, 16)) { if ((ptr = R_NEW (RBinAddr))) { ptr->vaddr = ptr->paddr = 0x9a; r_list_append (ret, ptr); } } return ret; }
static RList *sections(RBinFile *arch) { RList *ret = NULL; RBinSection *ptr = NULL; RRarBinObj *bin_obj = arch && arch->o? arch->o->bin_obj: NULL; const ut8 *buf = bin_obj? r_buf_buffer (bin_obj->buf): NULL; ut64 sz = 0; if (bin_obj) { sz = r_buf_size (bin_obj->buf); } if (!(ret = r_list_new ())) { return NULL; } ret->free = free; // TODO: return NULL here? if (!buf || sz < 0x30 || memcmp (buf + 0x30, RAR_CONST, 16)) { return ret; } // add text segment if (!(ptr = R_NEW0 (RBinSection))) { return ret; } strncpy (ptr->name, "header", R_BIN_SIZEOF_STRINGS); ptr->size = ptr->vsize = 0x9a; ptr->paddr = 0; ptr->vaddr = ptr->paddr; ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_MAP; // r-- ptr->add = true; r_list_append (ret, ptr); /* rarvm code */ if (!(ptr = R_NEW0 (RBinSection))) { return ret; } strncpy (ptr->name, "rarvm", R_BIN_SIZEOF_STRINGS); ptr->vsize = ptr->size = sz - 0x9a; ptr->vaddr = ptr->paddr = 0x9a; ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE | R_BIN_SCN_MAP; // r-x ptr->add = true; r_list_append (ret, ptr); return ret; }
static bool load(RBinFile *bf) { int result = false; const ut8 *bytes = bf? r_buf_buffer (bf->buf): NULL; ut64 sz = bf? r_buf_size (bf->buf): 0; struct r_bin_java_obj_t *bin_obj = NULL; if (!bf || !bf->o) { return false; } bin_obj = load_bytes (bf, bytes, sz, bf->o->loadaddr, bf->sdb); if (bin_obj) { if (!bf->o->kv) { bf->o->kv = bin_obj->kv; } bf->o->bin_obj = bin_obj; bin_obj->AllJavaBinObjs = DB; // XXX - /\ this is a hack, but (one way but) necessary to get access to // the object addrs from anal. If only global variables are used, // they get "lost" somehow after they are initialized and go out of // scope. // // There are several points of indirection, but here is the gist: // 1) RAnal->(through RBinBind) RBin->RBinJavaObj->DB // // The purpose is to ensure that information about a give class file // can be grabbed at any time from RAnal. This was tried with global // variables, but failed when attempting to access the DB // in the class.c scope. Once DB was moved here, it is initialized // once here and assigned to each of the other RBinJavaObjs. // // Now, the RAnal component of radare can get to each of the // RBinJavaObjs for analysing functions and dependencies using an Sdb. add_bin_obj_to_sdb (bin_obj); if (bf->file) { bin_obj->file = strdup (bf->file); } result = true; } return result; }
static RList *sections(RBinFile *arch) { RList *ret = NULL; RBinSection *s = R_NEW0 (RBinSection); ut64 sz = r_buf_size (arch->buf); if (!(ret = r_list_new ())) { free (s); return NULL; } strcpy (s->name, "ROM"); s->paddr = 0; s->vaddr = 0x8000000; s->size = sz; s->vsize = 0x2000000; s->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE | R_BIN_SCN_MAP; s->add = true; r_list_append (ret, s); return ret; }
static RList *sections(RBinFile *bf) { RList /*<RBinSection>*/ *ret = r_list_new (); if (!ret) { return NULL; } RBinSection *text = R_NEW0 (RBinSection); if (!text) { r_list_free (ret); return NULL; } text->name = strdup ("text"); text->size = r_buf_size (bf->buf) - N64_ROM_START; text->vsize = text->size; text->paddr = N64_ROM_START; text->vaddr = baddr (bf); text->perm = R_PERM_RX; text->add = true; r_list_append (ret, text); return ret; }
static int art_header_load(ARTHeader *art, RBuffer *buf, Sdb *db) { /* TODO: handle read errors here */ if (r_buf_size (buf) < sizeof (ARTHeader)) { return false; } (void) r_buf_fread_at (buf, 0, (ut8 *) art, "IIiiiiiiiiiiii", 1); sdb_set (db, "img.base", sdb_fmt (0, "0x%x", art->image_base), 0); sdb_set (db, "img.size", sdb_fmt (0, "0x%x", art->image_size), 0); sdb_set (db, "art.checksum", sdb_fmt (0, "0x%x", art->checksum), 0); sdb_set (db, "art.version", sdb_fmt (0, "%c%c%c", art->version[0], art->version[1], art->version[2]), 0); sdb_set (db, "oat.begin", sdb_fmt (0, "0x%x", art->oat_file_begin), 0); sdb_set (db, "oat.end", sdb_fmt (0, "0x%x", art->oat_file_end), 0); sdb_set (db, "oat_data.begin", sdb_fmt (0, "0x%x", art->oat_data_begin), 0); sdb_set (db, "oat_data.end", sdb_fmt (0, "0x%x", art->oat_data_end), 0); sdb_set (db, "patch_delta", sdb_fmt (0, "0x%x", art->patch_delta), 0); sdb_set (db, "image_roots", sdb_fmt (0, "0x%x", art->image_roots), 0); sdb_set (db, "compile_pic", sdb_fmt (0, "0x%x", art->compile_pic), 0); return true; }
static int lmf_header_load(lmf_header *lmfh, RBuffer *buf, Sdb *db) { if (r_buf_size (buf) < sizeof (lmf_header)) { return false; } if (r_buf_fread_at (buf, QNX_HEADER_ADDR, (ut8 *) lmfh, "iiiiiiiicccciiiicc", 1) < QNX_HDR_SIZE) { return false; } sdb_set (db, "qnx.version", sdb_fmt ("0x%xH", lmfh->version), 0); sdb_set (db, "qnx.cflags", sdb_fmt ("0x%xH", lmfh->cflags), 0); sdb_set (db, "qnx.cpu", sdb_fmt ("0x%xH", lmfh->cpu), 0); sdb_set (db, "qnx.fpu", sdb_fmt ("0x%xH", lmfh->fpu), 0); sdb_set (db, "qnx.code_index", sdb_fmt ("0x%x", lmfh->code_index), 0); sdb_set (db, "qnx.stack_index", sdb_fmt ("0x%x", lmfh->stack_index), 0); sdb_set (db, "qnx.heap_index", sdb_fmt ("0x%x", lmfh->heap_index), 0); sdb_set (db, "qnx.argv_index", sdb_fmt ("0x%x", lmfh->argv_index), 0); sdb_set (db, "qnx.code_offset", sdb_fmt ("0x%x", lmfh->code_offset), 0); sdb_set (db, "qnx.stack_nbytes", sdb_fmt ("0x%x", lmfh->stack_nbytes), 0); sdb_set (db, "qnx.heap_nbytes", sdb_fmt ("0x%x", lmfh->heap_nbytes), 0); sdb_set (db, "qnx.image_base", sdb_fmt ("0x%x", lmfh->image_base), 0); return true; }
static RList* symbols(RBinFile *bf) { RList *ret = NULL; const ut8 *b = bf ? r_buf_buffer (bf->buf) : NULL; ut64 sz = bf ? r_buf_size (bf->buf): 0; if (!(ret = r_list_newf (free))) { return NULL; } if (false) { // TODO bf->cpu && !strcmp (bf->cpu, "atmega8")) { /* ... */ } else { /* atmega8 */ addptr (ret, "int0", 2, b, sz); addptr (ret, "int1", 4, b, sz); addptr (ret, "timer2cmp", 6, b, sz); addptr (ret, "timer2ovf", 8, b, sz); addptr (ret, "timer1capt", 10, b, sz); addptr (ret, "timer1cmpa", 12, b, sz); /* ... */ } return ret; }
static RList* sections(RBinFile* bf) { RList* ret = NULL; RBinSection* sect = NULL; psxexe_header psxheader; ut64 sz = 0; if (!(ret = r_list_new ())) { return NULL; } if(!(sect = R_NEW0 (RBinSection))) { r_list_free (ret); return NULL; } if (r_buf_fread_at (bf->buf, 0, (ut8*)&psxheader, "8c17i", 1) < sizeof (psxexe_header)) { eprintf ("Truncated Header\n"); free (sect); r_list_free (ret); return NULL; } sz = r_buf_size (bf->buf); strcpy (sect->name, "TEXT"); sect->paddr = PSXEXE_TEXTSECTION_OFFSET; sect->size = sz - PSXEXE_TEXTSECTION_OFFSET; sect->vaddr = psxheader.t_addr; sect->vsize = psxheader.t_size; sect->srwx = R_BIN_SCN_EXECUTABLE; sect->add = true; sect->has_strings = true; r_list_append (ret, sect); return ret; }
static RBuffer* create(RBin* bin, const ut8 *code, int codelen, const ut8 *data, int datalen, RBinArchOptions *opt) { ut32 p_start, p_phoff, p_phdr; ut32 p_vaddr, p_paddr, p_fs, p_fs2; ut32 p_ehdrsz, p_phdrsz; ut64 filesize, code_va, code_pa, phoff; ut16 ehdrsz, phdrsz; ut64 baddr = 0x400000LL; RBuffer *buf = r_buf_new (); #define B(x,y) r_buf_append_bytes(buf,(const ut8*)(x),y) #define Q(x) r_buf_append_ut64(buf,x) #define D(x) r_buf_append_ut32(buf,x) #define H(x) r_buf_append_ut16(buf,x) #define Z(x) r_buf_append_nbytes(buf,x) #define W(x,y,z) r_buf_write_at(buf,x,(const ut8*)(y),z) /* Ehdr */ B ("\x7F" "ELF" "\x02\x01\x01\x00", 8); // e_ident (ei_class = ELFCLASS64) Z (8); H (2); // e_type = ET_EXEC H (62); // e_machine = EM_X86_64 D (1); // e_version = EV_CURRENT p_start = r_buf_size (buf); Q (-1); // e_entry = 0xFFFFFFFF p_phoff = r_buf_size (buf); Q (-1); // e_phoff = 0xFFFFFFFF Q (0); // e_shoff = 0xFFFFFFFF D (0); // e_flags p_ehdrsz = r_buf_size (buf); H (-1); // e_ehsize = 0xFFFFFFFF p_phdrsz = r_buf_size (buf); H (-1); // e_phentsize = 0xFFFFFFFF H (1); // e_phnum H (0); // e_shentsize H (0); // e_shnum H (0); // e_shstrndx /* Phdr */ p_phdr = r_buf_size (buf); D (1); // p_type D (5); // p_flags = PF_R | PF_X Q (0); // p_offset p_vaddr = r_buf_size (buf); Q (-1); // p_vaddr = 0xFFFFFFFF p_paddr = r_buf_size (buf); Q (-1); // p_paddr = 0xFFFFFFFF p_fs = r_buf_size (buf); Q (-1); // p_filesz p_fs2 = r_buf_size (buf); Q (-1); // p_memsz Q (0x200000); // p_align /* Calc fields */ ehdrsz = p_phdr; phdrsz = r_buf_size (buf) - p_phdr; code_pa = r_buf_size (buf); code_va = code_pa + baddr; phoff = p_phdr; filesize = code_pa + codelen + datalen; /* Write fields */ W (p_start, &code_va, 8); W (p_phoff, &phoff, 8); W (p_ehdrsz, &ehdrsz, 2); W (p_phdrsz, &phdrsz, 2); W (p_fs, &filesize, 8); W (p_fs2, &filesize, 8); W (p_vaddr, &baddr, 8); W (p_paddr, &baddr, 8); /* Append code */ B (code, codelen); if (data && datalen>0) { eprintf ("Warning: DATA section not support for ELF yet\n"); B (data, datalen); } return buf; }
static RList *patch_relocs(RBin *b) { struct r_bin_bflt_obj *bin = NULL; RList *list = NULL; RBinObject *obj; int i = 0; if (!b || !b->iob.io || !b->iob.io->desc) { return NULL; } if (!(b->iob.io->cached & R_PERM_W)) { eprintf ( "Warning: please run r2 with -e io.cache=true to patch " "relocations\n"); return list; } obj = r_bin_cur_object (b); if (!obj) { return NULL; } bin = obj->bin_obj; list = r_list_newf ((RListFree) free); if (!list) { return NULL; } if (bin->got_table) { struct reloc_struct_t *got_table = bin->got_table; for (i = 0; i < bin->n_got; i++) { __patch_reloc (bin->b, got_table[i].addr_to_patch, got_table[i].data_offset); RBinReloc *reloc = R_NEW0 (RBinReloc); if (reloc) { reloc->type = R_BIN_RELOC_32; reloc->paddr = got_table[i].addr_to_patch; reloc->vaddr = reloc->paddr; r_list_append (list, reloc); } } R_FREE (bin->got_table); } if (bin->reloc_table) { struct reloc_struct_t *reloc_table = bin->reloc_table; for (i = 0; i < bin->hdr->reloc_count; i++) { int found = search_old_relocation (reloc_table, reloc_table[i].addr_to_patch, bin->hdr->reloc_count); if (found != -1) { __patch_reloc (bin->b, reloc_table[found].addr_to_patch, reloc_table[i].data_offset); } else { __patch_reloc (bin->b, reloc_table[i].addr_to_patch, reloc_table[i].data_offset); } RBinReloc *reloc = R_NEW0 (RBinReloc); if (reloc) { reloc->type = R_BIN_RELOC_32; reloc->paddr = reloc_table[i].addr_to_patch; reloc->vaddr = reloc->paddr; r_list_append (list, reloc); } } R_FREE (bin->reloc_table); } b->iob.write_at (b->iob.io, bin->b->base, bin->b->buf, r_buf_size (bin->b)); return list; }
static int load(RBinFile *arch) { const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL; ut64 sz = arch ? r_buf_size (arch->buf): 0; return check_bytes (bytes, sz); }
static RList *sections(RBinFile *bf) { RList *ret = NULL; RBinSection *ptr = NULL; RBuffer *b = bf->buf; if (!bf->o->info) { return NULL; } if (!(ret = r_list_new ())) { return NULL; } ret->free = free; ut64 ba = baddr (bf); if (!(ptr = R_NEW0 (RBinSection))) { return ret; } strncpy (ptr->name, "header", R_BIN_SIZEOF_STRINGS); ptr->size = 0x80; ptr->vsize = 0x80; ptr->paddr = 0; ptr->vaddr = 0; ptr->srwx = R_BIN_SCN_READABLE; ptr->add = false; r_list_append (ret, ptr); int bufsz = r_buf_size (bf->buf); ut32 mod0 = readLE32 (bf->buf, NRO_OFFSET_MODMEMOFF); if (mod0 && mod0 + 8 < bufsz) { if (!(ptr = R_NEW0 (RBinSection))) { return ret; } ut32 mod0sz = readLE32 (bf->buf, mod0 + 4); strncpy (ptr->name, "mod0", R_BIN_SIZEOF_STRINGS); ptr->size = mod0sz; ptr->vsize = mod0sz; ptr->paddr = mod0; ptr->vaddr = mod0 + ba; ptr->srwx = R_BIN_SCN_READABLE; // rw- ptr->add = false; r_list_append (ret, ptr); } else { eprintf ("Invalid MOD0 address\n"); } ut32 sig0 = readLE32 (bf->buf, 0x18); if (sig0 && sig0 + 8 < bufsz) { if (!(ptr = R_NEW0 (RBinSection))) { return ret; } ut32 sig0sz = readLE32 (bf->buf, sig0 + 4); strncpy (ptr->name, "sig0", R_BIN_SIZEOF_STRINGS); ptr->size = sig0sz; ptr->vsize = sig0sz; ptr->paddr = sig0; ptr->vaddr = sig0 + ba; ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_MAP; // r-- ptr->add = true; r_list_append (ret, ptr); } else { eprintf ("Invalid SIG0 address\n"); } // add text segment if (!(ptr = R_NEW0 (RBinSection))) { return ret; } strncpy (ptr->name, "text", R_BIN_SIZEOF_STRINGS); ptr->vsize = readLE32 (b, NRO_OFF (text_size)); ptr->size = ptr->vsize; ptr->paddr = readLE32 (b, NRO_OFF (text_memoffset)); ptr->vaddr = ptr->paddr + ba; ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE | R_BIN_SCN_MAP; // r-x ptr->add = true; r_list_append (ret, ptr); // add ro segment if (!(ptr = R_NEW0 (RBinSection))) { return ret; } strncpy (ptr->name, "ro", R_BIN_SIZEOF_STRINGS); ptr->vsize = readLE32 (b, NRO_OFF (ro_size)); ptr->size = ptr->vsize; ptr->paddr = readLE32 (b, NRO_OFF (ro_memoffset)); ptr->vaddr = ptr->paddr + ba; ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_MAP; // r-x ptr->add = true; r_list_append (ret, ptr); // add data segment if (!(ptr = R_NEW0 (RBinSection))) { return ret; } strncpy (ptr->name, "data", R_BIN_SIZEOF_STRINGS); ptr->vsize = readLE32 (b, NRO_OFF (data_size)); ptr->size = ptr->vsize; ptr->paddr = readLE32 (b, NRO_OFF (data_memoffset)); ptr->vaddr = ptr->paddr + ba; ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_WRITABLE | R_BIN_SCN_MAP; // rw- ptr->add = true; eprintf ("Base Address 0x%08"PFMT64x "\n", ba); eprintf ("BSS Size 0x%08"PFMT64x "\n", (ut64) readLE32 (bf->buf, NRO_OFF (bss_size))); r_list_append (ret, ptr); return ret; }
R_API int r_core_write_op(RCore *core, const char *arg, char op) { int i, j, len, ret = false; char *str = NULL; ut8 *buf; // XXX we can work with config.block instead of dupping it buf = (ut8 *)malloc (core->blocksize); if (!buf) { goto beach; } memcpy (buf, core->block, core->blocksize); if (op!='e') { // fill key buffer either from arg or from clipboard if (arg) { // parse arg for key // r_hex_str2bin() is guaranteed to output maximum half the // input size, or 1 byte if there is just a single nibble. str = (char *)malloc (strlen (arg) / 2 + 1); if (!str) { goto beach; } len = r_hex_str2bin (arg, (ut8 *)str); // Output is invalid if there was just a single nibble, // but in that case, len is negative (-1). if (len <= 0) { eprintf ("Invalid hexpair string\n"); goto beach; } } else { // use clipboard as key len = r_buf_size (core->yank_buf); if (len <= 0) { eprintf ("Clipboard is empty and no value argument(s) given\n"); goto beach; } str = r_mem_dup (r_buf_buffer (core->yank_buf), len); if (!str) { goto beach; } } } else { len = 0; } // execute the operand if (op=='e') { int wordsize = 1; char *os, *p, *s = strdup (arg); int n = 0, from = 0, to = UT8_MAX, dif = 0, step = 1; os = s; p = strchr (s, ' '); if (p) { *p = 0; from = r_num_math (core->num, s); s = p + 1; } p = strchr (s, ' '); if (p) { *p = 0; to = r_num_math (core->num, s); s = p + 1; } p = strchr (s, ' '); if (p) { *p = 0; step = r_num_math (core->num, s); s = p + 1; wordsize = r_num_math (core->num, s); } else { step = r_num_math (core->num, s); } free (os); eprintf ("from %d to %d step %d size %d\n", from, to, step, wordsize); dif = (to <= from)? UT8_MAX: to - from + 1; if (wordsize == 1) { from %= (UT8_MAX + 1); } if (dif < 1) { dif = UT8_MAX + 1; } if (step < 1) { step = 1; } if (wordsize < 1) { wordsize = 1; } if (wordsize == 1) { for (i = n = 0; i < core->blocksize; i++, n += step) { buf[i] = (ut8)(n % dif) + from; } } else if (wordsize == 2) { ut16 num16 = from; for (i = 0; i < core->blocksize; i += wordsize, num16 += step) { r_write_le16 (buf + i, num16); } } else if (wordsize == 4) { ut32 num32 = from; for (i = 0; i < core->blocksize; i += wordsize, num32 += step) { r_write_le32 (buf + i, num32); } } else if (wordsize == 8) { ut64 num64 = from; for (i = 0; i < core->blocksize; i += wordsize, num64 += step) { r_write_le64 (buf + i, num64); } } else { eprintf ("Invalid word size. Use 1, 2, 4 or 8\n"); } } else if (op=='2' || op=='4') { op -= '0'; // if i < core->blocksize would pass the test but buf[i+3] goes beyond the buffer if (core->blocksize > 3) { for (i=0; i<core->blocksize-3; 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 'w': buf[i] = str[j]; break; case 'd': buf[i] = (str[j])? buf[i] / str[j]: 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); beach: free (buf); free (str); return ret; }
static int check(RBinFile *arch) { const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL; eprintf ("CHE2\n"); ut64 sz = arch ? r_buf_size (arch->buf): 0; return check_bytes (bytes, sz); }
static bool load(RBinFile *bf) { const ut8 *bytes = bf ? r_buf_buffer (bf->buf) : NULL; ut64 sz = bf ? r_buf_size (bf->buf): 0; ut64 la = (bf && bf->o) ? bf->o->loadaddr: 0; return load_bytes (bf, bytes, sz, la, bf? bf->sdb: NULL) != NULL; }
R_API bool r_buf_dump(RBuffer *b, const char *file) { if (!b || !file) { return false; } return r_file_dump (file, r_buf_get_at (b, 0, NULL), r_buf_size (b), 0); }
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; }