VirtualBox

Changeset 70403 in vbox for trunk/src/bldprogs


Ignore:
Timestamp:
Jan 1, 2018 3:30:04 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
120008
Message:

Additions,ValidationKit,VBoxPeSetVersion: Force linker to split .bss out from the .data section as NT 3.1 cannot deal with that (it doesn't check the Misc.VirtualSize field and maps raw bytes up to the next section). We tell the linker .bss is uncached, and have VBoxPeSetImage undo this change.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bldprogs/VBoxPeSetVersion.cpp

    r70373 r70403  
    141141
    142142    /*
    143      * Make the IAT writable for NT 3.1.
     143     * Make the IAT writable for NT 3.1 and drop the non-cachable flag from .bss.
     144     *
     145     * The latter is a trick we use to prevent the linker from merging .data and .bss,
     146     * because NT 3.1 does not honor Misc.VirtualSize and won't zero padd the .bss part
     147     * if it's not zero padded in the file.  This seemed simpler than adding zero padding.
    144148     */
    145149    if (   uNtVersion <= MK_VER(3, 10)
    146         && NtHdrsNew.FileHeader.NumberOfSections > 0
    147         && NtHdrsNew.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size > 0)
     150        && NtHdrsNew.FileHeader.NumberOfSections > 0)
    148151    {
    149152        uint32_t              cbShdrs = sizeof(IMAGE_SECTION_HEADER) * NtHdrsNew.FileHeader.NumberOfSections;
     
    161164            return Error("Failed to read section headers at %#lx: %s", offShdrs, strerror(errno));
    162165
    163         uint32_t const uRvaIat = NtHdrsNew.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress;
    164         uint32_t       uRvaEnd = NtHdrsNew.OptionalHeader.SizeOfImage;
    165         uint32_t       i       = NtHdrsNew.FileHeader.NumberOfSections;
     166        bool     fFoundBss = false;
     167        uint32_t uRvaEnd   = NtHdrsNew.OptionalHeader.SizeOfImage;
     168        uint32_t uRvaIat   = NtHdrsNew.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size > 0
     169                           ? NtHdrsNew.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress : UINT32_MAX;
     170        uint32_t i         = NtHdrsNew.FileHeader.NumberOfSections;
    166171        while (i-- > 0)
    167172            if (!(paShdrs[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
    168173            {
    169                 uint32_t uRva = paShdrs[i].VirtualAddress;
    170                 if (uRvaIat >= uRva && uRvaIat < uRvaEnd)
     174                bool     fModified = false;
     175                if (uRvaIat >= paShdrs[i].VirtualAddress && uRvaIat < uRvaEnd)
    171176                {
    172177                    if (!(paShdrs[i].Characteristics & IMAGE_SCN_MEM_WRITE))
    173178                    {
    174179                        paShdrs[i].Characteristics |= IMAGE_SCN_MEM_WRITE;
    175                         unsigned long offShdr = offShdrs + i * sizeof(IMAGE_SECTION_HEADER);
    176                         if (fseek(pFile, offShdr, SEEK_SET) != 0)
    177                             return Error("Failed to seek to section header #%u at %#lx: %s", i, offShdr, strerror(errno));
    178                         if (fwrite(&paShdrs[i], sizeof(IMAGE_SECTION_HEADER), 1, pFile) != 1)
    179                             return Error("Failed to write IAT section header header at %#lx: %s", offShdr, strerror(errno));
     180                        fModified = true;
    180181                    }
    181                     break;
    182                 }
    183                 uRvaEnd = uRva;
     182                    uRvaIat = UINT32_MAX;
     183                }
     184
     185                if (   !fFoundBss
     186                    && strcmp((const char *)paShdrs[i].Name, ".bss") == 0)
     187                {
     188                    if (paShdrs[i].Characteristics & IMAGE_SCN_MEM_NOT_CACHED)
     189                    {
     190                        paShdrs[i].Characteristics &= ~IMAGE_SCN_MEM_NOT_CACHED;
     191                        fModified = true;
     192                    }
     193                    fFoundBss = true;
     194                }
     195
     196                if (fModified)
     197                {
     198                    unsigned long offShdr = offShdrs + i * sizeof(IMAGE_SECTION_HEADER);
     199                    if (fseek(pFile, offShdr, SEEK_SET) != 0)
     200                        return Error("Failed to seek to section header #%u at %#lx: %s", i, offShdr, strerror(errno));
     201                    if (fwrite(&paShdrs[i], sizeof(IMAGE_SECTION_HEADER), 1, pFile) != 1)
     202                        return Error("Failed to write %8.8s section header header at %#lx: %s",
     203                                     paShdrs[i].Name, offShdr, strerror(errno));
     204                    if (uRvaIat == UINT32_MAX && fFoundBss)
     205                        break;
     206                }
     207
     208                /* Advance */
     209                uRvaEnd = paShdrs[i].VirtualAddress;
    184210            }
    185211
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette