Changeset 52523 in vbox
- Timestamp:
- Aug 29, 2014 6:52:04 AM (10 years ago)
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPLibInternal.h
r52366 r52523 438 438 DECLHIDDEN(void) supR3HardenedWinInitImports(void); 439 439 DECLHIDDEN(void) supR3HardenedWinVerifyProcess(void); 440 DECLHIDDEN(void) supR3HardenedWinEnableThreadCreation(void); 440 441 DECLHIDDEN(void) supR3HardenedWinResolveVerifyTrustApiAndHookThreadCreation(const char *pszProgName); 441 442 DECLHIDDEN(void) supR3HardenedWinFlushLoaderCache(); -
trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp
r52424 r52523 1750 1750 * Windows: Enable the use of windows APIs to verify images at load time. 1751 1751 */ 1752 supR3HardenedWinEnableThreadCreation(); 1752 1753 supR3HardenedWinFlushLoaderCache(); 1753 1754 supR3HardenedWinResolveVerifyTrustApiAndHookThreadCreation(g_pszSupLibHardenedProgName); -
trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp
r52488 r52523 823 823 */ 824 824 uint32_t cSkipAreas = 0; 825 SUPHNTVPSKIPAREA aSkipAreas[ 4];825 SUPHNTVPSKIPAREA aSkipAreas[5]; 826 826 if (pImage->fNtCreateSectionPatch) 827 827 { … … 842 842 aSkipAreas[cSkipAreas].uRva = (uint32_t)uValue; 843 843 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; 844 855 } 845 856 -
trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp
r52484 r52523 218 218 /** In the assembly file. */ 219 219 extern "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. */ 223 static bool g_fSupInitThunkSelfPatched; 224 /** The backup of our own LdrInitializeThunk code, for enabling and disabling 225 * thread creation in this process. */ 226 static uint8_t g_abLdrInitThunkSelfBackup[16]; 220 227 221 228 … … 2704 2711 2705 2712 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 */ 2732 static 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 */ 2814 static 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 */ 2853 static 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 */ 2872 DECLHIDDEN(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 2706 2887 2707 2888 /* … … 2764 2945 2765 2946 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 */ 2766 2955 static PVOID supR3HardNtPuChMapDllIntoChild(PSUPR3HARDNTPUCH pThis, PUNICODE_STRING pNtName, const char *pszShort) 2767 2956 { … … 2857 3046 2858 3047 /* 2859 * Back up the thunk code.3048 * Patch the child's LdrInitializeThunk to exit the thread immediately. 2860 3049 */ 2861 3050 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; 2909 3055 2910 3056 /* … … 2913 3059 CLIENT_ID Thread2Id; 2914 3060 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); 2925 3071 if (NT_SUCCESS(rcNt)) 2926 3072 { … … 2933 3079 2934 3080 /* 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 /*2950 3081 * Map kernel32.dll and kernelbase.dll (if applicable) into the process. 2951 3082 * This triggers should image load events that may set of AV activities … … 2991 3122 rcNt, pvKernelBase)); 2992 3123 } 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; 2993 3133 2994 3134 return VINF_SUCCESS; … … 3250 3390 PRTUTF16 pwszCmdLine = supR3HardenedWinConstructCmdLine(NULL, iWhich); 3251 3391 3392 supR3HardenedWinEnableThreadCreation(); 3252 3393 PROCESS_INFORMATION ProcessInfoW32; 3253 3394 if (!CreateProcessW(g_wszSupLibHardenedExePath, … … 3265 3406 "Command line: '%ls'", 3266 3407 GetLastError(), pwszCmdLine); 3408 supR3HardenedWinDisableThreadCreation(); 3267 3409 3268 3410 SUP_DPRINTF(("supR3HardenedWinDoReSpawn(%d): New child %x.%x [kernel32].\n", … … 3887 4029 3888 4030 /* 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 /* 3889 4038 * Init g_uNtVerCombined. (The code is shared with SUPR3.lib and lives in 3890 4039 * SUPHardenedVerfiyImage-win.cpp.) -
trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMainA-win.asm
r52403 r52523 28 28 ;* Header Files * 29 29 ;******************************************************************************* 30 %define RT_ASM_WITH_SEH64 30 31 %include "iprt/asmdefs.mac" 31 32 … … 43 44 %macro supR3HardenedJmpBack_NtCreateSection_Xxx 1 44 45 BEGINPROC supR3HardenedJmpBack_NtCreateSection_ %+ %1 46 SEH64_END_PROLOGUE 45 47 ; The code we replaced. 46 48 mov r10, rcx … … 120 122 %ifdef RT_ARCH_AMD64 121 123 BEGINPROC %1 %+ _SyscallType1 124 SEH64_END_PROLOGUE 122 125 mov eax, [NAME(g_uApiNo %+ %1) xWrtRIP] 123 126 mov r10, rcx
Note:
See TracChangeset
for help on using the changeset viewer.