VirtualBox

Changeset 96588 in vbox for trunk/src/VBox/Runtime/r3/win


Ignore:
Timestamp:
Sep 3, 2022 2:40:14 AM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
153465
Message:

IPRT/nocrt: Added workaround for NT3.1 not knowing about Misc.VirtualSize and not clearing uninitialized data at the end of sections. bugref:10261

Location:
trunk/src/VBox/Runtime/r3/win
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/win/nocrt-startup-common-win.cpp

    r96442 r96588  
    5555#include "internal/process.h"
    5656
     57
     58#ifdef RT_ARCH_X86
     59/**
     60 * NT 3.1 does not know about the IMAGE_SECTION_HEADER::Misc.VirtualSize field
     61 * and will therefore not handle merging initialized and uninitialized data into
     62 * the same section.
     63 *
     64 * We work around this by manually zeroing the uninitialized data before any
     65 * other code has been executed.
     66 */
     67void rtVccWinInitBssOnNt3(void *pvImageBase)
     68{
     69    /* We are called really early on, so we must figure out the NT version
     70       on our own.  It doesn't have to be all that accurate, though, as only
     71       NT 3.10 is affected (3.50 isn't). */
     72    DWORD const dwRawVer  = GetVersion();
     73    DWORD const uMajorVer = RT_BYTE1(dwRawVer);
     74    DWORD const uMinorVer = RT_BYTE2(dwRawVer);
     75    if (uMajorVer != 3 || uMinorVer >= 50)
     76        return;
     77
     78    /*
     79     * Locate the NT headers.
     80     */
     81    PIMAGE_NT_HEADERS   pNtHdrs;
     82    PIMAGE_DOS_HEADER   pDosHdr = (PIMAGE_DOS_HEADER)pvImageBase;
     83    if (pDosHdr->e_magic == IMAGE_DOS_SIGNATURE)
     84        pNtHdrs = (PIMAGE_NT_HEADERS)((uintptr_t)pvImageBase + pDosHdr->e_lfanew);
     85    else
     86        pNtHdrs = (PIMAGE_NT_HEADERS)pvImageBase;
     87    if (pNtHdrs->Signature == IMAGE_NT_SIGNATURE)
     88    {
     89        /*
     90         * Locate the section table and walk thru it, memsetting anything that
     91         * wasn't loaded from the file.
     92         */
     93        PIMAGE_SECTION_HEADER paSHdrs = (PIMAGE_SECTION_HEADER)(  (uintptr_t)&pNtHdrs->OptionalHeader
     94                                                                + pNtHdrs->FileHeader.SizeOfOptionalHeader);
     95        uint32_t const        cSections = pNtHdrs->FileHeader.NumberOfSections;
     96        for (uint32_t i = 0; i < cSections; i++)
     97        {
     98            if (paSHdrs[i].Misc.VirtualSize > paSHdrs[i].SizeOfRawData)
     99            {
     100                /* ASSUMES VirtualAddress is still an RVAs */
     101                uint8_t       *pbToZero = (uint8_t *)pvImageBase + paSHdrs[i].VirtualAddress + paSHdrs[i].SizeOfRawData;
     102                uint32_t const cbToZero = paSHdrs[i].Misc.VirtualSize - paSHdrs[i].SizeOfRawData;
     103
     104# if 0 /* very very crude debugging */
     105                const char *pszHex = "0123456789abcdef";
     106                char szMsg[128];
     107                char *psz = szMsg;
     108                *psz++ = 'd'; *psz++ = 'b'; *psz++ = 'g'; *psz++ = ':'; *psz++ = ' ';
     109                for (uint32_t q = 0, u = i; q < 8; q++, u >>= 4)
     110                    psz[7 - q] = pszHex[u & 0xf];
     111                psz += 8;
     112                *psz++ = ':';
     113                *psz++ = ' ';
     114                for (uint32_t q = 0, u = (uint32_t)pbToZero; q < 8; q++, u >>= 4)
     115                    psz[7 - q] = pszHex[u & 0xf];
     116                psz += 8;
     117                *psz++ = ' ';
     118                *psz++ = 'L';
     119                *psz++ = 'B';
     120                *psz++ = ' ';
     121                for (uint32_t q = 0, u = cbToZero; q < 8; q++, u >>= 4)
     122                    psz[7 - q] = pszHex[u & 0xf];
     123                psz += 8;
     124                *psz++ = ' ';
     125                for (uint32_t q = 0; q < 8; q++)
     126                    *psz++ = paSHdrs[i].Name[q] ? paSHdrs[i].Name[q] : ' ';
     127                *psz++ = ' '; *psz++ = '/'; *psz++ = ' '; *psz++ = 'v'; *psz++ = 'e'; *psz++ = 'r'; *psz++ = ' ';
     128                *psz++ = pszHex[(uMajorVer >> 4) & 0xf];
     129                *psz++ = pszHex[uMajorVer & 0xf];
     130                *psz++ = '.';
     131                *psz++ = pszHex[(uMinorVer >> 4) & 0xf];
     132                *psz++ = pszHex[uMinorVer & 0xf];
     133                *psz++ = '\r'; *psz++ = '\n';
     134                *psz   = '\0';
     135                DWORD cbIgn;
     136                HANDLE hOut = RTNtCurrentPeb()->ProcessParameters->StandardOutput;
     137                if (hOut == NULL || hOut == INVALID_HANDLE_VALUE)
     138                    hOut = RTNtCurrentPeb()->ProcessParameters->StandardError;
     139                if (hOut == NULL || hOut == INVALID_HANDLE_VALUE)
     140                    hOut = RTNtCurrentPeb()->ProcessParameters->ConsoleHandle;
     141                if (hOut == NULL || hOut == INVALID_HANDLE_VALUE)
     142                    hOut = GetStdHandle(STD_OUTPUT_HANDLE);
     143                WriteFile(hOut, szMsg, psz - szMsg, &cbIgn, NULL);
     144# endif
     145
     146                if (paSHdrs[i].Characteristics & IMAGE_SCN_MEM_WRITE)
     147                    memset(pbToZero, 0, cbToZero);
     148                else
     149                {
     150                    /* The section is not writable, so temporarily make it writable. */
     151                    PVOID pvAligned = pbToZero - ((uintptr_t)pbToZero & PAGE_OFFSET_MASK);
     152                    ULONG cbAligned = RT_ALIGN_32(cbToZero + ((uintptr_t)pbToZero & PAGE_OFFSET_MASK), PAGE_SIZE);
     153                    ULONG fNewProt  = paSHdrs[i].Characteristics & IMAGE_SCN_MEM_EXECUTE
     154                                    ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
     155                    ULONG fOldProt  = fNewProt;
     156                    NTSTATUS rcNt = NtProtectVirtualMemory(NtCurrentProcess(), &pvAligned, &cbAligned, fNewProt, &fOldProt);
     157                    if (NT_SUCCESS(rcNt))
     158                    {
     159                        memset(pbToZero, 0, cbToZero);
     160
     161                        rcNt = NtProtectVirtualMemory(NtCurrentProcess(), &pvAligned, &cbAligned, fOldProt, &fNewProt);
     162                    }
     163                    else
     164                        RT_BREAKPOINT();
     165                }
     166            }
     167        }
     168    }
     169    else
     170        RT_BREAKPOINT();
     171}
     172#endif
    57173
    58174
  • trunk/src/VBox/Runtime/r3/win/nocrt-startup-dll-win.cpp

    r96407 r96588  
    147147    {
    148148        case DLL_PROCESS_ATTACH:
     149#ifdef RT_ARCH_X86
     150            rtVccWinInitBssOnNt3((PVOID)hInstance);
     151#endif
    149152            rtVccInitSecurityCookie(); /* This function must be minimal because of this! */
    150153            return rtVccDllMainProcessAttach(hInstance, pvReserved);
  • trunk/src/VBox/Runtime/r3/win/nocrt-startup-exe-win.cpp

    r96407 r96588  
    9292     */
    9393#ifdef IPRT_NO_CRT
     94# ifdef RT_ARCH_X86
     95    rtVccWinInitBssOnNt3(pPeb->ImageBaseAddress);
     96# endif
    9497    rtVccInitSecurityCookie();
    9598#else
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