Beispiel #1
0
/** Returns the file offset associated with the virtual address of a mapped section.
 *
 *  NOTE: The MemoryMap class is a better interface to this same information. [RPM 2009-09-09] */
rose_addr_t
SgAsmGenericSection::get_va_offset(rose_addr_t va) const
{
    ROSE_ASSERT(is_mapped());
    ROSE_ASSERT(va >= get_base_va());
    rose_addr_t rva = va - get_base_va();
    ROSE_ASSERT(rva >= get_mapped_preferred_rva());
    return get_offset() + (rva - get_mapped_preferred_rva());
}
Beispiel #2
0
/** Returns (non-relative) virtual address if mapped, zero otherwise. */
rose_addr_t
SgAsmGenericSection::get_mapped_preferred_va() const
{
    ROSE_ASSERT(this != NULL);
    if (is_mapped())
        return get_base_va() + get_mapped_preferred_rva();
    return 0;
}
Beispiel #3
0
void *
SgAsmPEFileHeader::encode(PE64OptHeader_disk *disk) const
{
    host_to_le(p_e_opt_magic,          &(disk->e_opt_magic));
    host_to_le(p_e_lmajor,             &(disk->e_lmajor));
    host_to_le(p_e_lminor,             &(disk->e_lminor));
    host_to_le(p_e_code_size,          &(disk->e_code_size));
    host_to_le(p_e_data_size,          &(disk->e_data_size));
    host_to_le(p_e_bss_size,           &(disk->e_bss_size));
    host_to_le(get_entry_rva(),        &(disk->e_entrypoint_rva));
    host_to_le(p_e_code_rva,           &(disk->e_code_rva));
 // host_to_le(p_e_data_rva,           &(disk->e_data_rva)); /* not present in PE32+ */
    host_to_le(get_base_va(),          &(disk->e_image_base));
    host_to_le(p_e_section_align,      &(disk->e_section_align));
    host_to_le(p_e_file_align,         &(disk->e_file_align));
    host_to_le(p_e_os_major,           &(disk->e_os_major));
    host_to_le(p_e_os_minor,           &(disk->e_os_minor));
    host_to_le(p_e_user_major,         &(disk->e_user_major));
    host_to_le(p_e_user_minor,         &(disk->e_user_minor));
    host_to_le(p_e_subsys_major,       &(disk->e_subsys_major));
    host_to_le(p_e_subsys_minor,       &(disk->e_subsys_minor));
    host_to_le(p_e_reserved9,          &(disk->e_reserved9));
    host_to_le(p_e_image_size,         &(disk->e_image_size));
    host_to_le(p_e_header_size,        &(disk->e_header_size));
    host_to_le(p_e_file_checksum,      &(disk->e_file_checksum));
    host_to_le(p_e_subsystem,          &(disk->e_subsystem));
    host_to_le(p_e_dll_flags,          &(disk->e_dll_flags));
    host_to_le(p_e_stack_reserve_size, &(disk->e_stack_reserve_size));
    host_to_le(p_e_stack_commit_size,  &(disk->e_stack_commit_size));
    host_to_le(p_e_heap_reserve_size,  &(disk->e_heap_reserve_size));
    host_to_le(p_e_heap_commit_size,   &(disk->e_heap_commit_size));
    host_to_le(p_e_loader_flags,       &(disk->e_loader_flags));
    host_to_le(p_e_num_rvasize_pairs,  &(disk->e_num_rvasize_pairs));

    return disk;
}
Beispiel #4
0
/* Looks at the RVA/Size pairs in the PE header and creates an SgAsmGenericSection object for each one.  This must be done
 * after we build the mapping from virtual addresses to file offsets. */
void
SgAsmPEFileHeader::create_table_sections()
{

    /* First, only create the sections. */
    for (size_t i=0; i<p_rvasize_pairs->get_pairs().size(); i++) {
        SgAsmPERVASizePair *pair = p_rvasize_pairs->get_pairs()[i];
        if (0==pair->get_e_size())
            continue;

        /* Table names come from PE file specification and are hard coded by RVA/Size pair index */
        const char *tabname_short;
        std::string tabname = rvasize_pair_name((PairPurpose)i, &tabname_short);

        /* Find the starting offset in the file.
         * FIXME: We have a potential problem here in that ROSE sections are always contiguous in the file but a section created
         *        from an RVA/Size pair is not necessarily contiguous in the file.  Normally such sections are in fact
         *        contiguous and we'll just ignore this for now.  In any case, as long as these sections only ever read their
         *        data via the same MemoryMap that we use here, everything should be fine. [RPM 2009-08-17] */
        MemoryMap *map = get_loader_map();
        ROSE_ASSERT(map!=NULL);
        const MemoryMap::MapElement *elmt = map->find(get_base_va() + pair->get_e_rva());
        if (!elmt) {
            fprintf(stderr, "SgAsmPEFileHeader::create_table_sections: warning: pair-%zu, rva=0x%08"PRIx64", size=%"PRIu64
                    " bytes \"%s\": unable to find a mapping for the virtual address (skipping)\n",
                    i, pair->get_e_rva().get_rva(), pair->get_e_size(), tabname.c_str());
            continue;
        }
        rose_addr_t file_offset = elmt->is_anonymous() ? 0 : elmt->get_va_offset(get_base_va() + pair->get_e_rva(), 1);

        /* Create the new section */
        SgAsmGenericSection *tabsec = NULL;
        switch (i) {
            case 0: {
                /* Sometimes export sections are represented by a ".edata" section, and sometimes they're represented by an
                 * RVA/Size pair, and sometimes both point to the same part of the file. We don't want the exports duplicated
                 * in the AST, so we only create this table as exports if we haven't already seen some other export section. */
                SgAsmGenericSectionPtrList &sections = get_sections()->get_sections();
                bool seen_exports = false;
                for (SgAsmGenericSectionPtrList::iterator si=sections.begin(); !seen_exports && si!=sections.end(); ++si)
                    seen_exports = isSgAsmPEExportSection(*si);
                if (seen_exports) {
                    tabsec = new SgAsmGenericSection(get_file(), this);
                } else {
                    tabsec = new SgAsmPEExportSection(this);
                }
                break;
            }
            case 1: {
                /* Sometimes import sections are represented by a ".idata" section, and sometimes they're represented by an
                 * RVA/Size pair, and sometimes both point to the same part of the file.  We don't want the imports duplicated
                 * in the AST, so we only create this table as imports if we haven't already seen some other import section. */
                SgAsmGenericSectionPtrList &sections = get_sections()->get_sections();
                bool seen_imports = false;
                for (SgAsmGenericSectionPtrList::iterator si=sections.begin(); !seen_imports && si!=sections.end(); ++si)
                    seen_imports = isSgAsmPEImportSection(*si);
                if (seen_imports) {
                    tabsec = new SgAsmGenericSection(get_file(), this);
                } else {
                    tabsec = new SgAsmPEImportSection(this);
                }
                break;
            }
            default: {
                tabsec = new SgAsmGenericSection(get_file(), this);
                break;
            }
        }
        tabsec->set_name(new SgAsmBasicString(tabname));
        tabsec->set_short_name(tabname_short);
        tabsec->set_synthesized(true);
        tabsec->set_purpose(SP_HEADER);

        tabsec->set_offset(file_offset);
        tabsec->set_size(pair->get_e_size());
        tabsec->set_file_alignment(1);

        tabsec->set_mapped_alignment(1);
        tabsec->set_mapped_preferred_rva(pair->get_e_rva().get_rva());
        tabsec->set_mapped_actual_va(pair->get_e_rva().get_rva()+get_base_va()); /*FIXME: not sure this is correct. [RPM 2009-09-11]*/
        tabsec->set_mapped_size(pair->get_e_size());
        tabsec->set_mapped_rperm(true);
        tabsec->set_mapped_wperm(false);
        tabsec->set_mapped_xperm(false);
        pair->set_section(tabsec);
        pair->set_e_rva(pair->get_e_rva().set_section(tabsec));
    }

    /* Now parse the sections */
    for (size_t i=0; i<p_rvasize_pairs->get_pairs().size(); i++) {
        SgAsmPERVASizePair *pair = p_rvasize_pairs->get_pairs()[i];
        SgAsmGenericSection *tabsec = pair->get_section();
        if (tabsec)
            tabsec->parse();
    }
}
Beispiel #5
0
/** Returns the file offset associated with the relative virtual address of a mapped section.
 *
 *  NOTE: The MemoryMap class is a better interface to this same information. [RPM 2009-09-09] */
rose_addr_t
SgAsmGenericSection::get_rva_offset(rose_addr_t rva) const
{
    return get_va_offset(rva + get_base_va());
}