├── README.md ├── ThreadNotify.sln └── ThreadNotify ├── Source.cpp ├── ThreadNotify.inf ├── ThreadNotify.vcxproj ├── ThreadNotify.vcxproj.filters ├── ThreadNotify.vcxproj.user └── utils.h /README.md: -------------------------------------------------------------------------------- 1 | # POC Resgister-Callback Kernel 2 | 3 | 4 | Hooks the CiThreadNotification function in mmcss.sys. 5 | 6 | This function was registered by PsSetCreateThreadNotifyRoutine. 7 | 8 | 9 | ![136840273-fa0196ab-f20f-43f3-ae5f-9f5f0b358bc0](https://user-images.githubusercontent.com/29626806/136870172-fd40d99c-f295-4fbd-b8cd-ed8a4ba35bff.png) 10 | 11 | 12 | 13 | I don't know if this will be detected in the most decent Anti-Cheats like EAC, BE, VANGUARD, because it's in .text. 14 | 15 | 16 | # Load Driver with kdmapper 17 | -------------------------------------------------------------------------------- /ThreadNotify.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31605.320 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ThreadNotify", "ThreadNotify\ThreadNotify.vcxproj", "{280B4436-1B02-4328-A4FE-4438A668B84C}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM = Debug|ARM 11 | Debug|ARM64 = Debug|ARM64 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|ARM = Release|ARM 15 | Release|ARM64 = Release|ARM64 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Debug|ARM.ActiveCfg = Debug|ARM 21 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Debug|ARM.Build.0 = Debug|ARM 22 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Debug|ARM.Deploy.0 = Debug|ARM 23 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Debug|ARM64.ActiveCfg = Debug|ARM64 24 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Debug|ARM64.Build.0 = Debug|ARM64 25 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Debug|ARM64.Deploy.0 = Debug|ARM64 26 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Debug|x64.ActiveCfg = Debug|x64 27 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Debug|x64.Build.0 = Debug|x64 28 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Debug|x64.Deploy.0 = Debug|x64 29 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Debug|x86.ActiveCfg = Debug|Win32 30 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Debug|x86.Build.0 = Debug|Win32 31 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Debug|x86.Deploy.0 = Debug|Win32 32 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Release|ARM.ActiveCfg = Release|ARM 33 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Release|ARM.Build.0 = Release|ARM 34 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Release|ARM.Deploy.0 = Release|ARM 35 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Release|ARM64.ActiveCfg = Release|ARM64 36 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Release|ARM64.Build.0 = Release|ARM64 37 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Release|ARM64.Deploy.0 = Release|ARM64 38 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Release|x64.ActiveCfg = Release|x64 39 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Release|x64.Build.0 = Release|x64 40 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Release|x64.Deploy.0 = Release|x64 41 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Release|x86.ActiveCfg = Release|Win32 42 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Release|x86.Build.0 = Release|Win32 43 | {280B4436-1B02-4328-A4FE-4438A668B84C}.Release|x86.Deploy.0 = Release|Win32 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | GlobalSection(ExtensibilityGlobals) = postSolution 49 | SolutionGuid = {2CE11893-8C06-4C39-B7D4-8D2D2B8A6782} 50 | EndGlobalSection 51 | EndGlobal 52 | -------------------------------------------------------------------------------- /ThreadNotify/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | 3 | 4 | 5 | UCHAR ShellCode[] = { 6 | 0x50, 7 | 0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 8 | 0x48, 0x87, 0x04, 0x24, 9 | 0xC3 10 | }; 11 | 12 | void CiThreadNotification(HANDLE ProcessId, HANDLE ThreadId, BOOLEAN Create) 13 | { 14 | PEPROCESS Process; 15 | if (NT_SUCCESS(PsLookupProcessByProcessId(ProcessId, &Process)) && Create) 16 | { 17 | if (!Process) 18 | return; 19 | 20 | auto ProcessName = PsGetProcessImageFileName(Process); 21 | if (strcmp(ProcessName, "UserMode.exe") == 0) 22 | { 23 | DbgPrintEx( 24 | 0, 25 | 0, 26 | "[CiThreadNotification] ProcessId: %d | ProcessName: %s", 27 | ProcessId, 28 | ProcessName); 29 | } 30 | } 31 | } 32 | 33 | NTSTATUS 34 | DriverEntry( 35 | _In_ PDRIVER_OBJECT DriverObject, 36 | _In_ PUNICODE_STRING RegistryPath 37 | ) 38 | { 39 | UNREFERENCED_PARAMETER(DriverObject); 40 | UNREFERENCED_PARAMETER(RegistryPath); 41 | 42 | auto mmcssDriver = GetModuleBase(L"mmcss.sys"); 43 | if (!mmcssDriver) 44 | { 45 | DbgPrintEx(0, 0, "Failed to find mmcss.sys"); 46 | return STATUS_UNSUCCESSFUL; 47 | } 48 | 49 | auto fnCiThreadNotification = FindPatternImage(reinterpret_cast(mmcssDriver), "\x48\x83\xEC\x28\x45", "xxxxx"); 50 | if (!fnCiThreadNotification) 51 | { 52 | DbgPrintEx(0, 0, "Failed to find CiThreadNotification()"); 53 | return STATUS_UNSUCCESSFUL; 54 | } 55 | 56 | *(PVOID*)(ShellCode + 3) = reinterpret_cast(CiThreadNotification); 57 | 58 | if (!WriteToReadOnly(fnCiThreadNotification, ShellCode, sizeof(ShellCode))) 59 | { 60 | DbgPrintEx(0, 0, "Failed to Hooking"); 61 | return STATUS_UNSUCCESSFUL; 62 | } 63 | 64 | return STATUS_SUCCESS; 65 | } -------------------------------------------------------------------------------- /ThreadNotify/ThreadNotify.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; ThreadNotify.inf 3 | ; 4 | 5 | [Version] 6 | Signature="$WINDOWS NT$" 7 | Class=Sample ; TODO: edit Class 8 | ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid 9 | Provider=%ManufacturerName% 10 | CatalogFile=ThreadNotify.cat 11 | DriverVer= ; TODO: set DriverVer in stampinf property pages 12 | PnpLockDown=1 13 | 14 | [DestinationDirs] 15 | DefaultDestDir = 12 16 | ThreadNotify_Device_CoInstaller_CopyFiles = 11 17 | 18 | ; ================= Class section ===================== 19 | 20 | [ClassInstall32] 21 | Addreg=SampleClassReg 22 | 23 | [SampleClassReg] 24 | HKR,,,0,%ClassName% 25 | HKR,,Icon,,-5 26 | 27 | [SourceDisksNames] 28 | 1 = %DiskName%,,,"" 29 | 30 | [SourceDisksFiles] 31 | ThreadNotify.sys = 1,, 32 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames 33 | 34 | ;***************************************** 35 | ; Install Section 36 | ;***************************************** 37 | 38 | [Manufacturer] 39 | %ManufacturerName%=Standard,NT$ARCH$ 40 | 41 | [Standard.NT$ARCH$] 42 | %ThreadNotify.DeviceDesc%=ThreadNotify_Device, Root\ThreadNotify ; TODO: edit hw-id 43 | 44 | [ThreadNotify_Device.NT] 45 | CopyFiles=Drivers_Dir 46 | 47 | [Drivers_Dir] 48 | ThreadNotify.sys 49 | 50 | ;-------------- Service installation 51 | [ThreadNotify_Device.NT.Services] 52 | AddService = ThreadNotify,%SPSVCINST_ASSOCSERVICE%, ThreadNotify_Service_Inst 53 | 54 | ; -------------- ThreadNotify driver install sections 55 | [ThreadNotify_Service_Inst] 56 | DisplayName = %ThreadNotify.SVCDESC% 57 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 58 | StartType = 3 ; SERVICE_DEMAND_START 59 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 60 | ServiceBinary = %12%\ThreadNotify.sys 61 | 62 | ; 63 | ;--- ThreadNotify_Device Coinstaller installation ------ 64 | ; 65 | 66 | [ThreadNotify_Device.NT.CoInstallers] 67 | AddReg=ThreadNotify_Device_CoInstaller_AddReg 68 | CopyFiles=ThreadNotify_Device_CoInstaller_CopyFiles 69 | 70 | [ThreadNotify_Device_CoInstaller_AddReg] 71 | HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller" 72 | 73 | [ThreadNotify_Device_CoInstaller_CopyFiles] 74 | WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll 75 | 76 | [ThreadNotify_Device.NT.Wdf] 77 | KmdfService = ThreadNotify, ThreadNotify_wdfsect 78 | [ThreadNotify_wdfsect] 79 | KmdfLibraryVersion = $KMDFVERSION$ 80 | 81 | [Strings] 82 | SPSVCINST_ASSOCSERVICE= 0x00000002 83 | ManufacturerName="" ;TODO: Replace with your manufacturer name 84 | ClassName="Samples" ; TODO: edit ClassName 85 | DiskName = "ThreadNotify Installation Disk" 86 | ThreadNotify.DeviceDesc = "ThreadNotify Device" 87 | ThreadNotify.SVCDESC = "ThreadNotify Service" 88 | -------------------------------------------------------------------------------- /ThreadNotify/ThreadNotify.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | Debug 22 | ARM 23 | 24 | 25 | Release 26 | ARM 27 | 28 | 29 | Debug 30 | ARM64 31 | 32 | 33 | Release 34 | ARM64 35 | 36 | 37 | 38 | {280B4436-1B02-4328-A4FE-4438A668B84C} 39 | {1bc93793-694f-48fe-9372-81e2b05556fd} 40 | v4.5 41 | 12.0 42 | Debug 43 | Win32 44 | ThreadNotify 45 | 46 | 47 | 48 | Windows10 49 | true 50 | WindowsKernelModeDriver10.0 51 | Driver 52 | KMDF 53 | Universal 54 | 55 | 56 | Windows10 57 | false 58 | WindowsKernelModeDriver10.0 59 | Driver 60 | KMDF 61 | Universal 62 | false 63 | 64 | 65 | Windows10 66 | true 67 | WindowsKernelModeDriver10.0 68 | Driver 69 | KMDF 70 | Universal 71 | 72 | 73 | Windows10 74 | false 75 | WindowsKernelModeDriver10.0 76 | Driver 77 | KMDF 78 | Universal 79 | false 80 | 81 | 82 | Windows10 83 | true 84 | WindowsKernelModeDriver10.0 85 | Driver 86 | KMDF 87 | Universal 88 | 89 | 90 | Windows10 91 | false 92 | WindowsKernelModeDriver10.0 93 | Driver 94 | KMDF 95 | Universal 96 | 97 | 98 | Windows10 99 | true 100 | WindowsKernelModeDriver10.0 101 | Driver 102 | KMDF 103 | Universal 104 | 105 | 106 | Windows10 107 | false 108 | WindowsKernelModeDriver10.0 109 | Driver 110 | KMDF 111 | Universal 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | DbgengKernelDebugger 123 | 124 | 125 | DbgengKernelDebugger 126 | 127 | 128 | DbgengKernelDebugger 129 | 130 | 131 | DbgengKernelDebugger 132 | 133 | 134 | DbgengKernelDebugger 135 | 136 | 137 | DbgengKernelDebugger 138 | 139 | 140 | DbgengKernelDebugger 141 | 142 | 143 | DbgengKernelDebugger 144 | 145 | 146 | 147 | DriverEntry 148 | 149 | 150 | false 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /ThreadNotify/ThreadNotify.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;hpp;hxx;hm;inl;inc;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 | {8E41214B-6785-4CFE-B992-037D68949A14} 18 | inf;inv;inx;mof;mc; 19 | 20 | 21 | 22 | 23 | Driver Files 24 | 25 | 26 | 27 | 28 | Source Files 29 | 30 | 31 | 32 | 33 | Header Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /ThreadNotify/ThreadNotify.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Off 5 | 6 | -------------------------------------------------------------------------------- /ThreadNotify/utils.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | typedef unsigned long DWORD; 7 | typedef int BOOL; 8 | typedef unsigned char BYTE; 9 | typedef unsigned short WORD; 10 | typedef float FLOAT; 11 | typedef int PINT; 12 | 13 | extern "C" PLIST_ENTRY NTKERNELAPI PsLoadedModuleList; 14 | 15 | extern "C" NTKERNELAPI 16 | PCHAR 17 | PsGetProcessImageFileName( 18 | _In_ PEPROCESS Process 19 | ); 20 | 21 | typedef struct _PEB_LDR_DATA 22 | { 23 | ULONG Length; 24 | BOOLEAN Initialized; 25 | HANDLE SsHandle; 26 | LIST_ENTRY InLoadOrderModuleList; 27 | LIST_ENTRY InMemoryOrderModuleList; 28 | LIST_ENTRY InInitializationOrderModuleList; 29 | PVOID EntryInProgress; 30 | BOOLEAN ShutdownInProgress; 31 | HANDLE ShutdownThreadId; 32 | } PEB_LDR_DATA, * PPEB_LDR_DATA; 33 | 34 | typedef struct _LDR_SERVICE_TAG_RECORD 35 | { 36 | struct _LDR_SERVICE_TAG_RECORD* Next; 37 | ULONG ServiceTag; 38 | } LDR_SERVICE_TAG_RECORD, * PLDR_SERVICE_TAG_RECORD; 39 | 40 | typedef struct _LDRP_CSLIST 41 | { 42 | PSINGLE_LIST_ENTRY Tail; 43 | } LDRP_CSLIST, * PLDRP_CSLIST; 44 | 45 | typedef enum _LDR_DDAG_STATE { 46 | LdrModulesMerged = -5, 47 | LdrModulesInitError = -4, 48 | LdrModulesSnapError = -3, 49 | LdrModulesUnloaded = -2, 50 | LdrModulesUnloading = -1, 51 | LdrModulesPlaceHolder = 0, 52 | LdrModulesMapping = 1, 53 | LdrModulesMapped = 2, 54 | LdrModulesWaitingForDependencies = 3, 55 | LdrModulesSnapping = 4, 56 | LdrModulesSnapped = 5, 57 | LdrModulesCondensed = 6, 58 | LdrModulesReadyToInit = 7, 59 | LdrModulesInitializing = 8, 60 | LdrModulesReadyToRun = 9 61 | } LDR_DDAG_STATE; 62 | 63 | typedef struct _LDR_DDAG_NODE 64 | { 65 | LIST_ENTRY Modules; 66 | PLDR_SERVICE_TAG_RECORD ServiceTagList; 67 | ULONG LoadCount; 68 | ULONG LoadWhileUnloadingCount; 69 | ULONG LowestLink; 70 | union { 71 | LDRP_CSLIST Dependencies; 72 | SINGLE_LIST_ENTRY RemovalLink; 73 | }; 74 | LDRP_CSLIST IncomingDependencies; 75 | LDR_DDAG_STATE State; 76 | SINGLE_LIST_ENTRY CondenseLink; 77 | ULONG PreorderNumber; 78 | } LDR_DDAG_NODE, * PLDR_DDAG_NODE; 79 | 80 | typedef struct _LDR_DEPENDENCY_RECORD 81 | { 82 | SINGLE_LIST_ENTRY DependencyLink; 83 | PLDR_DDAG_NODE DependencyNode; 84 | SINGLE_LIST_ENTRY IncomingDependencyLink; 85 | PLDR_DDAG_NODE IncomingDependencyNode; 86 | } LDR_DEPENDENCY_RECORD, * PLDR_DEPENDENCY_RECORD; 87 | 88 | typedef enum _LDR_DLL_LOAD_REASON { 89 | LoadReasonStaticDependency, 90 | LoadReasonStaticForwarderDependency, 91 | LoadReasonDynamicForwarderDependency, 92 | LoadReasonDelayloadDependency, 93 | LoadReasonDynamicLoad, 94 | LoadReasonAsImageLoad, 95 | LoadReasonAsDataLoad, 96 | LoadReasonUnknown = -1 97 | } LDR_DLL_LOAD_REASON, 98 | * PLDR_DLL_LOAD_REASON; 99 | 100 | typedef struct _LDR_DATA_TABLE_ENTRY 101 | { 102 | LIST_ENTRY InLoadOrderLinks; 103 | LIST_ENTRY InMemoryOrderLinks; 104 | union { 105 | LIST_ENTRY InInitializationOrderLinks; 106 | LIST_ENTRY InProgressLinks; 107 | }; 108 | PVOID DllBase; 109 | PVOID EntryPoint; 110 | ULONG SizeOfImage; 111 | UNICODE_STRING FullDllName; 112 | UNICODE_STRING BaseDllName; 113 | union { 114 | UCHAR FlagGroup[4]; 115 | ULONG Flags; 116 | struct 117 | { 118 | ULONG PackagedBinary : 1; 119 | ULONG MarkedForRemoval : 1; 120 | ULONG ImageDll : 1; 121 | ULONG LoadNotificationsSent : 1; 122 | ULONG TelemetryEntryProcessed : 1; 123 | ULONG ProcessStaticImport : 1; 124 | ULONG InLegacyLists : 1; 125 | ULONG InIndexes : 1; 126 | ULONG ShimDll : 1; 127 | ULONG InExceptionTable : 1; 128 | ULONG ReservedFlags1 : 2; 129 | ULONG LoadInProgress : 1; 130 | ULONG LoadConfigProcessed : 1; 131 | ULONG EntryProcessed : 1; 132 | ULONG ProtectDelayLoad : 1; 133 | ULONG ReservedFlags3 : 2; 134 | ULONG DontCallForThreads : 1; 135 | ULONG ProcessAttachCalled : 1; 136 | ULONG ProcessAttachFailed : 1; 137 | ULONG CorDeferredValidate : 1; 138 | ULONG CorImage : 1; 139 | ULONG DontRelocate : 1; 140 | ULONG CorILOnly : 1; 141 | ULONG ReservedFlags5 : 3; 142 | ULONG Redirected : 1; 143 | ULONG ReservedFlags6 : 2; 144 | ULONG CompatDatabaseProcessed : 1; 145 | }; 146 | }; 147 | USHORT ObsoleteLoadCount; 148 | USHORT TlsIndex; 149 | LIST_ENTRY HashLinks; 150 | ULONG TimeDateStamp; 151 | struct _ACTIVATION_CONTEXT* EntryPointActivationContext; 152 | PVOID Lock; 153 | PLDR_DDAG_NODE DdagNode; 154 | LIST_ENTRY NodeModuleLink; 155 | struct _LDRP_LOAD_CONTEXT* LoadContext; 156 | PVOID ParentDllBase; 157 | PVOID SwitchBackContext; 158 | RTL_BALANCED_NODE BaseAddressIndexNode; 159 | RTL_BALANCED_NODE MappingInfoIndexNode; 160 | ULONG_PTR OriginalBase; 161 | LARGE_INTEGER LoadTime; 162 | ULONG BaseNameHashValue; 163 | LDR_DLL_LOAD_REASON LoadReason; 164 | ULONG ImplicitPathOptions; 165 | ULONG ReferenceCount; 166 | ULONG DependentLoadFlags; 167 | } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; 168 | 169 | BOOL CheckMask(PCHAR base, PCHAR pattern, PCHAR mask) 170 | { 171 | for (; *mask; ++base, ++pattern, ++mask) 172 | { 173 | if ('x' == *mask && *base != *pattern) 174 | { 175 | return FALSE; 176 | } 177 | } 178 | 179 | return TRUE; 180 | } 181 | 182 | PVOID FindPattern(PCHAR base, DWORD length, PCHAR pattern, PCHAR mask) 183 | { 184 | length -= (DWORD)strlen(mask); 185 | for (DWORD i = 0; i <= length; ++i) 186 | { 187 | PVOID addr = &base[i]; 188 | 189 | if (CheckMask((PCHAR)addr, pattern, mask)) 190 | { 191 | return addr; 192 | } 193 | } 194 | 195 | return 0; 196 | } 197 | 198 | PVOID FindPatternImage(PCHAR base, PCHAR pattern, PCHAR mask) 199 | { 200 | PVOID match = 0; 201 | 202 | PIMAGE_NT_HEADERS headers = (PIMAGE_NT_HEADERS)(base + ((PIMAGE_DOS_HEADER)base)->e_lfanew); 203 | PIMAGE_SECTION_HEADER sections = IMAGE_FIRST_SECTION(headers); 204 | for (DWORD i = 0; i < headers->FileHeader.NumberOfSections; ++i) 205 | { 206 | PIMAGE_SECTION_HEADER section = §ions[i]; 207 | if ('EGAP' == *(int*)section->Name || memcmp(section->Name, ".text", 5) == 0) 208 | { 209 | match = FindPattern(base + section->VirtualAddress, section->Misc.VirtualSize, pattern, mask); 210 | if (match) 211 | { 212 | break; 213 | } 214 | } 215 | } 216 | 217 | return match; 218 | } 219 | 220 | 221 | PVOID GetModuleBase(LPCWSTR moduleName) { 222 | 223 | PLIST_ENTRY ModuleList = reinterpret_cast(PsLoadedModuleList); 224 | if (!ModuleList) 225 | return NULL; 226 | 227 | UNICODE_STRING pmoduleName{ }; 228 | RtlInitUnicodeString(&pmoduleName, moduleName); 229 | 230 | for (auto entry = PsLoadedModuleList; entry != PsLoadedModuleList->Blink; entry = entry->Flink) 231 | { 232 | PLDR_DATA_TABLE_ENTRY Datatable = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 233 | 234 | if (Datatable->BaseDllName.Length == pmoduleName.Length && RtlEqualUnicodeString(&Datatable->BaseDllName, &pmoduleName, TRUE)) { 235 | return Datatable->DllBase; 236 | } 237 | } 238 | 239 | return NULL; 240 | } 241 | 242 | BOOLEAN 243 | WriteToReadOnly(PVOID destination, 244 | PVOID buffer, 245 | SIZE_T size 246 | ) 247 | { 248 | PMDL mdl = IoAllocateMdl(destination, size, FALSE, FALSE, 0); 249 | if (!mdl) 250 | return FALSE; 251 | 252 | MmProbeAndLockPages(mdl, KernelMode, IoReadAccess); 253 | MmProtectMdlSystemAddress(mdl, PAGE_EXECUTE_READWRITE); 254 | 255 | auto mmMap = MmMapLockedPagesSpecifyCache(mdl, KernelMode, MmNonCached, NULL, FALSE, NormalPagePriority); 256 | memcpy(mmMap, buffer, size); 257 | 258 | MmUnmapLockedPages(mmMap, mdl); 259 | MmUnlockPages(mdl); 260 | IoFreeMdl(mdl); 261 | 262 | return TRUE; 263 | } 264 | --------------------------------------------------------------------------------