├── a ├── binary1.bin ├── m.def ├── resource.h ├── dllmain.cpp ├── exception.cpp ├── thread.cpp ├── a.vcxproj.filters ├── a.rc └── gdiplus.cpp ├── 3rdparty ├── Detours │ ├── disolarm.cpp │ ├── disolia64.cpp │ ├── disolx64.cpp │ ├── disolx86.cpp │ ├── disolarm64.cpp │ ├── detver.h │ ├── LICENSE.md │ ├── README.md │ └── CREDITS.md └── phnt │ └── include │ ├── ntsmss.h │ ├── ntnls.h │ ├── ntxcapi.h │ ├── phnt_windows.h │ ├── phnt.h │ ├── subprocesstag.h │ ├── ntmisc.h │ ├── ntkeapi.h │ ├── ntgdi.h │ ├── ntpnpapi.h │ ├── ntdbg.h │ ├── phnt_ntdef.h │ ├── ntpfapi.h │ ├── nttp.h │ └── ntobapi.h ├── MemoryModule ├── MmpTlsFiber.h ├── Initialize.h ├── LoaderPrivate.h ├── BaseAddressIndex.h ├── MmpTls.h ├── MemoryModulePP.def ├── MmpDotNet.h ├── ImportTable.h ├── stdafx.h ├── LoadDllMemoryApi.h ├── MmpTlsp.h ├── LoadDllMemoryApi.cpp ├── MemoryModule.h ├── BaseAddressIndex.cpp ├── InvertedFunctionTable.h ├── ReflectiveDLLInjection.h ├── Loader.h ├── Utils.h ├── MmpTlsFiber.cpp ├── MmpGlobalData.h ├── ImportTable.cpp ├── MmpLdrpTls.cpp ├── ReflectiveLoader.h ├── InvertedFunctionTable.cpp ├── Loader.cpp ├── MemoryModule.cpp └── MemoryModule.vcxproj.filters ├── test ├── test.vcxproj.filters └── test.cpp ├── LICENSE ├── README.md ├── .gitattributes ├── MemoryModulePP.sln └── .gitignore /a/binary1.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bb107/MemoryModulePP/HEAD/a/binary1.bin -------------------------------------------------------------------------------- /3rdparty/Detours/disolarm.cpp: -------------------------------------------------------------------------------- 1 | #define DETOURS_ARM_OFFLINE_LIBRARY 2 | #include "disasm.cpp" 3 | -------------------------------------------------------------------------------- /3rdparty/Detours/disolia64.cpp: -------------------------------------------------------------------------------- 1 | #define DETOURS_IA64_OFFLINE_LIBRARY 2 | #include "disasm.cpp" 3 | -------------------------------------------------------------------------------- /3rdparty/Detours/disolx64.cpp: -------------------------------------------------------------------------------- 1 | #define DETOURS_X64_OFFLINE_LIBRARY 2 | #include "disasm.cpp" 3 | -------------------------------------------------------------------------------- /3rdparty/Detours/disolx86.cpp: -------------------------------------------------------------------------------- 1 | #define DETOURS_X86_OFFLINE_LIBRARY 2 | #include "disasm.cpp" 3 | -------------------------------------------------------------------------------- /3rdparty/Detours/disolarm64.cpp: -------------------------------------------------------------------------------- 1 | #define DETOURS_ARM64_OFFLINE_LIBRARY 2 | #include "disasm.cpp" 3 | -------------------------------------------------------------------------------- /MemoryModule/MmpTlsFiber.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | VOID WINAPI MmpQueuePostponedTls(PMMP_TLSP_RECORD record); 4 | VOID MmpTlsFiberInitialize(); 5 | -------------------------------------------------------------------------------- /a/m.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | exception 3 | test = __test__ 4 | thread 5 | Socket = ws2_32.WSASocketW 6 | VerifyTruse = wintrust.WinVerifyTrust 7 | GdiplusTest -------------------------------------------------------------------------------- /MemoryModule/Initialize.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | NTSTATUS NTAPI MmInitialize(); 4 | NTSTATUS NTAPI MmCleanup(); 5 | 6 | // 7 | // This function is available only if the MMPP is compiled as a DLL. 8 | // 9 | BOOL WINAPI ReflectiveMapDll(HMODULE hModule); 10 | -------------------------------------------------------------------------------- /MemoryModule/LoaderPrivate.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | NTSTATUS NTAPI LdrMapDllMemory( 4 | _In_ HMEMORYMODULE ViewBase, 5 | _In_ DWORD dwFlags, 6 | _In_opt_ PCWSTR DllName, 7 | _In_opt_ PCWSTR lpFullDllName, 8 | _Out_opt_ PLDR_DATA_TABLE_ENTRY* DataTableEntry 9 | ); 10 | -------------------------------------------------------------------------------- /MemoryModule/BaseAddressIndex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode( 4 | _In_ PLDR_DATA_TABLE_ENTRY DataTableEntry, 5 | _In_ PVOID BaseAddress 6 | ); 7 | 8 | NTSTATUS NTAPI RtlRemoveModuleBaseAddressIndexNode(_In_ PLDR_DATA_TABLE_ENTRY DataTableEntry); 9 | -------------------------------------------------------------------------------- /MemoryModule/MmpTls.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | BOOL NTAPI MmpTlsInitialize(); 4 | 5 | VOID NTAPI MmpTlsCleanup(); 6 | 7 | NTSTATUS NTAPI MmpReleaseTlsEntry(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry); 8 | 9 | NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry); 10 | -------------------------------------------------------------------------------- /MemoryModule/MemoryModulePP.def: -------------------------------------------------------------------------------- 1 | LIBRARY 2 | EXPORTS 3 | 4 | MmInitialize 5 | MmCleanup 6 | 7 | LoadLibraryMemory 8 | LoadLibraryMemoryExA 9 | LoadLibraryMemoryExW 10 | FreeLibraryMemory 11 | 12 | LdrLoadDllMemoryExW 13 | LdrUnloadDllMemory 14 | LdrUnloadDllMemoryAndExitThread 15 | LdrQuerySystemMemoryModuleFeatures 16 | 17 | MmpGlobalDataPtr 18 | -------------------------------------------------------------------------------- /MemoryModule/MmpDotNet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef HRESULT(WINAPI* GetFileVersion_T)( 4 | LPCWSTR szFilename, 5 | LPWSTR szBuffer, 6 | DWORD cchBuffer, 7 | DWORD* dwLength 8 | ); 9 | 10 | BOOL WINAPI MmpPreInitializeHooksForDotNet(); 11 | BOOL WINAPI MmpInitializeHooksForDotNet(); 12 | VOID WINAPI MmpCleanupDotNetHooks(); 13 | -------------------------------------------------------------------------------- /a/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by a.rc 4 | // 5 | #define IDS_STRING101 101 6 | #define IDR_BINARY1 102 7 | 8 | // Next default values for new objects 9 | // 10 | #ifdef APSTUDIO_INVOKED 11 | #ifndef APSTUDIO_READONLY_SYMBOLS 12 | #define _APS_NEXT_RESOURCE_VALUE 103 13 | #define _APS_NEXT_COMMAND_VALUE 40001 14 | #define _APS_NEXT_CONTROL_VALUE 1001 15 | #define _APS_NEXT_SYMED_VALUE 101 16 | #endif 17 | #endif 18 | -------------------------------------------------------------------------------- /3rdparty/phnt/include/ntsmss.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Windows Session Manager support functions 3 | * 4 | * This file is part of System Informer. 5 | */ 6 | 7 | #ifndef _NTSMSS_H 8 | #define _NTSMSS_H 9 | 10 | NTSYSAPI 11 | NTSTATUS 12 | NTAPI 13 | RtlConnectToSm( 14 | _In_ PUNICODE_STRING ApiPortName, 15 | _In_ HANDLE ApiPortHandle, 16 | _In_ DWORD ProcessImageType, 17 | _Out_ PHANDLE SmssConnection 18 | ); 19 | 20 | NTSYSAPI 21 | NTSTATUS 22 | NTAPI 23 | RtlSendMsgToSm( 24 | _In_ HANDLE ApiPortHandle, 25 | _In_ PPORT_MESSAGE MessageData 26 | ); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /3rdparty/Detours/detver.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Common version parameters. 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #define _USING_V110_SDK71_ 1 11 | #include "winver.h" 12 | #if 0 13 | #include 14 | #include 15 | #else 16 | #ifndef DETOURS_STRINGIFY 17 | #define DETOURS_STRINGIFY_(x) #x 18 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 19 | #endif 20 | 21 | #define VER_FILEFLAGSMASK 0x3fL 22 | #define VER_FILEFLAGS 0x0L 23 | #define VER_FILEOS 0x00040004L 24 | #define VER_FILETYPE 0x00000002L 25 | #define VER_FILESUBTYPE 0x00000000L 26 | #endif 27 | #define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) 28 | -------------------------------------------------------------------------------- /a/dllmain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #pragma comment(lib,"ws2_32.lib") 5 | #pragma comment(lib,"wintrust.lib") 6 | #pragma comment(lib,"ntdll.lib") 7 | 8 | BOOL APIENTRY DllMain( HMODULE hModule, 9 | DWORD ul_reason_for_call, 10 | LPVOID lpReserved 11 | ) 12 | { 13 | switch (ul_reason_for_call) 14 | { 15 | case DLL_PROCESS_ATTACH: 16 | printf("DLL_PROCESS_ATTACH\n"); break; 17 | case DLL_THREAD_ATTACH: 18 | printf("DLL_THREAD_ATTACH\n"); break; 19 | case DLL_THREAD_DETACH: 20 | printf("DLL_THREAD_DETACH\n"); break; 21 | case DLL_PROCESS_DETACH: 22 | printf("DLL_PROCESS_DETACH\n"); break; 23 | } 24 | return TRUE; 25 | } 26 | 27 | int __test__() { 28 | printf("HelloWorld!\n"); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /MemoryModule/ImportTable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef HMODULE(WINAPI* MM_IAT_RESOLVER_ENTRY)(LPCSTR lpModuleName); 4 | typedef BOOL(WINAPI* MM_IAT_FREE_ENTRY)(HMODULE hModule); 5 | 6 | typedef struct _MM_IAT_RESOLVER { 7 | 8 | LIST_ENTRY InMmpIatResolverList; 9 | 10 | MM_IAT_RESOLVER_ENTRY LoadLibraryProv; 11 | MM_IAT_FREE_ENTRY FreeLibraryProv; 12 | 13 | DWORD ReferenceCount; 14 | 15 | }MM_IAT_RESOLVER, * PMM_IAT_RESOLVER; 16 | 17 | VOID MemoryFreeImportTable(_In_ PMEMORYMODULE hMemoryModule); 18 | 19 | NTSTATUS MemoryResolveImportTable( 20 | _In_ LPBYTE base, 21 | _In_ PIMAGE_NT_HEADERS lpNtHeaders, 22 | _In_ PMEMORYMODULE hMemoryModule 23 | ); 24 | 25 | HANDLE WINAPI MmRegisterImportTableResolver( 26 | _In_ MM_IAT_RESOLVER_ENTRY LoadLibraryProv, 27 | _In_ MM_IAT_FREE_ENTRY FreeLibraryProv 28 | ); 29 | 30 | _Success_(return) 31 | BOOL WINAPI MmRemoveImportTableResolver(_In_ HANDLE hMmIatResolver); 32 | -------------------------------------------------------------------------------- /test/test.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /MemoryModule/stdafx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef WIN32_NO_STATUS 4 | #define WIN32_NO_STATUS 5 | #include "../3rdparty/phnt/include/phnt_windows.h" 6 | #include "../3rdparty/phnt/include/phnt.h" 7 | #undef WIN32_NO_STATUS 8 | #include 9 | #endif 10 | 11 | // 12 | // Determine whether to use MmpTls(1) or LdrpTls(0) 13 | // 14 | #ifndef MMPP_USE_TLS 15 | #define MMPP_USE_TLS 1 16 | #endif 17 | 18 | // offsetof() 19 | #include 20 | 21 | //memory module base support 22 | #include "MemoryModule.h" 23 | 24 | //import table support 25 | #include "ImportTable.h" 26 | 27 | //LDR_DATA_TABLE_ENTRY 28 | #include "LdrEntry.h" 29 | 30 | //rtl inverted function table for exception handling 31 | #include "InvertedFunctionTable.h" 32 | 33 | //base address index 34 | #include "BaseAddressIndex.h" 35 | 36 | //tls support 37 | #include "MmpTls.h" 38 | 39 | //DotNet support 40 | #include "MmpDotNet.h" 41 | 42 | //MemoryModulePP api interface 43 | #include "Loader.h" 44 | 45 | //utils 46 | #include "Utils.h" 47 | 48 | //global data 49 | #include "MmpGlobalData.h" -------------------------------------------------------------------------------- /3rdparty/phnt/include/ntnls.h: -------------------------------------------------------------------------------- 1 | /* 2 | * National Language Support functions 3 | * 4 | * This file is part of System Informer. 5 | */ 6 | 7 | #ifndef _NTNLS_H 8 | #define _NTNLS_H 9 | 10 | #define MAXIMUM_LEADBYTES 12 11 | 12 | typedef struct _CPTABLEINFO 13 | { 14 | USHORT CodePage; 15 | USHORT MaximumCharacterSize; 16 | USHORT DefaultChar; 17 | USHORT UniDefaultChar; 18 | USHORT TransDefaultChar; 19 | USHORT TransUniDefaultChar; 20 | USHORT DBCSCodePage; 21 | UCHAR LeadByte[MAXIMUM_LEADBYTES]; 22 | PUSHORT MultiByteTable; 23 | PVOID WideCharTable; 24 | PUSHORT DBCSRanges; 25 | PUSHORT DBCSOffsets; 26 | } CPTABLEINFO, *PCPTABLEINFO; 27 | 28 | typedef struct _NLSTABLEINFO 29 | { 30 | CPTABLEINFO OemTableInfo; 31 | CPTABLEINFO AnsiTableInfo; 32 | PUSHORT UpperCaseTable; 33 | PUSHORT LowerCaseTable; 34 | } NLSTABLEINFO, *PNLSTABLEINFO; 35 | 36 | #if (PHNT_MODE != PHNT_MODE_KERNEL) 37 | NTSYSAPI USHORT NlsAnsiCodePage; 38 | NTSYSAPI BOOLEAN NlsMbCodePageTag; 39 | NTSYSAPI BOOLEAN NlsMbOemCodePageTag; 40 | #endif 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Boring 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /3rdparty/Detours/LICENSE.md: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Corporation 2 | 3 | All rights reserved. 4 | 5 | # MIT License 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /a/exception.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /* 6 | exception type 7 | 0 int 8 | 1 char 9 | 2 std::exception 10 | ... DWORD64 11 | */ 12 | 13 | int exception(int exception_type) { 14 | //int a = 0; 15 | //__try { 16 | // *(PDWORD)(nullptr) = -1; 17 | // a = 2; 18 | //} 19 | //__except (EXCEPTION_EXECUTE_HANDLER) { 20 | // printf("-----------\n"); 21 | // getchar(); 22 | // a = 1; 23 | //} 24 | try { 25 | switch (exception_type) { 26 | case 0: 27 | throw 0; 28 | case 1: 29 | throw '1'; 30 | case 2: 31 | throw std::exception("2"); 32 | case 3: 33 | { 34 | std::string s = "foo"; 35 | s.at(10); 36 | } 37 | default: 38 | throw (DWORD64)-1; 39 | } 40 | return 0; 41 | } 42 | catch (int val) { 43 | printf("exception code = %d\n", val); 44 | return val; 45 | } 46 | catch (char val) { 47 | printf("exception code = %c\n", val); 48 | return val - '0'; 49 | } 50 | catch (const std::out_of_range& e) { 51 | printf("%s\n", e.what()); 52 | return 3; 53 | } 54 | catch (std::exception val) { 55 | printf("exception code = %s\n", val.what()); 56 | return 2; 57 | } 58 | catch (...) { 59 | printf("exception catched!!\n"); 60 | return 0; 61 | } 62 | //return a; 63 | } -------------------------------------------------------------------------------- /MemoryModule/LoadDllMemoryApi.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | typedef HMODULE HMEMORYMODULE; 5 | #include "Loader.h" 6 | #include "Initialize.h" 7 | 8 | #define MemoryModuleToModule(_hMemoryModule_) (_hMemoryModule_) 9 | 10 | #ifndef NT_SUCCESS 11 | #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) 12 | #endif 13 | 14 | extern "C" { 15 | 16 | HMEMORYMODULE WINAPI LoadLibraryMemory(_In_ PVOID BufferAddress); 17 | 18 | HMEMORYMODULE WINAPI LoadLibraryMemoryExA( 19 | _In_ PVOID BufferAddress, 20 | _In_ size_t Reserved, 21 | _In_opt_ LPCSTR DllBaseName, 22 | _In_opt_ LPCSTR DllFullName, 23 | _In_ DWORD Flags 24 | ); 25 | 26 | HMEMORYMODULE WINAPI LoadLibraryMemoryExW( 27 | _In_ PVOID BufferAddress, 28 | _In_ size_t Reserved, 29 | _In_opt_ LPCWSTR DllBaseName, 30 | _In_opt_ LPCWSTR DllFullName, 31 | _In_ DWORD Flags 32 | ); 33 | 34 | BOOL WINAPI FreeLibraryMemory(_In_ HMEMORYMODULE hMemoryModule); 35 | 36 | } 37 | 38 | #define NtLoadDllMemory LdrLoadDllMemory 39 | #define NtLoadDllMemoryExA LdrLoadDllMemoryExA 40 | #define NtLoadDllMemoryExW LdrLoadDllMemoryExW 41 | #define NtUnloadDllMemory LdrUnloadDllMemory 42 | #define NtUnloadDllMemoryAndExitThread LdrUnloadDllMemoryAndExitThread 43 | #define FreeLibraryMemoryAndExitThread LdrUnloadDllMemoryAndExitThread 44 | #define NtQuerySystemMemoryModuleFeatures LdrQuerySystemMemoryModuleFeatures 45 | 46 | #ifdef UNICODE 47 | #define LdrLoadDllMemoryEx LdrLoadDllMemoryExW 48 | #define LoadLibraryMemoryEx LoadLibraryMemoryExW 49 | #else 50 | #define LdrLoadDllMemoryEx LdrLoadDllMemoryExA 51 | #define LoadLibraryMemoryEx LoadLibraryMemoryExA 52 | #endif 53 | #define NtLoadDllMemoryEx LdrLoadDllMemoryEx 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /a/thread.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef NTSTATUS(NTAPI* PUSER_THREAD_START_ROUTINE)(_In_ PVOID ThreadParameter); 5 | 6 | #define NtCurrentProcess() (HANDLE)-1 7 | 8 | #ifdef _WIN64 9 | #define NtCurrentThreadLocalStoragePointer() *(LPVOID*)(LPBYTE(NtCurrentTeb()) + 0x58) 10 | #else 11 | #define NtCurrentThreadLocalStoragePointer() *(LPVOID*)(LPBYTE(NtCurrentTeb()) + 0x2C) 12 | #endif 13 | 14 | typedef struct _CLIENT_ID { 15 | VOID* UniqueProcess; 16 | VOID* UniqueThread; 17 | }CLIENT_ID, * PCLIENT_ID; 18 | 19 | extern "C" 20 | NTSYSAPI 21 | NTSTATUS 22 | NTAPI 23 | RtlCreateUserThread( 24 | _In_ HANDLE Process, 25 | _In_opt_ PSECURITY_DESCRIPTOR ThreadSecurityDescriptor, 26 | _In_ BOOLEAN CreateSuspended, 27 | _In_opt_ ULONG ZeroBits, 28 | _In_opt_ SIZE_T MaximumStackSize, 29 | _In_opt_ SIZE_T CommittedStackSize, 30 | _In_ PUSER_THREAD_START_ROUTINE StartAddress, 31 | _In_opt_ PVOID Parameter, 32 | _Out_opt_ PHANDLE Thread, 33 | _Out_opt_ PCLIENT_ID ClientId 34 | ); 35 | 36 | static thread_local int x = 0xffccffdd; 37 | NTSTATUS WINAPI Thread(PVOID) { 38 | printf("[1] ThreadLocalStoragePointer = %p\n", NtCurrentThreadLocalStoragePointer()); 39 | return x == 0xffccffdd ? 0 : 1; 40 | } 41 | 42 | int thread() { 43 | x = 2; 44 | printf("[0] ThreadLocalStoragePointer = %p\n", NtCurrentThreadLocalStoragePointer()); 45 | HANDLE hThread;// = CreateThread(nullptr, 0, Thread, nullptr, 0, nullptr); 46 | RtlCreateUserThread(NtCurrentProcess(), nullptr, FALSE, 0, 0, 0, Thread, nullptr, &hThread, nullptr); 47 | DWORD ret = -1; 48 | if (hThread) { 49 | WaitForSingleObject(hThread, 0xffffffff); 50 | GetExitCodeThread(hThread, &ret); 51 | CloseHandle(hThread); 52 | return ret; 53 | } 54 | return -1; 55 | } -------------------------------------------------------------------------------- /a/a.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | 32 | 33 | Header Files 34 | 35 | 36 | 37 | 38 | Resource Files 39 | 40 | 41 | 42 | 43 | Resource Files 44 | 45 | 46 | Resource Files 47 | 48 | 49 | -------------------------------------------------------------------------------- /a/a.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "winres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // Chinese (Simplified, PRC) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) 19 | LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED 20 | #pragma code_page(936) 21 | 22 | #ifdef APSTUDIO_INVOKED 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // TEXTINCLUDE 26 | // 27 | 28 | 1 TEXTINCLUDE 29 | BEGIN 30 | "resource.h\0" 31 | END 32 | 33 | 2 TEXTINCLUDE 34 | BEGIN 35 | "#include ""winres.h""\r\n" 36 | "\0" 37 | END 38 | 39 | 3 TEXTINCLUDE 40 | BEGIN 41 | "\r\n" 42 | "\0" 43 | END 44 | 45 | #endif // APSTUDIO_INVOKED 46 | 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | // 50 | // BINARY 51 | // 52 | 53 | IDR_BINARY1 BINARY "binary1.bin" 54 | 55 | 56 | ///////////////////////////////////////////////////////////////////////////// 57 | // 58 | // String Table 59 | // 60 | 61 | STRINGTABLE 62 | BEGIN 63 | IDS_STRING101 "aabbccdd" 64 | END 65 | 66 | #endif // Chinese (Simplified, PRC) resources 67 | ///////////////////////////////////////////////////////////////////////////// 68 | 69 | 70 | 71 | #ifndef APSTUDIO_INVOKED 72 | ///////////////////////////////////////////////////////////////////////////// 73 | // 74 | // Generated from the TEXTINCLUDE 3 resource. 75 | // 76 | 77 | 78 | ///////////////////////////////////////////////////////////////////////////// 79 | #endif // not APSTUDIO_INVOKED 80 | 81 | -------------------------------------------------------------------------------- /MemoryModule/MmpTlsp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // 4 | // ThreadLocalStoragePointer Tls indexs 5 | // [0, MMP_START_TLS_INDEX) Reserved for ntdll loader 6 | // [MMP_START_TLS_INDEX, MMP_MAXIMUM_TLS_INDEX) Reserved for MemoryModule 7 | // 8 | 9 | #define MMP_START_TLS_INDEX 0x80 //128 10 | 11 | #define MMP_MAXIMUM_TLS_INDEX 0x100 //256 12 | 13 | #define MMP_TLSP_INDEX_BUFFER_SIZE (MMP_MAXIMUM_TLS_INDEX / 8) //32 14 | 15 | #if (((MMP_START_TLS_INDEX | MMP_MAXIMUM_TLS_INDEX) & 7) || (MMP_START_TLS_INDEX >= MMP_MAXIMUM_TLS_INDEX)) 16 | #error "MMP_START_TLS_INDEX must be smaller than MMP_MAXIMUM_TLS_INDEX, and both are 8-bit aligned." 17 | #endif 18 | 19 | #define MmpAllocateTlsp() (PTLS_VECTOR)(RtlAllocateHeap(\ 20 | RtlProcessHeap(),\ 21 | HEAP_ZERO_MEMORY,\ 22 | sizeof(TLS_VECTOR) + sizeof(PVOID)* MMP_MAXIMUM_TLS_INDEX\ 23 | )) 24 | 25 | typedef struct _TLS_VECTOR { 26 | union 27 | { 28 | ULONG Length; 29 | HANDLE ThreadId; 30 | }; 31 | 32 | struct _TLS_VECTOR* PreviousDeferredTlsVector; 33 | PVOID ModuleTlsData[ANYSIZE_ARRAY]; 34 | } TLS_VECTOR, * PTLS_VECTOR; 35 | 36 | typedef struct _TLS_ENTRY { 37 | LIST_ENTRY TlsEntryLinks; 38 | IMAGE_TLS_DIRECTORY TlsDirectory; 39 | PLDR_DATA_TABLE_ENTRY ModuleEntry; 40 | } TLS_ENTRY, * PTLS_ENTRY; 41 | 42 | typedef struct _MMP_TLSP_RECORD { 43 | 44 | LIST_ENTRY InMmpThreadLocalStoragePointer; 45 | 46 | HANDLE UniqueThread; 47 | 48 | // PEB->ThreadLocalStoragePointer allocated by ntdll!Ldr 49 | PVOID* TlspLdrBlock; 50 | 51 | // PEB->ThreadLocalStoragePointer allocated by MemoryModulePP 52 | PVOID* TlspMmpBlock; 53 | }MMP_TLSP_RECORD, * PMMP_TLSP_RECORD; 54 | 55 | typedef struct _THREAD_CONTEXT { 56 | PTHREAD_START_ROUTINE ThreadStartRoutine; 57 | LPVOID ThreadParameter; 58 | }THREAD_CONTEXT, * PTHREAD_CONTEXT; 59 | -------------------------------------------------------------------------------- /MemoryModule/LoadDllMemoryApi.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include 3 | 4 | HMEMORYMODULE WINAPI LoadLibraryMemoryExW( 5 | _In_ PVOID BufferAddress, 6 | _In_ size_t Reserved, 7 | _In_opt_ LPCWSTR DllBaseName, 8 | _In_opt_ LPCWSTR DllFullName, 9 | _In_ DWORD Flags) { 10 | HMEMORYMODULE hMemoryModule = nullptr; 11 | NTSTATUS status = LdrLoadDllMemoryExW(&hMemoryModule, nullptr, Flags, BufferAddress, Reserved, DllBaseName, DllFullName); 12 | if (!NT_SUCCESS(status) || status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) { 13 | SetLastError(RtlNtStatusToDosError(status)); 14 | } 15 | return hMemoryModule; 16 | } 17 | 18 | HMEMORYMODULE WINAPI LoadLibraryMemoryExA( 19 | _In_ PVOID BufferAddress, 20 | _In_ size_t Reserved, 21 | _In_opt_ LPCSTR DllBaseName, 22 | _In_opt_ LPCSTR DllFullName, 23 | _In_ DWORD Flags) { 24 | LPWSTR _DllName = nullptr, _DllFullName = nullptr; 25 | size_t size; 26 | HMEMORYMODULE result = nullptr; 27 | HANDLE heap = NtCurrentPeb()->ProcessHeap; 28 | 29 | do { 30 | if (DllBaseName) { 31 | size = strlen(DllBaseName) + 1; 32 | _DllName = (LPWSTR)RtlAllocateHeap(heap, 0, sizeof(WCHAR) * size); 33 | 34 | if (!_DllName) { 35 | RtlNtStatusToDosError(STATUS_INSUFFICIENT_RESOURCES); 36 | break; 37 | } 38 | 39 | mbstowcs_s(nullptr, _DllName, size, DllBaseName, size); 40 | } 41 | 42 | if (DllFullName) { 43 | size = strlen(DllFullName) + 1; 44 | _DllFullName = (LPWSTR)RtlAllocateHeap(heap, 0, sizeof(WCHAR) * size); 45 | 46 | if (!_DllFullName) { 47 | RtlNtStatusToDosError(STATUS_INSUFFICIENT_RESOURCES); 48 | break; 49 | } 50 | 51 | mbstowcs_s(nullptr, _DllFullName, size, DllFullName, size); 52 | } 53 | 54 | result = LoadLibraryMemoryExW(BufferAddress, 0, _DllName, _DllFullName, Flags); 55 | } while (false); 56 | 57 | RtlFreeHeap(heap, 0, _DllName); 58 | RtlFreeHeap(heap, 0, _DllFullName); 59 | return result; 60 | } 61 | 62 | HMEMORYMODULE WINAPI LoadLibraryMemory(_In_ PVOID BufferAddress) { 63 | return LoadLibraryMemoryExW(BufferAddress, 0, nullptr, nullptr, 0); 64 | } 65 | 66 | BOOL WINAPI FreeLibraryMemory(_In_ HMEMORYMODULE hMemoryModule) { 67 | NTSTATUS status = LdrUnloadDllMemory(hMemoryModule); 68 | if (!NT_SUCCESS(status)) { 69 | SetLastError(RtlNtStatusToDosError(status)); 70 | return FALSE; 71 | } 72 | return TRUE; 73 | } 74 | -------------------------------------------------------------------------------- /MemoryModule/MemoryModule.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef __MEMORY_MODULE_HEADER 4 | #define __MEMORY_MODULE_HEADER 5 | 6 | typedef HMODULE HMEMORYMODULE; 7 | 8 | typedef struct _MEMORYMODULE { 9 | /* 10 | --------------------------- 11 | |xxxxxxxx BaseAddress | 12 | |... | 13 | |... | 14 | |... | --> IMAGE_DOS_HEADER 15 | |... | --> IMAGE_NT_HEADERS 16 | |... | 17 | |... | 18 | -------------------------- 19 | struct MEMORYMODULE; 20 | ... (align) 21 | codes 22 | */ 23 | ULONG64 Signature; 24 | 25 | DWORD SizeofHeaders; 26 | union { 27 | struct { 28 | //Status Flags 29 | BYTE initialized : 1; 30 | BYTE loadFromLdrLoadDllMemory : 1; 31 | BYTE underUnload : 1; 32 | BYTE reservedStatusFlags : 5; 33 | 34 | BYTE cbFlagsReserved; 35 | 36 | //Load Flags 37 | WORD MappedDll : 1; 38 | WORD InsertInvertedFunctionTableEntry : 1; 39 | WORD TlsHandled : 1; 40 | WORD UseReferenceCount : 1; 41 | WORD reservedLoadFlags : 12; 42 | 43 | }; 44 | DWORD dwFlags; 45 | }; 46 | 47 | LPBYTE codeBase; //codeBase == ImageBase 48 | PVOID lpReserved; 49 | 50 | PVOID hModulesList; //Import module handles 51 | DWORD dwModulesCount; //number of module handles 52 | DWORD dwReferenceCount; 53 | 54 | DWORD dwImageFileSize; 55 | DWORD dwReserved; 56 | 57 | PVOID LdrEntry; 58 | 59 | } MEMORYMODULE, * PMEMORYMODULE; 60 | 61 | 62 | #define MEMORY_MODULE_SIGNATURE 0x00aabbcc11ffee00 63 | 64 | #ifdef __cplusplus 65 | extern "C" { 66 | #endif 67 | 68 | NTSTATUS MemoryLoadLibrary( 69 | _Out_ HMEMORYMODULE* MemoryModuleHandle, 70 | _In_ LPCVOID data, 71 | _In_ DWORD size 72 | ); 73 | 74 | NTSTATUS MemorySetSectionProtection( 75 | _In_ LPBYTE base, 76 | _In_ PIMAGE_NT_HEADERS lpNtHeaders 77 | ); 78 | 79 | BOOL MemoryFreeLibrary(HMEMORYMODULE); 80 | 81 | BOOL WINAPI IsValidMemoryModuleHandle(HMEMORYMODULE hModule); 82 | 83 | PMEMORYMODULE WINAPI MapMemoryModuleHandle(HMEMORYMODULE hModule); 84 | 85 | NTSTATUS MmpInitializeStructure( 86 | DWORD ImageFileSize, 87 | LPCVOID ImageFileBuffer, 88 | PIMAGE_NT_HEADERS ImageHeaders 89 | ); 90 | 91 | #ifdef __cplusplus 92 | } 93 | #endif 94 | 95 | #endif // __MEMORY_MODULE_HEADER 96 | -------------------------------------------------------------------------------- /MemoryModule/BaseAddressIndex.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | VOID NTAPI RtlRbInsertNodeEx( 4 | _In_ PRTL_RB_TREE Tree, 5 | _In_ PRTL_BALANCED_NODE Parent, 6 | _In_ BOOLEAN Right, 7 | _Out_ PRTL_BALANCED_NODE Node) { 8 | RtlZeroMemory(Node, sizeof(*Node)); 9 | 10 | if (!MmpGlobalDataPtr->MmpBaseAddressIndex->_RtlRbInsertNodeEx)return; 11 | return decltype(&RtlRbInsertNodeEx)(MmpGlobalDataPtr->MmpBaseAddressIndex->_RtlRbInsertNodeEx)(Tree, Parent, Right, Node); 12 | } 13 | 14 | VOID NTAPI RtlRbRemoveNode( 15 | _In_ PRTL_RB_TREE Tree, 16 | _In_ PRTL_BALANCED_NODE Node) { 17 | if (!MmpGlobalDataPtr->MmpBaseAddressIndex->_RtlRbRemoveNode)return; 18 | return decltype(&RtlRbRemoveNode)(MmpGlobalDataPtr->MmpBaseAddressIndex->_RtlRbRemoveNode)(Tree, Node); 19 | } 20 | 21 | NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode( 22 | _In_ PLDR_DATA_TABLE_ENTRY DataTableEntry, 23 | _In_ PVOID BaseAddress) { 24 | auto LdrpModuleBaseAddressIndex = MmpGlobalDataPtr->MmpBaseAddressIndex->LdrpModuleBaseAddressIndex; 25 | if (!LdrpModuleBaseAddressIndex)return STATUS_UNSUCCESSFUL; 26 | 27 | PLDR_DATA_TABLE_ENTRY_WIN8 LdrNode = CONTAINING_RECORD(LdrpModuleBaseAddressIndex->Root, LDR_DATA_TABLE_ENTRY_WIN8, BaseAddressIndexNode); 28 | bool bRight = false; 29 | 30 | while (true) { 31 | if (BaseAddress < LdrNode->DllBase) { 32 | if (!LdrNode->BaseAddressIndexNode.Left)break; 33 | LdrNode = CONTAINING_RECORD(LdrNode->BaseAddressIndexNode.Left, LDR_DATA_TABLE_ENTRY_WIN8, BaseAddressIndexNode); 34 | } 35 | else if (BaseAddress > LdrNode->DllBase) { 36 | if (!LdrNode->BaseAddressIndexNode.Right) { 37 | bRight = true; 38 | break; 39 | } 40 | LdrNode = CONTAINING_RECORD(LdrNode->BaseAddressIndexNode.Right, LDR_DATA_TABLE_ENTRY_WIN8, BaseAddressIndexNode); 41 | } 42 | else { 43 | LdrNode->DdagNode->LoadCount++; 44 | if (RtlIsWindowsVersionOrGreater(10, 0, 0)) { 45 | PLDR_DATA_TABLE_ENTRY_WIN10(LdrNode)->ReferenceCount++; 46 | } 47 | return STATUS_SUCCESS; 48 | } 49 | } 50 | 51 | RtlRbInsertNodeEx(LdrpModuleBaseAddressIndex, &LdrNode->BaseAddressIndexNode, bRight, &PLDR_DATA_TABLE_ENTRY_WIN8(DataTableEntry)->BaseAddressIndexNode); 52 | return STATUS_SUCCESS; 53 | } 54 | 55 | NTSTATUS NTAPI RtlRemoveModuleBaseAddressIndexNode(_In_ PLDR_DATA_TABLE_ENTRY DataTableEntry) { 56 | RtlRbRemoveNode(MmpGlobalDataPtr->MmpBaseAddressIndex->LdrpModuleBaseAddressIndex, &PLDR_DATA_TABLE_ENTRY_WIN8(DataTableEntry)->BaseAddressIndexNode); 57 | return STATUS_SUCCESS; 58 | } 59 | -------------------------------------------------------------------------------- /MemoryModule/InvertedFunctionTable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _RTL_INVERTED_FUNCTION_TABLE_ENTRY_64 { 4 | PIMAGE_RUNTIME_FUNCTION_ENTRY ExceptionDirectory; 5 | PVOID ImageBase; 6 | ULONG ImageSize; 7 | ULONG ExceptionDirectorySize; 8 | } RTL_INVERTED_FUNCTION_TABLE_ENTRY_64, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY_64; 9 | typedef struct _RTL_INVERTED_FUNCTION_TABLE_64 { 10 | ULONG Count; 11 | ULONG MaxCount; 12 | ULONG Epoch; 13 | ULONG Overflow; 14 | RTL_INVERTED_FUNCTION_TABLE_ENTRY_64 Entries[0x200]; 15 | } RTL_INVERTED_FUNCTION_TABLE_64, * PRTL_INVERTED_FUNCTION_TABLE_64; 16 | 17 | // The correct data structure should be this. 18 | // 19 | //typedef struct _RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 { 20 | // PVOID EntrySEHandlerTableEncoded; 21 | // PVOID ImageBase; 22 | // ULONG ImageSize; 23 | // ULONG SEHandlerCount; 24 | //} RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32; 25 | //typedef struct _RTL_INVERTED_FUNCTION_TABLE_WIN7_32 { 26 | // ULONG Count; 27 | // ULONG MaxCount; 28 | // ULONG Overflow; 29 | // RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 Entries[0x200]; 30 | //} RTL_INVERTED_FUNCTION_TABLE_WIN7_32, * PRTL_INVERTED_FUNCTION_TABLE_WIN7_32; 31 | // 32 | // 33 | typedef struct _RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 { 34 | PVOID ImageBase; 35 | ULONG ImageSize; 36 | ULONG SEHandlerCount; 37 | PVOID NextEntrySEHandlerTableEncoded; 38 | } RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32; 39 | typedef struct _RTL_INVERTED_FUNCTION_TABLE_WIN7_32 { 40 | ULONG Count; 41 | ULONG MaxCount; 42 | ULONG Overflow; 43 | ULONG NextEntrySEHandlerTableEncoded; 44 | RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 Entries[0x200]; 45 | } RTL_INVERTED_FUNCTION_TABLE_WIN7_32, * PRTL_INVERTED_FUNCTION_TABLE_WIN7_32; 46 | 47 | #ifdef _WIN64 48 | typedef _RTL_INVERTED_FUNCTION_TABLE_ENTRY_64 _RTL_INVERTED_FUNCTION_TABLE_ENTRY, RTL_INVERTED_FUNCTION_TABLE_ENTRY, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY; 49 | typedef RTL_INVERTED_FUNCTION_TABLE_64 _RTL_INVERTED_FUNCTION_TABLE, RTL_INVERTED_FUNCTION_TABLE, * PRTL_INVERTED_FUNCTION_TABLE; 50 | #else 51 | typedef RTL_INVERTED_FUNCTION_TABLE_WIN7_32 _RTL_INVERTED_FUNCTION_TABLE, RTL_INVERTED_FUNCTION_TABLE, * PRTL_INVERTED_FUNCTION_TABLE; 52 | typedef _RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 _RTL_INVERTED_FUNCTION_TABLE_ENTRY, RTL_INVERTED_FUNCTION_TABLE_ENTRY, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY; 53 | #endif 54 | 55 | NTSTATUS NTAPI RtlInsertInvertedFunctionTable( 56 | _In_ PVOID BaseAddress, 57 | _In_ ULONG ImageSize 58 | ); 59 | 60 | NTSTATUS NTAPI RtlRemoveInvertedFunctionTable(_In_ PVOID ImageBase); 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MemoryModulePP 2 | 3 | MemoryModulePP, used to load a DLL from memory. MemoryModulePP is compatible with Win32 API and supports exception handling. 4 | 5 | **MemoryModulePP is developed based on [MemoryModule][ref1].** 6 | 7 | ## Features 8 | - Compatible with Win32 API (GetModuleHandle, GetModuleFileName, GetProcAddress and any Resource API) 9 | - Support for C++ exceptions and SEH 10 | > In order to support 32-bit dll exception handling, the dll should enable the /SAFESEH linker option, 11 | > otherwise the exception handler cannot pass the ```RtlIsValidHandler()``` check when an exception occurs 12 | - Support reference counting 13 | - Support Thread Local Storage
14 | *There are 2 ways to handle tls: MmpTls and LdrpTls, which you can control via ```MMPP_USE_TLS``` macro in stdafx.h.*

15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
18 | MmpTls(MmpTls.cpp)LdrpTls(MmpLdrpTls.cpp)
DescriptionImplemented by MemoryModulePPImplemented by NTDLL
CompatibilityMediumLow
StabilityLowHigh
37 | - DllMain can receive four types of notifications 38 | - Support forward export 39 | - Support ```SetUnhandledExceptionFilter()``` 40 | - Provides limited support for .NET assembly loading 41 | 42 | ## Tech 43 | 44 | MemoryModulePP uses many open source projects and references to work properly: 45 | 46 | * [Vergilius Project][ref0] - Some windows kernel structure reference. 47 | * [MemoryModule][ref1] - Load dll from memory, reference and improve part of this repository's code. 48 | * [Blackbone][ref2] - Windows memory hacking library, Referenced the idea of exception handling. 49 | * [Exceptions on Windows x64][ref3] - How Windows x64 Exception Handling Works. (Russian) 50 | * [Reactos][ref4] - How Windows loads dll. 51 | 52 | ## Todos 53 | - Add support for ReflectionLoader 54 | - Improve the stability of MmpTls 55 | - Bug fixes 56 | 57 | [ref0]: 58 | [ref1]: 59 | [ref2]: 60 | [ref3]: 61 | [ref4]: 62 | [ref5]: 63 | -------------------------------------------------------------------------------- /a/gdiplus.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace Gdiplus; 5 | #pragma comment (lib,"Gdiplus.lib") 6 | 7 | VOID OnPaint(HDC hdc) 8 | { 9 | Graphics graphics(hdc); 10 | Pen pen(Color(255, 0, 0, 255)); 11 | graphics.DrawLine(&pen, 0, 0, 200, 100); 12 | } 13 | 14 | LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 15 | WPARAM wParam, LPARAM lParam) 16 | { 17 | HDC hdc; 18 | PAINTSTRUCT ps; 19 | 20 | switch (message) 21 | { 22 | case WM_PAINT: 23 | hdc = BeginPaint(hWnd, &ps); 24 | OnPaint(hdc); 25 | EndPaint(hWnd, &ps); 26 | return 0; 27 | case WM_DESTROY: 28 | PostQuitMessage(0); 29 | return 0; 30 | default: 31 | return DefWindowProc(hWnd, message, wParam, lParam); 32 | } 33 | } 34 | 35 | int WINAPI GdiplusTest() 36 | { 37 | HWND hWnd; 38 | MSG msg; 39 | WNDCLASS wndClass; 40 | GdiplusStartupInput gdiplusStartupInput; 41 | ULONG_PTR gdiplusToken; 42 | 43 | // Initialize GDI+. 44 | GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); 45 | 46 | wndClass.style = CS_HREDRAW | CS_VREDRAW; 47 | wndClass.lpfnWndProc = WndProc; 48 | wndClass.cbClsExtra = 0; 49 | wndClass.cbWndExtra = 0; 50 | wndClass.hInstance = GetModuleHandle(nullptr); 51 | wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 52 | wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); 53 | wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 54 | wndClass.lpszMenuName = NULL; 55 | wndClass.lpszClassName = TEXT("GettingStarted"); 56 | 57 | RegisterClass(&wndClass); 58 | 59 | hWnd = CreateWindow( 60 | TEXT("GettingStarted"), // window class name 61 | TEXT("Getting Started"), // window caption 62 | WS_OVERLAPPEDWINDOW, // window style 63 | CW_USEDEFAULT, // initial x position 64 | CW_USEDEFAULT, // initial y position 65 | CW_USEDEFAULT, // initial x size 66 | CW_USEDEFAULT, // initial y size 67 | NULL, // parent window handle 68 | NULL, // window menu handle 69 | wndClass.hInstance, // program instance handle 70 | NULL); // creation parameters 71 | 72 | ShowWindow(hWnd, SW_SHOW); 73 | UpdateWindow(hWnd); 74 | 75 | while (GetMessage(&msg, NULL, 0, 0)) 76 | { 77 | TranslateMessage(&msg); 78 | DispatchMessage(&msg); 79 | } 80 | 81 | GdiplusShutdown(gdiplusToken); 82 | return msg.wParam; 83 | } 84 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /3rdparty/phnt/include/ntxcapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Exception support functions 3 | * 4 | * This file is part of System Informer. 5 | */ 6 | 7 | #ifndef _NTXCAPI_H 8 | #define _NTXCAPI_H 9 | 10 | NTSYSAPI 11 | BOOLEAN 12 | NTAPI 13 | RtlDispatchException( 14 | _In_ PEXCEPTION_RECORD ExceptionRecord, 15 | _In_ PCONTEXT ContextRecord 16 | ); 17 | 18 | NTSYSAPI 19 | DECLSPEC_NORETURN 20 | VOID 21 | NTAPI 22 | RtlRaiseStatus( 23 | _In_ NTSTATUS Status 24 | ); 25 | 26 | NTSYSAPI 27 | VOID 28 | NTAPI 29 | RtlRaiseException( 30 | _In_ PEXCEPTION_RECORD ExceptionRecord 31 | ); 32 | 33 | NTSYSCALLAPI 34 | NTSTATUS 35 | NTAPI 36 | NtContinue( 37 | _In_ PCONTEXT ContextRecord, 38 | _In_ BOOLEAN TestAlert 39 | ); 40 | 41 | #if (PHNT_VERSION >= PHNT_THRESHOLD) 42 | typedef enum _KCONTINUE_TYPE 43 | { 44 | KCONTINUE_UNWIND, 45 | KCONTINUE_RESUME, 46 | KCONTINUE_LONGJUMP, 47 | KCONTINUE_SET, 48 | KCONTINUE_LAST, 49 | } KCONTINUE_TYPE; 50 | 51 | typedef struct _KCONTINUE_ARGUMENT 52 | { 53 | KCONTINUE_TYPE ContinueType; 54 | ULONG ContinueFlags; 55 | ULONGLONG Reserved[2]; 56 | } KCONTINUE_ARGUMENT, *PKCONTINUE_ARGUMENT; 57 | 58 | #define KCONTINUE_FLAG_TEST_ALERT 0x00000001 // wbenny 59 | #define KCONTINUE_FLAG_DELIVER_APC 0x00000002 // wbenny 60 | 61 | NTSYSCALLAPI 62 | NTSTATUS 63 | NTAPI 64 | NtContinueEx( 65 | _In_ PCONTEXT ContextRecord, 66 | _In_ PVOID ContinueArgument // PKCONTINUE_ARGUMENT and BOOLEAN are valid 67 | ); 68 | 69 | //FORCEINLINE 70 | //NTSTATUS 71 | //NtContinue( 72 | // _In_ PCONTEXT ContextRecord, 73 | // _In_ BOOLEAN TestAlert 74 | // ) 75 | //{ 76 | // return NtContinueEx(ContextRecord, (PCONTINUE_ARGUMENT)TestAlert); 77 | //} 78 | #endif 79 | 80 | NTSYSCALLAPI 81 | NTSTATUS 82 | NTAPI 83 | NtRaiseException( 84 | _In_ PEXCEPTION_RECORD ExceptionRecord, 85 | _In_ PCONTEXT ContextRecord, 86 | _In_ BOOLEAN FirstChance 87 | ); 88 | 89 | __analysis_noreturn 90 | NTSYSCALLAPI 91 | VOID 92 | NTAPI 93 | RtlAssert( 94 | _In_ PVOID VoidFailedAssertion, 95 | _In_ PVOID VoidFileName, 96 | _In_ ULONG LineNumber, 97 | _In_opt_ PSTR MutableMessage 98 | ); 99 | 100 | #define RTL_ASSERT(exp) \ 101 | ((!(exp)) ? (RtlAssert((PVOID)#exp, (PVOID)__FILE__, __LINE__, NULL), FALSE) : TRUE) 102 | #define RTL_ASSERTMSG(msg, exp) \ 103 | ((!(exp)) ? (RtlAssert((PVOID)#exp, (PVOID)__FILE__, __LINE__, msg), FALSE) : TRUE) 104 | #define RTL_SOFT_ASSERT(_exp) \ 105 | ((!(_exp)) ? (DbgPrint("%s(%d): Soft assertion failed\n Expression: %s\n", __FILE__, __LINE__, #_exp), FALSE) : TRUE) 106 | #define RTL_SOFT_ASSERTMSG(_msg, _exp) \ 107 | ((!(_exp)) ? (DbgPrint("%s(%d): Soft assertion failed\n Expression: %s\n Message: %s\n", __FILE__, __LINE__, #_exp, (_msg)), FALSE) : TRUE) 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /MemoryModule/ReflectiveDLLInjection.h: -------------------------------------------------------------------------------- 1 | //===============================================================================================// 2 | // Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com) 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted 6 | // provided that the following conditions are met: 7 | // 8 | // * Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // * Redistributions in binary form must reproduce the above copyright notice, this list of 12 | // conditions and the following disclaimer in the documentation and/or other materials provided 13 | // with the distribution. 14 | // 15 | // * Neither the name of Harmony Security nor the names of its contributors may be used to 16 | // endorse or promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | // POSSIBILITY OF SUCH DAMAGE. 27 | //===============================================================================================// 28 | #ifndef _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H 29 | #define _REFLECTIVEDLLINJECTION_REFLECTIVEDLLINJECTION_H 30 | //===============================================================================================// 31 | #define WIN32_LEAN_AND_MEAN 32 | #include 33 | 34 | // we declare some common stuff in here... 35 | 36 | #define DLL_QUERY_HMODULE 6 37 | 38 | #define DEREF( name )*(UINT_PTR *)(name) 39 | #define DEREF_64( name )*(DWORD64 *)(name) 40 | #define DEREF_32( name )*(DWORD *)(name) 41 | #define DEREF_16( name )*(WORD *)(name) 42 | #define DEREF_8( name )*(BYTE *)(name) 43 | 44 | typedef ULONG_PTR(WINAPI* REFLECTIVELOADER)(VOID); 45 | typedef BOOL(WINAPI* DLLMAIN)(HINSTANCE, DWORD, LPVOID); 46 | 47 | #define DLLEXPORT __declspec( dllexport ) 48 | 49 | //===============================================================================================// 50 | #endif 51 | //===============================================================================================// -------------------------------------------------------------------------------- /3rdparty/phnt/include/phnt_windows.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Win32 definition support 3 | * 4 | * This file is part of System Informer. 5 | */ 6 | 7 | #ifndef _PHNT_WINDOWS_H 8 | #define _PHNT_WINDOWS_H 9 | 10 | // This header file provides access to Win32, plus NTSTATUS values and some access mask values. 11 | 12 | #ifndef __cplusplus 13 | #ifndef CINTERFACE 14 | #define CINTERFACE 15 | #endif 16 | 17 | #ifndef COBJMACROS 18 | #define COBJMACROS 19 | #endif 20 | #endif 21 | 22 | #ifndef INITGUID 23 | #define INITGUID 24 | #endif 25 | 26 | #ifndef WIN32_LEAN_AND_MEAN 27 | #define WIN32_LEAN_AND_MEAN 28 | #endif 29 | 30 | #ifndef WIN32_NO_STATUS 31 | #define WIN32_NO_STATUS 32 | #endif 33 | 34 | #ifndef __cplusplus 35 | // This is needed to workaround C17 preprocessor errors when using legacy versions of the Windows SDK. (dmex) 36 | #ifndef MICROSOFT_WINDOWS_WINBASE_H_DEFINE_INTERLOCKED_CPLUSPLUS_OVERLOADS 37 | #define MICROSOFT_WINDOWS_WINBASE_H_DEFINE_INTERLOCKED_CPLUSPLUS_OVERLOADS 0 38 | #endif 39 | #endif 40 | 41 | #include 42 | #include 43 | #undef WIN32_NO_STATUS 44 | #include 45 | #include 46 | 47 | typedef double DOUBLE; 48 | typedef GUID *PGUID; 49 | 50 | // Desktop access rights 51 | #define DESKTOP_ALL_ACCESS \ 52 | (DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | \ 53 | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | \ 54 | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS | \ 55 | STANDARD_RIGHTS_REQUIRED) 56 | #define DESKTOP_GENERIC_READ \ 57 | (DESKTOP_ENUMERATE | DESKTOP_READOBJECTS | STANDARD_RIGHTS_READ) 58 | #define DESKTOP_GENERIC_WRITE \ 59 | (DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_HOOKCONTROL | \ 60 | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_WRITEOBJECTS | \ 61 | STANDARD_RIGHTS_WRITE) 62 | #define DESKTOP_GENERIC_EXECUTE \ 63 | (DESKTOP_SWITCHDESKTOP | STANDARD_RIGHTS_EXECUTE) 64 | 65 | // Window station access rights 66 | #define WINSTA_GENERIC_READ \ 67 | (WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_READATTRIBUTES | \ 68 | WINSTA_READSCREEN | STANDARD_RIGHTS_READ) 69 | #define WINSTA_GENERIC_WRITE \ 70 | (WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | WINSTA_WRITEATTRIBUTES | \ 71 | STANDARD_RIGHTS_WRITE) 72 | #define WINSTA_GENERIC_EXECUTE \ 73 | (WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS | STANDARD_RIGHTS_EXECUTE) 74 | 75 | // WMI access rights 76 | #define WMIGUID_GENERIC_READ \ 77 | (WMIGUID_QUERY | WMIGUID_NOTIFICATION | WMIGUID_READ_DESCRIPTION | \ 78 | STANDARD_RIGHTS_READ) 79 | #define WMIGUID_GENERIC_WRITE \ 80 | (WMIGUID_SET | TRACELOG_CREATE_REALTIME | TRACELOG_CREATE_ONDISK | \ 81 | STANDARD_RIGHTS_WRITE) 82 | #define WMIGUID_GENERIC_EXECUTE \ 83 | (WMIGUID_EXECUTE | TRACELOG_GUID_ENABLE | TRACELOG_LOG_EVENT | \ 84 | TRACELOG_ACCESS_REALTIME | TRACELOG_REGISTER_GUIDS | \ 85 | STANDARD_RIGHTS_EXECUTE) 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /3rdparty/phnt/include/phnt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NT Header annotations 3 | * 4 | * This file is part of System Informer. 5 | */ 6 | 7 | #ifndef _PHNT_H 8 | #define _PHNT_H 9 | 10 | // This header file provides access to NT APIs. 11 | 12 | // Definitions are annotated to indicate their source. If a definition is not annotated, it has been 13 | // retrieved from an official Microsoft source (NT headers, DDK headers, winnt.h). 14 | 15 | // * "winbase" indicates that a definition has been reconstructed from a Win32-ized NT definition in 16 | // winbase.h. 17 | // * "rev" indicates that a definition has been reverse-engineered. 18 | // * "dbg" indicates that a definition has been obtained from a debug message or assertion in a 19 | // checked build of the kernel or file. 20 | 21 | // Reliability: 22 | // 1. No annotation. 23 | // 2. dbg. 24 | // 3. symbols, private. Types may be incorrect. 25 | // 4. winbase. Names and types may be incorrect. 26 | // 5. rev. 27 | 28 | // Mode 29 | #define PHNT_MODE_KERNEL 0 30 | #define PHNT_MODE_USER 1 31 | 32 | // Version 33 | #define PHNT_WIN2K 50 34 | #define PHNT_WINXP 51 35 | #define PHNT_WS03 52 36 | #define PHNT_VISTA 60 37 | #define PHNT_WIN7 61 38 | #define PHNT_WIN8 62 39 | #define PHNT_WINBLUE 63 40 | #define PHNT_THRESHOLD 100 41 | #define PHNT_THRESHOLD2 101 42 | #define PHNT_REDSTONE 102 43 | #define PHNT_REDSTONE2 103 44 | #define PHNT_REDSTONE3 104 45 | #define PHNT_REDSTONE4 105 46 | #define PHNT_REDSTONE5 106 47 | #define PHNT_19H1 107 48 | #define PHNT_19H2 108 49 | #define PHNT_20H1 109 50 | #define PHNT_20H2 110 51 | #define PHNT_21H1 111 52 | #define PHNT_21H2 112 53 | #define PHNT_WIN11 113 54 | 55 | #ifndef PHNT_MODE 56 | #define PHNT_MODE PHNT_MODE_USER 57 | #endif 58 | 59 | #ifndef PHNT_VERSION 60 | #define PHNT_VERSION PHNT_WIN7 61 | #endif 62 | 63 | // Options 64 | 65 | //#define PHNT_NO_INLINE_INIT_STRING 66 | 67 | #ifdef __cplusplus 68 | extern "C" { 69 | #endif 70 | 71 | #if (PHNT_MODE != PHNT_MODE_KERNEL) 72 | #include "phnt_ntdef.h" 73 | #include "ntnls.h" 74 | #include "ntkeapi.h" 75 | #endif 76 | 77 | #include "ntldr.h" 78 | #include "ntexapi.h" 79 | 80 | #include "ntbcd.h" 81 | #include "ntmmapi.h" 82 | #include "ntobapi.h" 83 | #include "ntpsapi.h" 84 | 85 | #if (PHNT_MODE != PHNT_MODE_KERNEL) 86 | #include "cfg.h" 87 | #include "ntdbg.h" 88 | #include "ntioapi.h" 89 | #include "ntlpcapi.h" 90 | #include "ntpfapi.h" 91 | #include "ntpnpapi.h" 92 | #include "ntpoapi.h" 93 | #include "ntregapi.h" 94 | #include "ntrtl.h" 95 | #endif 96 | 97 | #if (PHNT_MODE != PHNT_MODE_KERNEL) 98 | 99 | #include "ntseapi.h" 100 | #include "nttmapi.h" 101 | #include "nttp.h" 102 | #include "ntxcapi.h" 103 | 104 | #include "ntwow64.h" 105 | 106 | #include "ntlsa.h" 107 | #include "ntsam.h" 108 | 109 | #include "ntmisc.h" 110 | 111 | //#include "ntzwapi.h" 112 | 113 | #endif 114 | 115 | #ifdef __cplusplus 116 | } 117 | #endif 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /MemoryModule/Loader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define MEMORY_FEATURE_SUPPORT_VERSION 0x00000001 4 | #define MEMORY_FEATURE_MODULE_BASEADDRESS_INDEX 0x00000002 /* Windows8 and greater */ 5 | #define MEMORY_FEATURE_LDRP_HEAP 0x00000004 6 | #define MEMORY_FEATURE_LDRP_HASH_TABLE 0x00000008 7 | #define MEMORY_FEATURE_INVERTED_FUNCTION_TABLE 0x00000010 8 | #define MEMORY_FEATURE_LDRP_HANDLE_TLS_DATA 0x00000020 9 | #define MEMORY_FEATURE_LDRP_RELEASE_TLS_ENTRY 0x00000040 10 | #define MEMORY_FEATURE_ALL 0x0000007f 11 | 12 | 13 | /* 14 | LdrLoadDllMemoryEx dwFlags 15 | */ 16 | 17 | //If this flag is specified, all subsequent flags will be ignored. 18 | //Also, will be incompatible with Win32 API. 19 | #define LOAD_FLAGS_NOT_MAP_DLL 0x10000000 20 | 21 | //If this flag is specified, this routine will not fail even if the call to LdrpTlsData fails. 22 | #define LOAD_FLAGS_NOT_FAIL_IF_HANDLE_TLS 0x20000000 23 | 24 | //If this flag is specified, the input image buffer will not be checked before loading. 25 | #define LOAD_FLAGS_PASS_IMAGE_CHECK 0x40000000 26 | 27 | //If this flag is specified, exception handling will not be supported. 28 | #define LOAD_FLAGS_NOT_ADD_INVERTED_FUNCTION 0x00000001 29 | 30 | //If this flag is specified, LdrLoadDllMemory and LdrUnloadDllMemory will not use reference counting. 31 | //If you try to load the same module, it will fail. When you unload the module, 32 | // it will be unloaded without checking the reference count. 33 | #define LOAD_FLAGS_NOT_USE_REFERENCE_COUNT 0x00000002 34 | 35 | //If this flag is specified, DllName and DllFullName cannot be nullptr, 36 | // they can be arbitrary strings without having to be correct file names and paths. 37 | //Otherwise, DllName and DllFullName will use random names if they are nullptr. 38 | //For compatibility with GetModuleHandle, DllName and DllFullName should be guaranteed to always end in ".dll" 39 | #define LOAD_FLAGS_USE_DLL_NAME 0x00000004 40 | 41 | //Dont call LdrpHandleTlsData routine if this flag is specified. 42 | #define LOAD_FLAGS_NOT_HANDLE_TLS 0x00000008 43 | 44 | //Hook for dotnet dlls 45 | #define LOAD_FLAGS_HOOK_DOT_NET 0x00000010 46 | 47 | extern "C" { 48 | 49 | //Get the implementation of the currently running operating system. 50 | NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures); 51 | 52 | NTSTATUS NTAPI LdrLoadDllMemoryExW( 53 | _Out_ HMEMORYMODULE* BaseAddress, // Output module base address 54 | _Out_opt_ PVOID* LdrEntry, // Receive a pointer to the LDR node of the module 55 | _In_ DWORD dwFlags, // Flags 56 | _In_ LPVOID BufferAddress, // Pointer to the dll file data buffer 57 | _In_ size_t Reserved, // Reserved parameter, must be 0 58 | _In_opt_ LPCWSTR DllName, // Module file name 59 | _In_opt_ LPCWSTR DllFullName // Module file full path 60 | ); 61 | 62 | //Unload modules previously loaded from memory 63 | NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress); 64 | 65 | __declspec(noreturn) VOID NTAPI LdrUnloadDllMemoryAndExitThread( 66 | _In_ HMEMORYMODULE BaseAddress, 67 | _In_ DWORD dwExitCode 68 | ); 69 | } 70 | -------------------------------------------------------------------------------- /3rdparty/phnt/include/subprocesstag.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Subprocess tag information 3 | * 4 | * This file is part of System Informer. 5 | */ 6 | 7 | #ifndef _SUBPROCESSTAG_H 8 | #define _SUBPROCESSTAG_H 9 | 10 | typedef enum _TAG_INFO_LEVEL 11 | { 12 | eTagInfoLevelNameFromTag = 1, // TAG_INFO_NAME_FROM_TAG 13 | eTagInfoLevelNamesReferencingModule, // TAG_INFO_NAMES_REFERENCING_MODULE 14 | eTagInfoLevelNameTagMapping, // TAG_INFO_NAME_TAG_MAPPING 15 | eTagInfoLevelMax 16 | } TAG_INFO_LEVEL; 17 | 18 | typedef enum _TAG_TYPE 19 | { 20 | eTagTypeService = 1, 21 | eTagTypeMax 22 | } TAG_TYPE; 23 | 24 | typedef struct _TAG_INFO_NAME_FROM_TAG_IN_PARAMS 25 | { 26 | ULONG dwPid; 27 | ULONG dwTag; 28 | } TAG_INFO_NAME_FROM_TAG_IN_PARAMS, *PTAG_INFO_NAME_FROM_TAG_IN_PARAMS; 29 | 30 | typedef struct _TAG_INFO_NAME_FROM_TAG_OUT_PARAMS 31 | { 32 | ULONG eTagType; 33 | PWSTR pszName; 34 | } TAG_INFO_NAME_FROM_TAG_OUT_PARAMS, *PTAG_INFO_NAME_FROM_TAG_OUT_PARAMS; 35 | 36 | typedef struct _TAG_INFO_NAME_FROM_TAG 37 | { 38 | TAG_INFO_NAME_FROM_TAG_IN_PARAMS InParams; 39 | TAG_INFO_NAME_FROM_TAG_OUT_PARAMS OutParams; 40 | } TAG_INFO_NAME_FROM_TAG, *PTAG_INFO_NAME_FROM_TAG; 41 | 42 | typedef struct _TAG_INFO_NAMES_REFERENCING_MODULE_IN_PARAMS 43 | { 44 | ULONG dwPid; 45 | PWSTR pszModule; 46 | } TAG_INFO_NAMES_REFERENCING_MODULE_IN_PARAMS, *PTAG_INFO_NAMES_REFERENCING_MODULE_IN_PARAMS; 47 | 48 | typedef struct _TAG_INFO_NAMES_REFERENCING_MODULE_OUT_PARAMS 49 | { 50 | ULONG eTagType; 51 | PWSTR pmszNames; 52 | } TAG_INFO_NAMES_REFERENCING_MODULE_OUT_PARAMS, *PTAG_INFO_NAMES_REFERENCING_MODULE_OUT_PARAMS; 53 | 54 | typedef struct _TAG_INFO_NAMES_REFERENCING_MODULE 55 | { 56 | TAG_INFO_NAMES_REFERENCING_MODULE_IN_PARAMS InParams; 57 | TAG_INFO_NAMES_REFERENCING_MODULE_OUT_PARAMS OutParams; 58 | } TAG_INFO_NAMES_REFERENCING_MODULE, *PTAG_INFO_NAMES_REFERENCING_MODULE; 59 | 60 | typedef struct _TAG_INFO_NAME_TAG_MAPPING_IN_PARAMS 61 | { 62 | ULONG dwPid; 63 | } TAG_INFO_NAME_TAG_MAPPING_IN_PARAMS, *PTAG_INFO_NAME_TAG_MAPPING_IN_PARAMS; 64 | 65 | typedef struct _TAG_INFO_NAME_TAG_MAPPING_ELEMENT 66 | { 67 | ULONG eTagType; 68 | ULONG dwTag; 69 | PWSTR pszName; 70 | PWSTR pszGroupName; 71 | } TAG_INFO_NAME_TAG_MAPPING_ELEMENT, *PTAG_INFO_NAME_TAG_MAPPING_ELEMENT; 72 | 73 | typedef struct _TAG_INFO_NAME_TAG_MAPPING_OUT_PARAMS 74 | { 75 | ULONG cElements; 76 | PTAG_INFO_NAME_TAG_MAPPING_ELEMENT pNameTagMappingElements; 77 | } TAG_INFO_NAME_TAG_MAPPING_OUT_PARAMS, *PTAG_INFO_NAME_TAG_MAPPING_OUT_PARAMS; 78 | 79 | typedef struct _TAG_INFO_NAME_TAG_MAPPING 80 | { 81 | TAG_INFO_NAME_TAG_MAPPING_IN_PARAMS InParams; 82 | PTAG_INFO_NAME_TAG_MAPPING_OUT_PARAMS pOutParams; 83 | } TAG_INFO_NAME_TAG_MAPPING, *PTAG_INFO_NAME_TAG_MAPPING; 84 | 85 | _Must_inspect_result_ 86 | ULONG 87 | WINAPI 88 | I_QueryTagInformation( 89 | _In_opt_ PCWSTR MachineName, 90 | _In_ TAG_INFO_LEVEL InfoLevel, 91 | _Inout_ PVOID TagInfo 92 | ); 93 | 94 | typedef ULONG (WINAPI *PQUERY_TAG_INFORMATION)( 95 | _In_opt_ PCWSTR MachineName, 96 | _In_ TAG_INFO_LEVEL InfoLevel, 97 | _Inout_ PVOID TagInfo 98 | ); 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /MemoryModule/Utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef struct _SEARCH_CONTEXT { 4 | 5 | IN LPBYTE SearchPattern; 6 | IN SIZE_T PatternSize; 7 | 8 | OUT LPBYTE Result; 9 | SIZE_T MemoryBlockSize; 10 | 11 | }SEARCH_CONTEXT, * PSEARCH_CONTEXT; 12 | 13 | NTSTATUS NTAPI RtlFindMemoryBlockFromModuleSection( 14 | _In_ HMODULE ModuleHandle, 15 | _In_ LPCSTR SectionName, 16 | _Inout_ PSEARCH_CONTEXT SearchContext 17 | ); 18 | 19 | NTSTATUS NTAPI RtlResolveDllNameUnicodeString( 20 | _In_opt_ PCWSTR DllName, 21 | _In_opt_ PCWSTR DllFullName, 22 | _Out_ PUNICODE_STRING BaseDllName, 23 | _Out_ PUNICODE_STRING FullDllName 24 | ); 25 | 26 | BOOL NTAPI LdrpExecuteTLS(PMEMORYMODULE module); 27 | 28 | BOOL NTAPI LdrpCallInitializers(PMEMORYMODULE module, DWORD dwReason); 29 | 30 | BOOLEAN NTAPI RtlIsValidImageBuffer( 31 | _In_ PVOID Buffer, 32 | _Out_opt_ size_t* Size 33 | ); 34 | 35 | BOOLEAN NTAPI VirtualAccessCheck(LPCVOID pBuffer, size_t size, ACCESS_MASK protect); 36 | BOOLEAN NTAPI VirtualAccessCheckNoException(LPCVOID pBuffer, size_t size, ACCESS_MASK protect); 37 | #define ProbeForRead(pBuffer, size) VirtualAccessCheck(pBuffer, size, PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_WRITECOPY) 38 | #define ProbeForWrite(pBuffer, size) VirtualAccessCheck(pBuffer, size, PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) 39 | #define ProbeForReadWrite ProbeForWrite 40 | #define ProbeForExecute(pBuffer, size) VirtualAccessCheck(pBuffer, size, PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) 41 | 42 | #define _ProbeForRead(pBuffer, size) VirtualAccessCheckNoException(pBuffer, size, PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_WRITECOPY) 43 | #define _ProbeForWrite(pBuffer, size) VirtualAccessCheckNoException(pBuffer, size, PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) 44 | #define _ProbeForReadWrite _ProbeForWrite 45 | #define _ProbeForExecute(pBuffer, size) VirtualAccessCheckNoException(pBuffer, size, PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) 46 | 47 | #define RtlClearBit(BitMapHeader,BitNumber) RtlClearBits((BitMapHeader),(BitNumber),1) 48 | 49 | 50 | #define RTL_VERIFY_FLAGS_MAJOR_VERSION 0 51 | #define RTL_VERIFY_FLAGS_MINOR_VERSION 1 52 | #define RTL_VERIFY_FLAGS_BUILD_NUMBERS 2 53 | #define RTL_VERIFY_FLAGS_DEFAULT RTL_VERIFY_FLAGS_MAJOR_VERSION|RTL_VERIFY_FLAGS_MINOR_VERSION|RTL_VERIFY_FLAGS_BUILD_NUMBERS 54 | 55 | BOOL NTAPI RtlVerifyVersion( 56 | _In_ DWORD MajorVersion, 57 | _In_ DWORD MinorVersion, 58 | _In_ DWORD BuildNumber, 59 | _In_ BYTE Flags 60 | ); 61 | 62 | BOOL NTAPI RtlIsWindowsVersionOrGreater( 63 | _In_ DWORD MajorVersion, 64 | _In_ DWORD MinorVersion, 65 | _In_ DWORD BuildNumber 66 | ); 67 | 68 | BOOL NTAPI RtlIsWindowsVersionInScope( 69 | _In_ DWORD MinMajorVersion, 70 | _In_ DWORD MinMinorVersion, 71 | _In_ DWORD MinBuildNumber, 72 | 73 | _In_ DWORD MaxMajorVersion, 74 | _In_ DWORD MaxMinorVersion, 75 | _In_ DWORD MaxBuildNumber 76 | ); 77 | 78 | #ifndef _WIN64 79 | int NTAPI RtlCaptureImageExceptionValues(PVOID BaseAddress, PDWORD SEHandlerTable, PDWORD SEHandlerCount); 80 | #endif 81 | -------------------------------------------------------------------------------- /3rdparty/Detours/README.md: -------------------------------------------------------------------------------- 1 | # Microsoft Research Detours Package 2 | 3 | Detours is a software package for monitoring and instrumenting API calls on Windows. Detours 4 | has been used by many ISVs and is also used by product teams at Microsoft. Detours is now available under 5 | a standard open source license ([MIT](https://github.com/microsoft/Detours/blob/master/LICENSE.md)). This simplifies licensing for programmers using Detours 6 | and allows the community to support Detours using open source tools and processes. 7 | 8 | Detours is compatible with the Windows NT family of 9 | operating systems: Windows NT, Windows XP, Windows Server 2003, Windows 7, 10 | Windows 8, and Windows 10. It cannot be used by Windows Store apps 11 | because Detours requires APIs not available to those applications. 12 | This repo contains the source code for version 4.0.1 of Detours. 13 | 14 | For technical documentation on Detours, see the [Detours Wiki](https://github.com/microsoft/Detours/wiki). 15 | For directions on how to build and run samples, see the 16 | samples [README.txt](https://github.com/Microsoft/Detours/blob/master/samples/README.TXT) file. 17 | 18 | ## Contributing 19 | 20 | The [`Detours`](https://github.com/microsoft/detours) repository is where development is done. 21 | Here are some ways you can participate in the project: 22 | 23 | * [Answer questions](https://github.com/microsoft/detours/issues) about using Detours. 24 | * [Improve the Wiki](https://github.com/microsoft/detours/wiki). 25 | * [Submit bugs](https://github.com/microsoft/detours/issues) and help us verify fixes and changes as they are checked in. 26 | * Review [source code changes](https://github.com/microsoft/detours/pulls). 27 | 28 | Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that 29 | you have the right to, and actually do, grant us the rights to use your contribution. 30 | For details, visit https://cla.opensource.microsoft.com. 31 | 32 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 33 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 34 | provided by the bot. You will only need to do this once across all repos using our CLA. 35 | 36 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 37 | 38 | ## Issues, questions, and feedback 39 | 40 | * Open an issue on [GitHub Issues](https://github.com/Microsoft/detours/issues). 41 | 42 | ## Mailing list for announcements 43 | 44 | The detours-announce mailing list is a low-traffic email list for important announcements 45 | about the project, such as the availability of new versions of Detours. To join it, send 46 | an email to listserv@lists.research.microsoft.com with a 47 | message body containing only the text SUBSCRIBE DETOURS-ANNOUNCE. 48 | To leave it, send an email to listserv@lists.research.microsoft.com with a 49 | message body containing only the text UNSUBSCRIBE DETOURS-ANNOUNCE. 50 | 51 | 52 | ## License 53 | 54 | Copyright (c) Microsoft Corporation. All rights reserved. 55 | 56 | Licensed under the [MIT](LICENSE.md) License. 57 | -------------------------------------------------------------------------------- /3rdparty/phnt/include/ntmisc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Trace Control support functions 3 | * 4 | * This file is part of System Informer. 5 | */ 6 | 7 | #ifndef _NTMISC_H 8 | #define _NTMISC_H 9 | 10 | // Filter manager 11 | 12 | #define FLT_PORT_CONNECT 0x0001 13 | #define FLT_PORT_ALL_ACCESS (FLT_PORT_CONNECT | STANDARD_RIGHTS_ALL) 14 | 15 | // VDM 16 | 17 | typedef enum _VDMSERVICECLASS 18 | { 19 | VdmStartExecution, 20 | VdmQueueInterrupt, 21 | VdmDelayInterrupt, 22 | VdmInitialize, 23 | VdmFeatures, 24 | VdmSetInt21Handler, 25 | VdmQueryDir, 26 | VdmPrinterDirectIoOpen, 27 | VdmPrinterDirectIoClose, 28 | VdmPrinterInitialize, 29 | VdmSetLdtEntries, 30 | VdmSetProcessLdtInfo, 31 | VdmAdlibEmulation, 32 | VdmPMCliControl, 33 | VdmQueryVdmProcess, 34 | VdmPreInitialize 35 | } VDMSERVICECLASS, *PVDMSERVICECLASS; 36 | 37 | NTSYSCALLAPI 38 | NTSTATUS 39 | NTAPI 40 | NtVdmControl( 41 | _In_ VDMSERVICECLASS Service, 42 | _Inout_ PVOID ServiceData 43 | ); 44 | 45 | // WMI/ETW 46 | 47 | NTSYSCALLAPI 48 | NTSTATUS 49 | NTAPI 50 | NtTraceEvent( 51 | _In_ HANDLE TraceHandle, 52 | _In_ ULONG Flags, 53 | _In_ ULONG FieldSize, 54 | _In_ PVOID Fields 55 | ); 56 | 57 | typedef enum _TRACE_CONTROL_INFORMATION_CLASS 58 | { 59 | TraceControlStartLogger = 1, // inout WMI_LOGGER_INFORMATION 60 | TraceControlStopLogger = 2, // inout WMI_LOGGER_INFORMATION 61 | TraceControlQueryLogger = 3, // inout WMI_LOGGER_INFORMATION 62 | TraceControlUpdateLogger = 4, // inout WMI_LOGGER_INFORMATION 63 | TraceControlFlushLogger = 5, // inout WMI_LOGGER_INFORMATION 64 | TraceControlIncrementLoggerFile = 6, // inout WMI_LOGGER_INFORMATION 65 | TraceControlUnknown = 7, 66 | // unused 67 | TraceControlRealtimeConnect = 11, 68 | TraceControlActivityIdCreate = 12, 69 | TraceControlWdiDispatchControl = 13, 70 | TraceControlRealtimeDisconnectConsumerByHandle = 14, // in HANDLE 71 | TraceControlRegisterGuidsCode = 15, 72 | TraceControlReceiveNotification = 16, 73 | TraceControlSendDataBlock = 17, // ETW_ENABLE_NOTIFICATION_PACKET 74 | TraceControlSendReplyDataBlock = 18, 75 | TraceControlReceiveReplyDataBlock = 19, 76 | TraceControlWdiUpdateSem = 20, 77 | TraceControlEnumTraceGuidList = 21, // out GUID[] 78 | TraceControlGetTraceGuidInfo = 22, // in GUID, out TRACE_GUID_INFO 79 | TraceControlEnumerateTraceGuids = 23, 80 | TraceControlRegisterSecurityProv = 24, 81 | TraceControlQueryReferenceTime = 25, 82 | TraceControlTrackProviderBinary = 26, // in HANDLE 83 | TraceControlAddNotificationEvent = 27, 84 | TraceControlUpdateDisallowList = 28, 85 | TraceControlSetEnableAllKeywordsCode = 29, 86 | TraceControlSetProviderTraitsCode = 30, 87 | TraceControlUseDescriptorTypeCode = 31, 88 | TraceControlEnumTraceGroupList = 32, 89 | TraceControlGetTraceGroupInfo = 33, 90 | TraceControlTraceSetDisallowList = 34, 91 | TraceControlSetCompressionSettings = 35, 92 | TraceControlGetCompressionSettings = 36, 93 | TraceControlUpdatePeriodicCaptureState = 37, 94 | TraceControlGetPrivateSessionTraceHandle = 38, 95 | TraceControlRegisterPrivateSession = 39, 96 | TraceControlQuerySessionDemuxObject = 40, 97 | TraceControlSetProviderBinaryTracking = 41, 98 | TraceControlMaxLoggers = 42, // out ULONG 99 | TraceControlMaxPmcCounter = 43, // out ULONG 100 | TraceControlQueryUsedProcessorCount = 44, // ULONG // since WIN11 101 | TraceControlGetPmcOwnership = 45, 102 | } TRACE_CONTROL_INFORMATION_CLASS; 103 | 104 | #if (PHNT_VERSION >= PHNT_VISTA) 105 | NTSYSCALLAPI 106 | NTSTATUS 107 | NTAPI 108 | NtTraceControl( 109 | _In_ TRACE_CONTROL_INFORMATION_CLASS TraceInformationClass, 110 | _In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer, 111 | _In_ ULONG InputBufferLength, 112 | _Out_writes_bytes_opt_(TraceInformationLength) PVOID TraceInformation, 113 | _In_ ULONG TraceInformationLength, 114 | _Out_ PULONG ReturnLength 115 | ); 116 | #endif 117 | 118 | #endif 119 | -------------------------------------------------------------------------------- /MemoryModule/MmpTlsFiber.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "MmpTlsp.h" 3 | #include "MmpTlsFiber.h" 4 | 5 | #include 6 | #include 7 | 8 | typedef struct _MMP_POSTPONED_TLS { 9 | 10 | HANDLE hThread; 11 | PMMP_TLSP_RECORD lpTlsRecord; 12 | PTLS_VECTOR lpOldTlsVector; 13 | 14 | }MMP_POSTPONED_TLS, * PMMP_POSTPONED_TLS; 15 | 16 | std::vector* MmpPostponedTlsList; 17 | 18 | HANDLE MmpPostponedTlsEvent; 19 | CRITICAL_SECTION MmpPostponedTlsLock; 20 | 21 | DWORD WINAPI MmpReleasePostponedTlsWorker(PVOID) { 22 | 23 | DWORD code; 24 | DWORD waitTime = INFINITE; 25 | 26 | while (true) { 27 | WaitForSingleObject(MmpPostponedTlsEvent, waitTime); 28 | 29 | EnterCriticalSection(&MmpPostponedTlsLock); 30 | 31 | if (MmpPostponedTlsList) { 32 | auto iter = MmpPostponedTlsList->begin(); 33 | 34 | while (iter != MmpPostponedTlsList->end()) { 35 | GetExitCodeThread(iter->hThread, &code); 36 | 37 | if (code == STILL_ACTIVE) { 38 | ++iter; 39 | } 40 | else { 41 | 42 | RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock); 43 | 44 | auto TlspMmpBlock = (PVOID*)iter->lpOldTlsVector->ModuleTlsData; 45 | auto entry = MmpGlobalDataPtr->MmpTls->MmpTlsList.Flink; 46 | while (entry != &MmpGlobalDataPtr->MmpTls->MmpTlsList) { 47 | 48 | auto p = CONTAINING_RECORD(entry, TLS_ENTRY, TlsEntryLinks); 49 | RtlFreeHeap(RtlProcessHeap(), 0, TlspMmpBlock[p->TlsDirectory.Characteristics]); 50 | 51 | entry = entry->Flink; 52 | } 53 | 54 | RtlFreeHeap(RtlProcessHeap(), 0, CONTAINING_RECORD(iter->lpTlsRecord->TlspLdrBlock, TLS_VECTOR, TLS_VECTOR::ModuleTlsData)); 55 | RtlFreeHeap(RtlProcessHeap(), 0, iter->lpTlsRecord); 56 | RtlFreeHeap(RtlProcessHeap(), 0, iter->lpOldTlsVector); 57 | 58 | RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock); 59 | 60 | CloseHandle(iter->hThread); 61 | iter = MmpPostponedTlsList->erase(iter); 62 | } 63 | 64 | } 65 | 66 | waitTime = MmpPostponedTlsList->empty() ? INFINITE : 1000; 67 | } 68 | else { 69 | LeaveCriticalSection(&MmpPostponedTlsLock); 70 | break; 71 | } 72 | 73 | LeaveCriticalSection(&MmpPostponedTlsLock); 74 | } 75 | 76 | return 0; 77 | } 78 | 79 | DWORD WINAPI MmpReleasePostponedTlsWorker_Wrap(PVOID) { 80 | __try { 81 | return MmpReleasePostponedTlsWorker(nullptr); 82 | } 83 | __except (EXCEPTION_EXECUTE_HANDLER) { 84 | return 0; 85 | } 86 | } 87 | 88 | VOID WINAPI MmpQueuePostponedTls(PMMP_TLSP_RECORD record) { 89 | MMP_POSTPONED_TLS item; 90 | 91 | item.hThread = OpenThread( 92 | THREAD_QUERY_INFORMATION, 93 | FALSE, 94 | (DWORD)(ULONG_PTR)NtCurrentThreadId() 95 | ); 96 | 97 | item.lpOldTlsVector = MmpAllocateTlsp(); 98 | assert(item.lpOldTlsVector); 99 | 100 | item.lpTlsRecord = record; 101 | 102 | RtlCopyMemory( 103 | item.lpOldTlsVector->ModuleTlsData, 104 | record->TlspMmpBlock, 105 | sizeof(PVOID) * MMP_MAXIMUM_TLS_INDEX 106 | ); 107 | 108 | EnterCriticalSection(&MmpPostponedTlsLock); 109 | 110 | if (MmpPostponedTlsList) { 111 | MmpPostponedTlsList->push_back(item); 112 | SetEvent(MmpPostponedTlsEvent); 113 | } 114 | else { 115 | RtlFreeHeap(RtlProcessHeap(), 0, item.lpOldTlsVector); 116 | } 117 | 118 | LeaveCriticalSection(&MmpPostponedTlsLock); 119 | } 120 | 121 | VOID OnExit() { 122 | EnterCriticalSection(&MmpPostponedTlsLock); 123 | 124 | MmpPostponedTlsList->~vector(); 125 | HeapFree(RtlProcessHeap(), 0, MmpPostponedTlsList); 126 | MmpPostponedTlsList = nullptr; 127 | 128 | CloseHandle(MmpPostponedTlsEvent); 129 | 130 | LeaveCriticalSection(&MmpPostponedTlsLock); 131 | } 132 | 133 | VOID MmpTlsFiberInitialize() { 134 | InitializeCriticalSection(&MmpPostponedTlsLock); 135 | MmpPostponedTlsEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); 136 | MmpPostponedTlsList = new(HeapAlloc(GetProcessHeap(), 0, sizeof(std::vector))) std::vector(); 137 | 138 | atexit(OnExit); 139 | 140 | CreateThread(nullptr, 0, MmpReleasePostponedTlsWorker_Wrap, nullptr, 0, nullptr); 141 | } 142 | -------------------------------------------------------------------------------- /3rdparty/phnt/include/ntkeapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Kernel executive support library 3 | * 4 | * This file is part of System Informer. 5 | */ 6 | 7 | #ifndef _NTKEAPI_H 8 | #define _NTKEAPI_H 9 | 10 | #if (PHNT_MODE != PHNT_MODE_KERNEL) 11 | #define LOW_PRIORITY 0 // Lowest thread priority level 12 | #define LOW_REALTIME_PRIORITY 16 // Lowest realtime priority level 13 | #define HIGH_PRIORITY 31 // Highest thread priority level 14 | #define MAXIMUM_PRIORITY 32 // Number of thread priority levels 15 | #endif 16 | 17 | typedef enum _KTHREAD_STATE 18 | { 19 | Initialized, 20 | Ready, 21 | Running, 22 | Standby, 23 | Terminated, 24 | Waiting, 25 | Transition, 26 | DeferredReady, 27 | GateWaitObsolete, 28 | WaitingForProcessInSwap, 29 | MaximumThreadState 30 | } KTHREAD_STATE, *PKTHREAD_STATE; 31 | 32 | // private 33 | typedef enum _KHETERO_CPU_POLICY 34 | { 35 | KHeteroCpuPolicyAll = 0, 36 | KHeteroCpuPolicyLarge = 1, 37 | KHeteroCpuPolicyLargeOrIdle = 2, 38 | KHeteroCpuPolicySmall = 3, 39 | KHeteroCpuPolicySmallOrIdle = 4, 40 | KHeteroCpuPolicyDynamic = 5, 41 | KHeteroCpuPolicyStaticMax = 5, // valid 42 | KHeteroCpuPolicyBiasedSmall = 6, 43 | KHeteroCpuPolicyBiasedLarge = 7, 44 | KHeteroCpuPolicyDefault = 8, 45 | KHeteroCpuPolicyMax = 9 46 | } KHETERO_CPU_POLICY, *PKHETERO_CPU_POLICY; 47 | 48 | #if (PHNT_MODE != PHNT_MODE_KERNEL) 49 | 50 | typedef enum _KWAIT_REASON 51 | { 52 | Executive, 53 | FreePage, 54 | PageIn, 55 | PoolAllocation, 56 | DelayExecution, 57 | Suspended, 58 | UserRequest, 59 | WrExecutive, 60 | WrFreePage, 61 | WrPageIn, 62 | WrPoolAllocation, 63 | WrDelayExecution, 64 | WrSuspended, 65 | WrUserRequest, 66 | WrEventPair, 67 | WrQueue, 68 | WrLpcReceive, 69 | WrLpcReply, 70 | WrVirtualMemory, 71 | WrPageOut, 72 | WrRendezvous, 73 | WrKeyedEvent, 74 | WrTerminated, 75 | WrProcessInSwap, 76 | WrCpuRateControl, 77 | WrCalloutStack, 78 | WrKernel, 79 | WrResource, 80 | WrPushLock, 81 | WrMutex, 82 | WrQuantumEnd, 83 | WrDispatchInt, 84 | WrPreempted, 85 | WrYieldExecution, 86 | WrFastMutex, 87 | WrGuardedMutex, 88 | WrRundown, 89 | WrAlertByThreadId, 90 | WrDeferredPreempt, 91 | WrPhysicalFault, 92 | WrIoRing, 93 | WrMdlCache, 94 | MaximumWaitReason 95 | } KWAIT_REASON, *PKWAIT_REASON; 96 | 97 | typedef enum _KPROFILE_SOURCE 98 | { 99 | ProfileTime, 100 | ProfileAlignmentFixup, 101 | ProfileTotalIssues, 102 | ProfilePipelineDry, 103 | ProfileLoadInstructions, 104 | ProfilePipelineFrozen, 105 | ProfileBranchInstructions, 106 | ProfileTotalNonissues, 107 | ProfileDcacheMisses, 108 | ProfileIcacheMisses, 109 | ProfileCacheMisses, 110 | ProfileBranchMispredictions, 111 | ProfileStoreInstructions, 112 | ProfileFpInstructions, 113 | ProfileIntegerInstructions, 114 | Profile2Issue, 115 | Profile3Issue, 116 | Profile4Issue, 117 | ProfileSpecialInstructions, 118 | ProfileTotalCycles, 119 | ProfileIcacheIssues, 120 | ProfileDcacheAccesses, 121 | ProfileMemoryBarrierCycles, 122 | ProfileLoadLinkedIssues, 123 | ProfileMaximum 124 | } KPROFILE_SOURCE; 125 | 126 | #endif 127 | 128 | #if (PHNT_MODE != PHNT_MODE_KERNEL) 129 | 130 | NTSYSCALLAPI 131 | NTSTATUS 132 | NTAPI 133 | NtCallbackReturn( 134 | _In_reads_bytes_opt_(OutputLength) PVOID OutputBuffer, 135 | _In_ ULONG OutputLength, 136 | _In_ NTSTATUS Status 137 | ); 138 | 139 | #if (PHNT_VERSION >= PHNT_VISTA) 140 | NTSYSCALLAPI 141 | VOID 142 | NTAPI 143 | NtFlushProcessWriteBuffers( 144 | VOID 145 | ); 146 | #endif 147 | 148 | NTSYSCALLAPI 149 | NTSTATUS 150 | NTAPI 151 | NtQueryDebugFilterState( 152 | _In_ ULONG ComponentId, 153 | _In_ ULONG Level 154 | ); 155 | 156 | NTSYSCALLAPI 157 | NTSTATUS 158 | NTAPI 159 | NtSetDebugFilterState( 160 | _In_ ULONG ComponentId, 161 | _In_ ULONG Level, 162 | _In_ BOOLEAN State 163 | ); 164 | 165 | NTSYSCALLAPI 166 | NTSTATUS 167 | NTAPI 168 | NtYieldExecution( 169 | VOID 170 | ); 171 | 172 | #endif 173 | 174 | #endif 175 | -------------------------------------------------------------------------------- /test/test.cpp: -------------------------------------------------------------------------------- 1 | #include "../MemoryModule/stdafx.h" 2 | #include "../MemoryModule/LoadDllMemoryApi.h" 3 | #include 4 | #pragma comment(lib,"ntdll.lib") 5 | 6 | static void DisplayStatus() { 7 | printf( 8 | "\ 9 | MemoryModulePP [Version %d.%d%s]\n\n\t\ 10 | MmpFeatures = %08X\n\n\t\ 11 | LdrpModuleBaseAddressIndex = %p\n\t\ 12 | NtdllLdrEntry = %p\n\t\ 13 | RtlRbInsertNodeEx = %p\n\t\ 14 | RtlRbRemoveNode = %p\n\n\t\ 15 | LdrpInvertedFunctionTable = %p\n\n\t\ 16 | LdrpHashTable = %p\n\n\ 17 | ", 18 | MmpGlobalDataPtr->MajorVersion, 19 | MEMORY_MODULE_GET_MINOR_VERSION(MmpGlobalDataPtr->MinorVersion), 20 | MEMORY_MODULE_IS_PREVIEW(MmpGlobalDataPtr->MinorVersion) ? " Preview" : "", 21 | MmpGlobalDataPtr->MmpFeatures, 22 | MmpGlobalDataPtr->MmpBaseAddressIndex->LdrpModuleBaseAddressIndex, 23 | MmpGlobalDataPtr->MmpBaseAddressIndex->NtdllLdrEntry, 24 | MmpGlobalDataPtr->MmpBaseAddressIndex->_RtlRbInsertNodeEx, 25 | MmpGlobalDataPtr->MmpBaseAddressIndex->_RtlRbRemoveNode, 26 | MmpGlobalDataPtr->MmpInvertedFunctionTable->LdrpInvertedFunctionTable, 27 | MmpGlobalDataPtr->MmpLdrEntry->LdrpHashTable 28 | ); 29 | } 30 | 31 | static PVOID ReadDllFile(LPCSTR FileName) { 32 | LPVOID buffer; 33 | size_t size; 34 | FILE* f; 35 | fopen_s(&f, FileName, "rb"); 36 | if (!f)return 0; 37 | _fseeki64(f, 0, SEEK_END); 38 | if (!(size = _ftelli64(f))) { 39 | fclose(f); 40 | return 0; 41 | } 42 | _fseeki64(f, 0, SEEK_SET); 43 | 44 | buffer = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 45 | 46 | fread(buffer, 1, size, f); 47 | fclose(f); 48 | return buffer; 49 | } 50 | 51 | PVOID ReadDllFile2(LPCSTR FileName) { 52 | CHAR path[MAX_PATH + 4]; 53 | DWORD len = GetModuleFileNameA(nullptr, path, sizeof(path)); 54 | 55 | if (len) { 56 | while (len && path[len] != '\\') --len; 57 | 58 | if (len) { 59 | strcpy_s(&path[len + 1], sizeof(path) - len - 1, FileName); 60 | return ReadDllFile(path); 61 | } 62 | } 63 | 64 | return nullptr; 65 | } 66 | 67 | int test() { 68 | LPVOID buffer = ReadDllFile2("a.dll"); 69 | 70 | HMODULE hModule = nullptr; 71 | FARPROC pfn = nullptr; 72 | 73 | typedef int(*_exception)(int code); 74 | _exception exception = nullptr; 75 | HRSRC hRsrc; 76 | DWORD SizeofRes; 77 | HGLOBAL gRes; 78 | char str[10]; 79 | 80 | if (!NT_SUCCESS(LdrLoadDllMemoryExW(&hModule, nullptr, 0, buffer, 0, L"kernel64", nullptr))) goto end; 81 | 82 | //forward export 83 | pfn = (decltype(pfn))(GetProcAddress(hModule, "Socket")); //ws2_32.WSASocketW 84 | pfn = (decltype(pfn))(GetProcAddress(hModule, "VerifyTruse")); //wintrust.WinVerifyTrust 85 | 86 | //exception 87 | exception = (_exception)GetProcAddress(hModule, "exception"); 88 | if (exception) { 89 | for (int i = 0; i < 5; ++i)exception(i); 90 | } 91 | 92 | //tls 93 | pfn = GetProcAddress(hModule, "thread"); 94 | if (pfn && pfn()) { 95 | printf("thread test failed.\n"); 96 | } 97 | 98 | //resource 99 | if (!LoadStringA(hModule, 101, str, 10)) { 100 | printf("load string failed.\n"); 101 | } 102 | else { 103 | printf("%s\n", str); 104 | } 105 | if (!(hRsrc = FindResourceA(hModule, MAKEINTRESOURCEA(102), "BINARY"))) { 106 | printf("find binary resource failed.\n"); 107 | } 108 | else { 109 | if ((SizeofRes = SizeofResource(hModule, hRsrc)) != 0x10) { 110 | printf("invalid res size.\n"); 111 | } 112 | else { 113 | if (!(gRes = LoadResource(hModule, hRsrc))) { 114 | printf("load res failed.\n"); 115 | } 116 | else { 117 | if (!LockResource(gRes))printf("lock res failed.\n"); 118 | else { 119 | printf("resource test success.\n"); 120 | } 121 | } 122 | } 123 | } 124 | 125 | end: 126 | LdrUnloadDllMemory(hModule); 127 | VirtualFree(buffer, 0, MEM_RELEASE); 128 | return 0; 129 | } 130 | 131 | int main() { 132 | 133 | DisplayStatus(); 134 | 135 | test(); 136 | 137 | return 0; 138 | } 139 | -------------------------------------------------------------------------------- /MemoryModule/MmpGlobalData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //BaseAddressIndex.cpp 4 | typedef struct _MMP_BASE_ADDRESS_INDEX_DATA { 5 | PRTL_RB_TREE LdrpModuleBaseAddressIndex; 6 | PLDR_DATA_TABLE_ENTRY NtdllLdrEntry; 7 | 8 | PVOID _RtlRbInsertNodeEx; 9 | PVOID _RtlRbRemoveNode; 10 | }MMP_BASE_ADDRESS_INDEX_DATA, * PMMP_BASE_ADDRESS_INDEX_DATA; 11 | 12 | //InvertedFunctionTable.cpp 13 | typedef struct _MMP_INVERTED_FUNCTION_TABLE_DATA { 14 | PVOID LdrpInvertedFunctionTable; 15 | }MMP_INVERTED_FUNCTION_TABLE_DATA, * PMMP_INVERTED_FUNCTION_TABLE_DATA; 16 | 17 | //LdrEntry.cpp 18 | typedef struct _MMP_LDR_ENTRY_DATA { 19 | PLIST_ENTRY LdrpHashTable; 20 | }MMP_LDR_ENTRY_DATA, * PMMP_LDR_ENTRY_DATA; 21 | 22 | //MmpTls.cpp 23 | typedef struct _MMP_TLS_DATA { 24 | LIST_ENTRY MmpTlsList; 25 | RTL_BITMAP MmpTlsBitmap; 26 | SRWLOCK MmpTlsListLock; 27 | CRITICAL_SECTION MmpTlspLock; 28 | LIST_ENTRY MmpThreadLocalStoragePointer; 29 | DWORD MmpActiveThreadCount; 30 | 31 | struct { 32 | PVOID HookReserved1; 33 | PVOID HookReserved2; 34 | decltype(&NtSetInformationProcess) OriginNtSetInformationProcess; 35 | decltype(&LdrShutdownThread) OriginLdrShutdownThread; 36 | decltype(&RtlUserThreadStart) OriginRtlUserThreadStart; 37 | }Hooks; 38 | }MMP_TLS_DATA, * PMMP_TLS_DATA; 39 | 40 | //MmpDotNet.cpp 41 | typedef struct _MMP_DOT_NET_DATA { 42 | FILETIME AssemblyTimes; 43 | 44 | CRITICAL_SECTION MmpFakeHandleListLock; 45 | LIST_ENTRY MmpFakeHandleListHead; 46 | 47 | BOOLEAN PreHooked; 48 | BOOLEAN Initialized; 49 | 50 | struct { 51 | decltype(&CreateFileW) OriginCreateFileW; 52 | decltype(&GetFileInformationByHandle) OriginGetFileInformationByHandle; 53 | decltype(&GetFileAttributesExW) OriginGetFileAttributesExW; 54 | decltype(&GetFileSize) OriginGetFileSize; 55 | decltype(&GetFileSizeEx) OriginGetFileSizeEx; 56 | decltype(&CreateFileMappingW) OriginCreateFileMappingW; 57 | decltype(&MapViewOfFileEx) OriginMapViewOfFileEx; 58 | decltype(&MapViewOfFile) OriginMapViewOfFile; 59 | decltype(&UnmapViewOfFile)OriginUnmapViewOfFile; 60 | decltype(&CloseHandle)OriginCloseHandle; 61 | GetFileVersion_T OriginGetFileVersion1; 62 | GetFileVersion_T OriginGetFileVersion2; 63 | }Hooks; 64 | }MMP_DOT_NET_DATA, * PMMP_DOT_NET_DATA; 65 | 66 | typedef struct _MMP_FUNCTIONS { 67 | decltype(&LdrLoadDllMemoryExW) _LdrLoadDllMemoryExW; 68 | decltype(&LdrUnloadDllMemory) _LdrUnloadDllMemory; 69 | decltype(&LdrUnloadDllMemoryAndExitThread) _LdrUnloadDllMemoryAndExitThread; 70 | 71 | decltype(&MmpHandleTlsData) _MmpHandleTlsData; 72 | decltype(&MmpReleaseTlsEntry) _MmpReleaseTlsEntry; 73 | }MMP_FUNCTIONS, * PMMP_FUNCTIONS; 74 | 75 | //ImportTable.cpp 76 | typedef struct _MMP_IAT_DATA { 77 | 78 | LIST_ENTRY MmpIatResolverList; 79 | CRITICAL_SECTION MmpIatResolverListLock; 80 | MM_IAT_RESOLVER MmpIatResolverHead; 81 | 82 | }MMP_IAT_DATA, * PMMP_IAT_DATA; 83 | 84 | typedef enum class _WINDOWS_VERSION :BYTE { 85 | null, 86 | xp, 87 | vista, 88 | win7, 89 | win8, 90 | winBlue, 91 | win10, 92 | win10_1, 93 | win10_2, 94 | win11, 95 | invalid 96 | }WINDOWS_VERSION; 97 | 98 | #define MEMORY_MODULE_MAKE_PREVIEW(MinorVersion) (0x8000|(MinorVersion)) 99 | #define MEMORY_MODULE_IS_PREVIEW(MinorVersion) (!!(0x8000&(MinorVersion))) 100 | #define MEMORY_MODULE_GET_MINOR_VERSION(MinorVersion) (~0x8000&(MinorVersion)) 101 | 102 | #define MEMORY_MODULE_MAJOR_VERSION 2 103 | #define MEMORY_MODULE_MINOR_VERSION MEMORY_MODULE_MAKE_PREVIEW(2) 104 | 105 | typedef struct _MMP_GLOBAL_DATA { 106 | 107 | WORD MajorVersion; 108 | WORD MinorVersion; 109 | 110 | DWORD MmpFeatures; 111 | 112 | struct { 113 | DWORD MajorVersion; 114 | DWORD MinorVersion; 115 | DWORD BuildNumber; 116 | }NtVersions; 117 | 118 | WINDOWS_VERSION WindowsVersion; 119 | 120 | WORD LdrDataTableEntrySize; 121 | 122 | SYSTEM_INFO SystemInfo; 123 | 124 | PMMP_BASE_ADDRESS_INDEX_DATA MmpBaseAddressIndex; 125 | 126 | PMMP_INVERTED_FUNCTION_TABLE_DATA MmpInvertedFunctionTable; 127 | 128 | PMMP_LDR_ENTRY_DATA MmpLdrEntry; 129 | 130 | PMMP_TLS_DATA MmpTls; 131 | 132 | PMMP_DOT_NET_DATA MmpDotNet; 133 | 134 | PVOID BaseAddress; 135 | 136 | PMMP_FUNCTIONS MmpFunctions; 137 | 138 | PMMP_IAT_DATA MmpIat; 139 | 140 | DWORD ReferenceCount; 141 | 142 | }MMP_GLOBAL_DATA, * PMMP_GLOBAL_DATA; 143 | 144 | #define MMP_GLOBAL_DATA_SIZE (\ 145 | sizeof(MMP_GLOBAL_DATA) + \ 146 | sizeof(MMP_BASE_ADDRESS_INDEX_DATA) + \ 147 | sizeof(MMP_INVERTED_FUNCTION_TABLE_DATA) + \ 148 | sizeof(MMP_LDR_ENTRY_DATA) + \ 149 | sizeof(MMP_TLS_DATA) + \ 150 | sizeof(MMP_DOT_NET_DATA) + \ 151 | sizeof(MMP_FUNCTIONS) + \ 152 | sizeof(PMMP_IAT_DATA)\ 153 | ) 154 | 155 | extern PMMP_GLOBAL_DATA MmpGlobalDataPtr; 156 | -------------------------------------------------------------------------------- /3rdparty/phnt/include/ntgdi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Graphics device interface support 3 | * 4 | * This file is part of System Informer. 5 | */ 6 | 7 | #ifndef _NTGDI_H 8 | #define _NTGDI_H 9 | 10 | #define GDI_MAX_HANDLE_COUNT 0xFFFF // 0x4000 11 | 12 | #define GDI_HANDLE_INDEX_SHIFT 0 13 | #define GDI_HANDLE_INDEX_BITS 16 14 | #define GDI_HANDLE_INDEX_MASK 0xffff 15 | 16 | #define GDI_HANDLE_TYPE_SHIFT 16 17 | #define GDI_HANDLE_TYPE_BITS 5 18 | #define GDI_HANDLE_TYPE_MASK 0x1f 19 | 20 | #define GDI_HANDLE_ALTTYPE_SHIFT 21 21 | #define GDI_HANDLE_ALTTYPE_BITS 2 22 | #define GDI_HANDLE_ALTTYPE_MASK 0x3 23 | 24 | #define GDI_HANDLE_STOCK_SHIFT 23 25 | #define GDI_HANDLE_STOCK_BITS 1 26 | #define GDI_HANDLE_STOCK_MASK 0x1 27 | 28 | #define GDI_HANDLE_UNIQUE_SHIFT 24 29 | #define GDI_HANDLE_UNIQUE_BITS 8 30 | #define GDI_HANDLE_UNIQUE_MASK 0xff 31 | 32 | #define GDI_HANDLE_INDEX(Handle) ((ULONG)(Handle) & GDI_HANDLE_INDEX_MASK) 33 | #define GDI_HANDLE_TYPE(Handle) (((ULONG)(Handle) >> GDI_HANDLE_TYPE_SHIFT) & GDI_HANDLE_TYPE_MASK) 34 | #define GDI_HANDLE_ALTTYPE(Handle) (((ULONG)(Handle) >> GDI_HANDLE_ALTTYPE_SHIFT) & GDI_HANDLE_ALTTYPE_MASK) 35 | #define GDI_HANDLE_STOCK(Handle) (((ULONG)(Handle) >> GDI_HANDLE_STOCK_SHIFT)) & GDI_HANDLE_STOCK_MASK) 36 | 37 | #define GDI_MAKE_HANDLE(Index, Unique) ((ULONG)(((ULONG)(Unique) << GDI_HANDLE_INDEX_BITS) | (ULONG)(Index))) 38 | 39 | // GDI server-side types 40 | 41 | #define GDI_DEF_TYPE 0 // invalid handle 42 | #define GDI_DC_TYPE 1 43 | #define GDI_DD_DIRECTDRAW_TYPE 2 44 | #define GDI_DD_SURFACE_TYPE 3 45 | #define GDI_RGN_TYPE 4 46 | #define GDI_SURF_TYPE 5 47 | #define GDI_CLIENTOBJ_TYPE 6 48 | #define GDI_PATH_TYPE 7 49 | #define GDI_PAL_TYPE 8 50 | #define GDI_ICMLCS_TYPE 9 51 | #define GDI_LFONT_TYPE 10 52 | #define GDI_RFONT_TYPE 11 53 | #define GDI_PFE_TYPE 12 54 | #define GDI_PFT_TYPE 13 55 | #define GDI_ICMCXF_TYPE 14 56 | #define GDI_ICMDLL_TYPE 15 57 | #define GDI_BRUSH_TYPE 16 58 | #define GDI_PFF_TYPE 17 // unused 59 | #define GDI_CACHE_TYPE 18 // unused 60 | #define GDI_SPACE_TYPE 19 61 | #define GDI_DBRUSH_TYPE 20 // unused 62 | #define GDI_META_TYPE 21 63 | #define GDI_EFSTATE_TYPE 22 64 | #define GDI_BMFD_TYPE 23 // unused 65 | #define GDI_VTFD_TYPE 24 // unused 66 | #define GDI_TTFD_TYPE 25 // unused 67 | #define GDI_RC_TYPE 26 // unused 68 | #define GDI_TEMP_TYPE 27 // unused 69 | #define GDI_DRVOBJ_TYPE 28 70 | #define GDI_DCIOBJ_TYPE 29 // unused 71 | #define GDI_SPOOL_TYPE 30 72 | 73 | // GDI client-side types 74 | 75 | #define GDI_CLIENT_TYPE_FROM_HANDLE(Handle) ((ULONG)(Handle) & ((GDI_HANDLE_ALTTYPE_MASK << GDI_HANDLE_ALTTYPE_SHIFT) | \ 76 | (GDI_HANDLE_TYPE_MASK << GDI_HANDLE_TYPE_SHIFT))) 77 | #define GDI_CLIENT_TYPE_FROM_UNIQUE(Unique) GDI_CLIENT_TYPE_FROM_HANDLE((ULONG)(Unique) << 16) 78 | 79 | #define GDI_ALTTYPE_1 (1 << GDI_HANDLE_ALTTYPE_SHIFT) 80 | #define GDI_ALTTYPE_2 (2 << GDI_HANDLE_ALTTYPE_SHIFT) 81 | #define GDI_ALTTYPE_3 (3 << GDI_HANDLE_ALTTYPE_SHIFT) 82 | 83 | #define GDI_CLIENT_BITMAP_TYPE (GDI_SURF_TYPE << GDI_HANDLE_TYPE_SHIFT) 84 | #define GDI_CLIENT_BRUSH_TYPE (GDI_BRUSH_TYPE << GDI_HANDLE_TYPE_SHIFT) 85 | #define GDI_CLIENT_CLIENTOBJ_TYPE (GDI_CLIENTOBJ_TYPE << GDI_HANDLE_TYPE_SHIFT) 86 | #define GDI_CLIENT_DC_TYPE (GDI_DC_TYPE << GDI_HANDLE_TYPE_SHIFT) 87 | #define GDI_CLIENT_FONT_TYPE (GDI_LFONT_TYPE << GDI_HANDLE_TYPE_SHIFT) 88 | #define GDI_CLIENT_PALETTE_TYPE (GDI_PAL_TYPE << GDI_HANDLE_TYPE_SHIFT) 89 | #define GDI_CLIENT_REGION_TYPE (GDI_RGN_TYPE << GDI_HANDLE_TYPE_SHIFT) 90 | 91 | #define GDI_CLIENT_ALTDC_TYPE (GDI_CLIENT_DC_TYPE | GDI_ALTTYPE_1) 92 | #define GDI_CLIENT_DIBSECTION_TYPE (GDI_CLIENT_BITMAP_TYPE | GDI_ALTTYPE_1) 93 | #define GDI_CLIENT_EXTPEN_TYPE (GDI_CLIENT_BRUSH_TYPE | GDI_ALTTYPE_2) 94 | #define GDI_CLIENT_METADC16_TYPE (GDI_CLIENT_CLIENTOBJ_TYPE | GDI_ALTTYPE_3) 95 | #define GDI_CLIENT_METAFILE_TYPE (GDI_CLIENT_CLIENTOBJ_TYPE | GDI_ALTTYPE_2) 96 | #define GDI_CLIENT_METAFILE16_TYPE (GDI_CLIENT_CLIENTOBJ_TYPE | GDI_ALTTYPE_1) 97 | #define GDI_CLIENT_PEN_TYPE (GDI_CLIENT_BRUSH_TYPE | GDI_ALTTYPE_1) 98 | 99 | typedef struct _GDI_HANDLE_ENTRY 100 | { 101 | union 102 | { 103 | PVOID Object; 104 | PVOID NextFree; 105 | }; 106 | union 107 | { 108 | struct 109 | { 110 | USHORT ProcessId; 111 | USHORT Lock : 1; 112 | USHORT Count : 15; 113 | }; 114 | ULONG Value; 115 | } Owner; 116 | USHORT Unique; 117 | UCHAR Type; 118 | UCHAR Flags; 119 | PVOID UserPointer; 120 | } GDI_HANDLE_ENTRY, *PGDI_HANDLE_ENTRY; 121 | 122 | typedef struct _GDI_SHARED_MEMORY 123 | { 124 | GDI_HANDLE_ENTRY Handles[GDI_MAX_HANDLE_COUNT]; 125 | } GDI_SHARED_MEMORY, *PGDI_SHARED_MEMORY; 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /MemoryModulePP.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.7.34202.233 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MemoryModule", "MemoryModule\MemoryModule.vcxproj", "{5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test\test.vcxproj", "{5B3131BA-178A-4A28-BD54-315A45C97ED1}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "a", "a\a.vcxproj", "{DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|ARM = Debug|ARM 15 | Debug|ARM64 = Debug|ARM64 16 | Debug|x64 = Debug|x64 17 | Debug|x86 = Debug|x86 18 | Release|ARM = Release|ARM 19 | Release|ARM64 = Release|ARM64 20 | Release|x64 = Release|x64 21 | Release|x86 = Release|x86 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|ARM.ActiveCfg = Debug|ARM 25 | {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|ARM.Build.0 = Debug|ARM 26 | {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|ARM64.ActiveCfg = Debug|ARM64 27 | {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|ARM64.Build.0 = Debug|ARM64 28 | {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x64.ActiveCfg = Debug|x64 29 | {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x64.Build.0 = Debug|x64 30 | {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.ActiveCfg = Debug|Win32 31 | {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.Build.0 = Debug|Win32 32 | {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|ARM.ActiveCfg = Release|ARM 33 | {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|ARM.Build.0 = Release|ARM 34 | {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|ARM64.ActiveCfg = Release|ARM64 35 | {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|ARM64.Build.0 = Release|ARM64 36 | {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x64.ActiveCfg = Release|x64 37 | {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x64.Build.0 = Release|x64 38 | {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.ActiveCfg = Release|Win32 39 | {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.Build.0 = Release|Win32 40 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|ARM.ActiveCfg = Debug|ARM 41 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|ARM.Build.0 = Debug|ARM 42 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|ARM64.ActiveCfg = Debug|ARM64 43 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|ARM64.Build.0 = Debug|ARM64 44 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x64.ActiveCfg = Debug|x64 45 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x64.Build.0 = Debug|x64 46 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x64.Deploy.0 = Debug|x64 47 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x86.ActiveCfg = Debug|Win32 48 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x86.Build.0 = Debug|Win32 49 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x86.Deploy.0 = Debug|Win32 50 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|ARM.ActiveCfg = Release|ARM 51 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|ARM.Build.0 = Release|ARM 52 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|ARM64.ActiveCfg = Release|ARM64 53 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|ARM64.Build.0 = Release|ARM64 54 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|x64.ActiveCfg = Release|x64 55 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|x64.Build.0 = Release|x64 56 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|x86.ActiveCfg = Release|Win32 57 | {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Release|x86.Build.0 = Release|Win32 58 | {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|ARM.ActiveCfg = Debug|ARM 59 | {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|ARM.Build.0 = Debug|ARM 60 | {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|ARM64.ActiveCfg = Debug|ARM64 61 | {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|ARM64.Build.0 = Debug|ARM64 62 | {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|x64.ActiveCfg = Debug|x64 63 | {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|x64.Build.0 = Debug|x64 64 | {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|x86.ActiveCfg = Debug|Win32 65 | {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Debug|x86.Build.0 = Debug|Win32 66 | {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|ARM.ActiveCfg = Release|ARM 67 | {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|ARM.Build.0 = Release|ARM 68 | {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|ARM64.ActiveCfg = Release|ARM64 69 | {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|ARM64.Build.0 = Release|ARM64 70 | {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|x64.ActiveCfg = Release|x64 71 | {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|x64.Build.0 = Release|x64 72 | {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|x86.ActiveCfg = Release|Win32 73 | {DA79C619-BDAC-4CF1-A38C-B1F5E05F4485}.Release|x86.Build.0 = Release|Win32 74 | EndGlobalSection 75 | GlobalSection(SolutionProperties) = preSolution 76 | HideSolutionNode = FALSE 77 | EndGlobalSection 78 | GlobalSection(ExtensibilityGlobals) = postSolution 79 | SolutionGuid = {B19B9539-E26D-4C78-883F-3AF74BD46D3A} 80 | EndGlobalSection 81 | EndGlobal 82 | -------------------------------------------------------------------------------- /3rdparty/Detours/CREDITS.md: -------------------------------------------------------------------------------- 1 | # Detours Contributor Credits 2 | 3 | The following individuals have helped identify specific bugs and improvements 4 | in Detours. The entire Detours community has benefited from their help. 5 | 6 | * Jay Krell: Identified error in DetourFindPayload that caused a 7 | incorrect failure when pcbData is NULL. (Build_342) 8 | 9 | * Jay Krell: Identified issue with VirtualSize == 0 files created in 10 | NT 3.1 images. (Build_339) 11 | 12 | * Igor Odnovorov: Identified an issue with the placement of the trampoline 13 | region when a function is detoured twice and the second 14 | trampoline region is outside of the +/- 2GB range of 15 | the target. (Build_337) 16 | 17 | * Jay Krell: Identified need for some programs to enumerate the 18 | address of IAT entries. (Build_336) 19 | 20 | * Calvin Hsia: Identified need for some program to change the excluded 21 | system region. (Build_336) 22 | 23 | * Adam Smith: Identified error in failure handling when VirtualProect 24 | cannot make pages executable because the Prohibit 25 | Dynamic Code Generation mitigation policy has been 26 | applied to a process. (Build_335) 27 | 28 | * Ben Faull: Identified fix to detour_alloc_region_from_lo and 29 | detour_alloc_region_from_hi that preserves ASLR entropy. 30 | (Build_334) 31 | 32 | * Shaoxiang Su: Reported errors building with Visual Studio 2015. 33 | (Build_332) 34 | 35 | * Jay Krell: Identified and resolved significant gaps in the X86, X64 36 | and IA64 disassemblers for instruction found in code, 37 | but seldom found in function prologues. (Build_331) 38 | 39 | * Allan Murphy: Identify error in rep and jmp ds: encodings. (Build_331) 40 | 41 | * Philip Bacon: Identified incorrect entry point return for pure 42 | resource-only binaries. (Build_330) 43 | 44 | * Jay Krell: Identified failure in DetourAttachEx to update nAlign. 45 | (Build_330) 46 | 47 | * Sumit Sarin: Helped debug error with packed binaries. 48 | (Build_329) 49 | 50 | * Nitya Kumar Sharma: Reported bug in DetourAfterWithDll for 32/64 agnostic 51 | EXEs. 52 | (Build_327) 53 | 54 | * Richard Black: Identified a large number of typos in documentation. 55 | (Build_326) 56 | 57 | * Michael Bilodeau: Identified bug in DetourUpdateProcessWithDll when the 58 | target process contains a Detours payload *after* all 59 | valid PE binaries. 60 | (Build_324) 61 | 62 | * Meera Jindal: Reported bug in identification of target address in 63 | DetourCopyInstruction for jmp[] and call[] on x86 & x64, 64 | the ff15 and ff25 opcodes. 65 | (Build_323) 66 | 67 | * Ken Johnson: Assistance with SAL 2.0 annotations. 68 | (Build_319) 69 | 70 | * Nick Wood: Identified bug in DetourFindFunction on ARM. 71 | (Build_314) 72 | 73 | * Mark Russinovich: Helped debug DetourCreateProcessWithDllEx. 74 | (Build_314) 75 | 76 | * John Lin: Implementation idea for DetoursCreateProcessWithDllEx. 77 | (Build_314) 78 | 79 | * Andrew Zawadowskiy Reported an improper memory page permissions 80 | vulnerability in Detours 2.1. (Vulnerability does not 81 | exist in versions later than Detours 2.1.) 82 | (Build_223) 83 | 84 | * Nightxie: Identified bug in detour_alloc_round_up_to_region. 85 | (Build_310) 86 | 87 | * Diana Milirud: Identified bug in B* instructions on ARM. 88 | (Build_309) 89 | 90 | * Juan Carlos Identified correct MSIL entry point for unsigned MSIL. 91 | Luciani: (Build_308) 92 | 93 | * Lee Hunt Suggested improvements in algorithm for allocation of 94 | Lawrence Landauer trampoline regions on x64 to avoid collisions with 95 | Joe Laughlin: system DLLs. 96 | (Build_307) 97 | 98 | * Tyler Sims Identified bug in handling of "anycpu" MSIL binaries 99 | Darren Kennedy: on x64. 100 | (Build_307) 101 | 102 | * Andre Vachon: Help with optimized binaries. 103 | (Build 301) 104 | 105 | * Chris Mann: Identified fix not forward ported from 2.2 to 3.0. 106 | (Build_301) 107 | 108 | * Mark Irving: Identified bug with EXEs missing second import table. 109 | (Build_300) 110 | 111 | * Ben Schwarz: Identified bug in handling of multi-byte NOPs. 112 | (Build_300) 113 | 114 | * Aaron Giles Coded initial ARM/Thumb2 disassembler. 115 | Jared Henderson: (Build_300) 116 | 117 | * Doug Brubacher: Coded initial x86 disassembler. 118 | (Build_100) 119 | -------------------------------------------------------------------------------- /3rdparty/phnt/include/ntpnpapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Plug and Play support functions 3 | * 4 | * This file is part of System Informer. 5 | */ 6 | 7 | #ifndef _NTPNPAPI_H 8 | #define _NTPNPAPI_H 9 | 10 | typedef enum _PLUGPLAY_EVENT_CATEGORY 11 | { 12 | HardwareProfileChangeEvent, 13 | TargetDeviceChangeEvent, 14 | DeviceClassChangeEvent, 15 | CustomDeviceEvent, 16 | DeviceInstallEvent, 17 | DeviceArrivalEvent, 18 | PowerEvent, 19 | VetoEvent, 20 | BlockedDriverEvent, 21 | InvalidIDEvent, 22 | MaxPlugEventCategory 23 | } PLUGPLAY_EVENT_CATEGORY, *PPLUGPLAY_EVENT_CATEGORY; 24 | 25 | typedef struct _PLUGPLAY_EVENT_BLOCK 26 | { 27 | GUID EventGuid; 28 | PLUGPLAY_EVENT_CATEGORY EventCategory; 29 | PULONG Result; 30 | ULONG Flags; 31 | ULONG TotalSize; 32 | PVOID DeviceObject; 33 | 34 | union 35 | { 36 | struct 37 | { 38 | GUID ClassGuid; 39 | WCHAR SymbolicLinkName[1]; 40 | } DeviceClass; 41 | struct 42 | { 43 | WCHAR DeviceIds[1]; 44 | } TargetDevice; 45 | struct 46 | { 47 | WCHAR DeviceId[1]; 48 | } InstallDevice; 49 | struct 50 | { 51 | PVOID NotificationStructure; 52 | WCHAR DeviceIds[1]; 53 | } CustomNotification; 54 | struct 55 | { 56 | PVOID Notification; 57 | } ProfileNotification; 58 | struct 59 | { 60 | ULONG NotificationCode; 61 | ULONG NotificationData; 62 | } PowerNotification; 63 | struct 64 | { 65 | PNP_VETO_TYPE VetoType; 66 | WCHAR DeviceIdVetoNameBuffer[1]; // DeviceIdVetoName 67 | } VetoNotification; 68 | struct 69 | { 70 | GUID BlockedDriverGuid; 71 | } BlockedDriverNotification; 72 | struct 73 | { 74 | WCHAR ParentId[1]; 75 | } InvalidIDNotification; 76 | } u; 77 | } PLUGPLAY_EVENT_BLOCK, *PPLUGPLAY_EVENT_BLOCK; 78 | 79 | typedef enum _PLUGPLAY_CONTROL_CLASS 80 | { 81 | PlugPlayControlEnumerateDevice, // PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA 82 | PlugPlayControlRegisterNewDevice, // PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA 83 | PlugPlayControlDeregisterDevice, // PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA 84 | PlugPlayControlInitializeDevice, // PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA 85 | PlugPlayControlStartDevice, // PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA 86 | PlugPlayControlUnlockDevice, // PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA 87 | PlugPlayControlQueryAndRemoveDevice, // PLUGPLAY_CONTROL_QUERY_AND_REMOVE_DATA 88 | PlugPlayControlUserResponse, // PLUGPLAY_CONTROL_USER_RESPONSE_DATA 89 | PlugPlayControlGenerateLegacyDevice, // PLUGPLAY_CONTROL_LEGACY_DEVGEN_DATA 90 | PlugPlayControlGetInterfaceDeviceList, // PLUGPLAY_CONTROL_INTERFACE_LIST_DATA 91 | PlugPlayControlProperty, // PLUGPLAY_CONTROL_PROPERTY_DATA 92 | PlugPlayControlDeviceClassAssociation, // PLUGPLAY_CONTROL_CLASS_ASSOCIATION_DATA 93 | PlugPlayControlGetRelatedDevice, // PLUGPLAY_CONTROL_RELATED_DEVICE_DATA 94 | PlugPlayControlGetInterfaceDeviceAlias, // PLUGPLAY_CONTROL_INTERFACE_ALIAS_DATA 95 | PlugPlayControlDeviceStatus, // PLUGPLAY_CONTROL_STATUS_DATA 96 | PlugPlayControlGetDeviceDepth, // PLUGPLAY_CONTROL_DEPTH_DATA 97 | PlugPlayControlQueryDeviceRelations, // PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA 98 | PlugPlayControlTargetDeviceRelation, // PLUGPLAY_CONTROL_TARGET_RELATION_DATA 99 | PlugPlayControlQueryConflictList, // PLUGPLAY_CONTROL_CONFLICT_LIST 100 | PlugPlayControlRetrieveDock, // PLUGPLAY_CONTROL_RETRIEVE_DOCK_DATA 101 | PlugPlayControlResetDevice, // PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA 102 | PlugPlayControlHaltDevice, // PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA 103 | PlugPlayControlGetBlockedDriverList, // PLUGPLAY_CONTROL_BLOCKED_DRIVER_DATA 104 | PlugPlayControlGetDeviceInterfaceEnabled, // PLUGPLAY_CONTROL_DEVICE_INTERFACE_ENABLED 105 | MaxPlugPlayControl 106 | } PLUGPLAY_CONTROL_CLASS, *PPLUGPLAY_CONTROL_CLASS; 107 | 108 | #if (PHNT_VERSION < PHNT_WIN8) 109 | NTSYSCALLAPI 110 | NTSTATUS 111 | NTAPI 112 | NtGetPlugPlayEvent( 113 | _In_ HANDLE EventHandle, 114 | _In_opt_ PVOID Context, 115 | _Out_writes_bytes_(EventBufferSize) PPLUGPLAY_EVENT_BLOCK EventBlock, 116 | _In_ ULONG EventBufferSize 117 | ); 118 | #endif 119 | 120 | NTSYSCALLAPI 121 | NTSTATUS 122 | NTAPI 123 | NtPlugPlayControl( 124 | _In_ PLUGPLAY_CONTROL_CLASS PnPControlClass, 125 | _Inout_updates_bytes_(PnPControlDataLength) PVOID PnPControlData, 126 | _In_ ULONG PnPControlDataLength 127 | ); 128 | 129 | #if (PHNT_VERSION >= PHNT_WIN7) 130 | 131 | NTSYSCALLAPI 132 | NTSTATUS 133 | NTAPI 134 | NtSerializeBoot( 135 | VOID 136 | ); 137 | 138 | NTSYSCALLAPI 139 | NTSTATUS 140 | NTAPI 141 | NtEnableLastKnownGood( 142 | VOID 143 | ); 144 | 145 | NTSYSCALLAPI 146 | NTSTATUS 147 | NTAPI 148 | NtDisableLastKnownGood( 149 | VOID 150 | ); 151 | 152 | #endif 153 | 154 | #if (PHNT_VERSION >= PHNT_VISTA) 155 | NTSYSCALLAPI 156 | NTSTATUS 157 | NTAPI 158 | NtReplacePartitionUnit( 159 | _In_ PUNICODE_STRING TargetInstancePath, 160 | _In_ PUNICODE_STRING SpareInstancePath, 161 | _In_ ULONG Flags 162 | ); 163 | #endif 164 | 165 | #endif 166 | -------------------------------------------------------------------------------- /MemoryModule/ImportTable.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | typedef struct _MMP_IAT_HANDLE { 4 | 5 | HMODULE hModule; 6 | PMM_IAT_RESOLVER lpResolver; 7 | 8 | }MMP_IAT_HANDLE, * PMMP_IAT_HANDLE; 9 | 10 | HMODULE MmpLoadLibraryA( 11 | _In_ LPCSTR lpModuleName, 12 | _Out_ PMM_IAT_RESOLVER* lpModuleResolver) { 13 | 14 | HMODULE hModule = nullptr; 15 | PMM_IAT_RESOLVER resolver = nullptr; 16 | 17 | EnterCriticalSection(&MmpGlobalDataPtr->MmpIat->MmpIatResolverListLock); 18 | 19 | PLIST_ENTRY lpResolver = MmpGlobalDataPtr->MmpIat->MmpIatResolverList.Flink; 20 | while (lpResolver != &MmpGlobalDataPtr->MmpIat->MmpIatResolverList) { 21 | PMM_IAT_RESOLVER entry = CONTAINING_RECORD(lpResolver, MM_IAT_RESOLVER, MM_IAT_RESOLVER::InMmpIatResolverList); 22 | 23 | hModule = entry->LoadLibraryProv(lpModuleName); 24 | if (hModule) { 25 | resolver = entry; 26 | ++entry->ReferenceCount; 27 | break; 28 | } 29 | 30 | lpResolver = lpResolver->Flink; 31 | } 32 | 33 | LeaveCriticalSection(&MmpGlobalDataPtr->MmpIat->MmpIatResolverListLock); 34 | 35 | *lpModuleResolver = resolver; 36 | return hModule; 37 | } 38 | 39 | VOID MemoryFreeImportTable(_In_ PMEMORYMODULE hMemoryModule) { 40 | 41 | EnterCriticalSection(&MmpGlobalDataPtr->MmpIat->MmpIatResolverListLock); 42 | 43 | PMMP_IAT_HANDLE list = (PMMP_IAT_HANDLE)hMemoryModule->hModulesList; 44 | for (DWORD i = 0; i < hMemoryModule->dwModulesCount; ++i) { 45 | auto entry = list[i]; 46 | entry.lpResolver->FreeLibraryProv(entry.hModule); 47 | --entry.lpResolver->ReferenceCount; 48 | } 49 | 50 | LeaveCriticalSection(&MmpGlobalDataPtr->MmpIat->MmpIatResolverListLock); 51 | 52 | 53 | RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, hMemoryModule->hModulesList); 54 | hMemoryModule->hModulesList = nullptr; 55 | hMemoryModule->dwModulesCount = 0; 56 | } 57 | 58 | NTSTATUS MemoryResolveImportTable( 59 | _In_ LPBYTE base, 60 | _In_ PIMAGE_NT_HEADERS lpNtHeaders, 61 | _In_ PMEMORYMODULE hMemoryModule) { 62 | NTSTATUS status = STATUS_SUCCESS; 63 | PIMAGE_IMPORT_DESCRIPTOR importDesc = nullptr; 64 | DWORD count = 0; 65 | 66 | do { 67 | __try { 68 | PIMAGE_DATA_DIRECTORY dir = &lpNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; 69 | PIMAGE_IMPORT_DESCRIPTOR iat = nullptr; 70 | 71 | if (dir && dir->Size) { 72 | iat = importDesc = PIMAGE_IMPORT_DESCRIPTOR(lpNtHeaders->OptionalHeader.ImageBase + dir->VirtualAddress); 73 | } 74 | 75 | if (iat) { 76 | while (iat->Name) { 77 | ++count; 78 | ++iat; 79 | } 80 | } 81 | 82 | if (importDesc && count) { 83 | PMMP_IAT_HANDLE handles = (PMMP_IAT_HANDLE)RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof(MMP_IAT_HANDLE) * count); 84 | hMemoryModule->hModulesList = handles; 85 | if (!hMemoryModule->hModulesList) { 86 | status = STATUS_NO_MEMORY; 87 | break; 88 | } 89 | 90 | for (DWORD i = 0; i < count; ++i, ++importDesc) { 91 | uintptr_t* thunkRef; 92 | FARPROC* funcRef; 93 | PMM_IAT_RESOLVER resolver; 94 | HMODULE handle = MmpLoadLibraryA((LPCSTR)(base + importDesc->Name), &resolver); 95 | 96 | if (!handle) { 97 | status = STATUS_DLL_NOT_FOUND; 98 | break; 99 | } 100 | 101 | handles[hMemoryModule->dwModulesCount].hModule = handle; 102 | handles[hMemoryModule->dwModulesCount++].lpResolver = resolver; 103 | thunkRef = (uintptr_t*)(base + (importDesc->OriginalFirstThunk ? importDesc->OriginalFirstThunk : importDesc->FirstThunk)); 104 | funcRef = (FARPROC*)(base + importDesc->FirstThunk); 105 | while (*thunkRef) { 106 | *funcRef = GetProcAddress( 107 | handle, 108 | IMAGE_SNAP_BY_ORDINAL(*thunkRef) ? (LPCSTR)IMAGE_ORDINAL(*thunkRef) : (LPCSTR)PIMAGE_IMPORT_BY_NAME(base + (*thunkRef))->Name 109 | ); 110 | if (!*funcRef) { 111 | status = STATUS_ENTRYPOINT_NOT_FOUND; 112 | break; 113 | } 114 | ++thunkRef; 115 | ++funcRef; 116 | } 117 | 118 | if (!NT_SUCCESS(status))break; 119 | } 120 | 121 | } 122 | } 123 | __except (EXCEPTION_EXECUTE_HANDLER) { 124 | status = GetExceptionCode(); 125 | } 126 | } while (false); 127 | 128 | if (!NT_SUCCESS(status)) { 129 | MemoryFreeImportTable(hMemoryModule); 130 | } 131 | 132 | return status; 133 | } 134 | 135 | HANDLE WINAPI MmRegisterImportTableResolver( 136 | _In_ MM_IAT_RESOLVER_ENTRY LoadLibraryProv, 137 | _In_ MM_IAT_FREE_ENTRY FreeLibraryProv) { 138 | 139 | HANDLE heap = RtlProcessHeap(); 140 | PMM_IAT_RESOLVER resolver = (PMM_IAT_RESOLVER)RtlAllocateHeap(heap, 0, sizeof(MM_IAT_RESOLVER)); 141 | 142 | if (resolver) { 143 | EnterCriticalSection(&MmpGlobalDataPtr->MmpIat->MmpIatResolverListLock); 144 | 145 | resolver->ReferenceCount = 1; 146 | resolver->LoadLibraryProv = LoadLibraryProv; 147 | resolver->FreeLibraryProv = FreeLibraryProv; 148 | InsertTailList(&MmpGlobalDataPtr->MmpIat->MmpIatResolverList, &resolver->InMmpIatResolverList); 149 | 150 | LeaveCriticalSection(&MmpGlobalDataPtr->MmpIat->MmpIatResolverListLock); 151 | } 152 | 153 | return resolver; 154 | } 155 | 156 | _Success_(return) 157 | BOOL WINAPI MmRemoveImportTableResolver(_In_ HANDLE hMmIatResolver) { 158 | 159 | HANDLE heap = RtlProcessHeap(); 160 | 161 | if (hMmIatResolver == &MmpGlobalDataPtr->MmpIat->MmpIatResolverHead) { 162 | return FALSE; 163 | } 164 | 165 | PMM_IAT_RESOLVER resolver = CONTAINING_RECORD(hMmIatResolver, MM_IAT_RESOLVER, MM_IAT_RESOLVER::InMmpIatResolverList); 166 | 167 | EnterCriticalSection(&MmpGlobalDataPtr->MmpIat->MmpIatResolverListLock); 168 | 169 | if (resolver->ReferenceCount > 1) { 170 | LeaveCriticalSection(&MmpGlobalDataPtr->MmpIat->MmpIatResolverListLock); 171 | return FALSE; 172 | } 173 | 174 | RemoveHeadList(&resolver->InMmpIatResolverList); 175 | LeaveCriticalSection(&MmpGlobalDataPtr->MmpIat->MmpIatResolverListLock); 176 | 177 | return RtlFreeHeap(heap, 0, hMmIatResolver); 178 | } 179 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | [Aa][Rr][Mm]/ 24 | [Aa][Rr][Mm]64/ 25 | bld/ 26 | [Bb]in/ 27 | [Oo]bj/ 28 | [Ll]og/ 29 | 30 | # Visual Studio 2015/2017 cache/options directory 31 | .vs/ 32 | # Uncomment if you have tasks that create the project's static files in wwwroot 33 | #wwwroot/ 34 | 35 | # Visual Studio 2017 auto generated files 36 | Generated\ Files/ 37 | 38 | # MSTest test Results 39 | [Tt]est[Rr]esult*/ 40 | [Bb]uild[Ll]og.* 41 | 42 | # NUNIT 43 | *.VisualState.xml 44 | TestResult.xml 45 | 46 | # Build Results of an ATL Project 47 | [Dd]ebugPS/ 48 | [Rr]eleasePS/ 49 | dlldata.c 50 | 51 | # Benchmark Results 52 | BenchmarkDotNet.Artifacts/ 53 | 54 | # .NET Core 55 | project.lock.json 56 | project.fragment.lock.json 57 | artifacts/ 58 | 59 | # StyleCop 60 | StyleCopReport.xml 61 | 62 | # Files built by Visual Studio 63 | *_i.c 64 | *_p.c 65 | *_h.h 66 | *.ilk 67 | *.meta 68 | *.obj 69 | *.iobj 70 | *.pch 71 | *.pdb 72 | *.ipdb 73 | *.pgc 74 | *.pgd 75 | *.rsp 76 | *.sbr 77 | *.tlb 78 | *.tli 79 | *.tlh 80 | *.tmp 81 | *.tmp_proj 82 | *_wpftmp.csproj 83 | *.log 84 | *.vspscc 85 | *.vssscc 86 | .builds 87 | *.pidb 88 | *.svclog 89 | *.scc 90 | 91 | # Chutzpah Test files 92 | _Chutzpah* 93 | 94 | # Visual C++ cache files 95 | ipch/ 96 | *.aps 97 | *.ncb 98 | *.opendb 99 | *.opensdf 100 | *.sdf 101 | *.cachefile 102 | *.VC.db 103 | *.VC.VC.opendb 104 | 105 | # Visual Studio profiler 106 | *.psess 107 | *.vsp 108 | *.vspx 109 | *.sap 110 | 111 | # Visual Studio Trace Files 112 | *.e2e 113 | 114 | # TFS 2012 Local Workspace 115 | $tf/ 116 | 117 | # Guidance Automation Toolkit 118 | *.gpState 119 | 120 | # ReSharper is a .NET coding add-in 121 | _ReSharper*/ 122 | *.[Rr]e[Ss]harper 123 | *.DotSettings.user 124 | 125 | # JustCode is a .NET coding add-in 126 | .JustCode 127 | 128 | # TeamCity is a build add-in 129 | _TeamCity* 130 | 131 | # DotCover is a Code Coverage Tool 132 | *.dotCover 133 | 134 | # AxoCover is a Code Coverage Tool 135 | .axoCover/* 136 | !.axoCover/settings.json 137 | 138 | # Visual Studio code coverage results 139 | *.coverage 140 | *.coveragexml 141 | 142 | # NCrunch 143 | _NCrunch_* 144 | .*crunch*.local.xml 145 | nCrunchTemp_* 146 | 147 | # MightyMoose 148 | *.mm.* 149 | AutoTest.Net/ 150 | 151 | # Web workbench (sass) 152 | .sass-cache/ 153 | 154 | # Installshield output folder 155 | [Ee]xpress/ 156 | 157 | # DocProject is a documentation generator add-in 158 | DocProject/buildhelp/ 159 | DocProject/Help/*.HxT 160 | DocProject/Help/*.HxC 161 | DocProject/Help/*.hhc 162 | DocProject/Help/*.hhk 163 | DocProject/Help/*.hhp 164 | DocProject/Help/Html2 165 | DocProject/Help/html 166 | 167 | # Click-Once directory 168 | publish/ 169 | 170 | # Publish Web Output 171 | *.[Pp]ublish.xml 172 | *.azurePubxml 173 | # Note: Comment the next line if you want to checkin your web deploy settings, 174 | # but database connection strings (with potential passwords) will be unencrypted 175 | *.pubxml 176 | *.publishproj 177 | 178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 179 | # checkin your Azure Web App publish settings, but sensitive information contained 180 | # in these scripts will be unencrypted 181 | PublishScripts/ 182 | 183 | # NuGet Packages 184 | *.nupkg 185 | # The packages folder can be ignored because of Package Restore 186 | **/[Pp]ackages/* 187 | # except build/, which is used as an MSBuild target. 188 | !**/[Pp]ackages/build/ 189 | # Uncomment if necessary however generally it will be regenerated when needed 190 | #!**/[Pp]ackages/repositories.config 191 | # NuGet v3's project.json files produces more ignorable files 192 | *.nuget.props 193 | *.nuget.targets 194 | 195 | # Microsoft Azure Build Output 196 | csx/ 197 | *.build.csdef 198 | 199 | # Microsoft Azure Emulator 200 | ecf/ 201 | rcf/ 202 | 203 | # Windows Store app package directories and files 204 | AppPackages/ 205 | BundleArtifacts/ 206 | Package.StoreAssociation.xml 207 | _pkginfo.txt 208 | *.appx 209 | 210 | # Visual Studio cache files 211 | # files ending in .cache can be ignored 212 | *.[Cc]ache 213 | # but keep track of directories ending in .cache 214 | !?*.[Cc]ache/ 215 | 216 | # Others 217 | ClientBin/ 218 | ~$* 219 | *~ 220 | *.dbmdl 221 | *.dbproj.schemaview 222 | *.jfm 223 | *.pfx 224 | *.publishsettings 225 | orleans.codegen.cs 226 | 227 | # Including strong name files can present a security risk 228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 229 | #*.snk 230 | 231 | # Since there are multiple workflows, uncomment next line to ignore bower_components 232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 233 | #bower_components/ 234 | 235 | # RIA/Silverlight projects 236 | Generated_Code/ 237 | 238 | # Backup & report files from converting an old project file 239 | # to a newer Visual Studio version. Backup files are not needed, 240 | # because we have git ;-) 241 | _UpgradeReport_Files/ 242 | Backup*/ 243 | UpgradeLog*.XML 244 | UpgradeLog*.htm 245 | ServiceFabricBackup/ 246 | *.rptproj.bak 247 | 248 | # SQL Server files 249 | *.mdf 250 | *.ldf 251 | *.ndf 252 | 253 | # Business Intelligence projects 254 | *.rdl.data 255 | *.bim.layout 256 | *.bim_*.settings 257 | *.rptproj.rsuser 258 | *- Backup*.rdl 259 | 260 | # Microsoft Fakes 261 | FakesAssemblies/ 262 | 263 | # GhostDoc plugin setting file 264 | *.GhostDoc.xml 265 | 266 | # Node.js Tools for Visual Studio 267 | .ntvs_analysis.dat 268 | node_modules/ 269 | 270 | # Visual Studio 6 build log 271 | *.plg 272 | 273 | # Visual Studio 6 workspace options file 274 | *.opt 275 | 276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 277 | *.vbw 278 | 279 | # Visual Studio LightSwitch build output 280 | **/*.HTMLClient/GeneratedArtifacts 281 | **/*.DesktopClient/GeneratedArtifacts 282 | **/*.DesktopClient/ModelManifest.xml 283 | **/*.Server/GeneratedArtifacts 284 | **/*.Server/ModelManifest.xml 285 | _Pvt_Extensions 286 | 287 | # Paket dependency manager 288 | .paket/paket.exe 289 | paket-files/ 290 | 291 | # FAKE - F# Make 292 | .fake/ 293 | 294 | # JetBrains Rider 295 | .idea/ 296 | *.sln.iml 297 | 298 | # CodeRush personal settings 299 | .cr/personal 300 | 301 | # Python Tools for Visual Studio (PTVS) 302 | __pycache__/ 303 | *.pyc 304 | 305 | # Cake - Uncomment if you are using it 306 | # tools/** 307 | # !tools/packages.config 308 | 309 | # Tabs Studio 310 | *.tss 311 | 312 | # Telerik's JustMock configuration file 313 | *.jmconfig 314 | 315 | # BizTalk build output 316 | *.btp.cs 317 | *.btm.cs 318 | *.odx.cs 319 | *.xsd.cs 320 | 321 | # OpenCover UI analysis results 322 | OpenCover/ 323 | 324 | # Azure Stream Analytics local run output 325 | ASALocalRun/ 326 | 327 | # MSBuild Binary and Structured Log 328 | *.binlog 329 | 330 | # NVidia Nsight GPU debugger configuration file 331 | *.nvuser 332 | 333 | # MFractors (Xamarin productivity tool) working folder 334 | .mfractor/ 335 | 336 | # Local History for Visual Studio 337 | .localhistory/ 338 | 339 | # BeatPulse healthcheck temp database 340 | healthchecksdb 341 | /test/a.dll 342 | /MemoryModule/DebugDll 343 | -------------------------------------------------------------------------------- /MemoryModule/MmpLdrpTls.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #if (!MMPP_USE_TLS) 4 | 5 | static bool stdcall; 6 | static PVOID LdrpHandleTlsData; 7 | static PVOID LdrpReleaseTlsEntry; 8 | 9 | static NTSTATUS NTAPI RtlFindLdrpHandleTlsDataOld() { 10 | NTSTATUS status = STATUS_SUCCESS; 11 | LPCVOID Feature = nullptr; 12 | BYTE Size = 0; 13 | WORD OffsetOfFunctionBegin = 0; 14 | 15 | switch (MmpGlobalDataPtr->NtVersions.MajorVersion) { 16 | case 6: { 17 | switch (MmpGlobalDataPtr->NtVersions.MinorVersion) { 18 | //8.1 19 | case 3: { 20 | #ifdef _WIN64 21 | Size = 10; 22 | OffsetOfFunctionBegin = 0x43; 23 | Feature = "\x44\x8d\x43\x09\x4c\x8d\x4c\x24\x38"; 24 | #else 25 | Size = 8; 26 | OffsetOfFunctionBegin = 0x1B; 27 | Feature = "\x50\x6a\x09\x6a\x01\x8b\xc1"; 28 | #endif 29 | break; 30 | } 31 | //8 32 | case 2: { 33 | #ifdef _WIN64 34 | Size = 9; 35 | OffsetOfFunctionBegin = 0x49; 36 | Feature = "\x48\x8b\x79\x30\x45\x8d\x66\x01"; 37 | #else 38 | Size = 7; 39 | OffsetOfFunctionBegin = 0xC; 40 | Feature = "\x8b\x45\x08\x89\x45\xa0"; 41 | #endif 42 | break; 43 | } 44 | //7 45 | case 1: { 46 | #ifdef _WIN64 47 | Size = 12; 48 | OffsetOfFunctionBegin = 0x27; 49 | Feature = "\x41\xb8\x09\x00\x00\x00\x48\x8d\x44\x24\x38"; 50 | #else 51 | Size = 9; 52 | OffsetOfFunctionBegin = 0x14; 53 | Feature = "\x74\x20\x8d\x45\xd4\x50\x6a\x09"; 54 | #endif 55 | break; 56 | } 57 | default:return STATUS_NOT_SUPPORTED; 58 | } 59 | break; 60 | } 61 | 62 | default: { 63 | return STATUS_NOT_SUPPORTED; 64 | } 65 | } 66 | 67 | SEARCH_CONTEXT SearchContext{ SearchContext.SearchPattern = LPBYTE(Feature),SearchContext.PatternSize = Size - 1 }; 68 | if (!NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(HMODULE(MmpGlobalDataPtr->MmpBaseAddressIndex->NtdllLdrEntry->DllBase), ".text", &SearchContext))) 69 | return STATUS_NOT_SUPPORTED; 70 | 71 | LdrpHandleTlsData = SearchContext.Result - OffsetOfFunctionBegin; 72 | return status; 73 | } 74 | 75 | static NTSTATUS NTAPI RtlFindLdrpHandleTlsData10() { 76 | LPVOID DllBase = MmpGlobalDataPtr->MmpBaseAddressIndex->NtdllLdrEntry->DllBase; 77 | #ifdef _WIN64 78 | // search for LdrpHandleTls string literal 79 | SEARCH_CONTEXT SearchContext{ SearchContext.SearchPattern = LPBYTE("LdrpHandleTlsData\x00"), SearchContext.PatternSize = 18 }; 80 | if (!NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(HMODULE(DllBase), ".rdata", &SearchContext))) 81 | return STATUS_NOT_SUPPORTED; 82 | LPBYTE StringOffset = SearchContext.Result; 83 | 84 | SearchContext.Result = nullptr; 85 | SearchContext.PatternSize = 3; 86 | SearchContext.SearchPattern = LPBYTE("\x48\x8D\x15"); 87 | LPBYTE ExceptionBlock = nullptr; 88 | 89 | // Search for lea rdx,[rip+0x????] 90 | // ???? is the relative offset from RIP to LdrpHandleTls string literal 91 | while (NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(HMODULE(DllBase), ".text", &SearchContext))) { 92 | DWORD InsOff = *(DWORD*)(SearchContext.Result + 3); 93 | if (StringOffset == SearchContext.Result + InsOff + 7) { 94 | ExceptionBlock = SearchContext.Result; 95 | break; 96 | } 97 | } 98 | if (!ExceptionBlock) return STATUS_NOT_SUPPORTED; 99 | 100 | // Search back for exception block function header 101 | while (*ExceptionBlock != 0xcc) { 102 | // Normally ~13 bytes, but just in case... 103 | if (SearchContext.Result - ExceptionBlock > 0x50) return STATUS_NOT_SUPPORTED; 104 | ExceptionBlock--; 105 | } 106 | ExceptionBlock++; 107 | 108 | // search for C_SCOPE_TABLE 109 | union Converter { 110 | BYTE Bytes[4]; 111 | DWORD Dword; 112 | }; 113 | Converter ExceptionBlockAddress{}; // { .Dword = DWORD(ExceptionBlock - LPBYTE(DllBase)) }; 114 | ExceptionBlockAddress.Dword = DWORD(ExceptionBlock - LPBYTE(DllBase)); 115 | 116 | SearchContext.Result = nullptr; 117 | SearchContext.PatternSize = 4; 118 | SearchContext.SearchPattern = ExceptionBlockAddress.Bytes; 119 | if (!NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(HMODULE(DllBase), ".rdata", &SearchContext))) 120 | return STATUS_NOT_SUPPORTED; 121 | 122 | // C_SCOPE_TABLE$$Begin 123 | LPDWORD LdrpHandleTlsBlock = LPDWORD(*(LPDWORD)(SearchContext.Result - 8) + LPBYTE(DllBase)); 124 | // Pad to 0x04 125 | LdrpHandleTlsBlock = LPDWORD(LONGLONG(LdrpHandleTlsBlock) / 0x04 * 0x04); 126 | LPDWORD LdrpHandleTlsBlockBackup = LdrpHandleTlsBlock; 127 | 128 | // Search back for LdrpHandleTls 129 | // Search up for 4 consecutive 0xCC 130 | while (*LdrpHandleTlsBlock != 0xcccccccc) { 131 | // Normally ~0x140 bytes 132 | if (LdrpHandleTlsBlockBackup - LdrpHandleTlsBlock > 0x400) return STATUS_NOT_SUPPORTED; 133 | LdrpHandleTlsBlock--; 134 | } 135 | LdrpHandleTlsBlock++; 136 | LdrpHandleTlsData = LdrpHandleTlsBlock; 137 | return STATUS_SUCCESS; 138 | #else 139 | return STATUS_NOT_SUPPORTED; 140 | #endif 141 | } 142 | 143 | static NTSTATUS NTAPI RtlFindLdrpHandleTlsData() { 144 | if (MmpGlobalDataPtr->NtVersions.MajorVersion >= 10) { 145 | return RtlFindLdrpHandleTlsData10(); 146 | } 147 | else { 148 | return RtlFindLdrpHandleTlsDataOld(); 149 | } 150 | } 151 | 152 | static NTSTATUS NTAPI RtlFindLdrpReleaseTlsEntry() { 153 | NTSTATUS status = STATUS_SUCCESS; 154 | LPCVOID Feature = nullptr; 155 | BYTE Size = 0; 156 | WORD OffsetOfFunctionBegin = 0; 157 | 158 | switch (MmpGlobalDataPtr->NtVersions.MajorVersion) { 159 | case 10: { 160 | if (MmpGlobalDataPtr->NtVersions.MinorVersion) return STATUS_NOT_SUPPORTED; 161 | 162 | #ifdef _WIN64 163 | Feature = "\x48\x89\x5c\x24\x08\x57\x48\x83\xec\x20\x48\x8b\xfa\x48\x8b\xd9\x48\x85\xd2\x75\x0c"; 164 | Size = 21; 165 | #else 166 | return STATUS_NOT_SUPPORTED; 167 | #endif 168 | break; 169 | } 170 | default: 171 | return STATUS_NOT_SUPPORTED; 172 | } 173 | 174 | SEARCH_CONTEXT SearchContext{ SearchContext.SearchPattern = LPBYTE(Feature),SearchContext.PatternSize = Size - 1 }; 175 | if (!NT_SUCCESS(RtlFindMemoryBlockFromModuleSection(HMODULE(MmpGlobalDataPtr->MmpBaseAddressIndex->NtdllLdrEntry->DllBase), ".text", &SearchContext))) 176 | return STATUS_NOT_SUPPORTED; 177 | 178 | LdrpReleaseTlsEntry = SearchContext.Result - OffsetOfFunctionBegin; 179 | return status; 180 | } 181 | 182 | BOOL NTAPI MmpTlsInitialize() { 183 | if (!NT_SUCCESS(RtlFindLdrpHandleTlsData()) || 184 | !NT_SUCCESS(RtlFindLdrpReleaseTlsEntry())) { 185 | 186 | LdrpHandleTlsData = nullptr; 187 | LdrpReleaseTlsEntry = nullptr; 188 | 189 | MmpGlobalDataPtr->MmpFeatures &= ~MEMORY_FEATURE_LDRP_HANDLE_TLS_DATA; 190 | return FALSE; 191 | } 192 | 193 | stdcall = !RtlIsWindowsVersionOrGreater(6, 3, 0); 194 | return TRUE; 195 | } 196 | 197 | VOID NTAPI MmpTlsCleanup() { 198 | ; 199 | } 200 | 201 | NTSTATUS NTAPI MmpReleaseTlsEntry(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) { 202 | typedef NTSTATUS(__stdcall* STDCALL)(PLDR_DATA_TABLE_ENTRY, PVOID*); 203 | typedef NTSTATUS(__thiscall* THISCALL)(PLDR_DATA_TABLE_ENTRY, PVOID*); 204 | 205 | union { 206 | STDCALL stdcall; 207 | THISCALL thiscall; 208 | 209 | PVOID ptr; 210 | }fp; 211 | fp.ptr = LdrpReleaseTlsEntry; 212 | 213 | if (fp.ptr) { 214 | return stdcall ? fp.stdcall(lpModuleEntry, nullptr) : fp.thiscall(lpModuleEntry, nullptr); 215 | } 216 | else { 217 | return STATUS_NOT_SUPPORTED; 218 | } 219 | } 220 | 221 | NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) { 222 | typedef NTSTATUS(__stdcall* STDCALL)(PLDR_DATA_TABLE_ENTRY); 223 | typedef NTSTATUS(__thiscall* THISCALL)(PLDR_DATA_TABLE_ENTRY); 224 | 225 | union { 226 | STDCALL stdcall; 227 | THISCALL thiscall; 228 | 229 | PVOID ptr; 230 | }fp; 231 | fp.ptr = LdrpHandleTlsData; 232 | 233 | if (fp.ptr) { 234 | return stdcall ? fp.stdcall(lpModuleEntry) : fp.thiscall(lpModuleEntry); 235 | } 236 | else { 237 | return STATUS_NOT_SUPPORTED; 238 | } 239 | } 240 | 241 | #endif 242 | -------------------------------------------------------------------------------- /MemoryModule/ReflectiveLoader.h: -------------------------------------------------------------------------------- 1 | //===============================================================================================// 2 | // Copyright (c) 2012, Stephen Fewer of Harmony Security (www.harmonysecurity.com) 3 | // All rights reserved. 4 | // 5 | // Redistribution and use in source and binary forms, with or without modification, are permitted 6 | // provided that the following conditions are met: 7 | // 8 | // * Redistributions of source code must retain the above copyright notice, this list of 9 | // conditions and the following disclaimer. 10 | // 11 | // * Redistributions in binary form must reproduce the above copyright notice, this list of 12 | // conditions and the following disclaimer in the documentation and/or other materials provided 13 | // with the distribution. 14 | // 15 | // * Neither the name of Harmony Security nor the names of its contributors may be used to 16 | // endorse or promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 | // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | // POSSIBILITY OF SUCH DAMAGE. 27 | //===============================================================================================// 28 | #ifndef _REFLECTIVEDLLINJECTION_REFLECTIVELOADER_H 29 | #define _REFLECTIVEDLLINJECTION_REFLECTIVELOADER_H 30 | //===============================================================================================// 31 | #define WIN32_LEAN_AND_MEAN 32 | #include 33 | #include 34 | #include 35 | 36 | #include "ReflectiveDLLInjection.h" 37 | 38 | #ifdef _WIN64 39 | #define WIN_X64 40 | #else 41 | #define WIN_X86 42 | #endif 43 | 44 | typedef HMODULE(WINAPI* LOADLIBRARYA)(LPCSTR); 45 | typedef FARPROC(WINAPI* GETPROCADDRESS)(HMODULE, LPCSTR); 46 | typedef LPVOID(WINAPI* VIRTUALALLOC)(LPVOID, SIZE_T, DWORD, DWORD); 47 | typedef DWORD(NTAPI* NTFLUSHINSTRUCTIONCACHE)(HANDLE, PVOID, ULONG); 48 | 49 | #define KERNEL32DLL_HASH 0x6A4ABC5B 50 | #define NTDLLDLL_HASH 0x3CFA685D 51 | 52 | #define LOADLIBRARYA_HASH 0xEC0E4E8E 53 | #define GETPROCADDRESS_HASH 0x7C0DFCAA 54 | #define VIRTUALALLOC_HASH 0x91AFCA54 55 | #define NTFLUSHINSTRUCTIONCACHE_HASH 0x534C0AB8 56 | 57 | #define IMAGE_REL_BASED_ARM_MOV32A 5 58 | #define IMAGE_REL_BASED_ARM_MOV32T 7 59 | 60 | #define ARM_MOV_MASK (DWORD)(0xFBF08000) 61 | #define ARM_MOV_MASK2 (DWORD)(0xFBF08F00) 62 | #define ARM_MOVW 0xF2400000 63 | #define ARM_MOVT 0xF2C00000 64 | 65 | #define HASH_KEY 13 66 | //===============================================================================================// 67 | #pragma intrinsic( _rotr ) 68 | 69 | __forceinline DWORD ror(DWORD d) 70 | { 71 | return _rotr(d, HASH_KEY); 72 | } 73 | 74 | __forceinline DWORD hash(char* c) 75 | { 76 | register DWORD h = 0; 77 | do 78 | { 79 | h = ror(h); 80 | h += *c; 81 | } while (*++c); 82 | 83 | return h; 84 | } 85 | //===============================================================================================// 86 | typedef struct _UNICODE_STR 87 | { 88 | USHORT Length; 89 | USHORT MaximumLength; 90 | PWSTR pBuffer; 91 | } UNICODE_STR, * PUNICODE_STR; 92 | 93 | // WinDbg> dt -v ntdll!_LDR_DATA_TABLE_ENTRY 94 | //__declspec( align(8) ) 95 | typedef struct _LDR_DATA_TABLE_ENTRY 96 | { 97 | //LIST_ENTRY InLoadOrderLinks; // As we search from PPEB_LDR_DATA->InMemoryOrderModuleList we dont use the first entry. 98 | LIST_ENTRY InMemoryOrderModuleList; 99 | LIST_ENTRY InInitializationOrderModuleList; 100 | PVOID DllBase; 101 | PVOID EntryPoint; 102 | ULONG SizeOfImage; 103 | UNICODE_STR FullDllName; 104 | UNICODE_STR BaseDllName; 105 | ULONG Flags; 106 | SHORT LoadCount; 107 | SHORT TlsIndex; 108 | LIST_ENTRY HashTableEntry; 109 | ULONG TimeDateStamp; 110 | } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; 111 | 112 | // WinDbg> dt -v ntdll!_PEB_LDR_DATA 113 | typedef struct _PEB_LDR_DATA //, 7 elements, 0x28 bytes 114 | { 115 | DWORD dwLength; 116 | DWORD dwInitialized; 117 | LPVOID lpSsHandle; 118 | LIST_ENTRY InLoadOrderModuleList; 119 | LIST_ENTRY InMemoryOrderModuleList; 120 | LIST_ENTRY InInitializationOrderModuleList; 121 | LPVOID lpEntryInProgress; 122 | } PEB_LDR_DATA, * PPEB_LDR_DATA; 123 | 124 | // WinDbg> dt -v ntdll!_PEB_FREE_BLOCK 125 | typedef struct _PEB_FREE_BLOCK // 2 elements, 0x8 bytes 126 | { 127 | struct _PEB_FREE_BLOCK* pNext; 128 | DWORD dwSize; 129 | } PEB_FREE_BLOCK, * PPEB_FREE_BLOCK; 130 | 131 | // struct _PEB is defined in Winternl.h but it is incomplete 132 | // WinDbg> dt -v ntdll!_PEB 133 | typedef struct __PEB // 65 elements, 0x210 bytes 134 | { 135 | BYTE bInheritedAddressSpace; 136 | BYTE bReadImageFileExecOptions; 137 | BYTE bBeingDebugged; 138 | BYTE bSpareBool; 139 | LPVOID lpMutant; 140 | LPVOID lpImageBaseAddress; 141 | PPEB_LDR_DATA pLdr; 142 | LPVOID lpProcessParameters; 143 | LPVOID lpSubSystemData; 144 | LPVOID lpProcessHeap; 145 | PRTL_CRITICAL_SECTION pFastPebLock; 146 | LPVOID lpFastPebLockRoutine; 147 | LPVOID lpFastPebUnlockRoutine; 148 | DWORD dwEnvironmentUpdateCount; 149 | LPVOID lpKernelCallbackTable; 150 | DWORD dwSystemReserved; 151 | DWORD dwAtlThunkSListPtr32; 152 | PPEB_FREE_BLOCK pFreeList; 153 | DWORD dwTlsExpansionCounter; 154 | LPVOID lpTlsBitmap; 155 | DWORD dwTlsBitmapBits[2]; 156 | LPVOID lpReadOnlySharedMemoryBase; 157 | LPVOID lpReadOnlySharedMemoryHeap; 158 | LPVOID lpReadOnlyStaticServerData; 159 | LPVOID lpAnsiCodePageData; 160 | LPVOID lpOemCodePageData; 161 | LPVOID lpUnicodeCaseTableData; 162 | DWORD dwNumberOfProcessors; 163 | DWORD dwNtGlobalFlag; 164 | LARGE_INTEGER liCriticalSectionTimeout; 165 | DWORD dwHeapSegmentReserve; 166 | DWORD dwHeapSegmentCommit; 167 | DWORD dwHeapDeCommitTotalFreeThreshold; 168 | DWORD dwHeapDeCommitFreeBlockThreshold; 169 | DWORD dwNumberOfHeaps; 170 | DWORD dwMaximumNumberOfHeaps; 171 | LPVOID lpProcessHeaps; 172 | LPVOID lpGdiSharedHandleTable; 173 | LPVOID lpProcessStarterHelper; 174 | DWORD dwGdiDCAttributeList; 175 | LPVOID lpLoaderLock; 176 | DWORD dwOSMajorVersion; 177 | DWORD dwOSMinorVersion; 178 | WORD wOSBuildNumber; 179 | WORD wOSCSDVersion; 180 | DWORD dwOSPlatformId; 181 | DWORD dwImageSubsystem; 182 | DWORD dwImageSubsystemMajorVersion; 183 | DWORD dwImageSubsystemMinorVersion; 184 | DWORD dwImageProcessAffinityMask; 185 | DWORD dwGdiHandleBuffer[34]; 186 | LPVOID lpPostProcessInitRoutine; 187 | LPVOID lpTlsExpansionBitmap; 188 | DWORD dwTlsExpansionBitmapBits[32]; 189 | DWORD dwSessionId; 190 | ULARGE_INTEGER liAppCompatFlags; 191 | ULARGE_INTEGER liAppCompatFlagsUser; 192 | LPVOID lppShimData; 193 | LPVOID lpAppCompatInfo; 194 | UNICODE_STR usCSDVersion; 195 | LPVOID lpActivationContextData; 196 | LPVOID lpProcessAssemblyStorageMap; 197 | LPVOID lpSystemDefaultActivationContextData; 198 | LPVOID lpSystemAssemblyStorageMap; 199 | DWORD dwMinimumStackCommit; 200 | } _PEB, * _PPEB; 201 | 202 | typedef struct 203 | { 204 | WORD offset : 12; 205 | WORD type : 4; 206 | } IMAGE_RELOC, * PIMAGE_RELOC; 207 | //===============================================================================================// 208 | #endif 209 | //===============================================================================================// -------------------------------------------------------------------------------- /MemoryModule/InvertedFunctionTable.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | static VOID RtlpInsertInvertedFunctionTable( 4 | _In_ PRTL_INVERTED_FUNCTION_TABLE InvertedTable, 5 | _In_ PVOID ImageBase, 6 | _In_ ULONG SizeOfImage) { 7 | #ifdef _WIN64 8 | ULONG CurrentSize; 9 | PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionTable; 10 | ULONG Index; 11 | ULONG SizeOfTable = 0; 12 | bool IsWin8OrGreater = RtlIsWindowsVersionOrGreater(6, 2, 0); 13 | 14 | Index = (ULONG)IsWin8OrGreater; 15 | CurrentSize = InvertedTable->Count; 16 | if (CurrentSize != InvertedTable->MaxCount) { 17 | if (CurrentSize != 0) { 18 | while (Index < CurrentSize) { 19 | if (ImageBase < InvertedTable->Entries[Index].ImageBase)break; 20 | ++Index; 21 | } 22 | 23 | if (Index != CurrentSize) { 24 | RtlMoveMemory(&InvertedTable->Entries[Index + 1], 25 | &InvertedTable->Entries[Index], 26 | (CurrentSize - Index) * sizeof(RTL_INVERTED_FUNCTION_TABLE_ENTRY)); 27 | } 28 | } 29 | 30 | FunctionTable = (decltype(FunctionTable))RtlImageDirectoryEntryToData(ImageBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXCEPTION, &SizeOfTable); 31 | InvertedTable->Entries[Index].ExceptionDirectory = FunctionTable; 32 | InvertedTable->Entries[Index].ImageBase = ImageBase; 33 | InvertedTable->Entries[Index].ImageSize = SizeOfImage; 34 | InvertedTable->Entries[Index].ExceptionDirectorySize = SizeOfTable; 35 | InvertedTable->Count++; 36 | } 37 | else { 38 | IsWin8OrGreater ? (InvertedTable->Overflow = TRUE) : (InvertedTable->Epoch = TRUE); 39 | } 40 | 41 | #else 42 | DWORD ptr, count; 43 | bool IsWin8OrGreater = RtlIsWindowsVersionOrGreater(6, 2, 0); 44 | ULONG Index = IsWin8OrGreater ? 1 : 0; 45 | 46 | if (InvertedTable->Count == InvertedTable->MaxCount) { 47 | if (IsWin8OrGreater)InvertedTable->NextEntrySEHandlerTableEncoded = TRUE; 48 | else InvertedTable->Overflow = TRUE; 49 | return; 50 | } 51 | while (Index < InvertedTable->Count) { 52 | if (ImageBase < (IsWin8OrGreater ? 53 | ((PRTL_INVERTED_FUNCTION_TABLE_ENTRY_64)&InvertedTable->Entries[Index])->ImageBase : 54 | InvertedTable->Entries[Index].ImageBase)) 55 | break; 56 | Index++; 57 | } 58 | if (Index != InvertedTable->Count) { 59 | if (IsWin8OrGreater) { 60 | RtlMoveMemory(&InvertedTable->Entries[Index + 1], &InvertedTable->Entries[Index], 61 | (InvertedTable->Count - Index) * sizeof(RTL_INVERTED_FUNCTION_TABLE_ENTRY)); 62 | } 63 | else { 64 | RtlMoveMemory(&InvertedTable->Entries[Index].NextEntrySEHandlerTableEncoded, 65 | Index ? &InvertedTable->Entries[Index - 1].NextEntrySEHandlerTableEncoded : (PVOID)&InvertedTable->NextEntrySEHandlerTableEncoded, 66 | (InvertedTable->Count - Index) * sizeof(RTL_INVERTED_FUNCTION_TABLE_ENTRY)); 67 | } 68 | } 69 | 70 | RtlCaptureImageExceptionValues(ImageBase, &ptr, &count); 71 | if (IsWin8OrGreater) { 72 | //memory layout is same as x64 73 | PRTL_INVERTED_FUNCTION_TABLE_ENTRY_64 entry = (decltype(entry))&InvertedTable->Entries[Index]; 74 | entry->ExceptionDirectory = (PIMAGE_RUNTIME_FUNCTION_ENTRY)RtlEncodeSystemPointer((PVOID)ptr); 75 | entry->ExceptionDirectorySize = count; 76 | entry->ImageBase = ImageBase; 77 | entry->ImageSize = SizeOfImage; 78 | } 79 | else { 80 | if (Index) InvertedTable->Entries[Index - 1].NextEntrySEHandlerTableEncoded = RtlEncodeSystemPointer((PVOID)ptr); 81 | else InvertedTable->NextEntrySEHandlerTableEncoded = (DWORD)RtlEncodeSystemPointer((PVOID)ptr); 82 | InvertedTable->Entries[Index].ImageBase = ImageBase; 83 | InvertedTable->Entries[Index].ImageSize = SizeOfImage; 84 | InvertedTable->Entries[Index].SEHandlerCount = count; 85 | } 86 | 87 | ++InvertedTable->Count; 88 | #endif 89 | return; 90 | } 91 | 92 | static VOID RtlpRemoveInvertedFunctionTable( 93 | _In_ PRTL_INVERTED_FUNCTION_TABLE InvertedTable, 94 | _In_ PVOID ImageBase) { 95 | ULONG CurrentSize; 96 | ULONG Index; 97 | //bool need = RtlIsWindowsVersionOrGreater(6, 2, 0); 98 | bool IsWin8OrGreater = RtlIsWindowsVersionOrGreater(6, 2, 0); 99 | 100 | CurrentSize = InvertedTable->Count; 101 | for (Index = 0; Index < CurrentSize; Index += 1) { 102 | if (ImageBase == (IsWin8OrGreater ? 103 | ((PRTL_INVERTED_FUNCTION_TABLE_ENTRY_64)&InvertedTable->Entries[Index])->ImageBase : 104 | InvertedTable->Entries[Index].ImageBase)) 105 | break; 106 | } 107 | 108 | if (Index != CurrentSize) { 109 | //if (need)_InterlockedIncrement(&InvertedTable->Epoch); 110 | if (CurrentSize != 1) { 111 | #ifdef _WIN64 112 | RtlMoveMemory(&InvertedTable->Entries[Index], 113 | &InvertedTable->Entries[Index + 1], 114 | (CurrentSize - Index - 1) * sizeof(RTL_INVERTED_FUNCTION_TABLE_ENTRY)); 115 | #else 116 | if (IsWin8OrGreater) { 117 | RtlMoveMemory(&InvertedTable->Entries[Index], &InvertedTable->Entries[Index + 1], 118 | (CurrentSize - Index) * sizeof(RTL_INVERTED_FUNCTION_TABLE_ENTRY)); 119 | } 120 | else { 121 | RtlMoveMemory( 122 | Index ? &InvertedTable->Entries[Index - 1].NextEntrySEHandlerTableEncoded : (PVOID)&InvertedTable->NextEntrySEHandlerTableEncoded, 123 | &InvertedTable->Entries[Index].NextEntrySEHandlerTableEncoded, 124 | (CurrentSize - Index) * sizeof(RTL_INVERTED_FUNCTION_TABLE_ENTRY)); 125 | } 126 | #endif 127 | } 128 | InvertedTable->Count--; 129 | //if (need)_InterlockedIncrement(&InvertedTable->Epoch); 130 | } 131 | 132 | if (InvertedTable->Count != InvertedTable->MaxCount) { 133 | if (IsWin8OrGreater) { 134 | PRTL_INVERTED_FUNCTION_TABLE_64(InvertedTable)->Overflow = FALSE; 135 | } 136 | else { 137 | PRTL_INVERTED_FUNCTION_TABLE_WIN7_32(InvertedTable)->Overflow = FALSE; 138 | } 139 | } 140 | 141 | return; 142 | } 143 | 144 | static NTSTATUS RtlProtectMrdata(_In_ ULONG Protect) { 145 | static PVOID MrdataBase = nullptr; 146 | static SIZE_T size = 0; 147 | NTSTATUS status; 148 | PVOID tmp; 149 | SIZE_T tmp_len; 150 | ULONG old; 151 | 152 | if (!MrdataBase) { 153 | MEMORY_BASIC_INFORMATION mbi{}; 154 | status = NtQueryVirtualMemory(GetCurrentProcess(), MmpGlobalDataPtr->MmpInvertedFunctionTable->LdrpInvertedFunctionTable, MemoryBasicInformation, &mbi, sizeof(mbi), nullptr); 155 | if (!NT_SUCCESS(status))return status; 156 | MrdataBase = mbi.BaseAddress; 157 | size = mbi.RegionSize; 158 | } 159 | 160 | tmp = MrdataBase; 161 | tmp_len = size; 162 | return NtProtectVirtualMemory(GetCurrentProcess(), &tmp, &tmp_len, Protect, &old); 163 | } 164 | 165 | NTSTATUS NTAPI RtlInsertInvertedFunctionTable( 166 | _In_ PVOID BaseAddress, 167 | _In_ ULONG ImageSize) { 168 | auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->MmpInvertedFunctionTable->LdrpInvertedFunctionTable); 169 | if (!table)return STATUS_NOT_SUPPORTED; 170 | bool need_virtual_protect = RtlIsWindowsVersionOrGreater(6, 3, 0); 171 | NTSTATUS status; 172 | 173 | if (need_virtual_protect) { 174 | status = RtlProtectMrdata(PAGE_READWRITE); 175 | if (!NT_SUCCESS(status))return status; 176 | } 177 | RtlpInsertInvertedFunctionTable(table, BaseAddress, ImageSize); 178 | if (need_virtual_protect) { 179 | status = RtlProtectMrdata(PAGE_READONLY); 180 | if (!NT_SUCCESS(status))return status; 181 | } 182 | return (RtlIsWindowsVersionOrGreater(6, 2, 0) ? PRTL_INVERTED_FUNCTION_TABLE_64(table)->Overflow : PRTL_INVERTED_FUNCTION_TABLE_WIN7_32(table)->Overflow) ? 183 | STATUS_NO_MEMORY : STATUS_SUCCESS; 184 | } 185 | 186 | NTSTATUS NTAPI RtlRemoveInvertedFunctionTable(_In_ PVOID ImageBase) { 187 | auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->MmpInvertedFunctionTable->LdrpInvertedFunctionTable); 188 | bool need_virtual_protect = RtlIsWindowsVersionOrGreater(6, 3, 0); 189 | NTSTATUS status; 190 | 191 | if (need_virtual_protect) { 192 | status = RtlProtectMrdata(PAGE_READWRITE); 193 | if (!NT_SUCCESS(status))return status; 194 | } 195 | RtlpRemoveInvertedFunctionTable(table, ImageBase); 196 | if (need_virtual_protect) { 197 | status = RtlProtectMrdata(PAGE_READONLY); 198 | if (!NT_SUCCESS(status))return status; 199 | } 200 | 201 | return STATUS_SUCCESS; 202 | } 203 | -------------------------------------------------------------------------------- /3rdparty/phnt/include/ntdbg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Debugger support functions 3 | * 4 | * This file is part of System Informer. 5 | */ 6 | 7 | #ifndef _NTDBG_H 8 | #define _NTDBG_H 9 | 10 | // Debugging 11 | 12 | NTSYSAPI 13 | VOID 14 | NTAPI 15 | DbgUserBreakPoint( 16 | VOID 17 | ); 18 | 19 | NTSYSAPI 20 | VOID 21 | NTAPI 22 | DbgBreakPoint( 23 | VOID 24 | ); 25 | 26 | NTSYSAPI 27 | VOID 28 | NTAPI 29 | DbgBreakPointWithStatus( 30 | _In_ ULONG Status 31 | ); 32 | 33 | #define DBG_STATUS_CONTROL_C 1 34 | #define DBG_STATUS_SYSRQ 2 35 | #define DBG_STATUS_BUGCHECK_FIRST 3 36 | #define DBG_STATUS_BUGCHECK_SECOND 4 37 | #define DBG_STATUS_FATAL 5 38 | #define DBG_STATUS_DEBUG_CONTROL 6 39 | #define DBG_STATUS_WORKER 7 40 | 41 | NTSYSAPI 42 | ULONG 43 | STDAPIVCALLTYPE 44 | DbgPrint( 45 | _In_z_ _Printf_format_string_ PCSTR Format, 46 | ... 47 | ); 48 | 49 | NTSYSAPI 50 | ULONG 51 | STDAPIVCALLTYPE 52 | DbgPrintEx( 53 | _In_ ULONG ComponentId, 54 | _In_ ULONG Level, 55 | _In_z_ _Printf_format_string_ PCSTR Format, 56 | ... 57 | ); 58 | 59 | NTSYSAPI 60 | ULONG 61 | NTAPI 62 | vDbgPrintEx( 63 | _In_ ULONG ComponentId, 64 | _In_ ULONG Level, 65 | _In_z_ PCCH Format, 66 | _In_ va_list arglist 67 | ); 68 | 69 | NTSYSAPI 70 | ULONG 71 | NTAPI 72 | vDbgPrintExWithPrefix( 73 | _In_z_ PCCH Prefix, 74 | _In_ ULONG ComponentId, 75 | _In_ ULONG Level, 76 | _In_z_ PCCH Format, 77 | _In_ va_list arglist 78 | ); 79 | 80 | NTSYSAPI 81 | NTSTATUS 82 | NTAPI 83 | DbgQueryDebugFilterState( 84 | _In_ ULONG ComponentId, 85 | _In_ ULONG Level 86 | ); 87 | 88 | NTSYSAPI 89 | NTSTATUS 90 | NTAPI 91 | DbgSetDebugFilterState( 92 | _In_ ULONG ComponentId, 93 | _In_ ULONG Level, 94 | _In_ BOOLEAN State 95 | ); 96 | 97 | NTSYSAPI 98 | ULONG 99 | NTAPI 100 | DbgPrompt( 101 | _In_ PCCH Prompt, 102 | _Out_writes_bytes_(Length) PCH Response, 103 | _In_ ULONG Length 104 | ); 105 | 106 | // Definitions 107 | 108 | typedef struct _DBGKM_EXCEPTION 109 | { 110 | EXCEPTION_RECORD ExceptionRecord; 111 | ULONG FirstChance; 112 | } DBGKM_EXCEPTION, *PDBGKM_EXCEPTION; 113 | 114 | typedef struct _DBGKM_CREATE_THREAD 115 | { 116 | ULONG SubSystemKey; 117 | PVOID StartAddress; 118 | } DBGKM_CREATE_THREAD, *PDBGKM_CREATE_THREAD; 119 | 120 | typedef struct _DBGKM_CREATE_PROCESS 121 | { 122 | ULONG SubSystemKey; 123 | HANDLE FileHandle; 124 | PVOID BaseOfImage; 125 | ULONG DebugInfoFileOffset; 126 | ULONG DebugInfoSize; 127 | DBGKM_CREATE_THREAD InitialThread; 128 | } DBGKM_CREATE_PROCESS, *PDBGKM_CREATE_PROCESS; 129 | 130 | typedef struct _DBGKM_EXIT_THREAD 131 | { 132 | NTSTATUS ExitStatus; 133 | } DBGKM_EXIT_THREAD, *PDBGKM_EXIT_THREAD; 134 | 135 | typedef struct _DBGKM_EXIT_PROCESS 136 | { 137 | NTSTATUS ExitStatus; 138 | } DBGKM_EXIT_PROCESS, *PDBGKM_EXIT_PROCESS; 139 | 140 | typedef struct _DBGKM_LOAD_DLL 141 | { 142 | HANDLE FileHandle; 143 | PVOID BaseOfDll; 144 | ULONG DebugInfoFileOffset; 145 | ULONG DebugInfoSize; 146 | PVOID NamePointer; 147 | } DBGKM_LOAD_DLL, *PDBGKM_LOAD_DLL; 148 | 149 | typedef struct _DBGKM_UNLOAD_DLL 150 | { 151 | PVOID BaseAddress; 152 | } DBGKM_UNLOAD_DLL, *PDBGKM_UNLOAD_DLL; 153 | 154 | typedef enum _DBG_STATE 155 | { 156 | DbgIdle, 157 | DbgReplyPending, 158 | DbgCreateThreadStateChange, 159 | DbgCreateProcessStateChange, 160 | DbgExitThreadStateChange, 161 | DbgExitProcessStateChange, 162 | DbgExceptionStateChange, 163 | DbgBreakpointStateChange, 164 | DbgSingleStepStateChange, 165 | DbgLoadDllStateChange, 166 | DbgUnloadDllStateChange 167 | } DBG_STATE, *PDBG_STATE; 168 | 169 | typedef struct _DBGUI_CREATE_THREAD 170 | { 171 | HANDLE HandleToThread; 172 | DBGKM_CREATE_THREAD NewThread; 173 | } DBGUI_CREATE_THREAD, *PDBGUI_CREATE_THREAD; 174 | 175 | typedef struct _DBGUI_CREATE_PROCESS 176 | { 177 | HANDLE HandleToProcess; 178 | HANDLE HandleToThread; 179 | DBGKM_CREATE_PROCESS NewProcess; 180 | } DBGUI_CREATE_PROCESS, *PDBGUI_CREATE_PROCESS; 181 | 182 | typedef struct _DBGUI_WAIT_STATE_CHANGE 183 | { 184 | DBG_STATE NewState; 185 | CLIENT_ID AppClientId; 186 | union 187 | { 188 | DBGKM_EXCEPTION Exception; 189 | DBGUI_CREATE_THREAD CreateThread; 190 | DBGUI_CREATE_PROCESS CreateProcessInfo; 191 | DBGKM_EXIT_THREAD ExitThread; 192 | DBGKM_EXIT_PROCESS ExitProcess; 193 | DBGKM_LOAD_DLL LoadDll; 194 | DBGKM_UNLOAD_DLL UnloadDll; 195 | } StateInfo; 196 | } DBGUI_WAIT_STATE_CHANGE, *PDBGUI_WAIT_STATE_CHANGE; 197 | 198 | #define DEBUG_READ_EVENT 0x0001 199 | #define DEBUG_PROCESS_ASSIGN 0x0002 200 | #define DEBUG_SET_INFORMATION 0x0004 201 | #define DEBUG_QUERY_INFORMATION 0x0008 202 | #define DEBUG_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \ 203 | DEBUG_READ_EVENT | DEBUG_PROCESS_ASSIGN | DEBUG_SET_INFORMATION | \ 204 | DEBUG_QUERY_INFORMATION) 205 | 206 | #define DEBUG_KILL_ON_CLOSE 0x1 207 | 208 | typedef enum _DEBUGOBJECTINFOCLASS 209 | { 210 | DebugObjectUnusedInformation, 211 | DebugObjectKillProcessOnExitInformation, // s: ULONG 212 | MaxDebugObjectInfoClass 213 | } DEBUGOBJECTINFOCLASS, *PDEBUGOBJECTINFOCLASS; 214 | 215 | // System calls 216 | 217 | NTSYSCALLAPI 218 | NTSTATUS 219 | NTAPI 220 | NtCreateDebugObject( 221 | _Out_ PHANDLE DebugObjectHandle, 222 | _In_ ACCESS_MASK DesiredAccess, 223 | _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, 224 | _In_ ULONG Flags 225 | ); 226 | 227 | NTSYSCALLAPI 228 | NTSTATUS 229 | NTAPI 230 | NtDebugActiveProcess( 231 | _In_ HANDLE ProcessHandle, 232 | _In_ HANDLE DebugObjectHandle 233 | ); 234 | 235 | NTSYSCALLAPI 236 | NTSTATUS 237 | NTAPI 238 | NtDebugContinue( 239 | _In_ HANDLE DebugObjectHandle, 240 | _In_ PCLIENT_ID ClientId, 241 | _In_ NTSTATUS ContinueStatus 242 | ); 243 | 244 | NTSYSCALLAPI 245 | NTSTATUS 246 | NTAPI 247 | NtRemoveProcessDebug( 248 | _In_ HANDLE ProcessHandle, 249 | _In_ HANDLE DebugObjectHandle 250 | ); 251 | 252 | NTSYSCALLAPI 253 | NTSTATUS 254 | NTAPI 255 | NtSetInformationDebugObject( 256 | _In_ HANDLE DebugObjectHandle, 257 | _In_ DEBUGOBJECTINFOCLASS DebugObjectInformationClass, 258 | _In_ PVOID DebugInformation, 259 | _In_ ULONG DebugInformationLength, 260 | _Out_opt_ PULONG ReturnLength 261 | ); 262 | 263 | NTSYSCALLAPI 264 | NTSTATUS 265 | NTAPI 266 | NtWaitForDebugEvent( 267 | _In_ HANDLE DebugObjectHandle, 268 | _In_ BOOLEAN Alertable, 269 | _In_opt_ PLARGE_INTEGER Timeout, 270 | _Out_ PDBGUI_WAIT_STATE_CHANGE WaitStateChange 271 | ); 272 | 273 | // Debugging UI 274 | 275 | NTSYSAPI 276 | NTSTATUS 277 | NTAPI 278 | DbgUiConnectToDbg( 279 | VOID 280 | ); 281 | 282 | NTSYSAPI 283 | HANDLE 284 | NTAPI 285 | DbgUiGetThreadDebugObject( 286 | VOID 287 | ); 288 | 289 | NTSYSAPI 290 | VOID 291 | NTAPI 292 | DbgUiSetThreadDebugObject( 293 | _In_ HANDLE DebugObject 294 | ); 295 | 296 | NTSYSAPI 297 | NTSTATUS 298 | NTAPI 299 | DbgUiWaitStateChange( 300 | _Out_ PDBGUI_WAIT_STATE_CHANGE StateChange, 301 | _In_opt_ PLARGE_INTEGER Timeout 302 | ); 303 | 304 | NTSYSAPI 305 | NTSTATUS 306 | NTAPI 307 | DbgUiContinue( 308 | _In_ PCLIENT_ID AppClientId, 309 | _In_ NTSTATUS ContinueStatus 310 | ); 311 | 312 | NTSYSAPI 313 | NTSTATUS 314 | NTAPI 315 | DbgUiStopDebugging( 316 | _In_ HANDLE Process 317 | ); 318 | 319 | NTSYSAPI 320 | NTSTATUS 321 | NTAPI 322 | DbgUiDebugActiveProcess( 323 | _In_ HANDLE Process 324 | ); 325 | 326 | NTSYSAPI 327 | VOID 328 | NTAPI 329 | DbgUiRemoteBreakin( 330 | _In_ PVOID Context 331 | ); 332 | 333 | NTSYSAPI 334 | NTSTATUS 335 | NTAPI 336 | DbgUiIssueRemoteBreakin( 337 | _In_ HANDLE Process 338 | ); 339 | 340 | NTSYSAPI 341 | NTSTATUS 342 | NTAPI 343 | DbgUiConvertStateChangeStructure( 344 | _In_ PDBGUI_WAIT_STATE_CHANGE StateChange, 345 | _Out_ LPDEBUG_EVENT DebugEvent 346 | ); 347 | 348 | NTSYSAPI 349 | NTSTATUS 350 | NTAPI 351 | DbgUiConvertStateChangeStructureEx( 352 | _In_ PDBGUI_WAIT_STATE_CHANGE StateChange, 353 | _Out_ LPDEBUG_EVENT DebugEvent 354 | ); 355 | 356 | struct _EVENT_FILTER_DESCRIPTOR; 357 | 358 | typedef VOID (NTAPI *PENABLECALLBACK)( 359 | _In_ LPCGUID SourceId, 360 | _In_ ULONG IsEnabled, 361 | _In_ UCHAR Level, 362 | _In_ ULONGLONG MatchAnyKeyword, 363 | _In_ ULONGLONG MatchAllKeyword, 364 | _In_opt_ struct _EVENT_FILTER_DESCRIPTOR *FilterData, 365 | _Inout_opt_ PVOID CallbackContext 366 | ); 367 | 368 | typedef ULONGLONG REGHANDLE, *PREGHANDLE; 369 | 370 | NTSYSAPI 371 | NTSTATUS 372 | NTAPI 373 | EtwEventRegister( 374 | _In_ LPCGUID ProviderId, 375 | _In_opt_ PENABLECALLBACK EnableCallback, 376 | _In_opt_ PVOID CallbackContext, 377 | _Out_ PREGHANDLE RegHandle 378 | ); 379 | 380 | #endif 381 | -------------------------------------------------------------------------------- /3rdparty/phnt/include/phnt_ntdef.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Native definition support 3 | * 4 | * This file is part of System Informer. 5 | */ 6 | 7 | #ifndef _PHNT_NTDEF_H 8 | #define _PHNT_NTDEF_H 9 | 10 | #ifndef _NTDEF_ 11 | #define _NTDEF_ 12 | 13 | // This header file provides basic NT types not included in Win32. If you have included winnt.h 14 | // (perhaps indirectly), you must use this file instead of ntdef.h. 15 | 16 | #ifndef NOTHING 17 | #define NOTHING 18 | #endif 19 | 20 | // Basic types 21 | 22 | typedef struct _QUAD 23 | { 24 | union 25 | { 26 | __int64 UseThisFieldToCopy; 27 | double DoNotUseThisField; 28 | }; 29 | } QUAD, *PQUAD; 30 | 31 | // This isn't in NT, but it's useful. 32 | typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _QUAD_PTR 33 | { 34 | ULONG_PTR DoNotUseThisField1; 35 | ULONG_PTR DoNotUseThisField2; 36 | } QUAD_PTR, *PQUAD_PTR; 37 | 38 | typedef ULONG LOGICAL; 39 | typedef ULONG *PLOGICAL; 40 | 41 | typedef _Return_type_success_(return >= 0) LONG NTSTATUS; 42 | typedef NTSTATUS *PNTSTATUS; 43 | 44 | // Cardinal types 45 | 46 | typedef char CCHAR; 47 | typedef short CSHORT; 48 | typedef ULONG CLONG; 49 | 50 | typedef CCHAR *PCCHAR; 51 | typedef CSHORT *PCSHORT; 52 | typedef CLONG *PCLONG; 53 | 54 | typedef PCSTR PCSZ; 55 | 56 | // Specific 57 | 58 | typedef UCHAR KIRQL, *PKIRQL; 59 | typedef LONG KPRIORITY, *PKPRIORITY; 60 | typedef USHORT RTL_ATOM, *PRTL_ATOM; 61 | 62 | typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS; 63 | 64 | typedef struct _LARGE_INTEGER_128 65 | { 66 | LONGLONG QuadPart[2]; 67 | } LARGE_INTEGER_128, *PLARGE_INTEGER_128; 68 | 69 | // NT status macros 70 | 71 | #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) 72 | #define NT_INFORMATION(Status) ((((ULONG)(Status)) >> 30) == 1) 73 | #define NT_WARNING(Status) ((((ULONG)(Status)) >> 30) == 2) 74 | #define NT_ERROR(Status) ((((ULONG)(Status)) >> 30) == 3) 75 | 76 | #define NT_FACILITY_MASK 0xfff 77 | #define NT_FACILITY_SHIFT 16 78 | #define NT_FACILITY(Status) ((((ULONG)(Status)) >> NT_FACILITY_SHIFT) & NT_FACILITY_MASK) 79 | 80 | #define NT_NTWIN32(Status) (NT_FACILITY(Status) == FACILITY_NTWIN32) 81 | #define WIN32_FROM_NTSTATUS(Status) (((ULONG)(Status)) & 0xffff) 82 | 83 | // Functions 84 | 85 | #ifndef _WIN64 86 | #define FASTCALL __fastcall 87 | #else 88 | #define FASTCALL 89 | #endif 90 | 91 | // Synchronization enumerations 92 | 93 | typedef enum _EVENT_TYPE 94 | { 95 | NotificationEvent, 96 | SynchronizationEvent 97 | } EVENT_TYPE; 98 | 99 | typedef enum _TIMER_TYPE 100 | { 101 | NotificationTimer, 102 | SynchronizationTimer 103 | } TIMER_TYPE; 104 | 105 | typedef enum _WAIT_TYPE 106 | { 107 | WaitAll, 108 | WaitAny, 109 | WaitNotification 110 | } WAIT_TYPE; 111 | 112 | // Strings 113 | 114 | typedef struct _STRING 115 | { 116 | USHORT Length; 117 | USHORT MaximumLength; 118 | _Field_size_bytes_part_opt_(MaximumLength, Length) PCHAR Buffer; 119 | } STRING, *PSTRING, ANSI_STRING, *PANSI_STRING, OEM_STRING, *POEM_STRING; 120 | 121 | typedef STRING UTF8_STRING; 122 | typedef PSTRING PUTF8_STRING; 123 | 124 | typedef const STRING *PCSTRING; 125 | typedef const ANSI_STRING *PCANSI_STRING; 126 | typedef const OEM_STRING *PCOEM_STRING; 127 | 128 | typedef struct _UNICODE_STRING 129 | { 130 | USHORT Length; 131 | USHORT MaximumLength; 132 | _Field_size_bytes_part_(MaximumLength, Length) PWCH Buffer; 133 | } UNICODE_STRING, *PUNICODE_STRING; 134 | 135 | typedef const UNICODE_STRING *PCUNICODE_STRING; 136 | 137 | #define RTL_CONSTANT_STRING(s) { sizeof(s) - sizeof((s)[0]), sizeof(s), s } 138 | 139 | // Balanced tree node 140 | 141 | #define RTL_BALANCED_NODE_RESERVED_PARENT_MASK 3 142 | 143 | typedef struct _RTL_BALANCED_NODE 144 | { 145 | union 146 | { 147 | struct _RTL_BALANCED_NODE *Children[2]; 148 | struct 149 | { 150 | struct _RTL_BALANCED_NODE *Left; 151 | struct _RTL_BALANCED_NODE *Right; 152 | }; 153 | }; 154 | union 155 | { 156 | UCHAR Red : 1; 157 | UCHAR Balance : 2; 158 | ULONG_PTR ParentValue; 159 | }; 160 | } RTL_BALANCED_NODE, *PRTL_BALANCED_NODE; 161 | 162 | #define RTL_BALANCED_NODE_GET_PARENT_POINTER(Node) \ 163 | ((PRTL_BALANCED_NODE)((Node)->ParentValue & ~RTL_BALANCED_NODE_RESERVED_PARENT_MASK)) 164 | 165 | // Portability 166 | 167 | typedef struct _SINGLE_LIST_ENTRY32 168 | { 169 | ULONG Next; 170 | } SINGLE_LIST_ENTRY32, *PSINGLE_LIST_ENTRY32; 171 | 172 | typedef struct _STRING32 173 | { 174 | USHORT Length; 175 | USHORT MaximumLength; 176 | ULONG Buffer; 177 | } STRING32, *PSTRING32; 178 | 179 | typedef STRING32 UNICODE_STRING32, *PUNICODE_STRING32; 180 | typedef STRING32 ANSI_STRING32, *PANSI_STRING32; 181 | 182 | typedef struct _STRING64 183 | { 184 | USHORT Length; 185 | USHORT MaximumLength; 186 | ULONGLONG Buffer; 187 | } STRING64, *PSTRING64; 188 | 189 | typedef STRING64 UNICODE_STRING64, *PUNICODE_STRING64; 190 | typedef STRING64 ANSI_STRING64, *PANSI_STRING64; 191 | 192 | // Object attributes 193 | 194 | #define OBJ_PROTECT_CLOSE 0x00000001 195 | #define OBJ_INHERIT 0x00000002 196 | #define OBJ_AUDIT_OBJECT_CLOSE 0x00000004 197 | #define OBJ_PERMANENT 0x00000010 198 | #define OBJ_EXCLUSIVE 0x00000020 199 | #define OBJ_CASE_INSENSITIVE 0x00000040 200 | #define OBJ_OPENIF 0x00000080 201 | #define OBJ_OPENLINK 0x00000100 202 | #define OBJ_KERNEL_HANDLE 0x00000200 203 | #define OBJ_FORCE_ACCESS_CHECK 0x00000400 204 | #define OBJ_IGNORE_IMPERSONATED_DEVICEMAP 0x00000800 205 | #define OBJ_DONT_REPARSE 0x00001000 206 | #define OBJ_VALID_ATTRIBUTES 0x00001ff2 207 | 208 | typedef struct _OBJECT_ATTRIBUTES 209 | { 210 | ULONG Length; 211 | HANDLE RootDirectory; 212 | PUNICODE_STRING ObjectName; 213 | ULONG Attributes; 214 | PVOID SecurityDescriptor; // PSECURITY_DESCRIPTOR; 215 | PVOID SecurityQualityOfService; // PSECURITY_QUALITY_OF_SERVICE 216 | } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; 217 | 218 | typedef const OBJECT_ATTRIBUTES *PCOBJECT_ATTRIBUTES; 219 | 220 | #define InitializeObjectAttributes(p, n, a, r, s) { \ 221 | (p)->Length = sizeof(OBJECT_ATTRIBUTES); \ 222 | (p)->RootDirectory = r; \ 223 | (p)->Attributes = a; \ 224 | (p)->ObjectName = n; \ 225 | (p)->SecurityDescriptor = s; \ 226 | (p)->SecurityQualityOfService = NULL; \ 227 | } 228 | 229 | #define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a) { sizeof(OBJECT_ATTRIBUTES), NULL, n, a, NULL, NULL } 230 | #define RTL_INIT_OBJECT_ATTRIBUTES(n, a) RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a) 231 | 232 | #define OBJ_NAME_PATH_SEPARATOR ((WCHAR)L'\\') 233 | #define OBJ_NAME_ALTPATH_SEPARATOR ((WCHAR)L'/') 234 | 235 | // Portability 236 | 237 | typedef struct _OBJECT_ATTRIBUTES64 238 | { 239 | ULONG Length; 240 | ULONG64 RootDirectory; 241 | ULONG64 ObjectName; 242 | ULONG Attributes; 243 | ULONG64 SecurityDescriptor; 244 | ULONG64 SecurityQualityOfService; 245 | } OBJECT_ATTRIBUTES64, *POBJECT_ATTRIBUTES64; 246 | 247 | typedef const OBJECT_ATTRIBUTES64 *PCOBJECT_ATTRIBUTES64; 248 | 249 | typedef struct _OBJECT_ATTRIBUTES32 250 | { 251 | ULONG Length; 252 | ULONG RootDirectory; 253 | ULONG ObjectName; 254 | ULONG Attributes; 255 | ULONG SecurityDescriptor; 256 | ULONG SecurityQualityOfService; 257 | } OBJECT_ATTRIBUTES32, *POBJECT_ATTRIBUTES32; 258 | 259 | typedef const OBJECT_ATTRIBUTES32 *PCOBJECT_ATTRIBUTES32; 260 | 261 | // Product types 262 | 263 | typedef enum _NT_PRODUCT_TYPE 264 | { 265 | NtProductWinNt = 1, 266 | NtProductLanManNt, 267 | NtProductServer 268 | } NT_PRODUCT_TYPE, *PNT_PRODUCT_TYPE; 269 | 270 | typedef enum _SUITE_TYPE 271 | { 272 | SmallBusiness, 273 | Enterprise, 274 | BackOffice, 275 | CommunicationServer, 276 | TerminalServer, 277 | SmallBusinessRestricted, 278 | EmbeddedNT, 279 | DataCenter, 280 | SingleUserTS, 281 | Personal, 282 | Blade, 283 | EmbeddedRestricted, 284 | SecurityAppliance, 285 | StorageServer, 286 | ComputeServer, 287 | WHServer, 288 | PhoneNT, 289 | MaxSuiteType 290 | } SUITE_TYPE; 291 | 292 | // Specific 293 | 294 | typedef struct _CLIENT_ID 295 | { 296 | HANDLE UniqueProcess; 297 | HANDLE UniqueThread; 298 | } CLIENT_ID, *PCLIENT_ID; 299 | 300 | typedef struct _CLIENT_ID32 301 | { 302 | ULONG UniqueProcess; 303 | ULONG UniqueThread; 304 | } CLIENT_ID32, *PCLIENT_ID32; 305 | 306 | typedef struct _CLIENT_ID64 307 | { 308 | ULONGLONG UniqueProcess; 309 | ULONGLONG UniqueThread; 310 | } CLIENT_ID64, *PCLIENT_ID64; 311 | 312 | #include 313 | 314 | typedef struct _KSYSTEM_TIME 315 | { 316 | ULONG LowPart; 317 | LONG High1Time; 318 | LONG High2Time; 319 | } KSYSTEM_TIME, *PKSYSTEM_TIME; 320 | 321 | #include 322 | 323 | // NT macros used to test, set and clear flags 324 | #ifndef FlagOn 325 | #define FlagOn(_F, _SF) ((_F) & (_SF)) 326 | #endif 327 | #ifndef BooleanFlagOn 328 | #define BooleanFlagOn(F, SF) ((BOOLEAN)(((F) & (SF)) != 0)) 329 | #endif 330 | #ifndef SetFlag 331 | #define SetFlag(_F, _SF) ((_F) |= (_SF)) 332 | #endif 333 | #ifndef ClearFlag 334 | #define ClearFlag(_F, _SF) ((_F) &= ~(_SF)) 335 | #endif 336 | 337 | #endif 338 | 339 | #endif 340 | -------------------------------------------------------------------------------- /3rdparty/phnt/include/ntpfapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Prefetcher (Superfetch) support functions 3 | * 4 | * This file is part of System Informer. 5 | */ 6 | 7 | #ifndef _NTPFAPI_H 8 | #define _NTPFAPI_H 9 | 10 | // begin_private 11 | 12 | // Prefetch 13 | 14 | typedef enum _PF_BOOT_PHASE_ID 15 | { 16 | PfKernelInitPhase = 0, 17 | PfBootDriverInitPhase = 90, 18 | PfSystemDriverInitPhase = 120, 19 | PfSessionManagerInitPhase = 150, 20 | PfSMRegistryInitPhase = 180, 21 | PfVideoInitPhase = 210, 22 | PfPostVideoInitPhase = 240, 23 | PfBootAcceptedRegistryInitPhase = 270, 24 | PfUserShellReadyPhase = 300, 25 | PfMaxBootPhaseId = 900 26 | } PF_BOOT_PHASE_ID; 27 | 28 | typedef enum _PF_ENABLE_STATUS 29 | { 30 | PfSvNotSpecified, 31 | PfSvEnabled, 32 | PfSvDisabled, 33 | PfSvMaxEnableStatus 34 | } PF_ENABLE_STATUS; 35 | 36 | typedef struct _PF_TRACE_LIMITS 37 | { 38 | ULONG MaxNumPages; 39 | ULONG MaxNumSections; 40 | LONGLONG TimerPeriod; 41 | } PF_TRACE_LIMITS, *PPF_TRACE_LIMITS; 42 | 43 | typedef struct _PF_SYSTEM_PREFETCH_PARAMETERS 44 | { 45 | PF_ENABLE_STATUS EnableStatus[2]; 46 | PF_TRACE_LIMITS TraceLimits[2]; 47 | ULONG MaxNumActiveTraces; 48 | ULONG MaxNumSavedTraces; 49 | WCHAR RootDirPath[32]; 50 | WCHAR HostingApplicationList[128]; 51 | } PF_SYSTEM_PREFETCH_PARAMETERS, *PPF_SYSTEM_PREFETCH_PARAMETERS; 52 | 53 | #define PF_BOOT_CONTROL_VERSION 1 54 | 55 | typedef struct _PF_BOOT_CONTROL 56 | { 57 | ULONG Version; 58 | ULONG DisableBootPrefetching; 59 | } PF_BOOT_CONTROL, *PPF_BOOT_CONTROL; 60 | 61 | typedef enum _PREFETCHER_INFORMATION_CLASS 62 | { 63 | PrefetcherRetrieveTrace = 1, // q: CHAR[] 64 | PrefetcherSystemParameters, // q: PF_SYSTEM_PREFETCH_PARAMETERS 65 | PrefetcherBootPhase, // s: PF_BOOT_PHASE_ID 66 | PrefetcherSpare1, // PrefetcherRetrieveBootLoaderTrace // q: CHAR[] 67 | PrefetcherBootControl, // s: PF_BOOT_CONTROL 68 | PrefetcherScenarioPolicyControl, 69 | PrefetcherSpare2, 70 | PrefetcherAppLaunchScenarioControl, 71 | PrefetcherInformationMax 72 | } PREFETCHER_INFORMATION_CLASS; 73 | 74 | #define PREFETCHER_INFORMATION_VERSION 23 // rev 75 | #define PREFETCHER_INFORMATION_MAGIC ('kuhC') // rev 76 | 77 | typedef struct _PREFETCHER_INFORMATION 78 | { 79 | _In_ ULONG Version; 80 | _In_ ULONG Magic; 81 | _In_ PREFETCHER_INFORMATION_CLASS PrefetcherInformationClass; 82 | _Inout_ PVOID PrefetcherInformation; 83 | _Inout_ ULONG PrefetcherInformationLength; 84 | } PREFETCHER_INFORMATION, *PPREFETCHER_INFORMATION; 85 | 86 | // Superfetch 87 | 88 | typedef struct _PF_SYSTEM_SUPERFETCH_PARAMETERS 89 | { 90 | ULONG EnabledComponents; 91 | ULONG BootID; 92 | ULONG SavedSectInfoTracesMax; 93 | ULONG SavedPageAccessTracesMax; 94 | ULONG ScenarioPrefetchTimeoutStandby; 95 | ULONG ScenarioPrefetchTimeoutHibernate; 96 | ULONG ScenarioPrefetchTimeoutHiberBoot; 97 | } PF_SYSTEM_SUPERFETCH_PARAMETERS, *PPF_SYSTEM_SUPERFETCH_PARAMETERS; 98 | 99 | #define PF_PFN_PRIO_REQUEST_VERSION 1 100 | #define PF_PFN_PRIO_REQUEST_QUERY_MEMORY_LIST 0x1 101 | #define PF_PFN_PRIO_REQUEST_VALID_FLAGS 0x1 102 | 103 | typedef struct _PF_PFN_PRIO_REQUEST 104 | { 105 | ULONG Version; 106 | ULONG RequestFlags; 107 | ULONG_PTR PfnCount; 108 | SYSTEM_MEMORY_LIST_INFORMATION MemInfo; 109 | MMPFN_IDENTITY PageData[256]; 110 | } PF_PFN_PRIO_REQUEST, *PPF_PFN_PRIO_REQUEST; 111 | 112 | typedef enum _PFS_PRIVATE_PAGE_SOURCE_TYPE 113 | { 114 | PfsPrivateSourceKernel, 115 | PfsPrivateSourceSession, 116 | PfsPrivateSourceProcess, 117 | PfsPrivateSourceMax 118 | } PFS_PRIVATE_PAGE_SOURCE_TYPE; 119 | 120 | typedef struct _PFS_PRIVATE_PAGE_SOURCE 121 | { 122 | PFS_PRIVATE_PAGE_SOURCE_TYPE Type; 123 | union 124 | { 125 | ULONG SessionId; 126 | ULONG ProcessId; 127 | }; 128 | ULONG ImagePathHash; 129 | ULONG_PTR UniqueProcessHash; 130 | } PFS_PRIVATE_PAGE_SOURCE, *PPFS_PRIVATE_PAGE_SOURCE; 131 | 132 | typedef struct _PF_PRIVSOURCE_INFO 133 | { 134 | PFS_PRIVATE_PAGE_SOURCE DbInfo; 135 | PVOID EProcess; 136 | SIZE_T WsPrivatePages; 137 | SIZE_T TotalPrivatePages; 138 | ULONG SessionID; 139 | CHAR ImageName[16]; 140 | union { 141 | ULONG_PTR WsSwapPages; // process only PF_PRIVSOURCE_QUERY_WS_SWAP_PAGES. 142 | ULONG_PTR SessionPagedPoolPages; // session only. 143 | ULONG_PTR StoreSizePages; // process only PF_PRIVSOURCE_QUERY_STORE_INFO. 144 | }; 145 | ULONG_PTR WsTotalPages; // process/session only. 146 | ULONG DeepFreezeTimeMs; // process only. 147 | ULONG ModernApp : 1; // process only. 148 | ULONG DeepFrozen : 1; // process only. If set, DeepFreezeTimeMs contains the time at which the freeze occurred 149 | ULONG Foreground : 1; // process only. 150 | ULONG PerProcessStore : 1; // process only. 151 | ULONG Spare : 28; 152 | } PF_PRIVSOURCE_INFO, *PPF_PRIVSOURCE_INFO; 153 | 154 | #define PF_PRIVSOURCE_QUERY_REQUEST_VERSION 8 155 | 156 | typedef struct _PF_PRIVSOURCE_QUERY_REQUEST 157 | { 158 | ULONG Version; 159 | ULONG Flags; 160 | ULONG InfoCount; 161 | PF_PRIVSOURCE_INFO InfoArray[1]; 162 | } PF_PRIVSOURCE_QUERY_REQUEST, *PPF_PRIVSOURCE_QUERY_REQUEST; 163 | 164 | typedef enum _PF_PHASED_SCENARIO_TYPE 165 | { 166 | PfScenarioTypeNone, 167 | PfScenarioTypeStandby, 168 | PfScenarioTypeHibernate, 169 | PfScenarioTypeFUS, 170 | PfScenarioTypeMax 171 | } PF_PHASED_SCENARIO_TYPE; 172 | 173 | #define PF_SCENARIO_PHASE_INFO_VERSION 4 174 | 175 | typedef struct _PF_SCENARIO_PHASE_INFO 176 | { 177 | ULONG Version; 178 | PF_PHASED_SCENARIO_TYPE ScenType; 179 | ULONG PhaseId; 180 | ULONG SequenceNumber; 181 | ULONG Flags; 182 | ULONG FUSUserId; 183 | } PF_SCENARIO_PHASE_INFO, *PPF_SCENARIO_PHASE_INFO; 184 | 185 | typedef struct _PF_MEMORY_LIST_NODE 186 | { 187 | ULONGLONG Node : 8; 188 | ULONGLONG Spare : 56; 189 | ULONGLONG StandbyLowPageCount; 190 | ULONGLONG StandbyMediumPageCount; 191 | ULONGLONG StandbyHighPageCount; 192 | ULONGLONG FreePageCount; 193 | ULONGLONG ModifiedPageCount; 194 | } PF_MEMORY_LIST_NODE, *PPF_MEMORY_LIST_NODE; 195 | 196 | #define PF_MEMORY_LIST_INFO_VERSION 1 197 | 198 | typedef struct _PF_MEMORY_LIST_INFO 199 | { 200 | ULONG Version; 201 | ULONG Size; 202 | ULONG NodeCount; 203 | PF_MEMORY_LIST_NODE Nodes[1]; 204 | } PF_MEMORY_LIST_INFO, *PPF_MEMORY_LIST_INFO; 205 | 206 | typedef struct _PF_PHYSICAL_MEMORY_RANGE 207 | { 208 | ULONG_PTR BasePfn; 209 | ULONG_PTR PageCount; 210 | } PF_PHYSICAL_MEMORY_RANGE, *PPF_PHYSICAL_MEMORY_RANGE; 211 | 212 | #define PF_PHYSICAL_MEMORY_RANGE_INFO_V1_VERSION 1 213 | 214 | typedef struct _PF_PHYSICAL_MEMORY_RANGE_INFO_V1 215 | { 216 | ULONG Version; 217 | ULONG RangeCount; 218 | PF_PHYSICAL_MEMORY_RANGE Ranges[1]; 219 | } PF_PHYSICAL_MEMORY_RANGE_INFO_V1, *PPF_PHYSICAL_MEMORY_RANGE_INFO_V1; 220 | 221 | #define PF_PHYSICAL_MEMORY_RANGE_INFO_V2_VERSION 2 222 | 223 | typedef struct _PF_PHYSICAL_MEMORY_RANGE_INFO_V2 224 | { 225 | ULONG Version; 226 | ULONG Flags; 227 | ULONG RangeCount; 228 | PF_PHYSICAL_MEMORY_RANGE Ranges[ANYSIZE_ARRAY]; 229 | } PF_PHYSICAL_MEMORY_RANGE_INFO_V2, *PPF_PHYSICAL_MEMORY_RANGE_INFO_V2; 230 | 231 | // begin_rev 232 | 233 | #define PF_REPURPOSED_BY_PREFETCH_INFO_VERSION 1 234 | 235 | typedef struct _PF_REPURPOSED_BY_PREFETCH_INFO 236 | { 237 | ULONG Version; 238 | ULONG RepurposedByPrefetch; 239 | } PF_REPURPOSED_BY_PREFETCH_INFO, *PPF_REPURPOSED_BY_PREFETCH_INFO; 240 | 241 | // end_rev 242 | 243 | typedef enum _SUPERFETCH_INFORMATION_CLASS 244 | { 245 | SuperfetchRetrieveTrace = 1, // q: CHAR[] 246 | SuperfetchSystemParameters, // q: PF_SYSTEM_SUPERFETCH_PARAMETERS 247 | SuperfetchLogEvent, 248 | SuperfetchGenerateTrace, 249 | SuperfetchPrefetch, 250 | SuperfetchPfnQuery, // q: PF_PFN_PRIO_REQUEST 251 | SuperfetchPfnSetPriority, 252 | SuperfetchPrivSourceQuery, // q: PF_PRIVSOURCE_QUERY_REQUEST 253 | SuperfetchSequenceNumberQuery, // q: ULONG 254 | SuperfetchScenarioPhase, // 10 255 | SuperfetchWorkerPriority, 256 | SuperfetchScenarioQuery, // q: PF_SCENARIO_PHASE_INFO 257 | SuperfetchScenarioPrefetch, 258 | SuperfetchRobustnessControl, 259 | SuperfetchTimeControl, 260 | SuperfetchMemoryListQuery, // q: PF_MEMORY_LIST_INFO 261 | SuperfetchMemoryRangesQuery, // q: PF_PHYSICAL_MEMORY_RANGE_INFO 262 | SuperfetchTracingControl, 263 | SuperfetchTrimWhileAgingControl, 264 | SuperfetchRepurposedByPrefetch, // q: PF_REPURPOSED_BY_PREFETCH_INFO // rev 265 | SuperfetchChannelPowerRequest, 266 | SuperfetchMovePages, 267 | SuperfetchVirtualQuery, 268 | SuperfetchCombineStatsQuery, 269 | SuperfetchSetMinWsAgeRate, 270 | SuperfetchDeprioritizeOldPagesInWs, 271 | SuperfetchFileExtentsQuery, 272 | SuperfetchGpuUtilizationQuery, // PF_GPU_UTILIZATION_INFO 273 | SuperfetchInformationMax 274 | } SUPERFETCH_INFORMATION_CLASS; 275 | 276 | #define SUPERFETCH_INFORMATION_VERSION 45 // rev 277 | #define SUPERFETCH_INFORMATION_MAGIC ('kuhC') // rev 278 | 279 | typedef struct _SUPERFETCH_INFORMATION 280 | { 281 | _In_ ULONG Version; 282 | _In_ ULONG Magic; 283 | _In_ SUPERFETCH_INFORMATION_CLASS SuperfetchInformationClass; 284 | _Inout_ PVOID SuperfetchInformation; 285 | _Inout_ ULONG SuperfetchInformationLength; 286 | } SUPERFETCH_INFORMATION, *PSUPERFETCH_INFORMATION; 287 | 288 | // end_private 289 | 290 | #endif 291 | -------------------------------------------------------------------------------- /3rdparty/phnt/include/nttp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Thread Pool support functions 3 | * 4 | * This file is part of System Informer. 5 | */ 6 | 7 | #ifndef _NTTP_H 8 | #define _NTTP_H 9 | 10 | // Some types are already defined in winnt.h. 11 | 12 | typedef struct _TP_ALPC TP_ALPC, *PTP_ALPC; 13 | 14 | // private 15 | typedef VOID (NTAPI *PTP_ALPC_CALLBACK)( 16 | _Inout_ PTP_CALLBACK_INSTANCE Instance, 17 | _Inout_opt_ PVOID Context, 18 | _In_ PTP_ALPC Alpc 19 | ); 20 | 21 | // rev 22 | typedef VOID (NTAPI *PTP_ALPC_CALLBACK_EX)( 23 | _Inout_ PTP_CALLBACK_INSTANCE Instance, 24 | _Inout_opt_ PVOID Context, 25 | _In_ PTP_ALPC Alpc, 26 | _In_ PVOID ApcContext 27 | ); 28 | 29 | #if (PHNT_VERSION >= PHNT_VISTA) 30 | 31 | // private 32 | _Check_return_ 33 | NTSYSAPI 34 | NTSTATUS 35 | NTAPI 36 | TpAllocPool( 37 | _Out_ PTP_POOL *PoolReturn, 38 | _Reserved_ PVOID Reserved 39 | ); 40 | 41 | // winbase:CloseThreadpool 42 | NTSYSAPI 43 | VOID 44 | NTAPI 45 | TpReleasePool( 46 | _Inout_ PTP_POOL Pool 47 | ); 48 | 49 | // winbase:SetThreadpoolThreadMaximum 50 | NTSYSAPI 51 | VOID 52 | NTAPI 53 | TpSetPoolMaxThreads( 54 | _Inout_ PTP_POOL Pool, 55 | _In_ ULONG MaxThreads 56 | ); 57 | 58 | // private 59 | NTSYSAPI 60 | NTSTATUS 61 | NTAPI 62 | TpSetPoolMinThreads( 63 | _Inout_ PTP_POOL Pool, 64 | _In_ ULONG MinThreads 65 | ); 66 | 67 | #if (PHNT_VERSION >= PHNT_WIN7) 68 | // rev 69 | NTSYSAPI 70 | NTSTATUS 71 | NTAPI 72 | TpQueryPoolStackInformation( 73 | _In_ PTP_POOL Pool, 74 | _Out_ PTP_POOL_STACK_INFORMATION PoolStackInformation 75 | ); 76 | #endif 77 | 78 | #if (PHNT_VERSION >= PHNT_WIN7) 79 | // rev 80 | NTSYSAPI 81 | NTSTATUS 82 | NTAPI 83 | TpSetPoolStackInformation( 84 | _Inout_ PTP_POOL Pool, 85 | _In_ PTP_POOL_STACK_INFORMATION PoolStackInformation 86 | ); 87 | #endif 88 | 89 | // private 90 | _Check_return_ 91 | NTSYSAPI 92 | NTSTATUS 93 | NTAPI 94 | TpAllocCleanupGroup( 95 | _Out_ PTP_CLEANUP_GROUP *CleanupGroupReturn 96 | ); 97 | 98 | // winbase:CloseThreadpoolCleanupGroup 99 | NTSYSAPI 100 | VOID 101 | NTAPI 102 | TpReleaseCleanupGroup( 103 | _Inout_ PTP_CLEANUP_GROUP CleanupGroup 104 | ); 105 | 106 | // winbase:CloseThreadpoolCleanupGroupMembers 107 | NTSYSAPI 108 | VOID 109 | NTAPI 110 | TpReleaseCleanupGroupMembers( 111 | _Inout_ PTP_CLEANUP_GROUP CleanupGroup, 112 | _In_ LOGICAL CancelPendingCallbacks, 113 | _Inout_opt_ PVOID CleanupParameter 114 | ); 115 | 116 | // winbase:SetEventWhenCallbackReturns 117 | NTSYSAPI 118 | VOID 119 | NTAPI 120 | TpCallbackSetEventOnCompletion( 121 | _Inout_ PTP_CALLBACK_INSTANCE Instance, 122 | _In_ HANDLE Event 123 | ); 124 | 125 | // winbase:ReleaseSemaphoreWhenCallbackReturns 126 | NTSYSAPI 127 | VOID 128 | NTAPI 129 | TpCallbackReleaseSemaphoreOnCompletion( 130 | _Inout_ PTP_CALLBACK_INSTANCE Instance, 131 | _In_ HANDLE Semaphore, 132 | _In_ ULONG ReleaseCount 133 | ); 134 | 135 | // winbase:ReleaseMutexWhenCallbackReturns 136 | NTSYSAPI 137 | VOID 138 | NTAPI 139 | TpCallbackReleaseMutexOnCompletion( 140 | _Inout_ PTP_CALLBACK_INSTANCE Instance, 141 | _In_ HANDLE Mutex 142 | ); 143 | 144 | // winbase:LeaveCriticalSectionWhenCallbackReturns 145 | NTSYSAPI 146 | VOID 147 | NTAPI 148 | TpCallbackLeaveCriticalSectionOnCompletion( 149 | _Inout_ PTP_CALLBACK_INSTANCE Instance, 150 | _Inout_ PRTL_CRITICAL_SECTION CriticalSection 151 | ); 152 | 153 | // winbase:FreeLibraryWhenCallbackReturns 154 | NTSYSAPI 155 | VOID 156 | NTAPI 157 | TpCallbackUnloadDllOnCompletion( 158 | _Inout_ PTP_CALLBACK_INSTANCE Instance, 159 | _In_ PVOID DllHandle 160 | ); 161 | 162 | // winbase:CallbackMayRunLong 163 | NTSYSAPI 164 | NTSTATUS 165 | NTAPI 166 | TpCallbackMayRunLong( 167 | _Inout_ PTP_CALLBACK_INSTANCE Instance 168 | ); 169 | 170 | // winbase:DisassociateCurrentThreadFromCallback 171 | NTSYSAPI 172 | VOID 173 | NTAPI 174 | TpDisassociateCallback( 175 | _Inout_ PTP_CALLBACK_INSTANCE Instance 176 | ); 177 | 178 | // winbase:TrySubmitThreadpoolCallback 179 | _Check_return_ 180 | NTSYSAPI 181 | NTSTATUS 182 | NTAPI 183 | TpSimpleTryPost( 184 | _In_ PTP_SIMPLE_CALLBACK Callback, 185 | _Inout_opt_ PVOID Context, 186 | _In_opt_ PTP_CALLBACK_ENVIRON CallbackEnviron 187 | ); 188 | 189 | // private 190 | _Check_return_ 191 | NTSYSAPI 192 | NTSTATUS 193 | NTAPI 194 | TpAllocWork( 195 | _Out_ PTP_WORK *WorkReturn, 196 | _In_ PTP_WORK_CALLBACK Callback, 197 | _Inout_opt_ PVOID Context, 198 | _In_opt_ PTP_CALLBACK_ENVIRON CallbackEnviron 199 | ); 200 | 201 | // winbase:CloseThreadpoolWork 202 | NTSYSAPI 203 | VOID 204 | NTAPI 205 | TpReleaseWork( 206 | _Inout_ PTP_WORK Work 207 | ); 208 | 209 | // winbase:SubmitThreadpoolWork 210 | NTSYSAPI 211 | VOID 212 | NTAPI 213 | TpPostWork( 214 | _Inout_ PTP_WORK Work 215 | ); 216 | 217 | // winbase:WaitForThreadpoolWorkCallbacks 218 | NTSYSAPI 219 | VOID 220 | NTAPI 221 | TpWaitForWork( 222 | _Inout_ PTP_WORK Work, 223 | _In_ LOGICAL CancelPendingCallbacks 224 | ); 225 | 226 | // private 227 | _Check_return_ 228 | NTSYSAPI 229 | NTSTATUS 230 | NTAPI 231 | TpAllocTimer( 232 | _Out_ PTP_TIMER *Timer, 233 | _In_ PTP_TIMER_CALLBACK Callback, 234 | _Inout_opt_ PVOID Context, 235 | _In_opt_ PTP_CALLBACK_ENVIRON CallbackEnviron 236 | ); 237 | 238 | // winbase:CloseThreadpoolTimer 239 | NTSYSAPI 240 | VOID 241 | NTAPI 242 | TpReleaseTimer( 243 | _Inout_ PTP_TIMER Timer 244 | ); 245 | 246 | // winbase:SetThreadpoolTimer 247 | NTSYSAPI 248 | VOID 249 | NTAPI 250 | TpSetTimer( 251 | _Inout_ PTP_TIMER Timer, 252 | _In_opt_ PLARGE_INTEGER DueTime, 253 | _In_ ULONG Period, 254 | _In_opt_ ULONG WindowLength 255 | ); 256 | 257 | #if (PHNT_VERSION >= PHNT_WIN8) 258 | // winbase:SetThreadpoolTimerEx 259 | NTSYSAPI 260 | NTSTATUS 261 | NTAPI 262 | TpSetTimerEx( 263 | _Inout_ PTP_TIMER Timer, 264 | _In_opt_ PLARGE_INTEGER DueTime, 265 | _In_ ULONG Period, 266 | _In_opt_ ULONG WindowLength 267 | ); 268 | #endif 269 | 270 | // winbase:IsThreadpoolTimerSet 271 | NTSYSAPI 272 | LOGICAL 273 | NTAPI 274 | TpIsTimerSet( 275 | _In_ PTP_TIMER Timer 276 | ); 277 | 278 | // winbase:WaitForThreadpoolTimerCallbacks 279 | NTSYSAPI 280 | VOID 281 | NTAPI 282 | TpWaitForTimer( 283 | _Inout_ PTP_TIMER Timer, 284 | _In_ LOGICAL CancelPendingCallbacks 285 | ); 286 | 287 | // private 288 | _Check_return_ 289 | NTSYSAPI 290 | NTSTATUS 291 | NTAPI 292 | TpAllocWait( 293 | _Out_ PTP_WAIT *WaitReturn, 294 | _In_ PTP_WAIT_CALLBACK Callback, 295 | _Inout_opt_ PVOID Context, 296 | _In_opt_ PTP_CALLBACK_ENVIRON CallbackEnviron 297 | ); 298 | 299 | // winbase:CloseThreadpoolWait 300 | NTSYSAPI 301 | VOID 302 | NTAPI 303 | TpReleaseWait( 304 | _Inout_ PTP_WAIT Wait 305 | ); 306 | 307 | // winbase:SetThreadpoolWait 308 | NTSYSAPI 309 | VOID 310 | NTAPI 311 | TpSetWait( 312 | _Inout_ PTP_WAIT Wait, 313 | _In_opt_ HANDLE Handle, 314 | _In_opt_ PLARGE_INTEGER Timeout 315 | ); 316 | 317 | #if (PHNT_VERSION >= PHNT_WIN8) 318 | // winbase:SetThreadpoolWaitEx 319 | NTSYSAPI 320 | NTSTATUS 321 | NTAPI 322 | TpSetWaitEx( 323 | _Inout_ PTP_WAIT Wait, 324 | _In_opt_ HANDLE Handle, 325 | _In_opt_ PLARGE_INTEGER Timeout, 326 | _In_opt_ PVOID Reserved 327 | ); 328 | #endif 329 | 330 | // winbase:WaitForThreadpoolWaitCallbacks 331 | NTSYSAPI 332 | VOID 333 | NTAPI 334 | TpWaitForWait( 335 | _Inout_ PTP_WAIT Wait, 336 | _In_ LOGICAL CancelPendingCallbacks 337 | ); 338 | 339 | // private 340 | typedef VOID (NTAPI *PTP_IO_CALLBACK)( 341 | _Inout_ PTP_CALLBACK_INSTANCE Instance, 342 | _Inout_opt_ PVOID Context, 343 | _In_ PVOID ApcContext, 344 | _In_ PIO_STATUS_BLOCK IoSB, 345 | _In_ PTP_IO Io 346 | ); 347 | 348 | // private 349 | _Check_return_ 350 | NTSYSAPI 351 | NTSTATUS 352 | NTAPI 353 | TpAllocIoCompletion( 354 | _Out_ PTP_IO *IoReturn, 355 | _In_ HANDLE File, 356 | _In_ PTP_IO_CALLBACK Callback, 357 | _Inout_opt_ PVOID Context, 358 | _In_opt_ PTP_CALLBACK_ENVIRON CallbackEnviron 359 | ); 360 | 361 | // winbase:CloseThreadpoolIo 362 | NTSYSAPI 363 | VOID 364 | NTAPI 365 | TpReleaseIoCompletion( 366 | _Inout_ PTP_IO Io 367 | ); 368 | 369 | // winbase:StartThreadpoolIo 370 | NTSYSAPI 371 | VOID 372 | NTAPI 373 | TpStartAsyncIoOperation( 374 | _Inout_ PTP_IO Io 375 | ); 376 | 377 | // winbase:CancelThreadpoolIo 378 | NTSYSAPI 379 | VOID 380 | NTAPI 381 | TpCancelAsyncIoOperation( 382 | _Inout_ PTP_IO Io 383 | ); 384 | 385 | // winbase:WaitForThreadpoolIoCallbacks 386 | NTSYSAPI 387 | VOID 388 | NTAPI 389 | TpWaitForIoCompletion( 390 | _Inout_ PTP_IO Io, 391 | _In_ LOGICAL CancelPendingCallbacks 392 | ); 393 | 394 | // private 395 | NTSYSAPI 396 | NTSTATUS 397 | NTAPI 398 | TpAllocAlpcCompletion( 399 | _Out_ PTP_ALPC *AlpcReturn, 400 | _In_ HANDLE AlpcPort, 401 | _In_ PTP_ALPC_CALLBACK Callback, 402 | _Inout_opt_ PVOID Context, 403 | _In_opt_ PTP_CALLBACK_ENVIRON CallbackEnviron 404 | ); 405 | 406 | #if (PHNT_VERSION >= PHNT_WIN7) 407 | // rev 408 | NTSYSAPI 409 | NTSTATUS 410 | NTAPI 411 | TpAllocAlpcCompletionEx( 412 | _Out_ PTP_ALPC *AlpcReturn, 413 | _In_ HANDLE AlpcPort, 414 | _In_ PTP_ALPC_CALLBACK_EX Callback, 415 | _Inout_opt_ PVOID Context, 416 | _In_opt_ PTP_CALLBACK_ENVIRON CallbackEnviron 417 | ); 418 | #endif 419 | 420 | // private 421 | NTSYSAPI 422 | VOID 423 | NTAPI 424 | TpReleaseAlpcCompletion( 425 | _Inout_ PTP_ALPC Alpc 426 | ); 427 | 428 | // private 429 | NTSYSAPI 430 | VOID 431 | NTAPI 432 | TpWaitForAlpcCompletion( 433 | _Inout_ PTP_ALPC Alpc 434 | ); 435 | 436 | // private 437 | typedef enum _TP_TRACE_TYPE 438 | { 439 | TpTraceThreadPriority = 1, 440 | TpTraceThreadAffinity, 441 | MaxTpTraceType 442 | } TP_TRACE_TYPE; 443 | 444 | // private 445 | NTSYSAPI 446 | VOID 447 | NTAPI 448 | TpCaptureCaller( 449 | _In_ TP_TRACE_TYPE Type 450 | ); 451 | 452 | // private 453 | NTSYSAPI 454 | VOID 455 | NTAPI 456 | TpCheckTerminateWorker( 457 | _In_ HANDLE Thread 458 | ); 459 | 460 | #endif 461 | 462 | #endif 463 | -------------------------------------------------------------------------------- /MemoryModule/Loader.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include 3 | 4 | #ifdef _USRDLL 5 | #if (defined(_WIN64) || defined(_M_ARM)) 6 | #pragma comment(linker,"/export:LdrUnloadDllMemoryAndExitThread") 7 | #pragma comment(linker,"/export:FreeLibraryMemoryAndExitThread=LdrUnloadDllMemoryAndExitThread") 8 | #else 9 | #pragma comment(linker,"/export:LdrUnloadDllMemoryAndExitThread=_LdrUnloadDllMemoryAndExitThread@8") 10 | #pragma comment(linker,"/export:FreeLibraryMemoryAndExitThread=_LdrUnloadDllMemoryAndExitThread@8") 11 | #endif 12 | #endif 13 | 14 | NTSTATUS NTAPI LdrMapDllMemory( 15 | _In_ HMEMORYMODULE ViewBase, 16 | _In_ DWORD dwFlags, 17 | _In_opt_ PCWSTR DllName, 18 | _In_opt_ PCWSTR lpFullDllName, 19 | _Out_opt_ PLDR_DATA_TABLE_ENTRY* DataTableEntry) { 20 | 21 | UNICODE_STRING FullDllName, BaseDllName; 22 | PIMAGE_NT_HEADERS NtHeaders; 23 | PLDR_DATA_TABLE_ENTRY LdrEntry; 24 | HANDLE heap = NtCurrentPeb()->ProcessHeap; 25 | 26 | if (!(NtHeaders = RtlImageNtHeader(ViewBase))) return STATUS_INVALID_IMAGE_FORMAT; 27 | 28 | if (!(LdrEntry = RtlAllocateDataTableEntry(ViewBase))) return STATUS_NO_MEMORY; 29 | 30 | if (!NT_SUCCESS(RtlResolveDllNameUnicodeString(DllName, lpFullDllName, &BaseDllName, &FullDllName))) { 31 | RtlFreeHeap(heap, 0, LdrEntry); 32 | return STATUS_NO_MEMORY; 33 | } 34 | 35 | if (!RtlInitializeLdrDataTableEntry(LdrEntry, dwFlags, ViewBase, BaseDllName, FullDllName)) { 36 | RtlFreeHeap(heap, 0, LdrEntry); 37 | RtlFreeHeap(heap, 0, BaseDllName.Buffer); 38 | RtlFreeHeap(heap, 0, FullDllName.Buffer); 39 | return STATUS_UNSUCCESSFUL; 40 | } 41 | 42 | RtlInsertMemoryTableEntry(LdrEntry); 43 | if (DataTableEntry)*DataTableEntry = LdrEntry; 44 | return STATUS_SUCCESS; 45 | } 46 | 47 | NTSTATUS NTAPI LdrLoadDllMemoryExW( 48 | _Out_ HMEMORYMODULE* BaseAddress, 49 | _Out_opt_ PVOID* LdrEntry, 50 | _In_ DWORD dwFlags, 51 | _In_ LPVOID BufferAddress, 52 | _In_ size_t BufferSize, 53 | _In_opt_ LPCWSTR DllName, 54 | _In_opt_ LPCWSTR DllFullName) { 55 | PMEMORYMODULE module = nullptr; 56 | NTSTATUS status = STATUS_SUCCESS; 57 | PLDR_DATA_TABLE_ENTRY ModuleEntry = nullptr; 58 | PIMAGE_NT_HEADERS headers = nullptr; 59 | 60 | if (BufferSize)return STATUS_INVALID_PARAMETER_5; 61 | __try { 62 | *BaseAddress = nullptr; 63 | if (LdrEntry)*LdrEntry = nullptr; 64 | 65 | if (!RtlIsValidImageBuffer(BufferAddress, &BufferSize) && !(dwFlags & LOAD_FLAGS_PASS_IMAGE_CHECK)) { 66 | status = STATUS_INVALID_IMAGE_FORMAT; 67 | } 68 | 69 | if (MmpGlobalDataPtr == nullptr) { 70 | status = STATUS_INVALID_PARAMETER; 71 | } 72 | } 73 | __except (EXCEPTION_EXECUTE_HANDLER) { 74 | status = GetExceptionCode(); 75 | } 76 | if (!NT_SUCCESS(status))return status; 77 | 78 | if (dwFlags & LOAD_FLAGS_NOT_MAP_DLL) { 79 | dwFlags &= LOAD_FLAGS_NOT_MAP_DLL; 80 | DllName = DllFullName = nullptr; 81 | } 82 | if (dwFlags & LOAD_FLAGS_USE_DLL_NAME && (!DllName || !DllFullName))return STATUS_INVALID_PARAMETER_3; 83 | 84 | if (DllName) { 85 | int length = (int)wcslen(DllName); 86 | PLIST_ENTRY ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList, ListEntry = ListHead->Flink; 87 | PIMAGE_NT_HEADERS h1 = RtlImageNtHeader(BufferAddress), h2 = nullptr; 88 | if (!h1)return STATUS_INVALID_IMAGE_FORMAT; 89 | 90 | while (ListEntry != ListHead) { 91 | PLDR_DATA_TABLE_ENTRY CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 92 | ListEntry = ListEntry->Flink; 93 | 94 | /* Check if it's being unloaded */ 95 | if (!CurEntry->InMemoryOrderLinks.Flink) continue; 96 | 97 | auto dist = (CurEntry->BaseDllName.Length / sizeof(wchar_t)) - length; 98 | bool equal = false; 99 | if (dist == 0 || dist == 4) { 100 | equal = !_wcsnicmp(DllName, CurEntry->BaseDllName.Buffer, length); 101 | } 102 | else { 103 | continue; 104 | } 105 | 106 | /* Check if name matches */ 107 | if (equal) { 108 | 109 | /* Let's compare their headers */ 110 | if (!(h2 = RtlImageNtHeader(CurEntry->DllBase)))continue; 111 | if (!(module = MapMemoryModuleHandle((HMEMORYMODULE)CurEntry->DllBase)))continue; 112 | if ((h1->OptionalHeader.SizeOfCode == h2->OptionalHeader.SizeOfCode) && 113 | (h1->OptionalHeader.SizeOfHeaders == h2->OptionalHeader.SizeOfHeaders)) { 114 | 115 | /* This is our entry!, update load count and return success */ 116 | if (!module->UseReferenceCount || dwFlags & LOAD_FLAGS_NOT_USE_REFERENCE_COUNT)return STATUS_INVALID_PARAMETER_3; 117 | 118 | RtlUpdateReferenceCount(module, FLAG_REFERENCE); 119 | *BaseAddress = (HMEMORYMODULE)CurEntry->DllBase; 120 | if (LdrEntry)*LdrEntry = CurEntry; 121 | return STATUS_SUCCESS; 122 | } 123 | } 124 | } 125 | } 126 | 127 | status = MemoryLoadLibrary(BaseAddress, BufferAddress, (DWORD)BufferSize); 128 | if (!NT_SUCCESS(status) || status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH)return status; 129 | 130 | if (!(module = MapMemoryModuleHandle(*BaseAddress))) { 131 | __fastfail(FAST_FAIL_FATAL_APP_EXIT); 132 | DebugBreak(); 133 | ExitProcess(STATUS_INVALID_ADDRESS); 134 | TerminateProcess(NtCurrentProcess(), STATUS_INVALID_ADDRESS); 135 | } 136 | module->loadFromLdrLoadDllMemory = true; 137 | 138 | headers = RtlImageNtHeader(*BaseAddress); 139 | if (headers->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NO_SEH)dwFlags |= LOAD_FLAGS_NOT_ADD_INVERTED_FUNCTION; 140 | 141 | if (dwFlags & LOAD_FLAGS_NOT_MAP_DLL) { 142 | 143 | do { 144 | status = MemoryResolveImportTable(LPBYTE(*BaseAddress), headers, module); 145 | if (!NT_SUCCESS(status))break; 146 | 147 | status = MemorySetSectionProtection(LPBYTE(*BaseAddress), headers); 148 | if (!NT_SUCCESS(status))break; 149 | 150 | if (!LdrpExecuteTLS(module) || !LdrpCallInitializers(module, DLL_PROCESS_ATTACH)) { 151 | status = STATUS_DLL_INIT_FAILED; 152 | break; 153 | } 154 | 155 | } while (false); 156 | 157 | if (!NT_SUCCESS(status)) { 158 | MemoryFreeLibrary(*BaseAddress); 159 | } 160 | 161 | return status; 162 | } 163 | 164 | do { 165 | 166 | status = LdrMapDllMemory(*BaseAddress, dwFlags, DllName, DllFullName, &ModuleEntry); 167 | if (!NT_SUCCESS(status))break; 168 | 169 | module->MappedDll = true; 170 | module->LdrEntry = ModuleEntry; 171 | 172 | status = MemoryResolveImportTable(LPBYTE(*BaseAddress), headers, module); 173 | if (!NT_SUCCESS(status))break; 174 | 175 | status = MemorySetSectionProtection(LPBYTE(*BaseAddress), headers); 176 | if (!NT_SUCCESS(status))break; 177 | 178 | if (!(dwFlags & LOAD_FLAGS_NOT_USE_REFERENCE_COUNT))module->UseReferenceCount = true; 179 | 180 | if (!(dwFlags & LOAD_FLAGS_NOT_ADD_INVERTED_FUNCTION)) { 181 | status = RtlInsertInvertedFunctionTable((PVOID)module->codeBase, headers->OptionalHeader.SizeOfImage); 182 | if (!NT_SUCCESS(status)) break; 183 | 184 | module->InsertInvertedFunctionTableEntry = true; 185 | } 186 | 187 | if (!(dwFlags & LOAD_FLAGS_NOT_HANDLE_TLS)) { 188 | status = MmpGlobalDataPtr->MmpFunctions->_MmpHandleTlsData(ModuleEntry); 189 | if (!NT_SUCCESS(status)) { 190 | if (dwFlags & LOAD_FLAGS_NOT_FAIL_IF_HANDLE_TLS) status = 0x7fffffff; 191 | if (!NT_SUCCESS(status))break; 192 | } 193 | else { 194 | module->TlsHandled = true; 195 | } 196 | } 197 | 198 | if (dwFlags & LOAD_FLAGS_HOOK_DOT_NET) { 199 | MmpPreInitializeHooksForDotNet(); 200 | } 201 | 202 | if (!LdrpExecuteTLS(module) || !LdrpCallInitializers(module, DLL_PROCESS_ATTACH)) { 203 | status = STATUS_DLL_INIT_FAILED; 204 | break; 205 | } 206 | 207 | if (dwFlags & LOAD_FLAGS_HOOK_DOT_NET) { 208 | MmpInitializeHooksForDotNet(); 209 | } 210 | 211 | } while (false); 212 | 213 | if (NT_SUCCESS(status)) { 214 | if (LdrEntry)*LdrEntry = ModuleEntry; 215 | } 216 | else { 217 | LdrUnloadDllMemory(*BaseAddress); 218 | *BaseAddress = nullptr; 219 | } 220 | 221 | return status; 222 | } 223 | 224 | NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress) { 225 | PLDR_DATA_TABLE_ENTRY CurEntry; 226 | ULONG count = 0; 227 | NTSTATUS status = STATUS_SUCCESS; 228 | PMEMORYMODULE module = MapMemoryModuleHandle(BaseAddress); 229 | PIMAGE_NT_HEADERS headers = RtlImageNtHeader(BaseAddress); 230 | 231 | do { 232 | 233 | //Not a memory module loaded via LdrLoadDllMemory 234 | if (!module || !module->loadFromLdrLoadDllMemory) { 235 | status = STATUS_INVALID_HANDLE; 236 | break; 237 | } 238 | 239 | if (MmpGlobalDataPtr == nullptr) { 240 | status = STATUS_INVALID_PARAMETER; 241 | break; 242 | } 243 | 244 | //Mapping dll failed 245 | if (!module->MappedDll) { 246 | module->underUnload = true; 247 | status = (MemoryFreeLibrary(BaseAddress) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); 248 | break; 249 | } 250 | 251 | CurEntry = (PLDR_DATA_TABLE_ENTRY)module->LdrEntry; 252 | 253 | if (headers->OptionalHeader.SizeOfImage != CurEntry->SizeOfImage) __fastfail(FAST_FAIL_FATAL_APP_EXIT); 254 | 255 | if (module->UseReferenceCount) { 256 | status = RtlGetReferenceCount(module, &count); 257 | if (!NT_SUCCESS(status)) break; 258 | } 259 | 260 | if (count & ~1) { 261 | status = RtlUpdateReferenceCount(module, FLAG_DEREFERENCE); 262 | break; 263 | } 264 | 265 | module->underUnload = true; 266 | if (module->initialized) { 267 | PLDR_INIT_ROUTINE((LPVOID)(module->codeBase + headers->OptionalHeader.AddressOfEntryPoint))( 268 | (HINSTANCE)module->codeBase, 269 | DLL_PROCESS_DETACH, 270 | 0 271 | ); 272 | } 273 | 274 | if (module->MappedDll) { 275 | if (module->InsertInvertedFunctionTableEntry) { 276 | status = RtlRemoveInvertedFunctionTable(BaseAddress); 277 | if (!NT_SUCCESS(status)) __fastfail(FAST_FAIL_CORRUPT_LIST_ENTRY); 278 | } 279 | 280 | if (module->TlsHandled) { 281 | status = MmpGlobalDataPtr->MmpFunctions->_MmpReleaseTlsEntry(CurEntry); 282 | if (!NT_SUCCESS(status)) __fastfail(FAST_FAIL_FATAL_APP_EXIT); 283 | } 284 | 285 | if (!RtlFreeLdrDataTableEntry(CurEntry)) __fastfail(FAST_FAIL_FATAL_APP_EXIT); 286 | } 287 | 288 | if (!MemoryFreeLibrary(BaseAddress)) __fastfail(FAST_FAIL_FATAL_APP_EXIT); 289 | 290 | } while (false); 291 | 292 | return status; 293 | } 294 | 295 | DECLSPEC_NORETURN 296 | VOID NTAPI LdrUnloadDllMemoryAndExitThread(_In_ HMEMORYMODULE BaseAddress, _In_ DWORD dwExitCode) { 297 | LdrUnloadDllMemory(BaseAddress); 298 | RtlExitUserThread(dwExitCode); 299 | } 300 | 301 | NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures) { 302 | NTSTATUS status = STATUS_SUCCESS; 303 | __try { 304 | *pFeatures = MmpGlobalDataPtr->MmpFeatures; 305 | } 306 | __except (EXCEPTION_EXECUTE_HANDLER) { 307 | status = GetExceptionCode(); 308 | } 309 | return status; 310 | } 311 | -------------------------------------------------------------------------------- /MemoryModule/MemoryModule.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | 3 | #if defined(_M_ARM64) 4 | #define HOST_MACHINE IMAGE_FILE_MACHINE_ARM64 5 | #elif defined(_M_ARM) 6 | #define HOST_MACHINE IMAGE_FILE_MACHINE_ARM 7 | #elif defined(_WIN64) 8 | #define HOST_MACHINE IMAGE_FILE_MACHINE_AMD64 9 | #else 10 | #define HOST_MACHINE IMAGE_FILE_MACHINE_I386 11 | #endif 12 | 13 | #define GET_HEADER_DICTIONARY(headers, idx) &headers->OptionalHeader.DataDirectory[idx] 14 | 15 | #define AlignValueUp(value, alignment) ((size_t(value) + size_t(alignment) - 1) & ~(size_t(alignment) - 1)) 16 | 17 | #define OffsetPointer(data, offset) LPVOID(LPBYTE(data) + ptrdiff_t(offset)) 18 | 19 | // Protection flags for memory pages (Executable, Readable, Writeable) 20 | static const int ProtectionFlags[2][2][2] = { 21 | { 22 | // not executable 23 | {PAGE_NOACCESS, PAGE_WRITECOPY}, 24 | {PAGE_READONLY, PAGE_READWRITE}, 25 | }, { 26 | // executable 27 | {PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY}, 28 | {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE}, 29 | }, 30 | }; 31 | 32 | int MmpSizeOfImageHeadersUnsafe(PVOID BaseAddress) { 33 | PIMAGE_DOS_HEADER dh = (PIMAGE_DOS_HEADER)BaseAddress; 34 | PIMAGE_NT_HEADERS nh = (PIMAGE_NT_HEADERS)((LPBYTE)BaseAddress + dh->e_lfanew); 35 | 36 | //https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_optional_header32 37 | int sizeOfHeaders = dh->e_lfanew + // e_lfanew member of IMAGE_DOS_HEADER 38 | 4 + // 4 byte signature 39 | sizeof(IMAGE_FILE_HEADER) + // size of IMAGE_FILE_HEADER 40 | sizeof(IMAGE_OPTIONAL_HEADER) + // size of optional header 41 | sizeof(IMAGE_SECTION_HEADER) * nh->FileHeader.NumberOfSections; // size of all section headers 42 | return sizeOfHeaders; 43 | } 44 | 45 | PMEMORYMODULE WINAPI MapMemoryModuleHandle(HMEMORYMODULE hModule) { 46 | 47 | if (!hModule)return nullptr; 48 | 49 | PIMAGE_NT_HEADERS nh = RtlImageNtHeader(hModule); 50 | if (!nh)return nullptr; 51 | 52 | int sizeOfHeaders = MmpSizeOfImageHeadersUnsafe(hModule); 53 | PMEMORYMODULE pModule = (PMEMORYMODULE)((LPBYTE)hModule + sizeOfHeaders); 54 | if (pModule->Signature != MEMORY_MODULE_SIGNATURE || pModule->codeBase != (LPBYTE)hModule)return nullptr; 55 | return pModule; 56 | } 57 | 58 | BOOL WINAPI IsValidMemoryModuleHandle(HMEMORYMODULE hModule) { 59 | return MapMemoryModuleHandle(hModule) != nullptr; 60 | } 61 | 62 | NTSTATUS MmpInitializeStructure(DWORD ImageFileSize, LPCVOID ImageFileBuffer, PIMAGE_NT_HEADERS ImageHeaders) { 63 | 64 | if (!ImageHeaders)return STATUS_ACCESS_VIOLATION; 65 | 66 | // 67 | // Make sure there have enough free space to embed our structure. 68 | // 69 | int sizeOfHeaders = MmpSizeOfImageHeadersUnsafe((PVOID)ImageHeaders->OptionalHeader.ImageBase); 70 | PIMAGE_SECTION_HEADER pSections = IMAGE_FIRST_SECTION(ImageHeaders); 71 | for (int i = 0; i < ImageHeaders->FileHeader.NumberOfSections; ++i) { 72 | if (pSections[i].VirtualAddress < sizeOfHeaders + sizeof(MEMORYMODULE)) { 73 | return STATUS_NOT_SUPPORTED; 74 | } 75 | } 76 | 77 | // 78 | // Setup MemoryModule structure. 79 | // 80 | PMEMORYMODULE hMemoryModule = (PMEMORYMODULE)(ImageHeaders->OptionalHeader.ImageBase + sizeOfHeaders); 81 | RtlZeroMemory(hMemoryModule, sizeof(MEMORYMODULE)); 82 | hMemoryModule->codeBase = (PBYTE)ImageHeaders->OptionalHeader.ImageBase; 83 | hMemoryModule->dwImageFileSize = ImageFileSize; 84 | hMemoryModule->Signature = MEMORY_MODULE_SIGNATURE; 85 | hMemoryModule->SizeofHeaders = ImageHeaders->OptionalHeader.SizeOfHeaders; 86 | hMemoryModule->lpReserved = (LPVOID)ImageFileBuffer; 87 | hMemoryModule->dwReferenceCount = 1; 88 | 89 | return STATUS_SUCCESS; 90 | } 91 | 92 | NTSTATUS MemorySetSectionProtection( 93 | _In_ LPBYTE base, 94 | _In_ PIMAGE_NT_HEADERS lpNtHeaders) { 95 | NTSTATUS status = STATUS_SUCCESS; 96 | PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(lpNtHeaders); 97 | 98 | for (DWORD i = 0; i < lpNtHeaders->FileHeader.NumberOfSections; ++i, ++section) { 99 | LPVOID address = LPBYTE(base) + section->VirtualAddress; 100 | SIZE_T size = AlignValueUp(section->Misc.VirtualSize, lpNtHeaders->OptionalHeader.SectionAlignment); 101 | 102 | BOOL executable = (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0, 103 | readable = (section->Characteristics & IMAGE_SCN_MEM_READ) != 0, 104 | writeable = (section->Characteristics & IMAGE_SCN_MEM_WRITE) != 0; 105 | DWORD protect = ProtectionFlags[executable][readable][writeable], oldProtect; 106 | 107 | if (section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED) protect |= PAGE_NOCACHE; 108 | 109 | status = NtProtectVirtualMemory(NtCurrentProcess(), &address, &size, protect, &oldProtect); 110 | if (!NT_SUCCESS(status))break; 111 | } 112 | 113 | return status; 114 | } 115 | 116 | NTSTATUS MemoryLoadLibrary( 117 | _Out_ HMEMORYMODULE* MemoryModuleHandle, 118 | _In_ LPCVOID data, 119 | _In_ DWORD size) { 120 | 121 | PIMAGE_DOS_HEADER dos_header = nullptr; 122 | PIMAGE_NT_HEADERS old_header = nullptr; 123 | BOOLEAN CorImage = FALSE; 124 | NTSTATUS status = STATUS_SUCCESS; 125 | 126 | // 127 | // Check parameters 128 | // 129 | __try { 130 | 131 | *MemoryModuleHandle = nullptr; 132 | 133 | // 134 | // Check dos magic 135 | // 136 | dos_header = (PIMAGE_DOS_HEADER)data; 137 | if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) { 138 | status = STATUS_INVALID_IMAGE_FORMAT; 139 | __leave; 140 | } 141 | 142 | // 143 | // Check nt headers 144 | // 145 | old_header = (PIMAGE_NT_HEADERS)((size_t)data + dos_header->e_lfanew); 146 | if (old_header->Signature != IMAGE_NT_SIGNATURE || 147 | old_header->OptionalHeader.SectionAlignment & 1) { 148 | status = STATUS_INVALID_IMAGE_FORMAT; 149 | __leave; 150 | } 151 | 152 | // 153 | // Match machine type 154 | // 155 | if (old_header->FileHeader.Machine != HOST_MACHINE) { 156 | status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH; 157 | __leave; 158 | } 159 | 160 | // 161 | // Only dll image support 162 | // 163 | if (!(old_header->FileHeader.Characteristics & IMAGE_FILE_DLL)) { 164 | status = STATUS_NOT_SUPPORTED; 165 | __leave; 166 | } 167 | } 168 | __except (EXCEPTION_EXECUTE_HANDLER) { 169 | status = GetExceptionCode(); 170 | } 171 | if (!NT_SUCCESS(status) || status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH)return status; 172 | 173 | // 174 | // Reserve the address range of image 175 | // 176 | LPBYTE base = nullptr; 177 | if ((old_header->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0) { 178 | base = (LPBYTE)VirtualAlloc( 179 | LPVOID(old_header->OptionalHeader.ImageBase), 180 | old_header->OptionalHeader.SizeOfImage, 181 | MEM_RESERVE, 182 | PAGE_EXECUTE_READWRITE 183 | ); 184 | } 185 | if (!base) { 186 | base = (LPBYTE)VirtualAlloc( 187 | nullptr, 188 | old_header->OptionalHeader.SizeOfImage, 189 | MEM_RESERVE, 190 | PAGE_EXECUTE_READWRITE 191 | ); 192 | if (!base) status = STATUS_NO_MEMORY; 193 | } 194 | 195 | if (!NT_SUCCESS(status)) { 196 | return status; 197 | } 198 | 199 | // 200 | // Allocate memory for image headers 201 | // 202 | size_t alignedHeadersSize = (DWORD)AlignValueUp(old_header->OptionalHeader.SizeOfHeaders + sizeof(MEMORYMODULE), MmpGlobalDataPtr->SystemInfo.dwPageSize); 203 | if (!VirtualAlloc(base, alignedHeadersSize, MEM_COMMIT, PAGE_READWRITE)) { 204 | VirtualFree(base, 0, MEM_RELEASE); 205 | status = STATUS_NO_MEMORY; 206 | return status; 207 | } 208 | 209 | // 210 | // Copy headers 211 | // 212 | PIMAGE_DOS_HEADER new_dos_header = (PIMAGE_DOS_HEADER)base; 213 | PIMAGE_NT_HEADERS new_header = (PIMAGE_NT_HEADERS)(base + dos_header->e_lfanew); 214 | RtlCopyMemory( 215 | new_dos_header, 216 | dos_header, 217 | old_header->OptionalHeader.SizeOfHeaders 218 | ); 219 | new_header->OptionalHeader.ImageBase = (size_t)base; 220 | 221 | do { 222 | // 223 | // Setup MEMORYMODULE structure. 224 | // 225 | status = MmpInitializeStructure(size, data, new_header); 226 | if (!NT_SUCCESS(status)) break; 227 | 228 | // 229 | // Allocate and copy sections 230 | // 231 | PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(new_header); 232 | for (DWORD i = 0; i < new_header->FileHeader.NumberOfSections; ++i, ++section) { 233 | 234 | DWORD size = AlignValueUp( 235 | section->Misc.VirtualSize, 236 | new_header->OptionalHeader.SectionAlignment 237 | ); 238 | if (size < section->SizeOfRawData) { 239 | status = STATUS_INVALID_IMAGE_FORMAT; 240 | break; 241 | } 242 | 243 | LPVOID dest = VirtualAlloc( 244 | (LPSTR)new_header->OptionalHeader.ImageBase + section->VirtualAddress, 245 | size, 246 | MEM_COMMIT, 247 | PAGE_READWRITE 248 | ); 249 | if (!dest) { 250 | status = STATUS_NO_MEMORY; 251 | break; 252 | } 253 | 254 | if (section->SizeOfRawData) { 255 | RtlCopyMemory( 256 | dest, 257 | LPBYTE(data) + section->PointerToRawData, 258 | section->SizeOfRawData 259 | ); 260 | } 261 | 262 | } 263 | if (!NT_SUCCESS(status))break; 264 | 265 | // 266 | // Rebase image 267 | // 268 | auto locationDelta = new_header->OptionalHeader.ImageBase - old_header->OptionalHeader.ImageBase; 269 | if (locationDelta) { 270 | typedef struct _REBASE_INFO { 271 | USHORT Offset : 12; 272 | USHORT Type : 4; 273 | }REBASE_INFO, * PREBASE_INFO; 274 | typedef struct _IMAGE_BASE_RELOCATION_HEADER { 275 | DWORD VirtualAddress; 276 | DWORD SizeOfBlock; 277 | REBASE_INFO TypeOffset[ANYSIZE_ARRAY]; 278 | 279 | DWORD TypeOffsetCount()const { 280 | return (this->SizeOfBlock - 8) / sizeof(_REBASE_INFO); 281 | } 282 | }IMAGE_BASE_RELOCATION_HEADER, * PIMAGE_BASE_RELOCATION_HEADER; 283 | 284 | PIMAGE_DATA_DIRECTORY dir = GET_HEADER_DICTIONARY(new_header, IMAGE_DIRECTORY_ENTRY_BASERELOC); 285 | PIMAGE_BASE_RELOCATION_HEADER relocation = (PIMAGE_BASE_RELOCATION_HEADER)(LPBYTE(base) + dir->VirtualAddress); 286 | 287 | if (dir->Size && dir->VirtualAddress) { 288 | while ((LPBYTE(relocation) < LPBYTE(base) + dir->VirtualAddress + dir->Size) && relocation->VirtualAddress > 0) { 289 | auto relInfo = (_REBASE_INFO*)&relocation->TypeOffset; 290 | for (DWORD i = 0; i < relocation->TypeOffsetCount(); ++i, ++relInfo) { 291 | switch (relInfo->Type) { 292 | case IMAGE_REL_BASED_HIGHLOW: *(DWORD*)(base + relocation->VirtualAddress + relInfo->Offset) += (DWORD)locationDelta; break; 293 | #ifdef _WIN64 294 | case IMAGE_REL_BASED_DIR64: *(ULONGLONG*)(base + relocation->VirtualAddress + relInfo->Offset) += (ULONGLONG)locationDelta; break; 295 | #endif 296 | case IMAGE_REL_BASED_ABSOLUTE: 297 | default: break; 298 | } 299 | } 300 | 301 | // advance to next relocation block 302 | //relocation->VirtualAddress += module->headers_align; 303 | relocation = decltype(relocation)(OffsetPointer(relocation, relocation->SizeOfBlock)); 304 | } 305 | } 306 | 307 | } 308 | if (!NT_SUCCESS(status))break; 309 | 310 | __try { 311 | *MemoryModuleHandle = (HMEMORYMODULE)base; 312 | } 313 | __except (EXCEPTION_EXECUTE_HANDLER) { 314 | status = GetExceptionCode(); 315 | break; 316 | } 317 | 318 | return status; 319 | } while (false); 320 | 321 | MemoryFreeLibrary((HMEMORYMODULE)base); 322 | return status; 323 | } 324 | 325 | BOOL MemoryFreeLibrary(HMEMORYMODULE mod) { 326 | PMEMORYMODULE module = MapMemoryModuleHandle(mod); 327 | PIMAGE_NT_HEADERS headers = RtlImageNtHeader(mod); 328 | 329 | if (!module) return FALSE; 330 | if (module->loadFromLdrLoadDllMemory && !module->underUnload)return FALSE; 331 | if (module->hModulesList)MemoryFreeImportTable(module); 332 | 333 | if (module->codeBase) VirtualFree(mod, 0, MEM_RELEASE); 334 | return TRUE; 335 | } 336 | -------------------------------------------------------------------------------- /MemoryModule/MemoryModule.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {8baeecde-ca9b-43da-b847-c24b02413572} 18 | 19 | 20 | {21335c89-8359-427a-a6c6-d621b31be2ce} 21 | 22 | 23 | {22e60119-4e33-49c4-81c4-b95ea98501e3} 24 | 25 | 26 | {10bf9b0e-09d4-473b-a4bb-d7c4cecc65b4} 27 | 28 | 29 | {e1243ce3-529c-401e-83a4-fe009cda27b1} 30 | 31 | 32 | {3e49fb44-9cfb-4a48-b497-6fe396e1a258} 33 | 34 | 35 | {4bbbea53-468a-49af-9b66-b61471058da1} 36 | 37 | 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files 50 | 51 | 52 | Source Files 53 | 54 | 55 | Source Files\3rdparty\Detours 56 | 57 | 58 | Source Files\3rdparty\Detours 59 | 60 | 61 | Source Files\3rdparty\Detours 62 | 63 | 64 | Source Files\3rdparty\Detours 65 | 66 | 67 | Source Files\3rdparty\Detours 68 | 69 | 70 | Source Files\3rdparty\Detours 71 | 72 | 73 | Source Files\3rdparty\Detours 74 | 75 | 76 | Source Files\3rdparty\Detours 77 | 78 | 79 | Source Files\3rdparty\Detours 80 | 81 | 82 | Source Files\3rdparty\Detours 83 | 84 | 85 | Source Files 86 | 87 | 88 | Source Files 89 | 90 | 91 | Source Files 92 | 93 | 94 | Source Files 95 | 96 | 97 | Source Files 98 | 99 | 100 | Source Files 101 | 102 | 103 | Source Files\3rdparty\ReflectiveLoader 104 | 105 | 106 | Source Files 107 | 108 | 109 | Source Files 110 | 111 | 112 | 113 | 114 | Header Files 115 | 116 | 117 | Header Files 118 | 119 | 120 | Header Files 121 | 122 | 123 | Header Files 124 | 125 | 126 | Header Files 127 | 128 | 129 | Header Files\3rdparty\Detours 130 | 131 | 132 | Header Files\3rdparty\Detours 133 | 134 | 135 | Header Files 136 | 137 | 138 | Header Files 139 | 140 | 141 | Header Files 142 | 143 | 144 | Header Files 145 | 146 | 147 | Header Files 148 | 149 | 150 | Header Files\3rdparty\phnt 151 | 152 | 153 | Header Files\3rdparty\phnt 154 | 155 | 156 | Header Files\3rdparty\phnt 157 | 158 | 159 | Header Files\3rdparty\phnt 160 | 161 | 162 | Header Files\3rdparty\phnt 163 | 164 | 165 | Header Files\3rdparty\phnt 166 | 167 | 168 | Header Files\3rdparty\phnt 169 | 170 | 171 | Header Files\3rdparty\phnt 172 | 173 | 174 | Header Files\3rdparty\phnt 175 | 176 | 177 | Header Files\3rdparty\phnt 178 | 179 | 180 | Header Files\3rdparty\phnt 181 | 182 | 183 | Header Files\3rdparty\phnt 184 | 185 | 186 | Header Files\3rdparty\phnt 187 | 188 | 189 | Header Files\3rdparty\phnt 190 | 191 | 192 | Header Files\3rdparty\phnt 193 | 194 | 195 | Header Files\3rdparty\phnt 196 | 197 | 198 | Header Files\3rdparty\phnt 199 | 200 | 201 | Header Files\3rdparty\phnt 202 | 203 | 204 | Header Files\3rdparty\phnt 205 | 206 | 207 | Header Files\3rdparty\phnt 208 | 209 | 210 | Header Files\3rdparty\phnt 211 | 212 | 213 | Header Files\3rdparty\phnt 214 | 215 | 216 | Header Files\3rdparty\phnt 217 | 218 | 219 | Header Files\3rdparty\phnt 220 | 221 | 222 | Header Files\3rdparty\phnt 223 | 224 | 225 | Header Files\3rdparty\phnt 226 | 227 | 228 | Header Files\3rdparty\phnt 229 | 230 | 231 | Header Files\3rdparty\phnt 232 | 233 | 234 | Header Files\3rdparty\phnt 235 | 236 | 237 | Header Files\3rdparty\phnt 238 | 239 | 240 | Header Files\3rdparty\phnt 241 | 242 | 243 | Header Files 244 | 245 | 246 | Header Files\3rdparty\ReflectiveLoader 247 | 248 | 249 | Header Files\3rdparty\ReflectiveLoader 250 | 251 | 252 | Header Files 253 | 254 | 255 | Header Files 256 | 257 | 258 | Header Files 259 | 260 | 261 | Header Files 262 | 263 | 264 | Header Files 265 | 266 | 267 | 268 | 269 | Resource Files 270 | 271 | 272 | Resource Files 273 | 274 | 275 | -------------------------------------------------------------------------------- /3rdparty/phnt/include/ntobapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Object Manager support functions 3 | * 4 | * This file is part of System Informer. 5 | */ 6 | 7 | #ifndef _NTOBAPI_H 8 | #define _NTOBAPI_H 9 | 10 | #if (PHNT_MODE != PHNT_MODE_KERNEL) 11 | #define OBJECT_TYPE_CREATE 0x0001 12 | #define OBJECT_TYPE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1) 13 | #endif 14 | 15 | #if (PHNT_MODE != PHNT_MODE_KERNEL) 16 | #define DIRECTORY_QUERY 0x0001 17 | #define DIRECTORY_TRAVERSE 0x0002 18 | #define DIRECTORY_CREATE_OBJECT 0x0004 19 | #define DIRECTORY_CREATE_SUBDIRECTORY 0x0008 20 | #define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xf) 21 | #endif 22 | 23 | #if (PHNT_MODE != PHNT_MODE_KERNEL) 24 | #define SYMBOLIC_LINK_QUERY 0x0001 25 | #define SYMBOLIC_LINK_SET 0x0002 26 | #define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1) 27 | #define SYMBOLIC_LINK_ALL_ACCESS_EX (STANDARD_RIGHTS_REQUIRED | 0xFFFF) 28 | #endif 29 | 30 | #ifndef OBJ_PROTECT_CLOSE 31 | #define OBJ_PROTECT_CLOSE 0x00000001 32 | #endif 33 | #ifndef OBJ_INHERIT 34 | #define OBJ_INHERIT 0x00000002 35 | #endif 36 | #ifndef OBJ_AUDIT_OBJECT_CLOSE 37 | #define OBJ_AUDIT_OBJECT_CLOSE 0x00000004 38 | #endif 39 | 40 | #if (PHNT_MODE != PHNT_MODE_KERNEL) 41 | typedef enum _OBJECT_INFORMATION_CLASS 42 | { 43 | ObjectBasicInformation, // q: OBJECT_BASIC_INFORMATION 44 | ObjectNameInformation, // q: OBJECT_NAME_INFORMATION 45 | ObjectTypeInformation, // q: OBJECT_TYPE_INFORMATION 46 | ObjectTypesInformation, // q: OBJECT_TYPES_INFORMATION 47 | ObjectHandleFlagInformation, // qs: OBJECT_HANDLE_FLAG_INFORMATION 48 | ObjectSessionInformation, // s: void // change object session // (requires SeTcbPrivilege) 49 | ObjectSessionObjectInformation, // s: void // change object session // (requires SeTcbPrivilege) 50 | MaxObjectInfoClass 51 | } OBJECT_INFORMATION_CLASS; 52 | #else 53 | #define ObjectBasicInformation 0 54 | #define ObjectNameInformation 1 55 | #define ObjectTypeInformation 2 56 | #define ObjectTypesInformation 3 57 | #define ObjectHandleFlagInformation 4 58 | #define ObjectSessionInformation 5 59 | #define ObjectSessionObjectInformation 6 60 | #endif 61 | 62 | typedef struct _OBJECT_BASIC_INFORMATION 63 | { 64 | ULONG Attributes; 65 | ACCESS_MASK GrantedAccess; 66 | ULONG HandleCount; 67 | ULONG PointerCount; 68 | ULONG PagedPoolCharge; 69 | ULONG NonPagedPoolCharge; 70 | ULONG Reserved[3]; 71 | ULONG NameInfoSize; 72 | ULONG TypeInfoSize; 73 | ULONG SecurityDescriptorSize; 74 | LARGE_INTEGER CreationTime; 75 | } OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION; 76 | 77 | #if (PHNT_MODE != PHNT_MODE_KERNEL) 78 | typedef struct _OBJECT_NAME_INFORMATION 79 | { 80 | UNICODE_STRING Name; 81 | } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; 82 | #endif 83 | 84 | typedef struct _OBJECT_TYPE_INFORMATION 85 | { 86 | UNICODE_STRING TypeName; 87 | ULONG TotalNumberOfObjects; 88 | ULONG TotalNumberOfHandles; 89 | ULONG TotalPagedPoolUsage; 90 | ULONG TotalNonPagedPoolUsage; 91 | ULONG TotalNamePoolUsage; 92 | ULONG TotalHandleTableUsage; 93 | ULONG HighWaterNumberOfObjects; 94 | ULONG HighWaterNumberOfHandles; 95 | ULONG HighWaterPagedPoolUsage; 96 | ULONG HighWaterNonPagedPoolUsage; 97 | ULONG HighWaterNamePoolUsage; 98 | ULONG HighWaterHandleTableUsage; 99 | ULONG InvalidAttributes; 100 | GENERIC_MAPPING GenericMapping; 101 | ULONG ValidAccessMask; 102 | BOOLEAN SecurityRequired; 103 | BOOLEAN MaintainHandleCount; 104 | UCHAR TypeIndex; // since WINBLUE 105 | CHAR ReservedByte; 106 | ULONG PoolType; 107 | ULONG DefaultPagedPoolCharge; 108 | ULONG DefaultNonPagedPoolCharge; 109 | } OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; 110 | 111 | typedef struct _OBJECT_TYPES_INFORMATION 112 | { 113 | ULONG NumberOfTypes; 114 | } OBJECT_TYPES_INFORMATION, *POBJECT_TYPES_INFORMATION; 115 | 116 | typedef struct _OBJECT_HANDLE_FLAG_INFORMATION 117 | { 118 | BOOLEAN Inherit; 119 | BOOLEAN ProtectFromClose; 120 | } OBJECT_HANDLE_FLAG_INFORMATION, *POBJECT_HANDLE_FLAG_INFORMATION; 121 | 122 | // Objects, handles 123 | 124 | #if (PHNT_MODE != PHNT_MODE_KERNEL) 125 | 126 | NTSYSCALLAPI 127 | NTSTATUS 128 | NTAPI 129 | NtQueryObject( 130 | _In_opt_ HANDLE Handle, 131 | _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass, 132 | _Out_writes_bytes_opt_(ObjectInformationLength) PVOID ObjectInformation, 133 | _In_ ULONG ObjectInformationLength, 134 | _Out_opt_ PULONG ReturnLength 135 | ); 136 | 137 | NTSYSCALLAPI 138 | NTSTATUS 139 | NTAPI 140 | NtSetInformationObject( 141 | _In_ HANDLE Handle, 142 | _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass, 143 | _In_reads_bytes_(ObjectInformationLength) PVOID ObjectInformation, 144 | _In_ ULONG ObjectInformationLength 145 | ); 146 | 147 | #define DUPLICATE_CLOSE_SOURCE 0x00000001 148 | #define DUPLICATE_SAME_ACCESS 0x00000002 149 | #define DUPLICATE_SAME_ATTRIBUTES 0x00000004 150 | 151 | NTSYSCALLAPI 152 | NTSTATUS 153 | NTAPI 154 | NtDuplicateObject( 155 | _In_ HANDLE SourceProcessHandle, 156 | _In_ HANDLE SourceHandle, 157 | _In_opt_ HANDLE TargetProcessHandle, 158 | _Out_opt_ PHANDLE TargetHandle, 159 | _In_ ACCESS_MASK DesiredAccess, 160 | _In_ ULONG HandleAttributes, 161 | _In_ ULONG Options 162 | ); 163 | 164 | NTSYSCALLAPI 165 | NTSTATUS 166 | NTAPI 167 | NtMakeTemporaryObject( 168 | _In_ HANDLE Handle 169 | ); 170 | 171 | NTSYSCALLAPI 172 | NTSTATUS 173 | NTAPI 174 | NtMakePermanentObject( 175 | _In_ HANDLE Handle 176 | ); 177 | 178 | NTSYSCALLAPI 179 | NTSTATUS 180 | NTAPI 181 | NtSignalAndWaitForSingleObject( 182 | _In_ HANDLE SignalHandle, 183 | _In_ HANDLE WaitHandle, 184 | _In_ BOOLEAN Alertable, 185 | _In_opt_ PLARGE_INTEGER Timeout 186 | ); 187 | 188 | NTSYSCALLAPI 189 | NTSTATUS 190 | NTAPI 191 | NtWaitForSingleObject( 192 | _In_ HANDLE Handle, 193 | _In_ BOOLEAN Alertable, 194 | _In_opt_ PLARGE_INTEGER Timeout 195 | ); 196 | 197 | NTSYSCALLAPI 198 | NTSTATUS 199 | NTAPI 200 | NtWaitForMultipleObjects( 201 | _In_ ULONG Count, 202 | _In_reads_(Count) HANDLE Handles[], 203 | _In_ WAIT_TYPE WaitType, 204 | _In_ BOOLEAN Alertable, 205 | _In_opt_ PLARGE_INTEGER Timeout 206 | ); 207 | 208 | #if (PHNT_VERSION >= PHNT_WS03) 209 | NTSYSCALLAPI 210 | NTSTATUS 211 | NTAPI 212 | NtWaitForMultipleObjects32( 213 | _In_ ULONG Count, 214 | _In_reads_(Count) LONG Handles[], 215 | _In_ WAIT_TYPE WaitType, 216 | _In_ BOOLEAN Alertable, 217 | _In_opt_ PLARGE_INTEGER Timeout 218 | ); 219 | #endif 220 | 221 | NTSYSCALLAPI 222 | NTSTATUS 223 | NTAPI 224 | NtSetSecurityObject( 225 | _In_ HANDLE Handle, 226 | _In_ SECURITY_INFORMATION SecurityInformation, 227 | _In_ PSECURITY_DESCRIPTOR SecurityDescriptor 228 | ); 229 | 230 | NTSYSCALLAPI 231 | NTSTATUS 232 | NTAPI 233 | NtQuerySecurityObject( 234 | _In_ HANDLE Handle, 235 | _In_ SECURITY_INFORMATION SecurityInformation, 236 | _Out_writes_bytes_opt_(Length) PSECURITY_DESCRIPTOR SecurityDescriptor, 237 | _In_ ULONG Length, 238 | _Out_ PULONG LengthNeeded 239 | ); 240 | 241 | NTSYSCALLAPI 242 | NTSTATUS 243 | NTAPI 244 | NtClose( 245 | _In_ _Post_ptr_invalid_ HANDLE Handle 246 | ); 247 | 248 | #if (PHNT_VERSION >= PHNT_THRESHOLD) 249 | NTSYSCALLAPI 250 | NTSTATUS 251 | NTAPI 252 | NtCompareObjects( 253 | _In_ HANDLE FirstObjectHandle, 254 | _In_ HANDLE SecondObjectHandle 255 | ); 256 | #endif 257 | 258 | #endif 259 | 260 | // Directory objects 261 | 262 | #if (PHNT_MODE != PHNT_MODE_KERNEL) 263 | 264 | NTSYSCALLAPI 265 | NTSTATUS 266 | NTAPI 267 | NtCreateDirectoryObject( 268 | _Out_ PHANDLE DirectoryHandle, 269 | _In_ ACCESS_MASK DesiredAccess, 270 | _In_ POBJECT_ATTRIBUTES ObjectAttributes 271 | ); 272 | 273 | #if (PHNT_VERSION >= PHNT_WIN8) 274 | NTSYSCALLAPI 275 | NTSTATUS 276 | NTAPI 277 | NtCreateDirectoryObjectEx( 278 | _Out_ PHANDLE DirectoryHandle, 279 | _In_ ACCESS_MASK DesiredAccess, 280 | _In_ POBJECT_ATTRIBUTES ObjectAttributes, 281 | _In_ HANDLE ShadowDirectoryHandle, 282 | _In_ ULONG Flags 283 | ); 284 | #endif 285 | 286 | NTSYSCALLAPI 287 | NTSTATUS 288 | NTAPI 289 | NtOpenDirectoryObject( 290 | _Out_ PHANDLE DirectoryHandle, 291 | _In_ ACCESS_MASK DesiredAccess, 292 | _In_ POBJECT_ATTRIBUTES ObjectAttributes 293 | ); 294 | 295 | typedef struct _OBJECT_DIRECTORY_INFORMATION 296 | { 297 | UNICODE_STRING Name; 298 | UNICODE_STRING TypeName; 299 | } OBJECT_DIRECTORY_INFORMATION, *POBJECT_DIRECTORY_INFORMATION; 300 | 301 | NTSYSCALLAPI 302 | NTSTATUS 303 | NTAPI 304 | NtQueryDirectoryObject( 305 | _In_ HANDLE DirectoryHandle, 306 | _Out_writes_bytes_opt_(Length) PVOID Buffer, 307 | _In_ ULONG Length, 308 | _In_ BOOLEAN ReturnSingleEntry, 309 | _In_ BOOLEAN RestartScan, 310 | _Inout_ PULONG Context, 311 | _Out_opt_ PULONG ReturnLength 312 | ); 313 | 314 | #endif 315 | 316 | // Private namespaces 317 | 318 | #if (PHNT_MODE != PHNT_MODE_KERNEL) 319 | 320 | #if (PHNT_VERSION >= PHNT_VISTA) 321 | 322 | // private 323 | typedef enum _BOUNDARY_ENTRY_TYPE 324 | { 325 | OBNS_Invalid, 326 | OBNS_Name, 327 | OBNS_SID, 328 | OBNS_IL 329 | } BOUNDARY_ENTRY_TYPE; 330 | 331 | // private 332 | typedef struct _OBJECT_BOUNDARY_ENTRY 333 | { 334 | BOUNDARY_ENTRY_TYPE EntryType; 335 | ULONG EntrySize; 336 | } OBJECT_BOUNDARY_ENTRY, *POBJECT_BOUNDARY_ENTRY; 337 | 338 | // rev 339 | #define OBJECT_BOUNDARY_DESCRIPTOR_VERSION 1 340 | 341 | // private 342 | typedef struct _OBJECT_BOUNDARY_DESCRIPTOR 343 | { 344 | ULONG Version; 345 | ULONG Items; 346 | ULONG TotalSize; 347 | union 348 | { 349 | ULONG Flags; 350 | struct 351 | { 352 | ULONG AddAppContainerSid : 1; 353 | ULONG Reserved : 31; 354 | }; 355 | }; 356 | } OBJECT_BOUNDARY_DESCRIPTOR, *POBJECT_BOUNDARY_DESCRIPTOR; 357 | 358 | NTSYSCALLAPI 359 | NTSTATUS 360 | NTAPI 361 | NtCreatePrivateNamespace( 362 | _Out_ PHANDLE NamespaceHandle, 363 | _In_ ACCESS_MASK DesiredAccess, 364 | _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, 365 | _In_ POBJECT_BOUNDARY_DESCRIPTOR BoundaryDescriptor 366 | ); 367 | 368 | NTSYSCALLAPI 369 | NTSTATUS 370 | NTAPI 371 | NtOpenPrivateNamespace( 372 | _Out_ PHANDLE NamespaceHandle, 373 | _In_ ACCESS_MASK DesiredAccess, 374 | _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, 375 | _In_ POBJECT_BOUNDARY_DESCRIPTOR BoundaryDescriptor 376 | ); 377 | 378 | NTSYSCALLAPI 379 | NTSTATUS 380 | NTAPI 381 | NtDeletePrivateNamespace( 382 | _In_ HANDLE NamespaceHandle 383 | ); 384 | 385 | #endif 386 | 387 | #endif 388 | 389 | // Symbolic links 390 | 391 | #if (PHNT_MODE != PHNT_MODE_KERNEL) 392 | 393 | NTSYSCALLAPI 394 | NTSTATUS 395 | NTAPI 396 | NtCreateSymbolicLinkObject( 397 | _Out_ PHANDLE LinkHandle, 398 | _In_ ACCESS_MASK DesiredAccess, 399 | _In_ POBJECT_ATTRIBUTES ObjectAttributes, 400 | _In_ PUNICODE_STRING LinkTarget 401 | ); 402 | 403 | NTSYSCALLAPI 404 | NTSTATUS 405 | NTAPI 406 | NtOpenSymbolicLinkObject( 407 | _Out_ PHANDLE LinkHandle, 408 | _In_ ACCESS_MASK DesiredAccess, 409 | _In_ POBJECT_ATTRIBUTES ObjectAttributes 410 | ); 411 | 412 | NTSYSCALLAPI 413 | NTSTATUS 414 | NTAPI 415 | NtQuerySymbolicLinkObject( 416 | _In_ HANDLE LinkHandle, 417 | _Inout_ PUNICODE_STRING LinkTarget, 418 | _Out_opt_ PULONG ReturnedLength 419 | ); 420 | 421 | typedef enum _SYMBOLIC_LINK_INFO_CLASS 422 | { 423 | SymbolicLinkGlobalInformation = 1, // s: ULONG 424 | SymbolicLinkAccessMask, // s: ACCESS_MASK 425 | MaxnSymbolicLinkInfoClass 426 | } SYMBOLIC_LINK_INFO_CLASS; 427 | 428 | #if (PHNT_VERSION >= PHNT_THRESHOLD) 429 | NTSYSCALLAPI 430 | NTSTATUS 431 | NTAPI 432 | NtSetInformationSymbolicLink( 433 | _In_ HANDLE LinkHandle, 434 | _In_ SYMBOLIC_LINK_INFO_CLASS SymbolicLinkInformationClass, 435 | _In_reads_bytes_(SymbolicLinkInformationLength) PVOID SymbolicLinkInformation, 436 | _In_ ULONG SymbolicLinkInformationLength 437 | ); 438 | #endif 439 | 440 | #endif 441 | 442 | #endif 443 | --------------------------------------------------------------------------------