VirtualBox

Changeset 70362 in vbox for trunk/src/VBox/Runtime/r0drv/nt


Ignore:
Timestamp:
Dec 27, 2017 4:59:39 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
119962
Message:

iprt/rtR0Nt3InitVersion: Turned out registry has no version info during early boot, so use ntoskrnl header and resources as fallback.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/nt/nt3fakes-r0drv-nt.cpp

    r70341 r70362  
    4545#include "internal-r0drv-nt.h"
    4646
     47typedef uint32_t DWORD;
     48#include <VerRsrc.h>
     49
    4750
    4851/*********************************************************************************************************************************
     
    5962static uint32_t         g_uNt3BuildNo   = 1057;
    6063static bool             g_fNt3Checked   = false;
    61 static bool             g_fNt3Smp       = false;
     64static bool             g_fNt3Smp       = false; /**< Not reliable. */
    6265static bool volatile    g_fNt3VersionInitialized = false;
    6366
     
    119122
    120123RT_C_DECLS_END
     124
     125
     126/*********************************************************************************************************************************
     127*   Internal Functions                                                                                                           *
     128*********************************************************************************************************************************/
     129static void rtR0Nt3InitModuleInfo(void);
    121130
    122131
     
    287296static void rtR0Nt3InitVersion(void)
    288297{
     298    /*
     299     * No PsGetVersion, so try the registry.  Unfortunately not necessarily
     300     * initialized when we're loaded.
     301     */
    289302    RTL_QUERY_REGISTRY_TABLE aQuery[4];
    290303    RT_ZERO(aQuery);
     
    314327    if (!NT_SUCCESS(rcNt))
    315328        RTLogBackdoorPrintf("rtR0Nt3InitVersion: RtlQueryRegistryValues failed: %#x\n", rcNt);
    316     else if (fFound != 7)
     329    else
    317330        RTLogBackdoorPrintf("rtR0Nt3InitVersion: Didn't get all values: fFound=%#x\n", fFound);
     331
     332    /*
     333     * We really need the version number.  Build, type and SMP is off less importance.
     334     * Derive it from the NT kernel PE header.
     335     */
     336    if (!(fFound & RT_BIT_32(0)))
     337    {
     338        if (!g_fNt3ModuleInfoInitialized)
     339            rtR0Nt3InitModuleInfo();
     340
     341        PIMAGE_DOS_HEADER   pMzHdr  = (PIMAGE_DOS_HEADER)g_pbNt3OsKrnl;
     342        PIMAGE_NT_HEADERS32 pNtHdrs = (PIMAGE_NT_HEADERS32)&g_pbNt3OsKrnl[pMzHdr->e_lfanew];
     343        if (pNtHdrs->OptionalHeader.MajorOperatingSystemVersion == 1)
     344        {
     345            /* NT 3.1 and NT 3.50 both set OS version to 1.0 in the optional header. */
     346            g_uNt3MajorVer = 3;
     347            if (   pNtHdrs->OptionalHeader.MajorLinkerVersion == 2
     348                && pNtHdrs->OptionalHeader.MinorLinkerVersion < 50)
     349                g_uNt3MinorVer = 10;
     350            else
     351                g_uNt3MinorVer = 50;
     352        }
     353        else
     354        {
     355            g_uNt3MajorVer = pNtHdrs->OptionalHeader.MajorOperatingSystemVersion;
     356            g_uNt3MinorVer = pNtHdrs->OptionalHeader.MinorOperatingSystemVersion;
     357        }
     358        RTLogBackdoorPrintf("rtR0Nt3InitVersion: guessed %u.%u from PE header\n", g_uNt3MajorVer, g_uNt3MinorVer);
     359
     360        /* Check out the resource section, looking for VS_FIXEDFILEINFO. */
     361        __try
     362        {
     363            PIMAGE_SECTION_HEADER paShdrs = (PIMAGE_SECTION_HEADER)(pNtHdrs + 1);
     364            uint32_t const        cShdrs  = pNtHdrs->FileHeader.NumberOfSections;
     365            uint32_t              iShdr   = 0;
     366            while (iShdr < cShdrs && memcmp(paShdrs[iShdr].Name, ".rsrc", 6) != 0)
     367                iShdr++;
     368            if (iShdr < cShdrs)
     369            {
     370                if (   paShdrs[iShdr].VirtualAddress > 0
     371                    && paShdrs[iShdr].VirtualAddress < pNtHdrs->OptionalHeader.SizeOfImage)
     372                {
     373                    uint32_t const  cbRsrc   = RT_MIN(paShdrs[iShdr].Misc.VirtualSize
     374                                                      ? paShdrs[iShdr].Misc.VirtualSize : paShdrs[iShdr].SizeOfRawData,
     375                                                      pNtHdrs->OptionalHeader.SizeOfImage - paShdrs[iShdr].VirtualAddress);
     376                    uint8_t const  *pbRsrc   = &g_pbNt3OsKrnl[paShdrs[iShdr].VirtualAddress];
     377                    uint32_t const *puDwords = (uint32_t const *)pbRsrc;
     378                    uint32_t        cDWords  = (cbRsrc - sizeof(VS_FIXEDFILEINFO) + sizeof(uint32_t)) / sizeof(uint32_t);
     379                    while (cDWords-- > 0)
     380                    {
     381                        if (   puDwords[0] == VS_FFI_SIGNATURE
     382                            && puDwords[1] == VS_FFI_STRUCVERSION)
     383                        {
     384                            VS_FIXEDFILEINFO const *pVerInfo = (VS_FIXEDFILEINFO const *)puDwords;
     385                            g_uNt3MajorVer = pVerInfo->dwProductVersionMS >> 16;
     386                            g_uNt3MinorVer = pVerInfo->dwProductVersionMS >> 16;
     387                            g_uNt3BuildNo  = pVerInfo->dwProductVersionLS >> 16;
     388                            RTLogBackdoorPrintf("rtR0Nt3InitVersion: Found version info %u.%u build %u\n",
     389                                                g_uNt3MajorVer, g_uNt3MinorVer, g_uNt3BuildNo);
     390                            break;
     391                        }
     392                        puDwords++;
     393                    }
     394                }
     395            }
     396        }
     397        __except(EXCEPTION_EXECUTE_HANDLER)
     398        {
     399            RTLogBackdoorPrintf("rtR0Nt3InitVersion: Exception scanning .rsrc section for version info!\n");
     400        }
     401    }
     402
     403    /*
     404     * If we've got PsGetVersion, use it to override the above finding!
     405     * (We may end up here for reasons other than the PsGetVersion fallback.)
     406     */
     407    if (g_pfnrtPsGetVersion)
     408    {
     409        WCHAR          wszCsd[64];
     410        UNICODE_STRING UniStr;
     411        UniStr.Buffer        = wszCsd;
     412        UniStr.MaximumLength = sizeof(wszCsd) - sizeof(WCHAR);
     413        UniStr.Length        = 0;
     414        RT_ZERO(wszCsd);
     415        ULONG   uMajor   = 3;
     416        ULONG   uMinor   = 51;
     417        ULONG   uBuildNo = 1057;
     418        BOOLEAN fChecked = g_pfnrtPsGetVersion(&uMajor, &uMinor, &uBuildNo, &UniStr);
     419
     420        g_uNt3MajorVer           = uMajor;
     421        g_uNt3MinorVer           = uMinor;
     422        g_uNt3BuildNo            = uBuildNo;
     423        g_fNt3Checked            = fChecked != FALSE;
     424    }
    318425
    319426    g_fNt3VersionInitialized = true;
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