VirtualBox

Changeset 54998 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 28, 2015 7:57:12 PM (10 years ago)
Author:
vboxsync
Message:

supHardNt: Some more memory replacment hacking - take evasive action on failure; flush log file and if possible log volume as we process.

Location:
trunk/src/VBox
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPLibInternal.h

    r53002 r54998  
    9292# define supR3HardenedLogV                 supR3HardenedStaticLogV
    9393# define supR3HardenedLog                  supR3HardenedStaticLog
     94# define supR3HardenedLogFlush             supR3HardenedStaticLogFlush
    9495# define supR3HardenedVerifyAll            supR3HardenedStaticVerifyAll
    9596# define supR3HardenedVerifyFixedDir       supR3HardenedStaticVerifyFixedDir
     
    433434 */
    434435DECLHIDDEN(void)    supR3HardenedLog(const char *pszFormat, ...);
     436
     437/**
     438 * Flushes the log file.
     439 */
     440DECLHIDDEN(void)    supR3HardenedLogFlush(void);
    435441
    436442
  • trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp

    r53045 r54998  
    169169 * release log at runtime. */
    170170static PFNRTLOGRELPRINTF g_pfnRTLogRelPrintf = NULL;
     171/** Log volume name (for attempting volume flush). */
     172static RTUTF16          g_wszStartupLogVol[16];
    171173#endif
    172174
     
    10021004                                      NULL);
    10031005                if (RT_SUCCESS(rc))
     1006                {
    10041007                    SUP_DPRINTF(("Log file opened: " VBOX_VERSION_STRING "r%u g_hStartupLog=%p g_uNtVerCombined=%#x\n",
    10051008                                 VBOX_SVN_REV, g_hStartupLog, g_uNtVerCombined));
     1009
     1010                    /*
     1011                     * If the path contains a drive volume, save it so we can
     1012                     * use it to flush the volume containing the log file.
     1013                     */
     1014                    if (RT_C_IS_ALPHA(pszLogFile[0]) && pszLogFile[1] == ':')
     1015                    {
     1016                        RTUtf16CopyAscii(g_wszStartupLogVol, RT_ELEMENTS(g_wszStartupLogVol), "\\??\\");
     1017                        g_wszStartupLogVol[sizeof("\\??\\") - 1] = RT_C_TO_UPPER(pszLogFile[0]);
     1018                        g_wszStartupLogVol[sizeof("\\??\\") + 0] = ':';
     1019                        g_wszStartupLogVol[sizeof("\\??\\") + 1] = '\0';
     1020                    }
     1021                }
    10061022                else
    10071023                    g_hStartupLog = NULL;
     
    10511067    supR3HardenedLogV(pszFormat, va);
    10521068    va_end(va);
     1069}
     1070
     1071
     1072DECLHIDDEN(void) supR3HardenedLogFlush(void)
     1073{
     1074#ifdef RT_OS_WINDOWS
     1075    if (   g_hStartupLog != NULL
     1076        && g_cbStartupLog < 16*_1M)
     1077    {
     1078        IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
     1079        NTSTATUS rcNt = NtFlushBuffersFile(g_hStartupLog, &Ios);
     1080
     1081        /*
     1082         * Try flush the volume containing the log file too.
     1083         */
     1084        if (g_wszStartupLogVol[0])
     1085        {
     1086            HANDLE              hLogVol = RTNT_INVALID_HANDLE_VALUE;
     1087            UNICODE_STRING      NtName;
     1088            NtName.Buffer        = g_wszStartupLogVol;
     1089            NtName.Length        = (USHORT)(RTUtf16Len(g_wszStartupLogVol) * sizeof(RTUTF16));
     1090            NtName.MaximumLength = NtName.Length + 1;
     1091            OBJECT_ATTRIBUTES   ObjAttr;
     1092            InitializeObjectAttributes(&ObjAttr, &NtName, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
     1093            RTNT_IO_STATUS_BLOCK_REINIT(&Ios);
     1094            rcNt = NtCreateFile(&hLogVol,
     1095                                GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE | FILE_READ_ATTRIBUTES,
     1096                                &ObjAttr,
     1097                                &Ios,
     1098                                NULL /* Allocation Size*/,
     1099                                0 /*FileAttributes*/,
     1100                                FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
     1101                                FILE_OPEN,
     1102                                FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
     1103                                NULL /*EaBuffer*/,
     1104                                0 /*EaLength*/);
     1105            if (NT_SUCCESS(rcNt))
     1106                rcNt = Ios.Status;
     1107            if (NT_SUCCESS(rcNt))
     1108            {
     1109                RTNT_IO_STATUS_BLOCK_REINIT(&Ios);
     1110                rcNt = NtFlushBuffersFile(hLogVol, &Ios);
     1111                NtClose(hLogVol);
     1112            }
     1113            else
     1114            {
     1115                /* This may have sideeffects similar to what we want... */
     1116                hLogVol = RTNT_INVALID_HANDLE_VALUE;
     1117                RTNT_IO_STATUS_BLOCK_REINIT(&Ios);
     1118                rcNt = NtCreateFile(&hLogVol,
     1119                                    GENERIC_READ | SYNCHRONIZE | FILE_READ_ATTRIBUTES,
     1120                                    &ObjAttr,
     1121                                    &Ios,
     1122                                    NULL /* Allocation Size*/,
     1123                                    0 /*FileAttributes*/,
     1124                                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
     1125                                    FILE_OPEN,
     1126                                    FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
     1127                                    NULL /*EaBuffer*/,
     1128                                    0 /*EaLength*/);
     1129                if (NT_SUCCESS(rcNt) && NT_SUCCESS(Ios.Status))
     1130                    NtClose(hLogVol);
     1131            }
     1132        }
     1133    }
     1134#else
     1135    /* later */
     1136#endif
    10531137}
    10541138
  • trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp

    r54993 r54998  
    15451545 * Frees (or replaces) executable memory of allocation type private.
    15461546 *
    1547  * @returns VBox status code.
     1547 * @returns True if nothing really bad happen, false if to quit ASAP because we
     1548 *          killed the process being scanned.
    15481549 * @param   pThis               The process scanning state structure. Details
    15491550 *                              about images are added to this.
     
    15521553 *                              executable memory.
    15531554 */
    1554 static void supHardNtVpFreeOrReplacePrivateExecMemory(PSUPHNTVPSTATE pThis, HANDLE hProcess,
     1555static bool supHardNtVpFreeOrReplacePrivateExecMemory(PSUPHNTVPSTATE pThis, HANDLE hProcess,
    15551556                                                      MEMORY_BASIC_INFORMATION const *pMemInfo)
    15561557{
     
    15961597        {
    15971598            supHardNtVpSetInfo2(pThis, VERR_SUP_VP_REPLACE_VIRTUAL_MEMORY_FAILED, "RTMemAllocZ(%#zx) failed", cbCopy);
    1598             return;
     1599            return true;
    15991600        }
    16001601
     
    16031604            supHardNtVpSetInfo2(pThis, VERR_SUP_VP_REPLACE_VIRTUAL_MEMORY_FAILED,
    16041605                                "Error reading data from original alloc: %#x (%p LB %#zx)", rcNt, uCopySrc, cbCopy, rcNt);
     1606        supR3HardenedLogFlush();
    16051607    }
    16061608
     
    16131615        SIZE_T cbFreeInOut = 0;
    16141616        rcNt = NtFreeVirtualMemory(hProcess, &pvFreeInOut, &cbFreeInOut, MEM_RELEASE);
    1615         if (!NT_SUCCESS(rcNt))
     1617        if (NT_SUCCESS(rcNt))
     1618        {
     1619            SUP_DPRINTF(("supHardNtVpFreeOrReplacePrivateExecMemory: Free attempt #1 succeeded: %#x [%p/%p LB 0/%#zx]\n",
     1620                         rcNt, pvFree, pvFreeInOut, cbFreeInOut));
     1621            supR3HardenedLogFlush();
     1622        }
     1623        else
    16161624        {
    16171625            SUP_DPRINTF(("supHardNtVpFreeOrReplacePrivateExecMemory: Free attempt #1 failed: %#x [%p LB 0]\n", rcNt, pvFree));
     1626            supR3HardenedLogFlush();
    16181627            pvFreeInOut = pvFree;
    16191628            cbFreeInOut = cbFree;
    16201629            rcNt = NtFreeVirtualMemory(hProcess, &pvFreeInOut, &cbFreeInOut, MEM_RELEASE);
    1621             if (!NT_SUCCESS(rcNt))
     1630            if (NT_SUCCESS(rcNt))
     1631            {
     1632                SUP_DPRINTF(("supHardNtVpFreeOrReplacePrivateExecMemory: Free attempt #2 succeeded: %#x [%p/%p LB %#zx/%#zx]\n",
     1633                             rcNt, pvFree, pvFreeInOut, cbFree, cbFreeInOut));
     1634                supR3HardenedLogFlush();
     1635            }
     1636            else
    16221637            {
    16231638                SUP_DPRINTF(("supHardNtVpFreeOrReplacePrivateExecMemory: Free attempt #2 failed: %#x [%p LB %#zx]\n",
    16241639                             rcNt, pvFree, cbFree));
     1640                supR3HardenedLogFlush();
    16251641                pvFreeInOut = pMemInfo->BaseAddress;
    16261642                cbFreeInOut = pMemInfo->RegionSize;
     
    16321648                    SUP_DPRINTF(("supHardNtVpFreeOrReplacePrivateExecMemory: Free attempt #3 succeeded [%p LB %#zx]\n",
    16331649                                 pvFree, cbFree));
     1650                    supR3HardenedLogFlush();
    16341651                }
    16351652                else
     
    16431660         * Query the region again, redo the free operation if there's still memory there.
    16441661         */
    1645         if (!NT_SUCCESS(rcNt) || (pThis->fFlags & SUPHARDNTVP_F_EXEC_ALLOC_REPLACE_WITH_RW))
     1662        if (!NT_SUCCESS(rcNt) || !(pThis->fFlags & SUPHARDNTVP_F_EXEC_ALLOC_REPLACE_WITH_RW))
    16461663            break;
    16471664        SIZE_T                      cbActual = 0;
     
    16541671                     i, MemInfo3.AllocationBase, MemInfo3.BaseAddress, MemInfo3.RegionSize, MemInfo3.State,
    16551672                     MemInfo3.AllocationProtect, MemInfo3.Protect));
     1673        supR3HardenedLogFlush();
    16561674        if (pMemInfo->State == MEM_FREE)
    16571675            break;
     1676        NtYieldExecution();
    16581677        SUP_DPRINTF(("supHardNtVpFreeOrReplacePrivateExecMemory: Retrying free...\n"));
     1678        supR3HardenedLogFlush();
    16591679    }
    16601680
     
    16691689        rcNt = NtAllocateVirtualMemory(hProcess, &pvAlloc, 0, &cbAlloc, MEM_COMMIT, PAGE_READWRITE);
    16701690        if (!NT_SUCCESS(rcNt))
     1691        {
    16711692            supHardNtVpSetInfo2(pThis, VERR_SUP_VP_REPLACE_VIRTUAL_MEMORY_FAILED,
    16721693                                "NtAllocateVirtualMemory (%p LB %#zx) failed with rcNt=%#x allocating "
     
    16741695                                "See VBoxStartup.log for more details",
    16751696                                pvAlloc, cbFree, rcNt);
    1676         else if (   (uintptr_t)pvFree < (uintptr_t)pvAlloc
    1677                  || (uintptr_t)pvFree + cbFree > (uintptr_t)pvAlloc + cbFree)
     1697            supR3HardenedLogFlush();
     1698            NtTerminateProcess(hProcess, VERR_SUP_VP_REPLACE_VIRTUAL_MEMORY_FAILED);
     1699            return false;
     1700        }
     1701
     1702        if (   (uintptr_t)pvFree < (uintptr_t)pvAlloc
     1703            || (uintptr_t)pvFree + cbFree > (uintptr_t)pvAlloc + cbFree)
     1704        {
    16781705            supHardNtVpSetInfo2(pThis, VERR_SUP_VP_REPLACE_VIRTUAL_MEMORY_FAILED,
    16791706                                "We wanted NtAllocateVirtualMemory to get us %p LB %#zx, but it returned %p LB %#zx.",
    16801707                                pMemInfo->BaseAddress, pMemInfo->RegionSize, pvFree, cbFree, rcNt);
     1708            supR3HardenedLogFlush();
     1709            NtTerminateProcess(hProcess, VERR_SUP_VP_REPLACE_VIRTUAL_MEMORY_FAILED);
     1710            return false;
     1711        }
     1712
     1713        /*
     1714         * Copy what we can, considering the 2nd free attempt.
     1715         */
     1716        uint8_t *pbDst = (uint8_t *)pvFree;
     1717        size_t   cbDst = cbFree;
     1718        uint8_t *pbSrc = (uint8_t *)pvCopy;
     1719        size_t   cbSrc = cbCopy;
     1720        if ((uintptr_t)pbDst != uCopySrc)
     1721        {
     1722            if ((uintptr_t)pbDst > uCopySrc)
     1723            {
     1724                uintptr_t cbAdj = (uintptr_t)pbDst - uCopySrc;
     1725                pbSrc += cbAdj;
     1726                cbSrc -= cbSrc;
     1727            }
     1728            else
     1729            {
     1730                uintptr_t cbAdj = uCopySrc - (uintptr_t)pbDst;
     1731                pbDst += cbAdj;
     1732                cbDst -= cbAdj;
     1733            }
     1734        }
     1735        if (cbSrc > cbDst)
     1736            cbSrc = cbDst;
     1737
     1738        SIZE_T cbWritten;
     1739        rcNt = NtWriteVirtualMemory(hProcess, pbDst, pbSrc, cbSrc, &cbWritten);
     1740        if (NT_SUCCESS(rcNt))
     1741        {
     1742            SUP_DPRINTF(("supHardNtVpFreeOrReplacePrivateExecMemory: Restored the exec memory as non-exec.\n"));
     1743            supR3HardenedLogFlush();
     1744        }
    16811745        else
    16821746        {
    1683             /*
    1684              * Copy what we can, considering the 2nd free attempt.
    1685              */
    1686             uint8_t *pbDst = (uint8_t *)pvFree;
    1687             size_t   cbDst = cbFree;
    1688             uint8_t *pbSrc = (uint8_t *)pvCopy;
    1689             size_t   cbSrc = cbCopy;
    1690             if ((uintptr_t)pbDst != uCopySrc)
    1691             {
    1692                 if ((uintptr_t)pbDst > uCopySrc)
    1693                 {
    1694                     uintptr_t cbAdj = (uintptr_t)pbDst - uCopySrc;
    1695                     pbSrc += cbAdj;
    1696                     cbSrc -= cbSrc;
    1697                 }
    1698                 else
    1699                 {
    1700                     uintptr_t cbAdj = uCopySrc - (uintptr_t)pbDst;
    1701                     pbDst += cbAdj;
    1702                     cbDst -= cbAdj;
    1703                 }
    1704             }
    1705             if (cbSrc > cbDst)
    1706                 cbSrc = cbDst;
    1707 
    1708             SIZE_T cbWritten;
    1709             rcNt = NtWriteVirtualMemory(hProcess, pbDst, pbSrc, cbSrc, &cbWritten);
    1710             if (!NT_SUCCESS(rcNt))
    1711                 supHardNtVpSetInfo2(pThis, VERR_SUP_VP_FREE_VIRTUAL_MEMORY_FAILED,
    1712                                     "NtWriteVirtualMemory (%p LB %#zx) failed: %#x",
    1713                                     pMemInfo->BaseAddress, pMemInfo->RegionSize, rcNt);
     1747            supHardNtVpSetInfo2(pThis, VERR_SUP_VP_FREE_VIRTUAL_MEMORY_FAILED,
     1748                                "NtWriteVirtualMemory (%p LB %#zx) failed: %#x",
     1749                                pMemInfo->BaseAddress, pMemInfo->RegionSize, rcNt);
     1750            supR3HardenedLogFlush();
     1751            NtTerminateProcess(hProcess, VERR_SUP_VP_REPLACE_VIRTUAL_MEMORY_FAILED);
     1752            return false;
    17141753        }
    17151754    }
    17161755    if (pvCopy)
    17171756        RTMemFree(pvCopy);
     1757    return true;
    17181758}
    17191759#endif /* IN_RING3 */
     
    18571897                 */
    18581898                if (MemInfo.Type == MEM_PRIVATE)
    1859                     supHardNtVpFreeOrReplacePrivateExecMemory(pThis, hProcess, &MemInfo);
     1899                {
     1900                    if (!supHardNtVpFreeOrReplacePrivateExecMemory(pThis, hProcess, &MemInfo))
     1901                        break;
     1902                }
    18601903                /*
    18611904                 * Unmap mapped memory, failing that, drop exec privileges.
  • trunk/src/VBox/HostDrivers/Support/win/import-template-ntdll.h

    r53822 r54998  
    88SUPHARNT_IMPORT_SYSCALL(NtDeviceIoControlFile, 40)
    99SUPHARNT_IMPORT_SYSCALL(NtDuplicateObject, 28)
     10SUPHARNT_IMPORT_SYSCALL(NtFlushBuffersFile, 8)
    1011SUPHARNT_IMPORT_SYSCALL(NtFreeVirtualMemory, 16)
    1112SUPHARNT_IMPORT_SYSCALL(NtGetContextThread, 8)
  • trunk/src/VBox/Runtime/r3/win/ntdll-mini-implib.def

    r53819 r54998  
    55
    66;
    7 ; Copyright (C) 2010-2014 Oracle Corporation
     7; Copyright (C) 2010-2015 Oracle Corporation
    88;
    99; This file is part of VirtualBox Open Source Edition (OSE), as
     
    4242    NtDeviceIoControlFile                 ;;= _NtDeviceIoControlFile@40
    4343    NtDuplicateObject                     ;;= _NtDuplicateObject@28
     44    NtFlushBuffersFile                    ;;= _NtFlushBuffersFile@8
    4445    NtFreeVirtualMemory                   ;;= _NtFreeVirtualMemory@16
    4546    NtGetContextThread                    ;;= _NtGetContextThread@8
Note: See TracChangeset for help on using the changeset viewer.

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