VirtualBox

Changeset 52523 in vbox


Ignore:
Timestamp:
Aug 29, 2014 6:52:04 AM (10 years ago)
Author:
vboxsync
Message:

SUP: Sabotage thread creation in the stub process and for the initial part of the VM process.

Location:
trunk/src/VBox/HostDrivers/Support
Files:
5 edited

Legend:

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

    r52366 r52523  
    438438DECLHIDDEN(void)    supR3HardenedWinInitImports(void);
    439439DECLHIDDEN(void)    supR3HardenedWinVerifyProcess(void);
     440DECLHIDDEN(void)    supR3HardenedWinEnableThreadCreation(void);
    440441DECLHIDDEN(void)    supR3HardenedWinResolveVerifyTrustApiAndHookThreadCreation(const char *pszProgName);
    441442DECLHIDDEN(void)    supR3HardenedWinFlushLoaderCache();
  • trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp

    r52424 r52523  
    17501750     * Windows: Enable the use of windows APIs to verify images at load time.
    17511751     */
     1752    supR3HardenedWinEnableThreadCreation();
    17521753    supR3HardenedWinFlushLoaderCache();
    17531754    supR3HardenedWinResolveVerifyTrustApiAndHookThreadCreation(g_pszSupLibHardenedProgName);
  • trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp

    r52488 r52523  
    823823     */
    824824    uint32_t         cSkipAreas = 0;
    825     SUPHNTVPSKIPAREA aSkipAreas[4];
     825    SUPHNTVPSKIPAREA aSkipAreas[5];
    826826    if (pImage->fNtCreateSectionPatch)
    827827    {
     
    842842            aSkipAreas[cSkipAreas].uRva = (uint32_t)uValue;
    843843            aSkipAreas[cSkipAreas++].cb = 5 + (ARCH_BITS == 64);
     844        }
     845
     846        if (   pThis->enmKind == SUPHARDNTVPKIND_SELF_PURIFICATION
     847            || pThis->enmKind == SUPHARDNTVPKIND_VERIFY_ONLY)
     848        {
     849            /* Ignore our patched LdrInitializeThunk hack. */
     850            rc = RTLdrGetSymbolEx(pImage->pCacheEntry->hLdrMod, pbBits, 0, UINT32_MAX, "LdrInitializeThunk", &uValue);
     851            if (RT_FAILURE(rc))
     852                return supHardNtVpSetInfo2(pThis, rc, "%s: Failed to find 'LdrInitializeThunk': %Rrc", pImage->pszName, rc);
     853            aSkipAreas[cSkipAreas].uRva = (uint32_t)uValue;
     854            aSkipAreas[cSkipAreas++].cb = 10;
    844855        }
    845856
  • trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp

    r52484 r52523  
    218218/** In the assembly file. */
    219219extern "C" uint8_t          g_abSupHardReadWriteExecPage[PAGE_SIZE];
     220
     221/** Whether we've patched our own LdrInitializeThunk or not.  We do this to
     222 * disable thread creation. */
     223static bool                 g_fSupInitThunkSelfPatched;
     224/** The backup of our own LdrInitializeThunk code, for enabling and disabling
     225 * thread creation in this process. */
     226static uint8_t              g_abLdrInitThunkSelfBackup[16];
    220227
    221228
     
    27042711
    27052712
     2713/**
     2714 * Common code used for child and parent to make new threads exit immediately.
     2715 *
     2716 * This patches the LdrInitializeThunk code to call NtTerminateThread with
     2717 * STATUS_SUCCESS instead of doing the NTDLL initialization.
     2718 *
     2719 * @returns VBox status code.
     2720 * @param   hProcess            The process to do this to.
     2721 * @param   pvLdrInitThunk      The address of the LdrInitializeThunk code to
     2722 *                              override.
     2723 * @param   pvNtTerminateThread The address of the NtTerminateThread function in
     2724 *                              the NTDLL instance we're patching.  (Must be +/-
     2725 *                              2GB from the thunk code.)
     2726 * @param   pabBackup           Where to back up the original instruction bytes
     2727 *                              at pvLdrInitThunk.
     2728 * @param   cbBackup            The size of the backup area. Must be 16 bytes.
     2729 * @param   pErrInfo            Where to return extended error information.
     2730 *                              Optional.
     2731 */
     2732static int supR3HardNtDisableThreadCreationEx(HANDLE hProcess, void *pvLdrInitThunk, void *pvNtTerminateThread,
     2733                                              uint8_t *pabBackup, size_t cbBackup, PRTERRINFO pErrInfo)
     2734{
     2735    SUP_DPRINTF(("supR3HardNtDisableThreadCreation: pvLdrInitThunk=%p pvNtTerminateThread=%p\n", pvLdrInitThunk, pvNtTerminateThread));
     2736    SUPR3HARDENED_ASSERT(cbBackup == 16);
     2737    SUPR3HARDENED_ASSERT(RT_ABS((intptr_t)pvLdrInitThunk - (intptr_t)pvNtTerminateThread) < 16*_1M);
     2738
     2739    /*
     2740     * Back up the thunk code.
     2741     */
     2742    SIZE_T  cbIgnored;
     2743    NTSTATUS rcNt = NtReadVirtualMemory(hProcess, pvLdrInitThunk, pabBackup, cbBackup, &cbIgnored);
     2744    if (!NT_SUCCESS(rcNt))
     2745        return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
     2746                             "supR3HardNtDisableThreadCreation: NtReadVirtualMemory/LdrInitializeThunk failed: %#x", rcNt);
     2747
     2748    /*
     2749     * Cook up replacement code that calls NtTerminateThread.
     2750     */
     2751    uint8_t abReplacement[16];
     2752    memcpy(abReplacement, pabBackup, sizeof(abReplacement));
     2753
     2754#ifdef RT_ARCH_AMD64
     2755    abReplacement[0] = 0x31;    /* xor ecx, ecx */
     2756    abReplacement[1] = 0xc9;
     2757    abReplacement[2] = 0x31;    /* xor edx, edx */
     2758    abReplacement[3] = 0xd2;
     2759    abReplacement[4] = 0xe8;    /* call near NtTerminateThread */
     2760    *(int32_t *)&abReplacement[5] = (int32_t)((uintptr_t)pvNtTerminateThread - ((uintptr_t)pvLdrInitThunk + 9));
     2761    abReplacement[9] = 0xcc;    /* int3 */
     2762#elif defined(RT_ARCH_X86)
     2763    abReplacement[0] = 0x6a;    /* push 0 */
     2764    abReplacement[1] = 0x00;
     2765    abReplacement[2] = 0x6a;    /* push 0 */
     2766    abReplacement[3] = 0x00;
     2767    abReplacement[4] = 0xe8;    /* call near NtTerminateThread */
     2768    *(int32_t *)&abReplacement[5] = (int32_t)((uintptr_t)pvNtTerminateThread - ((uintptr_t)pvLdrInitThunk + 9));
     2769    abReplacement[9] = 0xcc;    /* int3 */
     2770#else
     2771# error "Unsupported arch."
     2772#endif
     2773
     2774    /*
     2775     * Install the replacment code.
     2776     */
     2777    PVOID  pvProt   = pvLdrInitThunk;
     2778    SIZE_T cbProt   = cbBackup;
     2779    ULONG  fOldProt = 0;
     2780    rcNt = NtProtectVirtualMemory(hProcess, &pvProt, &cbProt, PAGE_EXECUTE_READWRITE, &fOldProt);
     2781    if (!NT_SUCCESS(rcNt))
     2782        return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
     2783                             "supR3HardNtDisableThreadCreationEx: NtProtectVirtualMemory/LdrInitializeThunk failed: %#x", rcNt);
     2784
     2785    rcNt = NtWriteVirtualMemory(hProcess, pvLdrInitThunk, abReplacement, sizeof(abReplacement), &cbIgnored);
     2786    if (!NT_SUCCESS(rcNt))
     2787        return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
     2788                             "supR3HardNtDisableThreadCreationEx: NtWriteVirtualMemory/LdrInitializeThunk failed: %#x", rcNt);
     2789
     2790    pvProt   = pvLdrInitThunk;
     2791    cbProt   = cbBackup;
     2792    rcNt = NtProtectVirtualMemory(hProcess, &pvProt, &cbProt, fOldProt, &fOldProt);
     2793    if (!NT_SUCCESS(rcNt))
     2794        return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
     2795                             "supR3HardNtDisableThreadCreationEx: NtProtectVirtualMemory/LdrInitializeThunk/2 failed: %#x", rcNt);
     2796
     2797    return VINF_SUCCESS;
     2798}
     2799
     2800
     2801/**
     2802 * Undo the effects of supR3HardNtDisableThreadCreationEx.
     2803 *
     2804 * @returns VBox status code.
     2805 * @param   hProcess            The process to do this to.
     2806 * @param   pvLdrInitThunk      The address of the LdrInitializeThunk code to
     2807 *                              override.
     2808 * @param   pabBackup           Where to back up the original instruction bytes
     2809 *                              at pvLdrInitThunk.
     2810 * @param   cbBackup            The size of the backup area. Must be 16 bytes.
     2811 * @param   pErrInfo            Where to return extended error information.
     2812 *                              Optional.
     2813 */
     2814static int supR3HardNtEnableThreadCreationEx(HANDLE hProcess, void *pvLdrInitThunk, uint8_t const *pabBackup, size_t cbBackup,
     2815                                             PRTERRINFO pErrInfo)
     2816{
     2817    SUP_DPRINTF(("supR3HardNtEnableThreadCreation:\n"));
     2818    SUPR3HARDENED_ASSERT(cbBackup == 16);
     2819
     2820    PVOID  pvProt   = pvLdrInitThunk;
     2821    SIZE_T cbProt   = cbBackup;
     2822    ULONG  fOldProt = 0;
     2823    NTSTATUS rcNt = NtProtectVirtualMemory(hProcess, &pvProt, &cbProt, PAGE_EXECUTE_READWRITE, &fOldProt);
     2824    if (!NT_SUCCESS(rcNt))
     2825        return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
     2826                             "supR3HardNtDisableThreadCreationEx: NtProtectVirtualMemory/LdrInitializeThunk failed: %#x", rcNt);
     2827
     2828    SIZE_T cbIgnored;
     2829    rcNt = NtWriteVirtualMemory(hProcess, pvLdrInitThunk, pabBackup, cbBackup, &cbIgnored);
     2830    if (!NT_SUCCESS(rcNt))
     2831        return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
     2832                             "supR3HardNtEnableThreadCreation: NtWriteVirtualMemory/LdrInitializeThunk[restore] failed: %#x",
     2833                             rcNt);
     2834
     2835    pvProt   = pvLdrInitThunk;
     2836    cbProt   = cbBackup;
     2837    rcNt = NtProtectVirtualMemory(hProcess, &pvProt, &cbProt, fOldProt, &fOldProt);
     2838    if (!NT_SUCCESS(rcNt))
     2839        return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
     2840                             "supR3HardNtEnableThreadCreation: NtProtectVirtualMemory/LdrInitializeThunk[restore] failed: %#x",
     2841                             rcNt);
     2842
     2843    return VINF_SUCCESS;
     2844}
     2845
     2846
     2847/**
     2848 * Disable thread creation for the current process.
     2849 *
     2850 * @remarks Doesn't really disables it, just makes the threads exit immediately
     2851 *          without executing any real code.
     2852 */
     2853static void supR3HardenedWinDisableThreadCreation(void)
     2854{
     2855    /* Cannot use the imported NtTerminateThread as it's pointing to our own
     2856       syscall assembly code. */
     2857    FARPROC pfnNtTerminateThread = GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "NtTerminateThread");
     2858    SUPR3HARDENED_ASSERT(pfnNtTerminateThread);
     2859
     2860    int rc = supR3HardNtDisableThreadCreationEx(NtCurrentProcess(),
     2861                                                (void *)(uintptr_t)&LdrInitializeThunk,
     2862                                                (void *)(uintptr_t)pfnNtTerminateThread,
     2863                                                g_abLdrInitThunkSelfBackup, sizeof(g_abLdrInitThunkSelfBackup),
     2864                                                NULL /* pErrInfo*/);
     2865    g_fSupInitThunkSelfPatched = RT_SUCCESS(rc);
     2866}
     2867
     2868
     2869/**
     2870 * Undoes the effects of supR3HardenedWinDisableThreadCreation.
     2871 */
     2872DECLHIDDEN(void) supR3HardenedWinEnableThreadCreation(void)
     2873{
     2874    if (g_fSupInitThunkSelfPatched)
     2875    {
     2876        int rc = supR3HardNtEnableThreadCreationEx(NtCurrentProcess(),
     2877                                                   (void *)(uintptr_t)&LdrInitializeThunk,
     2878                                                   g_abLdrInitThunkSelfBackup, sizeof(g_abLdrInitThunkSelfBackup),
     2879                                                   RTErrInfoInitStatic(&g_ErrInfoStatic));
     2880        if (RT_FAILURE(rc))
     2881            supR3HardenedError(rc, true /*fFatal*/, "%s", g_ErrInfoStatic.szMsg);
     2882        g_fSupInitThunkSelfPatched = false;
     2883    }
     2884}
     2885
     2886
    27062887
    27072888/*
     
    27642945
    27652946
     2947/**
     2948 * Maps a DLL into the child process.
     2949 *
     2950 * @returns Pointer to the DLL mapping on success, NULL on failure.
     2951 * @param   pThis               The child purification instance data.
     2952 * @param   pNtName             The path to the DLL.
     2953 * @param   pszShort            The short name (for logging).
     2954 */
    27662955static PVOID supR3HardNtPuChMapDllIntoChild(PSUPR3HARDNTPUCH pThis, PUNICODE_STRING pNtName, const char *pszShort)
    27672956{
     
    28573046
    28583047    /*
    2859      * Back up the thunk code.
     3048     * Patch the child's LdrInitializeThunk to exit the thread immediately.
    28603049     */
    28613050    uint8_t abBackup[16];
    2862     SIZE_T  cbIgnored;
    2863     NTSTATUS rcNt = NtReadVirtualMemory(pThis->hProcess, pvLdrInitThunk, abBackup, sizeof(abBackup), &cbIgnored);
    2864     if (!NT_SUCCESS(rcNt))
    2865         return RTErrInfoSetF(pThis->pErrInfo, VERR_GENERAL_FAILURE,
    2866                              "NtReadVirtualMemory/LdrInitializeThunk failed: %#x", rcNt);
    2867 
    2868     /*
    2869      * Cook up replacement code that calls NtTerminateThread.
    2870      */
    2871     uint8_t abReplacement[sizeof(abBackup)] ;
    2872     memcpy(abReplacement, abBackup, sizeof(abReplacement));
    2873 
    2874 #ifdef RT_ARCH_AMD64
    2875     abReplacement[0] = 0x31;    /* xor ecx, ecx */
    2876     abReplacement[1] = 0xc9;
    2877     abReplacement[2] = 0x31;    /* xor edx, edx */
    2878     abReplacement[3] = 0xd2;
    2879     abReplacement[4] = 0xe8;    /* call near NtTerminateThread */
    2880     *(int32_t *)&abReplacement[5] = (int32_t)(uNtTerminateThread - (uLdrInitThunk + 9));
    2881     abReplacement[9] = 0xcc;    /* int3 */
    2882 #elif defined(RT_ARCH_X86)
    2883     abReplacement[0] = 0x6a;    /* push 0 */
    2884     abReplacement[1] = 0x00;
    2885     abReplacement[2] = 0x6a;    /* push 0 */
    2886     abReplacement[3] = 0x00;
    2887     abReplacement[4] = 0xe8;    /* call near NtTerminateThread */
    2888     *(int32_t *)&abReplacement[5] = (int32_t)(uNtTerminateThread - (uLdrInitThunk + 9));
    2889     abReplacement[9] = 0xcc;    /* int3 */
    2890 #else
    2891 # error "Unsupported arch."
    2892 #endif
    2893 
    2894     /*
    2895      * Install the replacment code.
    2896      */
    2897     PVOID  pvProt   = pvLdrInitThunk;
    2898     SIZE_T cbProt   = 16;
    2899     ULONG  fOldProt = 0;
    2900     rcNt = NtProtectVirtualMemory(pThis->hProcess, &pvProt, &cbProt, PAGE_EXECUTE_READWRITE, &fOldProt);
    2901     if (!NT_SUCCESS(rcNt))
    2902         return RTErrInfoSetF(pThis->pErrInfo, VERR_GENERAL_FAILURE,
    2903                              "NtProtectVirtualMemory/LdrInitializeThunk failed: %#x", rcNt);
    2904 
    2905     rcNt = NtWriteVirtualMemory(pThis->hProcess, pvLdrInitThunk, abReplacement, sizeof(abReplacement), &cbIgnored);
    2906     if (!NT_SUCCESS(rcNt))
    2907         return RTErrInfoSetF(pThis->pErrInfo, VERR_GENERAL_FAILURE,
    2908                              "NtWriteVirtualMemory/LdrInitializeThunk failed: %#x", rcNt);
     3051    rc = supR3HardNtDisableThreadCreationEx(pThis->hProcess, pvLdrInitThunk, (void *)(uintptr_t)uNtTerminateThread,
     3052                                            abBackup, sizeof(abBackup), pThis->pErrInfo);
     3053    if (RT_FAILURE(rc))
     3054        return rc;
    29093055
    29103056    /*
     
    29133059    CLIENT_ID Thread2Id;
    29143060    HANDLE hThread2;
    2915     rcNt = RtlCreateUserThread(pThis->hProcess,
    2916                                NULL /* SecurityAttribs */,
    2917                                FALSE /* CreateSuspended */,
    2918                                0 /* ZeroBits */,
    2919                                0 /* MaximumStackSize */,
    2920                                0 /* CommittedStackSize */,
    2921                                (PFNRT)2 /* StartAddress */,
    2922                                NULL /*Parameter*/ ,
    2923                                &hThread2,
    2924                                &Thread2Id);
     3061    NTSTATUS rcNt = RtlCreateUserThread(pThis->hProcess,
     3062                                        NULL /* SecurityAttribs */,
     3063                                        FALSE /* CreateSuspended */,
     3064                                        0 /* ZeroBits */,
     3065                                        0 /* MaximumStackSize */,
     3066                                        0 /* CommittedStackSize */,
     3067                                        (PFNRT)2 /* StartAddress */,
     3068                                        NULL /*Parameter*/ ,
     3069                                        &hThread2,
     3070                                        &Thread2Id);
    29253071    if (NT_SUCCESS(rcNt))
    29263072    {
     
    29333079
    29343080    /*
    2935      * Restore the original thunk code and protection.
    2936      */
    2937     rcNt = NtWriteVirtualMemory(pThis->hProcess, pvLdrInitThunk, abBackup, sizeof(abBackup), &cbIgnored);
    2938     if (!NT_SUCCESS(rcNt))
    2939         return RTErrInfoSetF(pThis->pErrInfo, VERR_GENERAL_FAILURE,
    2940                              "NtWriteVirtualMemory/LdrInitializeThunk[restore] failed: %#x", rcNt);
    2941 
    2942     pvProt   = pvLdrInitThunk;
    2943     cbProt   = 16;
    2944     rcNt = NtProtectVirtualMemory(pThis->hProcess, &pvProt, &cbProt, fOldProt, &fOldProt);
    2945     if (!NT_SUCCESS(rcNt))
    2946         return RTErrInfoSetF(pThis->pErrInfo, VERR_GENERAL_FAILURE,
    2947                              "NtProtectVirtualMemory/LdrInitializeThunk[restore] failed: %#x", rcNt);
    2948 
    2949     /*
    29503081     * Map kernel32.dll and kernelbase.dll (if applicable) into the process.
    29513082     * This triggers should image load events that may set of AV activities
     
    29913122                         rcNt, pvKernelBase));
    29923123    }
     3124
     3125    /*
     3126     * Restore the original thunk code and protection.
     3127     * We do this after waiting as anyone trying to kick of threads in the
     3128     * process will get nothing done as long as our patch is in place.
     3129     */
     3130    rc = supR3HardNtEnableThreadCreationEx(pThis->hProcess, pvLdrInitThunk, abBackup, sizeof(abBackup), pThis->pErrInfo);
     3131    if (RT_FAILURE(rc))
     3132        return rc;
    29933133
    29943134    return VINF_SUCCESS;
     
    32503390    PRTUTF16 pwszCmdLine = supR3HardenedWinConstructCmdLine(NULL, iWhich);
    32513391
     3392    supR3HardenedWinEnableThreadCreation();
    32523393    PROCESS_INFORMATION ProcessInfoW32;
    32533394    if (!CreateProcessW(g_wszSupLibHardenedExePath,
     
    32653406                              "Command line: '%ls'",
    32663407                              GetLastError(), pwszCmdLine);
     3408    supR3HardenedWinDisableThreadCreation();
    32673409
    32683410    SUP_DPRINTF(("supR3HardenedWinDoReSpawn(%d): New child %x.%x [kernel32].\n",
     
    38874029
    38884030    /*
     4031     * After having resolved imports we patch the LdrInitializeThunk code so
     4032     * that it's more difficult to invade our privacy by CreateRemoteThread.
     4033     * We'll re-enable this after opening the driver or temporarily while respawning.
     4034     */
     4035    supR3HardenedWinDisableThreadCreation();
     4036
     4037    /*
    38894038     * Init g_uNtVerCombined. (The code is shared with SUPR3.lib and lives in
    38904039     * SUPHardenedVerfiyImage-win.cpp.)
  • trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMainA-win.asm

    r52403 r52523  
    2828;* Header Files                                                                *
    2929;*******************************************************************************
     30%define RT_ASM_WITH_SEH64
    3031%include "iprt/asmdefs.mac"
    3132
     
    4344 %macro supR3HardenedJmpBack_NtCreateSection_Xxx 1
    4445 BEGINPROC supR3HardenedJmpBack_NtCreateSection_ %+ %1
     46        SEH64_END_PROLOGUE
    4547        ; The code we replaced.
    4648        mov     r10, rcx
     
    120122 %ifdef RT_ARCH_AMD64
    121123BEGINPROC %1 %+ _SyscallType1
     124        SEH64_END_PROLOGUE
    122125        mov     eax, [NAME(g_uApiNo %+ %1) xWrtRIP]
    123126        mov     r10, rcx
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