VirtualBox

Changeset 70210 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Dec 18, 2017 8:43:19 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
119794
Message:

nt3fakes-r0drv-nt.cpp: Get version from registry. Just for fun/completeness try find the modules via symbols we import from them.

File:
1 edited

Legend:

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

    r70192 r70210  
    3737#define ZwYieldExecution            ZwYieldExecution_Nt4Plus
    3838
     39#define _IMAGE_NT_HEADERS           RT_CONCAT(_IMAGE_NT_HEADERS,ARCH_BITS)
    3940#include "the-nt-kernel.h"
    4041#include <iprt/mem.h>
    4142
    4243#include <iprt/assert.h>
     44#include <iprt/ctype.h>
    4345#include <iprt/err.h>
     46#include <iprt/log.h>
     47#include <iprt/string.h>
     48#include <iprt/formats/mz.h>
     49#include <iprt/formats/pecoff.h>
    4450#include "internal-r0drv-nt.h"
    4551
     
    5662*   Global Variables                                                                                                             *
    5763*********************************************************************************************************************************/
    58 static uint32_t g_uNt3Version = 351;
    59 
     64static uint32_t         g_uNt3MajorVer  = 3;
     65static uint32_t         g_uNt3MinorVer  = 51;
     66static uint32_t         g_uNt3BuildNo   = 1057;
     67static bool             g_fNt3Checked   = false;
     68static bool             g_fNt3Smp       = false;
     69static bool volatile    g_fNt3VersionInitialized = false;
     70
     71static uint8_t         *g_pbNt3OsKrnl   = (uint8_t *)UINT32_C(0x80100000);
     72static uint32_t         g_cbNt3OsKrnl   = 0x300000;
     73static uint8_t         *g_pbNt3Hal      = (uint8_t *)UINT32_C(0x80400000);
     74static uint32_t         g_cbNt3Hal      = _512K;
     75static bool volatile    g_fNt3ModuleInfoInitialized = false;
     76
     77
     78/**
     79 * Converts a string to a number, stopping at the first non-digit.
     80 *
     81 * @returns The value
     82 * @param   ppwcValue       Pointer to the string pointer variable.  Updated.
     83 * @param   pcwcValue       Pointer to the string length variable.  Updated.
     84 */
     85static uint32_t rtR0Nt3StringToNum(PCRTUTF16 *ppwcValue, size_t *pcwcValue)
     86{
     87    uint32_t  uValue   = 0;
     88    PCRTUTF16 pwcValue = *ppwcValue;
     89    size_t    cwcValue = *pcwcValue;
     90
     91    while (cwcValue > 0)
     92    {
     93        RTUTF16 uc = *pwcValue;
     94        unsigned uDigit = (unsigned)uc - (unsigned)'0';
     95        if (uDigit < (unsigned)10)
     96        {
     97            uValue *= 10;
     98            uValue += uDigit;
     99        }
     100        else
     101            break;
     102        pwcValue++;
     103        cwcValue--;
     104    }
     105
     106    *ppwcValue = pwcValue;
     107    *pcwcValue = cwcValue;
     108    return uValue;
     109}
     110
     111
     112/**
     113 * Implements RTL_QUERY_REGISTRY_ROUTINE for processing
     114 * 'HKLM/Software/Microsoft/Window NT/CurrentVersion/CurrentVersion'
     115 */
     116static NTSTATUS NTAPI rtR0Nt3VerEnumCallback_CurrentVersion(PWSTR pwszValueName, ULONG uValueType,
     117                                                            PVOID pvValue, ULONG cbValue, PVOID pvUser, PVOID pvEntryCtx)
     118{
     119    RT_NOREF(pwszValueName, pvEntryCtx);
     120    if (   uValueType == REG_SZ
     121        || uValueType == REG_EXPAND_SZ)
     122    {
     123        PCRTUTF16 pwcValue = (PCRTUTF16)pvValue;
     124        size_t    cwcValue  = cbValue / sizeof(*pwcValue);
     125        uint32_t uMajor = rtR0Nt3StringToNum(&pwcValue, &cwcValue);
     126        uint32_t uMinor = 0;
     127        if (cwcValue > 1)
     128        {
     129            pwcValue++;
     130            cwcValue--;
     131            uMinor = rtR0Nt3StringToNum(&pwcValue, &cwcValue);
     132        }
     133
     134        if (uMajor >= 3)
     135        {
     136            g_uNt3MajorVer = uMajor;
     137            g_uNt3MinorVer = uMinor;
     138            RTLogBackdoorPrintf("rtR0Nt3VerEnumCallback_CurrentVersion found: uMajor=%u uMinor=%u\n", uMajor, uMinor);
     139            *(uint32_t *)pvUser |= RT_BIT_32(0);
     140            return STATUS_SUCCESS;
     141        }
     142
     143        RTLogBackdoorPrintf("rtR0Nt3VerEnumCallback_CurrentVersion: '%.*ls'\n", cbValue / sizeof(RTUTF16), pvValue);
     144    }
     145    else
     146        RTLogBackdoorPrintf("rtR0Nt3VerEnumCallback_CurrentVersion: uValueType=%u %.*Rhxs\n", uValueType, cbValue, pvValue);
     147    return STATUS_SUCCESS;
     148}
     149
     150
     151/**
     152 * Implements RTL_QUERY_REGISTRY_ROUTINE for processing
     153 * 'HKLM/Software/Microsoft/Window NT/CurrentVersion/CurrentBuildNumber'
     154 */
     155static NTSTATUS NTAPI rtR0Nt3VerEnumCallback_CurrentBuildNumber(PWSTR pwszValueName, ULONG uValueType,
     156                                                                PVOID pvValue, ULONG cbValue, PVOID pvUser, PVOID pvEntryCtx)
     157{
     158    RT_NOREF(pwszValueName, pvEntryCtx);
     159    if (   uValueType == REG_SZ
     160        || uValueType == REG_EXPAND_SZ)
     161    {
     162        PCRTUTF16 pwcValue = (PCRTUTF16)pvValue;
     163        size_t    cwcValue  = cbValue / sizeof(*pwcValue);
     164        uint32_t uBuildNo = rtR0Nt3StringToNum(&pwcValue, &cwcValue);
     165
     166        if (uBuildNo >= 100 && uBuildNo < _1M)
     167        {
     168            g_uNt3BuildNo = uBuildNo;
     169            RTLogBackdoorPrintf("rtR0Nt3VerEnumCallback_CurrentBuildNumber found: uBuildNo=%u\n", uBuildNo);
     170            *(uint32_t *)pvUser |= RT_BIT_32(1);
     171            return STATUS_SUCCESS;
     172        }
     173
     174        RTLogBackdoorPrintf("rtR0Nt3VerEnumCallback_CurrentBuildNumber: '%.*ls'\n", cbValue / sizeof(RTUTF16), pvValue);
     175    }
     176    else
     177        RTLogBackdoorPrintf("rtR0Nt3VerEnumCallback_CurrentBuildNumber: uValueType=%u %.*Rhxs\n", uValueType, cbValue, pvValue);
     178    return STATUS_SUCCESS;
     179}
     180
     181
     182/**
     183 * Implements RTL_QUERY_REGISTRY_ROUTINE for processing
     184 * 'HKLM/Software/Microsoft/Window NT/CurrentVersion/CurrentType'
     185 */
     186static NTSTATUS NTAPI rtR0Nt3VerEnumCallback_CurrentType(PWSTR pwszValueName, ULONG uValueType,
     187                                                         PVOID pvValue, ULONG cbValue, PVOID pvUser, PVOID pvEntryCtx)
     188{
     189    RT_NOREF(pwszValueName, pvEntryCtx);
     190    if (   uValueType == REG_SZ
     191        || uValueType == REG_EXPAND_SZ)
     192    {
     193        PCRTUTF16 pwcValue = (PCRTUTF16)pvValue;
     194        size_t    cwcValue = cbValue / sizeof(*pwcValue);
     195
     196        int fSmp = -1;
     197        if (cwcValue >= 12 && RTUtf16NICmpAscii(pwcValue, "Uniprocessor", 12) == 0)
     198        {
     199            cwcValue -= 12;
     200            pwcValue += 12;
     201            fSmp = 0;
     202        }
     203        else if (cwcValue >= 14 && RTUtf16NICmpAscii(pwcValue, "Multiprocessor", 14) == 0)
     204        {
     205            cwcValue -= 14;
     206            pwcValue += 14;
     207            fSmp = 1;
     208        }
     209        if (fSmp != -1)
     210        {
     211            while (cwcValue > 0 && RT_C_IS_SPACE(*pwcValue))
     212                cwcValue--, pwcValue++;
     213
     214            int fChecked = -1;
     215            if (cwcValue >= 4 && RTUtf16NICmpAscii(pwcValue, "Free", 4) == 0)
     216                fChecked = 0;
     217            else if (cwcValue >= 7 && RTUtf16NICmpAscii(pwcValue, "Checked", 7) == 0)
     218                fChecked = 1;
     219            if (fChecked != -1)
     220            {
     221                g_fNt3Smp     = fSmp     != 0;
     222                g_fNt3Checked = fChecked != 0;
     223                RTLogBackdoorPrintf("rtR0Nt3VerEnumCallback_CurrentType found: fSmp=%d fChecked=%d\n", fSmp, fChecked);
     224                *(uint32_t *)pvUser |= RT_BIT_32(2);
     225                return STATUS_SUCCESS;
     226            }
     227        }
     228
     229        RTLogBackdoorPrintf("rtR0Nt3VerEnumCallback_CurrentType: '%.*ls'\n", cbValue / sizeof(RTUTF16), pvValue);
     230    }
     231    else
     232        RTLogBackdoorPrintf("rtR0Nt3VerEnumCallback_CurrentType: uValueType=%u %.*Rhxs\n", uValueType, cbValue, pvValue);
     233    return STATUS_SUCCESS;
     234}
     235
     236
     237/**
     238 * Figure out the NT 3 version from the registry.
     239 */
     240static void rtR0Nt3InitVersion(void)
     241{
     242    RTL_QUERY_REGISTRY_TABLE aQuery[4];
     243    RT_ZERO(aQuery);
     244    aQuery[0].QueryRoutine = rtR0Nt3VerEnumCallback_CurrentVersion;
     245    aQuery[0].Flags        = 0;
     246    aQuery[0].Name         = L"CurrentVersion";
     247    aQuery[0].EntryContext = NULL;
     248    aQuery[0].DefaultType  = REG_NONE;
     249
     250    aQuery[1].QueryRoutine = rtR0Nt3VerEnumCallback_CurrentBuildNumber;
     251    aQuery[1].Flags        = 0;
     252    aQuery[1].Name         = L"CurrentBuildNumber";
     253    aQuery[1].EntryContext = NULL;
     254    aQuery[1].DefaultType  = REG_NONE;
     255
     256    aQuery[2].QueryRoutine = rtR0Nt3VerEnumCallback_CurrentType;
     257    aQuery[2].Flags        = 0;
     258    aQuery[2].Name         = L"CurrentType";
     259    aQuery[2].EntryContext = NULL;
     260    aQuery[2].DefaultType  = REG_NONE;
     261
     262    uint32_t fFound = 0;
     263    //NTSTATUS rcNt = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT, NULL, &aQuery[0], &fFound, NULL /*Environment*/);
     264    NTSTATUS rcNt = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
     265                                           L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion",
     266                                           &aQuery[0], &fFound, NULL /*Environment*/);
     267    if (!NT_SUCCESS(rcNt))
     268        RTLogBackdoorPrintf("rtR0Nt3InitVersion: RtlQueryRegistryValues failed: %#x\n", rcNt);
     269    else if (fFound != 7)
     270        RTLogBackdoorPrintf("rtR0Nt3InitVersion: Didn't get all values: fFound=%#x\n", fFound);
     271
     272    g_fNt3VersionInitialized = true;
     273}
    60274
    61275
     
    63277PsGetVersion(ULONG *puMajor, ULONG *puMinor, ULONG *puBuildNo, UNICODE_STRING *pCsdStr)
    64278{
     279    if (!g_fNt3VersionInitialized)
     280        rtR0Nt3InitVersion();
    65281    if (puMajor)
    66         *puMajor = 3;
     282        *puMajor = g_uNt3MajorVer;
    67283    if (puMinor)
    68         *puMinor = 51;
     284        *puMinor = g_uNt3MinorVer;
    69285    if (puBuildNo)
    70         *puMinor = 1057;
     286        *puBuildNo = g_uNt3BuildNo;
    71287    if (pCsdStr)
    72288    {
     
    74290        pCsdStr->Length = 0;
    75291    }
    76     return FALSE; /* not checked. */
     292    return g_fNt3Checked;
     293}
     294
     295
     296/**
     297 * Worker for rtR0Nt3InitModuleInfo.
     298 */
     299static bool rtR0Nt3InitModuleInfoOne(const char *pszImage, uint8_t const *pbCode, uint8_t **ppbModule, uint32_t *pcbModule)
     300{
     301    uintptr_t const uImageAlign = _64K;
     302
     303    /* Align pbCode. */
     304    pbCode = (uint8_t const *)((uintptr_t)pbCode & ~(uintptr_t)(uImageAlign - 1));
     305
     306    /* Scan backwards till we find a PE signature. */
     307    for (uint32_t cbChecked = 0; cbChecked < _64M; cbChecked += uImageAlign, pbCode -= uImageAlign)
     308    {
     309        uint32_t uZero     = 0;
     310        uint32_t offNewHdr = 0;
     311        __try
     312        {
     313            uZero     = *(uint32_t const *)pbCode;
     314            offNewHdr = *(uint32_t const *)&pbCode[RT_OFFSETOF(IMAGE_DOS_HEADER, e_lfanew)];
     315        }
     316        __except(EXCEPTION_EXECUTE_HANDLER)
     317        {
     318            RTLogBackdoorPrintf("rtR0Nt3InitModuleInfo: Exception at %p scanning for DOS header...\n", pbCode);
     319            continue;
     320        }
     321        if (   (uint16_t)uZero == IMAGE_DOS_SIGNATURE
     322            && offNewHdr < _2K
     323            && offNewHdr >= sizeof(IMAGE_DOS_HEADER))
     324        {
     325            RT_CONCAT(IMAGE_NT_HEADERS,ARCH_BITS) NtHdrs;
     326            __try
     327            {
     328                NtHdrs = *(decltype(NtHdrs) const *)&pbCode[offNewHdr];
     329            }
     330            __except(EXCEPTION_EXECUTE_HANDLER)
     331            {
     332                RTLogBackdoorPrintf("rtR0Nt3InitModuleInfo: Exception at %p reading NT headers...\n", pbCode);
     333                continue;
     334            }
     335            if (   NtHdrs.Signature == IMAGE_NT_SIGNATURE
     336                && NtHdrs.FileHeader.SizeOfOptionalHeader == sizeof(NtHdrs.OptionalHeader)
     337                && NtHdrs.FileHeader.NumberOfSections > 2
     338                && NtHdrs.FileHeader.NumberOfSections < _4K
     339                && NtHdrs.OptionalHeader.Magic == RT_CONCAT3(IMAGE_NT_OPTIONAL_HDR,ARCH_BITS,_MAGIC))
     340            {
     341                *ppbModule = (uint8_t *)pbCode;
     342                *pcbModule = NtHdrs.OptionalHeader.SizeOfImage;
     343                RTLogBackdoorPrintf("rtR0Nt3InitModuleInfo: Found %s at %#p LB %#x\n",
     344                                    pszImage, pbCode, NtHdrs.OptionalHeader.SizeOfImage);
     345                return true;
     346            }
     347        }
     348    }
     349    RTLogBackdoorPrintf("rtR0Nt3InitModuleInfo: Warning! Unable to locate %s...\n");
     350    return false;
     351}
     352
     353
     354/**
     355 * Initializes the module information (NTOSKRNL + HAL) using exported symbols.
     356 * This only works as long as noone is intercepting the symbols.
     357 */
     358static void rtR0Nt3InitModuleInfo(void)
     359{
     360    rtR0Nt3InitModuleInfoOne("ntoskrnl.exe", (uint8_t const *)(uintptr_t)IoGetCurrentProcess, &g_pbNt3OsKrnl, &g_cbNt3OsKrnl);
     361    rtR0Nt3InitModuleInfoOne("hal.dll",      (uint8_t const *)(uintptr_t)HalGetBusData,       &g_pbNt3Hal,    &g_cbNt3Hal);
     362    g_fNt3ModuleInfoInitialized = true;
    77363}
    78364
     
    92378                return STATUS_INFO_LENGTH_MISMATCH;
    93379
     380            if (!g_fNt3ModuleInfoInitialized)
     381                rtR0Nt3InitModuleInfo();
     382
    94383            pInfo->NumberOfModules = 2;
    95384
    96385            /* ntoskrnl.exe */
    97386            pInfo->Modules[0].Section           = NULL;
    98             pInfo->Modules[0].MappedBase        = (PVOID)UINT32_C(0x80100000);
    99             pInfo->Modules[0].ImageBase         = (PVOID)UINT32_C(0x80100000);
    100             pInfo->Modules[0].ImageSize         = UINT32_C(0x80400000) - UINT32_C(0x80100000);
     387            pInfo->Modules[0].MappedBase        = g_pbNt3OsKrnl;
     388            pInfo->Modules[0].ImageBase         = g_pbNt3OsKrnl;
     389            pInfo->Modules[0].ImageSize         = g_cbNt3OsKrnl;
    101390            pInfo->Modules[0].Flags             = 0;
    102391            pInfo->Modules[0].LoadOrderIndex    = 0;
     
    108397            /* hal.dll */
    109398            pInfo->Modules[1].Section           = NULL;
    110             pInfo->Modules[1].MappedBase        = (PVOID)UINT32_C(0x80400000);
    111             pInfo->Modules[1].ImageBase         = (PVOID)UINT32_C(0x80400000);
    112             pInfo->Modules[1].ImageSize         = _512K;
     399            pInfo->Modules[1].MappedBase        = g_pbNt3Hal;
     400            pInfo->Modules[1].ImageBase         = g_pbNt3Hal;
     401            pInfo->Modules[1].ImageSize         = g_cbNt3Hal;
    113402            pInfo->Modules[1].Flags             = 0;
    114403            pInfo->Modules[1].LoadOrderIndex    = 1;
     
    156445PsGetCurrentProcessId(void)
    157446{
     447    if (!g_fNt3VersionInitialized)
     448        rtR0Nt3InitVersion();
     449
    158450    uint8_t const *pbProcess = (uint8_t const *)IoGetCurrentProcess();
    159     if (g_uNt3Version >= 350)
     451    if (   g_uNt3MajorVer > 3
     452        || g_uNt3MinorVer >= 50)
    160453        return *(HANDLE const *)&pbProcess[0x94];
    161454    return *(HANDLE const *)&pbProcess[0xb0];
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