static RList* sections(RBinFile *arch) { xbe_section *sect; r_bin_xbe_obj_t *obj; RList *ret; int i; if (!arch || !arch->o) return NULL; obj = arch->o->bin_obj; if (obj->header->sections < 1) return NULL; ret = r_list_new (); if (!ret) return NULL; if (!arch->buf) { free (ret); return NULL; } ret->free = free; sect = calloc (obj->header->sections, sizeof (xbe_section)); r_buf_read_at (arch->buf, obj->header->sechdr_addr - obj->header->base, (ut8 *)sect, sizeof (xbe_section)*obj->header->sections); for (i = 0; i < obj->header->sections; i++) { RBinSection *item = R_NEW0(RBinSection); char tmp[0x100]; r_buf_read_at (arch->buf, sect[i].name_addr - obj->header->base, (ut8 *)tmp, sizeof(tmp)); snprintf(item->name, R_BIN_SIZEOF_STRINGS, "%s.%i", tmp, i); item->paddr = sect[i].offset; item->vaddr = sect[i].vaddr; item->size = sect[i].size; item->vsize = sect[i].vsize; item->srwx |= 4; if (sect[i].flags & SECT_FLAG_X) item->srwx |= 1; if (sect[i].flags & SECT_FLAG_W) item->srwx |= 2; r_list_append (ret, item); } free (sect); return ret; }
static RList* libs(RBinFile *arch) { r_bin_xbe_obj_t *obj; int i, off, libs, r; xbe_lib lib; RList *ret; char *s; if (!arch || !arch->o) return NULL; obj = arch->o->bin_obj; ret = r_list_new (); if (!ret) return NULL; ret->free = free; if ( obj->header->kernel_lib_addr < obj->header->base) { off = 0; } else { off = obj->header->kernel_lib_addr - obj->header->base; } r = r_buf_read_at (arch->buf, off, (ut8 *)&lib, sizeof(xbe_lib)); if (r == 0 || r == -1) return NULL; s = r_str_newf ("%s %i.%i.%i", lib.name, lib.major, lib.minor, lib.build); if (s) r_list_append (ret, s); if (obj->header->xapi_lib_addr < obj->header->base) { off = 0; } else { off = obj->header->xapi_lib_addr - obj->header->base; } r = r_buf_read_at (arch->buf, off, (ut8 *)&lib, sizeof(xbe_lib)); if (r == 0 || r == -1) return NULL; s = r_str_newf ("%s %i.%i.%i", lib.name, lib.major, lib.minor, lib.build); if (s) r_list_append (ret, s); libs = obj->header->lib_versions; if (libs<1) libs = 0; for (i = 0; i < libs; i++) { r = r_buf_read_at (arch->buf, obj->header->lib_versions_addr - \ obj->header->base + (i * sizeof (xbe_lib)), (ut8 *)&lib, sizeof (xbe_lib)); if (r == 0 || r == -1) continue; s = r_str_newf ("%s %i.%i.%i", lib.name, lib.major, lib.minor, lib.build); if (s) r_list_append(ret, s); } return ret; }
ut64 r_bin_mz_get_main_vaddr(struct r_bin_mz_obj_t *bin) { int entry; int n; ut8 b[512]; if (!bin || !bin->b) { return 0LL; } entry = r_bin_mz_get_entrypoint (bin); ZERO_FILL (b); if (r_buf_read_at (bin->b, entry, b, sizeof (b)) < 0) { eprintf ("Warning: Cannot read entry at 0x%08"PFMT32x "\n", (ut32) entry); return 0LL; } // MSVC if (b[0] == 0xb4 && b[1] == 0x30) { // ff 36 XX XX push XXXX // ff 36 XX XX push argv // ff 36 XX XX push argc // 9a XX XX XX XX lcall _main // 50 push ax for (n = 0; n < sizeof (b) - 18; n++) { if (b[n] == 0xff && b[n + 4] == 0xff && b[n + 8] == 0xff && b[n + 12] == 0x9a && b[n + 17] == 0x50) { const ut16 call_addr = r_read_ble16 (b + n + 13, 0);; const ut16 call_seg = r_read_ble16 (b + n + 15, 0);; const ut64 call_dst = r_bin_mz_seg_to_paddr (bin, call_seg) + call_addr; return call_dst; } } } return 0LL; }
static int rabin_dump_sections(char *scnname) { RList *sections; RListIter *iter; RBinSection *section; ut8 *buf; char *ret; if ((sections = r_bin_get_sections (bin)) == NULL) return R_FALSE; r_list_foreach (sections, iter, section) { if (!strcmp (scnname, section->name)) { if (!(buf = malloc (section->size))) return R_FALSE; if (!(ret = malloc (section->size*2+1))) { free (buf); return R_FALSE; } r_buf_read_at (bin->cur->buf, section->paddr, buf, section->size); if (output) { r_file_dump (output, buf, section->size); } else { r_hex_bin2str (buf, section->size, ret); printf ("%s\n", ret); } free (buf); free (ret); break; } } return R_TRUE; }
static int check(RBinFile *arch) { ut8 lict[48]; if (!arch || !arch->buf) return 0; r_buf_read_at (arch->buf, 0x104, lict,48); return (!memcmp (lict, lic, 48))? 1: 0; }
static RList *parseSegments(RBuffer *buf, int off, int count) { ut8 *b = calloc (count, 32); (void)r_buf_read_at (buf, off, b, count * 32); int x = off; int X = 0; int i; RList *segments = r_list_newf ((RListFree)r_bin_section_free); if (!segments) { return NULL; } // eprintf ("Segments: %d\n", count); for (i = 0; i < count; i++) { int A = r_read_le32 (b + X + 16); int B = r_read_le32 (b + X + 16 + 8); // eprintf ("0x%08x segment 0x%08x 0x%08x %s\n", // x, A, A + B, b + X); const char *cname = (const char *)(b + X); char *name = r_str_ndup (cname, r_str_nlen (cname, 16)); RBinSection *section = newSection (name, A, A + B, true); free (name); r_list_append (segments, section); x += 32; X += 32; } return segments; }
static RBinInfo* info(RBinFile *arch) { RBinInfo *ret = NULL; PebbleAppInfo pai; memset (&pai, 0, sizeof (pai)); int reat = r_buf_read_at (arch->buf, 0, (ut8*)&pai, sizeof (pai)); if (reat != sizeof (pai)) { eprintf ("Truncated Header\n"); return NULL; } if (!(ret = R_NEW0 (RBinInfo))) return NULL; ret->lang = NULL; ret->file = strdup (arch->file); ret->type = strdup ("pebble"); ret->bclass = r_str_ndup (pai.name, 32); ret->rclass = r_str_ndup (pai.company, 32); ret->os = strdup ("rtos"); ret->subsystem = strdup ("pebble"); ret->machine = strdup ("watch"); ret->arch = strdup ("arm"); // thumb only ret->has_va = 1; ret->bits = 16; ret->big_endian = 0; ret->dbg_info = 0; return ret; }
static RBinInfo *info(RBinFile *arch) { ut8 rom_info[16]; RBinInfo *ret = R_NEW0 (RBinInfo); if (!ret) { return NULL; } if (!arch || !arch->buf) { free (ret); return NULL; } ret->lang = NULL; r_buf_read_at (arch->buf, 0xa0, rom_info, 16); ret->file = r_str_ndup ((const char *) rom_info, 12); ret->type = r_str_ndup ((char *) &rom_info[12], 4); ret->machine = strdup ("GameBoy Advance"); ret->os = strdup ("any"); ret->arch = strdup ("arm"); ret->has_va = 1; ret->bits = 32; ret->big_endian = 0; ret->dbg_info = 0; return ret; }
static RBinInfo* info(RBinFile *arch) { ut8 rom_info[16]; RBinInfo *ret = R_NEW0 (RBinInfo); if (!ret) return NULL; if (!arch || !arch->buf) { free (ret); return NULL; } ret->lang = NULL; r_buf_read_at (arch->buf, 0xa0, rom_info, 16); strncpy (ret->file, (char *) rom_info, 12); strncpy (ret->type, (char *) &rom_info[12], 4); strncpy (ret->machine, "Gameboy Advanced", sizeof (ret->machine)-1); strncpy (ret->os, "any", sizeof (ret->os)-1); strcpy (ret->arch, "arm"); ret->has_va = 1; ret->bits = 32; ret->big_endian = 0; ret->dbg_info = 0; return ret; }
static RBinInfo *info(RBinFile *bf) { RBinInfo *ret = R_NEW0 (RBinInfo); if (!ret) { return NULL; } ut8 magic[4]; r_buf_read_at (bf->buf, NRO_OFF (magic), magic, sizeof (magic)); const char *ft = fileType (magic); if (!ft) { ft = "nro"; } ret->file = strdup (bf->file); ret->rclass = strdup (ft); ret->os = strdup ("switch"); ret->arch = strdup ("arm"); ret->machine = strdup ("Nintendo Switch"); ret->subsystem = strdup (ft); if (!strncmp (ft, "nrr", 3)) { ret->bclass = strdup ("program"); ret->type = strdup ("EXEC (executable file)"); } else if (!strncmp (ft, "nro", 3)) { ret->bclass = strdup ("object"); ret->type = strdup ("OBJECT (executable code)"); } else { // mod ret->bclass = strdup ("library"); ret->type = strdup ("MOD (executable library)"); } ret->bits = 64; ret->has_va = true; ret->has_lit = true; ret->big_endian = false; ret->dbg_info = 0; ret->dbg_info = 0; return ret; }
static RBinInfo* info(RBinFile *arch) { RBinInfo *ret = NULL; PebbleAppInfo pai; if (!r_buf_read_at (arch->buf, 0, (ut8*)&pai, sizeof (pai))) { eprintf ("Truncated Header\n"); return NULL; } if (!(ret = R_NEW0 (RBinInfo))) return NULL; ret->lang = NULL; strncpy (ret->file, arch->file, R_BIN_SIZEOF_STRINGS-1); strncpy (ret->rpath, "NONE", R_BIN_SIZEOF_STRINGS-1); strncpy (ret->type, "pebble", sizeof (ret->type)-1); // asm.arch strncpy (ret->bclass, pai.name, sizeof (ret->bclass)-1); strncpy (ret->rclass, pai.company, sizeof (ret->rclass)-1); // file.type strncpy (ret->os, "rtos", sizeof (ret->os)-1); strncpy (ret->subsystem, "pebble", sizeof (ret->subsystem)-1); strncpy (ret->machine, "watch", sizeof (ret->machine)-1); strcpy (ret->arch, "arm"); // ARM THUMB ONLY ret->has_va = 1; ret->bits = 16; ret->big_endian = 0; ret->dbg_info = 0; return ret; }
static int rabin_dump_symbols(int len) { RList *symbols; RListIter *iter; RBinSymbol *symbol; ut8 *buf; char *ret; int olen = len; if ((symbols = r_bin_get_symbols (bin)) == NULL) return R_FALSE; r_list_foreach (symbols, iter, symbol) { if (symbol->size != 0 && (olen > symbol->size || olen == 0)) len = symbol->size; else if (symbol->size == 0 && olen == 0) len = 32; else len = olen; if (!(buf = malloc (len))) { return R_FALSE; } if (!(ret = malloc (len*2+1))) { free (buf); return R_FALSE; } r_buf_read_at (bin->cur->buf, symbol->paddr, buf, len); r_hex_bin2str (buf, len, ret); printf ("%s %s\n", symbol->name, ret); free (buf); free (ret); } return R_TRUE; }
static RBinInfo *info(RBinFile *bf) { r_bin_xbe_obj_t *obj; RBinInfo *ret; ut8 dbg_name[256]; if (!bf || !bf->buf) { return NULL; } ret = R_NEW0 (RBinInfo); if (!ret) { return NULL; } obj = bf->o->bin_obj; memset (dbg_name, 0, sizeof (dbg_name)); r_buf_read_at (bf->buf, obj->header->debug_name_addr -\ obj->header->base, dbg_name, sizeof (dbg_name)); dbg_name[sizeof(dbg_name) - 1] = 0; ret->file = strdup ((char *) dbg_name); ret->bclass = strdup ("program"); ret->machine = strdup ("Microsoft Xbox"); ret->os = strdup ("xbox"); ret->type = strdup ("Microsoft Xbox executable"); ret->arch = strdup ("x86"); ret->has_va = 1; ret->bits = 32; ret->big_endian = 0; ret->dbg_info = 0; ret->lang = NULL; return ret; }
static RList* sections(RBinFile *bf) { RList *ret = NULL; RBinSection *ptr = NULL; spc_hdr spchdr; memset (&spchdr, 0, SPC_HDR_SIZE); int reat = r_buf_read_at (bf->buf, 0, (ut8*)&spchdr, SPC_HDR_SIZE); if (reat != SPC_HDR_SIZE) { eprintf ("Truncated Header\n"); return NULL; } if (!(ret = r_list_new ())) { return NULL; } if (!(ptr = R_NEW0 (RBinSection))) { r_list_free (ret); return NULL; } strcpy (ptr->name, "RAM"); ptr->paddr = RAM_START_ADDRESS; ptr->size = RAM_SIZE; ptr->vaddr = 0x0; ptr->vsize = RAM_SIZE; ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_MAP; ptr->add = true; r_list_append (ret, ptr); return ret; }
static RBinInfo* info(RBinFile *arch) { ut8 rom_header[76]; RBinInfo *ret = R_NEW0 (RBinInfo); if (!ret) return NULL; if (!arch || !arch->buf) { free (ret); return NULL; } ret->lang = NULL; r_buf_read_at (arch->buf,0x104,rom_header,76); strncpy (ret->file, (const char*)&rom_header[48], 16); gb_get_gbtype (ret->type,rom_header[66],rom_header[63]); gb_add_cardtype (ret->type,rom_header[67]); // XXX strncpy (ret->machine, "Gameboy", sizeof (ret->machine)-1); strncpy (ret->os, "any", sizeof (ret->os)-1); strcpy (ret->arch, "gb"); ret->has_va = 1; ret->bits = 8; ret->big_endian = 0; ret->dbg_info = 0; return ret; }
static RBinInfo* info(RBinFile *arch) { ut8 rom_header[76]; RBinInfo *ret = R_NEW0 (RBinInfo); if (!ret) return NULL; if (!arch || !arch->buf) { free (ret); return NULL; } r_buf_read_at (arch->buf, 0x104, rom_header, 76); ret->file = calloc (1, 17); strncpy (ret->file, (const char*)&rom_header[48], 16); ret->type = malloc (128); ret->type[0] = 0; gb_get_gbtype (ret->type, rom_header[66], rom_header[63]); gb_add_cardtype (ret->type, rom_header[67]); // XXX ret->machine = strdup ("Gameboy"); ret->os = strdup ("any"); ret->arch = strdup ("gb"); ret->has_va = 1; ret->bits = 16; ret->big_endian = 0; ret->dbg_info = 0; return ret; }
static int bootimg_header_load(BootImage *bi, RBuffer *buf, Sdb *db) { char *n; int i; if (r_buf_size (buf) < sizeof (BootImage)) { return false; } // TODO make it endian-safe (void)r_buf_fread_at (buf, 0, (ut8*)bi, "IIiiiiiiiiiiii", 1); (void)r_buf_read_at (buf, 0, (ut8*)bi, sizeof (BootImage)); if ((n = r_str_ndup ((char*)bi->name, BOOT_NAME_SIZE))) { sdb_set (db, "name", n, 0); free (n); } if ((n = r_str_ndup ((char*)bi->cmdline, BOOT_ARGS_SIZE))) { sdb_set (db, "cmdline", n, 0); free (n); } for (i=0; i<8; i++) { sdb_num_set (db, "id", (ut64)bi->id[i], 0); } if ((n = r_str_ndup ((char*)bi->extra_cmdline, BOOT_EXTRA_ARGS_SIZE))) { sdb_set (db, "extra_cmdline", n, 0); free (n); } return true; }
static RBinInfo* info(RBinFile *arch) { r_bin_xbe_obj_t *obj; RBinInfo *ret; ut8 dbg_name[256]; if (!arch || !arch->buf) return NULL; ret = R_NEW0 (RBinInfo); if (!ret) return NULL; obj = arch->o->bin_obj; r_buf_read_at (arch->buf, obj->header->debug_name_addr - \ obj->header->base, dbg_name, sizeof(dbg_name)); strncpy (ret->file, (const char*)dbg_name, R_BIN_SIZEOF_STRINGS); strncpy (ret->bclass, "program", R_BIN_SIZEOF_STRINGS); strncpy (ret->machine, "Microsoft Xbox", R_BIN_SIZEOF_STRINGS); strncpy (ret->os, "xbox", R_BIN_SIZEOF_STRINGS); strncpy (ret->type, "Microsoft Xbox executable", R_BIN_SIZEOF_STRINGS); strncpy (ret->arch, "x86", R_BIN_SIZEOF_STRINGS); ret->has_va = 1; ret->bits = 32; ret->big_endian = 0; ret->dbg_info = 0; ret->lang = NULL; return ret; }
char* r_bin_dex_get_version(RBinDexObj *bin) { if (bin) { ut8* version = calloc (1, 8); r_buf_read_at (bin->b, 4, version, 3); return (char *)version; } return NULL; }
static RList* sections(RBinFile *bf){ ut8 bank; int i; RList *ret; if (!bf) { return NULL; } ret = r_list_new(); if (!ret) { return NULL; } r_buf_read_at (bf->buf, 0x148, &bank, 1); bank = gb_get_rombanks(bank); #ifdef _MSC_VER RBinSection **rombank = (RBinSection**) malloc (sizeof (RBinSection*) * bank); #else RBinSection *rombank[bank]; #endif if (!bf->buf) { free (ret); #ifdef _MSC_VER free (rombank); #endif return NULL; } ret->free = free; rombank[0] = R_NEW0 (RBinSection); rombank[0]->name = strdup ("rombank00"); rombank[0]->paddr = 0; rombank[0]->size = 0x4000; rombank[0]->vsize = 0x4000; rombank[0]->vaddr = 0; rombank[0]->perm = r_str_rwx ("rx"); rombank[0]->add = true; r_list_append (ret, rombank[0]); for (i = 1; i < bank; i++) { rombank[i] = R_NEW0 (RBinSection); rombank[i]->name = r_str_newf ("rombank%02x", i); rombank[i]->paddr = i*0x4000; rombank[i]->vaddr = i*0x10000-0xc000; //spaaaaaaaaaaaaaaaace!!! rombank[i]->size = rombank[i]->vsize = 0x4000; rombank[i]->perm = r_str_rwx ("rx"); rombank[i]->add = true; r_list_append (ret,rombank[i]); } #ifdef _MSC_VER free (rombank); #endif return ret; }
static RList* sections(RBinFile *arch) { ut64 textsize = UT64_MAX; RList *ret = NULL; RBinSection *ptr = NULL; PebbleAppInfo pai; memset (&pai, 0, sizeof (pai)); if (!r_buf_read_at (arch->buf, 0, (ut8*)&pai, sizeof(pai))) { eprintf ("Truncated Header\n"); return NULL; } if (!(ret = r_list_new ())) return NULL; ret->free = free; // TODO: load all relocs if (!(ptr = R_NEW0 (RBinSection))) return ret; strcpy (ptr->name, "relocs"); ptr->vsize = ptr->size = pai.num_reloc_entries * sizeof (ut32); ptr->vaddr = ptr->paddr = pai.reloc_list_start; ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_WRITABLE | R_BIN_SCN_MAP; ptr->add = true; r_list_append (ret, ptr); if (ptr->vaddr<textsize) textsize = ptr->vaddr; // imho this must be a symbol if (!(ptr = R_NEW0 (RBinSection))) return ret; strcpy (ptr->name, "symtab"); ptr->vsize = ptr->size = 0; ptr->vaddr = ptr->paddr = pai.sym_table_addr; ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_MAP; ptr->add = true; r_list_append (ret, ptr); if (ptr->vaddr<textsize) textsize = ptr->vaddr; if (!(ptr = R_NEW0 (RBinSection))) return ret; strcpy (ptr->name, "text"); ptr->vaddr = ptr->paddr = 0x80; ptr->vsize = ptr->size = textsize - ptr->paddr; ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_WRITABLE | R_BIN_SCN_EXECUTABLE | R_BIN_SCN_MAP; ptr->add = true; r_list_append (ret, ptr); if (!(ptr = R_NEW0 (RBinSection))) return ret; strcpy (ptr->name, "header"); ptr->vsize = ptr->size = sizeof (PebbleAppInfo); ptr->vaddr = ptr->paddr = 0; ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_MAP; ptr->add = true; r_list_append (ret, ptr); return ret; }
static RBinInfo* info(RBinFile *bf) { sfc_int_hdr sfchdr = {{0}}; RBinInfo *ret = NULL; int hdroffset = 0; #if THIS_IS_ALWAYS_FALSE_WTF if ((bf->size & 0x8000) == 0x200) { hdroffset = 0x200; } #endif int reat = r_buf_read_at (bf->buf, 0x7FC0 + hdroffset, (ut8*)&sfchdr, SFC_HDR_SIZE); if (reat != SFC_HDR_SIZE) { eprintf ("Unable to read SFC/SNES header\n"); return NULL; } if ( (sfchdr.comp_check != (ut16)~(sfchdr.checksum)) || ((sfchdr.rom_setup & 0x1) != 0) ){ // if the fixed 0x33 byte or the LoROM indication are not found, then let's try interpreting the ROM as HiROM reat = r_buf_read_at (bf->buf, 0xFFC0 + hdroffset, (ut8*)&sfchdr, SFC_HDR_SIZE); if (reat != SFC_HDR_SIZE) { eprintf ("Unable to read SFC/SNES header\n"); return NULL; } if ( (sfchdr.comp_check != (ut16)~(sfchdr.checksum)) || ((sfchdr.rom_setup & 0x1) != 1) ) { eprintf ("Cannot determine if this is a LoROM or HiROM file\n"); return NULL; } } if (!(ret = R_NEW0 (RBinInfo))) { return NULL; } ret->file = strdup (bf->file); ret->type = strdup ("ROM"); ret->machine = strdup ("Super NES / Super Famicom"); ret->os = strdup ("snes"); ret->arch = strdup ("snes"); ret->bits = 16; ret->has_va = 1; return ret; }
static int r_io_def_mmap_read(RIO *io, RIODesc *fd, ut8 *buf, int count) { RIOMMapFileObj *mmo = NULL; if (!fd || !fd->data || !buf) { // in this case we fallback reopening in raw mode return -1; } if (io->off == UT64_MAX) { memset (buf, 0xff, count); return count; } mmo = fd->data; if (!mmo) { return -1; } if (mmo->rawio) { if (fd->obsz) { char *a_buf; int a_count; // only do aligned reads in aligned offsets const int aligned = fd->obsz; //512; // XXX obey fd->obsz? or it may be too slow? 128K.. //ut64 a_off = (io->off >> 9 ) << 9; //- (io->off & aligned); ut64 a_off = io->off - (io->off % aligned); //(io->off >> 9 ) << 9; //- (io->off & aligned); int a_delta = io->off - a_off; if (a_delta<0) { memset (buf, 0xff, count); return -1; } a_count = count + (aligned-(count%aligned)); a_buf = malloc (a_count+aligned); if (a_buf) { int i; memset (a_buf, 0xff, a_count + aligned); if (lseek (mmo->fd, a_off, SEEK_SET) < 0) { free (a_buf); return -1; } for (i=0; i< a_count ; i+= aligned) { (void)read (mmo->fd, a_buf+i, aligned);//a_count); } memcpy (buf, a_buf+a_delta, count); } else { memset (buf, 0xff, count); } free (a_buf); return count; } if (lseek (mmo->fd, io->off, SEEK_SET) < 0) { return -1; } return read (mmo->fd, buf, count); } if (mmo->buf->length < io->off) { io->off = mmo->buf->length; } return r_buf_read_at (mmo->buf, io->off, buf, count); }
static int r_io_def_mmap_read(RIO *io, RIODesc *fd, ut8 *buf, int count) { RIOMMapFileObj *mmo = NULL; if (!fd || !fd->data || !buf) return -1; mmo = fd->data; if (mmo->buf->length < io->off) io->off = mmo->buf->length; return r_buf_read_at (mmo->buf, io->off, buf, count); }
static RList *relocs(RBinFile *arch) { struct r_bin_coff_obj *bin = (struct r_bin_coff_obj*)arch->o->bin_obj; RBinReloc *reloc; struct coff_reloc *rel; int j, i = 0; RList *list_rel; list_rel = r_list_new (); if (!list_rel || !bin || !bin->scn_hdrs) { r_list_free (list_rel); return NULL; } for (i = 0; i < bin->hdr.f_nscns; i++) { if (bin->scn_hdrs[i].s_nreloc) { int len = 0, size = bin->scn_hdrs[i].s_nreloc * sizeof (struct coff_reloc); if (size < 0) { return list_rel; } rel = calloc (1, size + sizeof (struct coff_reloc)); if (!rel) { return list_rel; } if (bin->scn_hdrs[i].s_relptr > bin->size || bin->scn_hdrs[i].s_relptr + size > bin->size) { free (rel); return list_rel; } len = r_buf_read_at (bin->b, bin->scn_hdrs[i].s_relptr, (ut8*)rel, size); if (len != size) { free (rel); return list_rel; } for (j = 0; j < bin->scn_hdrs[i].s_nreloc; j++) { RBinSymbol *symbol = R_NEW0 (RBinSymbol); if (!symbol) { continue; } if (!_fill_bin_symbol (bin, rel[j].r_symndx, &symbol)) { free (symbol); continue; } reloc = R_NEW0 (RBinReloc); if (!reloc) { free (symbol); continue; } reloc->type = rel[j].r_type; //XXX the type if different from what r2 expects reloc->symbol = symbol; reloc->paddr = bin->scn_hdrs[i].s_scnptr + rel[j].r_vaddr; reloc->vaddr = reloc->paddr; r_list_append (list_rel, reloc); } free (rel); } } return list_rel; }
static int __read(RIO *io, RIODesc *fd, ut8 *buf, int count) { ut64 o; RBuffer *b; if (fd == NULL || fd->data == NULL) return -1; b = RIOSPARSE_BUF(fd); o = RIOSPARSE_OFF(fd); (void)r_buf_read_at (b, o, buf, count); return count; }
//TODO static RList* classes (RBinArch *arch) { RList *ret = NULL; struct r_bin_dex_obj_t *bin = (struct r_bin_dex_obj_t *) arch->bin_obj; struct dex_class_t entry; int i; if (!(ret = r_list_new ())) return NULL; ret->free = free; for (i = 0; i < bin->header.class_size; i++) { r_buf_read_at (bin->b, (ut64) bin->header.class_offset + (sizeof (struct dex_class_t)*i), (ut8*)&entry, sizeof (struct dex_class_t)); // r_list_append // TODO: implement sections.. each section specifies a class boundary #if 1 //eprintf ("ut32 class_id = %d;\n", entry.class_id); { int len = 100; char *name = malloc (len); if (!name) { eprintf ("error malloc string length %d\n", len); break; } r_buf_read_at (bin->b, bin->strings[entry.source_file], (ut8*)name, len); //snprintf (ptr->name, sizeof (ptr->name), "field.%s.%d", name, i); eprintf ("class.%s=%d\n", name[0]==12?name+1:name, entry.class_id); free (name); } eprintf ("# access_flags = %x;\n", entry.access_flags); eprintf ("# super_class = %d;\n", entry.super_class); eprintf ("# interfaces_offset = %08x;\n", entry.interfaces_offset); //eprintf ("ut32 source_file = %08x;\n", entry.source_file); eprintf ("# anotations_offset = %08x;\n", entry.anotations_offset); eprintf ("# class_data_offset = %08x;\n", entry.class_data_offset); eprintf ("# static_values_offset = %08x;\n\n", entry.static_values_offset); #endif } return 0; //FIXME: This must be main offset }
static RList *parseStrings(RBuffer *buf, int string_section, int string_section_end) { int sss = string_section_end + string_section; if (sss < 1) { return NULL; } char *b = calloc (1, sss); if (!b) { return NULL; } int o = 0; char *s = b; char *os = s; int nstrings = 0; int available = r_buf_read_at (buf, string_section, (ut8 *)b, sss); if (available != sss) { sss = available; } if (sss < 1) { eprintf ("Cannot read strings at 0x%08" PFMT64x "\n", (ut64)string_section); free (b); return NULL; } RList *res = r_list_newf ((RListFree)r_bin_string_free); int i; char *s_end = s + sss; for (i = 0; true; i++) { o = s - os; if (string_section + o + 8 > string_section_end) { break; } if (s + 4 > s_end) { break; } nstrings++; // eprintf ("0x%08x 0x%08x %s\n", o + string_section, o, s); RBinString *bs = R_NEW0 (RBinString); if (!bs) { break; } bs->string = strdup (s); // eprintf ("%s\n", s); bs->vaddr = o + string_section; bs->paddr = o + string_section; bs->ordinal = i; bs->length = strlen (s); r_list_append (res, bs); s += bs->length + 1; } free (b); return res; }
static int r_bin_te_init_hdr(struct r_bin_te_obj_t* bin) { if (!(bin->header = malloc(sizeof(TE_image_file_header)))) { perror ("malloc (header)"); return R_FALSE; } if (r_buf_read_at (bin->b, 0, (ut8*)bin->header, sizeof(TE_image_file_header)) == -1) { eprintf("Error: read (header)\n"); return R_FALSE; } if (strncmp ((char*)&bin->header->Signature, "VZ", 2)) return R_FALSE; return R_TRUE; }
static RBinAddr* binsym(RBinFile *bf, int type) { if (type == R_BIN_SYM_MAIN && bf && bf->buf) { ut8 init_jmp[4]; RBinAddr *ret = R_NEW0 (RBinAddr); if (!ret) return NULL; r_buf_read_at (bf->buf, 0x100, init_jmp, 4); if (init_jmp[1] == 0xc3) { ret->paddr = ret->vaddr = init_jmp[3]*0x100 + init_jmp[2]; return ret; } free (ret); } return NULL; }