static int check_bytes(const ut8 *buf, ut64 length) { if (buf && length >= 4) { ut32 cls = r_mem_get_num (buf, 4); ut32 cls2 = r_mem_get_num (buf + 4, 4); if (cls + 4 == length && !cls2) { return true; } } return false; }
static int size(RBinFile *arch) { ut64 text, data, syms, spsz; int big_endian; if (!arch->o->info) arch->o->info = info (arch); big_endian = arch->o->info->big_endian; // TODO: reuse section list text = r_mem_get_num (arch->buf->buf+4, 4, big_endian); data = r_mem_get_num (arch->buf->buf+8, 4, big_endian); syms = r_mem_get_num (arch->buf->buf+16, 4, big_endian); spsz = r_mem_get_num (arch->buf->buf+24, 4, big_endian); return text+data+syms+spsz+(6*4); }
static ut64 size(RBinFile *bf) { ut64 text, data, syms, spsz; int big_endian; if (!bf->o->info) { bf->o->info = info (bf); } if (!bf->o->info) { return 0; } big_endian = bf->o->info->big_endian; // TODO: reuse section list text = r_mem_get_num (bf->buf->buf + 4, 4, big_endian); data = r_mem_get_num (bf->buf->buf + 8, 4, big_endian); syms = r_mem_get_num (bf->buf->buf + 16, 4, big_endian); spsz = r_mem_get_num (bf->buf->buf + 24, 4, big_endian); return text + data + syms + spsz + (6 * 4); }
static ut64 is_pointer(RIOBind *iob, const ut8 *buf, int endian, int size) { ut8 buf2[32]; int ret; ut64 n = r_mem_get_num (buf, size, endian); if (!n) return 1; // null pointer ret = iob->read_at (iob->io, n, buf2, size); if (ret != size) return 0; return is_invalid (buf2, size)? 0: n; }
static RList* sections(RBinFile *arch) { RList *ret = NULL; RBinSection *ptr = NULL; ut64 textsize, datasize, symssize, spszsize, pcszsize; ut64 entry0 = findEntry (arch->buf, 0); ut64 entry1 = findEntry (arch->buf, 1); ut64 entry2 = findEntry (arch->buf, 2); if (!(ret = r_list_newf (free))) { return NULL; } // add text segment textsize = r_mem_get_num (arch->buf->buf + 4, 4); if (!(ptr = R_NEW0 (RBinSection))) { return ret; } if (!entry1) { entry1 = arch->buf->length; } strncpy (ptr->name, "init", R_BIN_SIZEOF_STRINGS); ptr->size = entry1-entry0; ptr->vsize = entry1-entry0; ptr->paddr = entry0 + 4; ptr->vaddr = entry0; ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE | R_BIN_SCN_MAP; // r-x r_list_append (ret, ptr); if (entry1) { if (entry2) { if (!(ptr = R_NEW0 (RBinSection))) return ret; strncpy (ptr->name, "fini", R_BIN_SIZEOF_STRINGS); ptr->size = entry2-entry1; ptr->vsize = entry2-entry1; ptr->paddr = entry1 + 4; ptr->vaddr = entry1; ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE | R_BIN_SCN_MAP; // r-x r_list_append (ret, ptr); } else { entry2 = entry1; } } if (entry2) { if (!(ptr = R_NEW0 (RBinSection))) return ret; strncpy (ptr->name, "text", R_BIN_SIZEOF_STRINGS); ptr->size = arch->buf->length - entry2; ptr->vsize = arch->buf->length - entry2; ptr->paddr = entry2 + 4; ptr->vaddr = entry2; ptr->srwx = R_BIN_SCN_READABLE | R_BIN_SCN_EXECUTABLE | R_BIN_SCN_MAP; // r-x r_list_append (ret, ptr); } return ret; }
static ut64 is_pointer(RIOBind *iob, const ut8 *buf, int endian, int size) { ut8 buf2[32]; int ret; if (size > sizeof (buf2)) size = sizeof (buf2); ut64 n = r_mem_get_num (buf, size, endian); if (!n) return 1; // null pointer // optimization to ignore very low and very high pointers // this makes disasm 5x faster, but can result in some false positives if (n<0x1000) return 0; // probably wrong if (n>0xffffffffffff) return 0; // probably wrong ret = iob->read_at (iob->io, n, buf2, size); if (ret != size) return 0; return is_invalid (buf2, size)? 0: n; }
static ut64 is_pointer(RIOBind *iob, const ut8 *buf, int endian, int size) { ut64 n; ut8 buf2[32]; int ret; if (size > sizeof (buf2)) size = sizeof (buf2); n = r_mem_get_num (buf, size, endian); if (!n) return 1; // null pointer // optimization to ignore very low and very high pointers // this makes disasm 5x faster, but can result in some false positives // we should compare with current offset, to avoid // short/long references. and discard invalid ones if (n<0x1000) return 0; // probably wrong if (n>0xffffffffffffLL) return 0; // probably wrong ret = iob->read_at (iob->io, n, buf2, size); if (ret != size) return 0; return is_invalid (buf2, size)? 0: n; }
static ut64 is_pointer(RAnal *anal, const ut8 *buf, int size) { ut64 n; ut8 buf2[32]; RIOBind *iob = &anal->iob; if (size > sizeof (buf2)) size = sizeof (buf2); n = r_mem_get_num (buf, size); if (!n) return 1; // null pointer #if USE_IS_VALID_OFFSET int r = iob->is_valid_offset (iob->io, n, 0); return r? n: 0LL; #else // optimization to ignore very low and very high pointers // this makes disasm 5x faster, but can result in some false positives // we should compare with current offset, to avoid // short/long references. and discard invalid ones if (n < 0x1000) return 0; // probably wrong if (n > 0xffffffffffffLL) return 0; // probably wrong if (iob->read_at (iob->io, n, buf2, size) != size) return 0; return is_invalid (buf2, size)? 0: n; #endif }
static int is_number (const ut8 *buf, int endian, int size) { ut64 n = r_mem_get_num (buf, size, endian); return (n<UT32_MAX)? (int)n: 0; }
static RList* sections(RBinFile *arch) { RList *ret = NULL; RBinSection *ptr = NULL; ut64 textsize, datasize, symssize, spszsize, pcszsize; int big_endian = arch->o->info->big_endian; if (!(ret = r_list_new ())) return NULL; ret->free = free; // add text segment textsize = r_mem_get_num (arch->buf->buf+4, 4, big_endian); if (!(ptr = R_NEW0 (RBinSection))) return ret; strncpy (ptr->name, "text", R_BIN_SIZEOF_STRINGS); ptr->size = textsize; ptr->vsize = textsize + (textsize%4096); ptr->paddr = 8*4; ptr->vaddr = ptr->paddr; ptr->srwx = 5; // r-x r_list_append (ret, ptr); // add data segment datasize = r_mem_get_num (arch->buf->buf+8, 4, big_endian); if (datasize>0) { if (!(ptr = R_NEW0 (RBinSection))) return ret; strncpy (ptr->name, "data", R_BIN_SIZEOF_STRINGS); ptr->size = datasize; ptr->vsize = datasize + (datasize%4096); ptr->paddr = textsize+(8*4); ptr->vaddr = ptr->paddr; ptr->srwx = 6; // rw- r_list_append (ret, ptr); } // ignore bss or what // add syms segment symssize = r_mem_get_num (arch->buf->buf+16, 4, big_endian); if (symssize) { if (!(ptr = R_NEW0 (RBinSection))) return ret; strncpy (ptr->name, "syms", R_BIN_SIZEOF_STRINGS); ptr->size = symssize; ptr->vsize = symssize + (symssize%4096); ptr->paddr = datasize+textsize+(8*4); ptr->vaddr = ptr->paddr; ptr->srwx = 4; // r-- r_list_append (ret, ptr); } // add spsz segment spszsize = r_mem_get_num (arch->buf->buf+24, 4, big_endian); if (spszsize) { if (!(ptr = R_NEW0 (RBinSection))) return ret; strncpy (ptr->name, "spsz", R_BIN_SIZEOF_STRINGS); ptr->size = spszsize; ptr->vsize = spszsize + (spszsize%4096); ptr->paddr = symssize+datasize+textsize+(8*4); ptr->vaddr = ptr->paddr; ptr->srwx = 4; // r-- r_list_append (ret, ptr); } // add pcsz segment pcszsize = r_mem_get_num (arch->buf->buf+24, 4, big_endian); if (pcszsize) { if (!(ptr = R_NEW0 (RBinSection))) return ret; strncpy (ptr->name, "pcsz", R_BIN_SIZEOF_STRINGS); ptr->size = pcszsize; ptr->vsize = pcszsize + (pcszsize%4096); ptr->paddr = spszsize+symssize+datasize+textsize+(8*4); ptr->vaddr = ptr->paddr; ptr->srwx = 4; // r-- r_list_append (ret, ptr); } return ret; }