├── MemScanner.sln ├── MemScanner ├── DriverScanner.c ├── DriverScanner.h ├── Import.h ├── MemScanner.vcxproj ├── MemScanner.vcxproj.filters ├── NativeStruct.h ├── Private.c ├── Private.h ├── ProcessScanner.c ├── ProcessScanner.h ├── SectionScanner.c ├── SectionScanner.h ├── Utils.c ├── Utils.h └── main.c └── README.md /MemScanner.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30611.23 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MemScanner", "MemScanner\MemScanner.vcxproj", "{A03B3488-ABEB-4D77-8C35-CEBFFC44699E}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {A03B3488-ABEB-4D77-8C35-CEBFFC44699E}.Debug|x64.ActiveCfg = Debug|x64 15 | {A03B3488-ABEB-4D77-8C35-CEBFFC44699E}.Debug|x64.Build.0 = Debug|x64 16 | {A03B3488-ABEB-4D77-8C35-CEBFFC44699E}.Debug|x64.Deploy.0 = Debug|x64 17 | {A03B3488-ABEB-4D77-8C35-CEBFFC44699E}.Release|x64.ActiveCfg = Release|x64 18 | {A03B3488-ABEB-4D77-8C35-CEBFFC44699E}.Release|x64.Build.0 = Release|x64 19 | {A03B3488-ABEB-4D77-8C35-CEBFFC44699E}.Release|x64.Deploy.0 = Release|x64 20 | EndGlobalSection 21 | GlobalSection(SolutionProperties) = preSolution 22 | HideSolutionNode = FALSE 23 | EndGlobalSection 24 | GlobalSection(ExtensibilityGlobals) = postSolution 25 | SolutionGuid = {3AF30B78-0863-4DD0-9F09-E07067B13245} 26 | EndGlobalSection 27 | EndGlobal 28 | -------------------------------------------------------------------------------- /MemScanner/DriverScanner.c: -------------------------------------------------------------------------------- 1 | #include "DriverScanner.h" 2 | #include "Private.h" 3 | #include "Utils.h" 4 | 5 | 6 | extern POBJECT_TYPE* IoDriverObjectType; 7 | 8 | extern DYNAMIC_DATA g_dynData; 9 | extern PDRIVER_OBJECT g_DriverObject; 10 | //------------------------------------------------------------------------------------------------------------------------------------- 11 | VOID ScanDriverByDriverObjectMemory() 12 | { 13 | PVOID lpStartAddr = NULL; 14 | SIZE_T ulSize = 0; 15 | ULONG_PTR lpSearchAddr = 0; 16 | ULONG_PTR lpEndAddr = 0; 17 | ULONG ulEntrySize = 0; 18 | ULONG ulCurrentSize = 0; 19 | ULONG_PTR pDriverObject = 0; 20 | NTSTATUS status = STATUS_SUCCESS; 21 | PKLDR_DATA_TABLE_ENTRY pLdr = NULL; 22 | 23 | 24 | if (g_dynData.ver >= WINVER_7) 25 | { 26 | lpStartAddr = g_DriverObject; 27 | lpStartAddr = (PVOID)((ULONG_PTR)lpStartAddr & 0xFFFFFFFF00000000); 28 | ulSize = 0x300000000; 29 | } 30 | else 31 | { 32 | return; 33 | } 34 | 35 | lpSearchAddr = (ULONG_PTR)lpStartAddr; 36 | lpEndAddr = lpSearchAddr + ulSize - sizeof(DRIVER_OBJECT); 37 | 38 | KdPrint(("[%s] lpSearchAddr:%p lpEndAddr:%p\n", __FUNCTION__, lpSearchAddr, lpEndAddr)); 39 | 40 | while (TRUE) 41 | { 42 | if (lpSearchAddr + PAGE_SIZE > lpEndAddr) 43 | { 44 | ulEntrySize = (ULONG)(lpEndAddr - lpSearchAddr); 45 | } 46 | else 47 | { 48 | ulEntrySize = PAGE_SIZE; 49 | } 50 | 51 | if (!MmsIsAddressValidLength((PVOID)lpSearchAddr, ulEntrySize)) 52 | { 53 | goto NextLoop; 54 | } 55 | 56 | pDriverObject = lpSearchAddr; 57 | 58 | ulCurrentSize = 0; 59 | ulEntrySize -= sizeof(DRIVER_OBJECT); 60 | 61 | while (ulCurrentSize < ulEntrySize) 62 | { 63 | if (MmsIsRealDriverObject((PDRIVER_OBJECT)pDriverObject)) 64 | { 65 | pLdr = (PKLDR_DATA_TABLE_ENTRY)(((PDRIVER_OBJECT)pDriverObject)->DriverSection); 66 | KdPrint(("[%s] pDriverObject:%p FullName:%wZ, DllBase:%I64x, Size:%x\n", __FUNCTION__, pDriverObject, &pLdr->FullDllName, pLdr->DllBase, pLdr->SizeOfImage)); 67 | 68 | ulCurrentSize += sizeof(DRIVER_OBJECT); 69 | pDriverObject += sizeof(DRIVER_OBJECT); 70 | } 71 | else 72 | { 73 | ulCurrentSize += sizeof(ULONG_PTR); 74 | pDriverObject += sizeof(ULONG_PTR); 75 | } 76 | } 77 | 78 | NextLoop: 79 | lpSearchAddr += PAGE_SIZE; 80 | if (lpSearchAddr >= lpEndAddr) 81 | { 82 | break; 83 | } 84 | } 85 | } 86 | //------------------------------------------------------------------------------------------------------------------------------------- 87 | VOID ScanDriverByLdrDataTableEntryMemory() 88 | { 89 | PVOID lpStartAddr = NULL; 90 | SIZE_T ulSize = 0; 91 | ULONG_PTR lpSearchAddr = 0; 92 | ULONG_PTR lpTargetAddr = 0; 93 | ULONG ulEntrySize = 0; 94 | ULONG_PTR lpEndAddr = 0; 95 | PLDR_DATA_TABLE_ENTRY lpLdrEntry = NULL; 96 | PPOOL_HEADER PoolHeader = NULL; 97 | 98 | if (g_dynData.ver >= WINVER_7) 99 | { 100 | lpStartAddr = g_DriverObject->DriverSection; 101 | lpStartAddr = (PVOID)((ULONG_PTR)lpStartAddr & 0xFFFFFFFF00000000); 102 | ulSize = 0x300000000; 103 | } 104 | else 105 | { 106 | return; 107 | } 108 | 109 | if (!lpStartAddr) 110 | { 111 | return; 112 | } 113 | 114 | lpSearchAddr = (ULONG_PTR)lpStartAddr; 115 | lpEndAddr = lpSearchAddr + ulSize - sizeof(POOL_HEADER); 116 | 117 | KdPrint(("[%s] lpSearchAddr:%p lpEndAddr:%p\n", __FUNCTION__, lpSearchAddr, lpEndAddr)); 118 | 119 | // Search For _ldr_data_table_entry 120 | while (TRUE) 121 | { 122 | if (lpSearchAddr + PAGE_SIZE > lpEndAddr) 123 | { 124 | ulEntrySize = (ULONG)(lpEndAddr - lpSearchAddr); 125 | } 126 | else 127 | { 128 | ulEntrySize = PAGE_SIZE; 129 | } 130 | 131 | if (!MmsIsAddressValidLength((PVOID)lpSearchAddr, ulEntrySize)) 132 | { 133 | goto NextLoop; 134 | } 135 | 136 | lpTargetAddr = lpSearchAddr; 137 | 138 | while (TRUE) 139 | { 140 | PoolHeader = (PPOOL_HEADER)lpTargetAddr; 141 | if (PoolHeader->PoolTag == 'dLmM') 142 | { 143 | lpLdrEntry = (PLDR_DATA_TABLE_ENTRY)(lpTargetAddr + sizeof(POOL_HEADER)); 144 | if (lpTargetAddr + sizeof(LDR_DATA_TABLE_ENTRY) + sizeof(POOL_HEADER) > lpSearchAddr + ulEntrySize) 145 | { 146 | if (!MmsIsAddressValidLength((PVOID)lpTargetAddr, sizeof(LDR_DATA_TABLE_ENTRY) + sizeof(POOL_HEADER))) 147 | { 148 | break; 149 | } 150 | } 151 | 152 | if (MmsIsValidUnicodeString(&lpLdrEntry->FullDllName) && 153 | MmsIsValidUnicodeString(&lpLdrEntry->BaseDllName) && 154 | lpLdrEntry->DllBase && 155 | lpLdrEntry->SizeOfImage && 156 | MmIsAddressValid(lpLdrEntry->DllBase)) 157 | { 158 | KdPrint(("[%s] FullName:%wZ, BaseName:%wZ, DllBase:%p, Size:%x\n", __FUNCTION__, &lpLdrEntry->FullDllName, &lpLdrEntry->BaseDllName, lpLdrEntry->DllBase, lpLdrEntry->SizeOfImage)); 159 | } 160 | 161 | lpTargetAddr += sizeof(LDR_DATA_TABLE_ENTRY) + sizeof(POOL_HEADER); 162 | } 163 | else 164 | { 165 | lpTargetAddr += sizeof(ULONG); 166 | } 167 | 168 | if (lpTargetAddr + sizeof(POOL_HEADER) >= lpSearchAddr + ulEntrySize) 169 | { 170 | break; 171 | } 172 | } 173 | 174 | NextLoop: 175 | lpSearchAddr += PAGE_SIZE; 176 | if (lpSearchAddr >= lpEndAddr) 177 | { 178 | break; 179 | } 180 | } 181 | } 182 | //------------------------------------------------------------------------------------------------------------------------------------- 183 | VOID ScanDriverByBigPoolSuspiciousPE() 184 | { 185 | //Not Implement 186 | } 187 | //------------------------------------------------------------------------------------------------------------------------------------- 188 | VOID ScanDriverByMmSessionSuspiciousPE() 189 | { 190 | //Not Implement 191 | } 192 | //------------------------------------------------------------------------------------------------------------------------------------- 193 | VOID ScanDriverBySystemPtesSuspiciousPE() 194 | { 195 | //Not Implement 196 | } 197 | //------------------------------------------------------------------------------------------------------------------------------------- 198 | VOID ScanDriverByDriverImageSuspiciousPE() 199 | { 200 | //Not Implement 201 | } 202 | //------------------------------------------------------------------------------------------------------------------------------------- 203 | VOID ScanDriver() 204 | { 205 | ScanDriverByDriverObjectMemory(); 206 | 207 | ScanDriverByLdrDataTableEntryMemory(); 208 | 209 | // 内存扫描 210 | // 1. For BigPool which allocated By ExAllocatePoolWithTag 211 | ScanDriverByBigPoolSuspiciousPE(); 212 | 213 | // 2. For MmSession which allocated By MmMapViewInSystemSpace 214 | ScanDriverByMmSessionSuspiciousPE(); 215 | 216 | // 3. For SystemPtes which allocated By MmMapLockPagesSpecifyCache 217 | ScanDriverBySystemPtesSuspiciousPE(); 218 | 219 | // 4. For DriverImage which allocated By System Loader... 220 | ScanDriverByDriverImageSuspiciousPE(); 221 | } 222 | //------------------------------------------------------------------------------------------------------------------------------------- 223 | -------------------------------------------------------------------------------- /MemScanner/DriverScanner.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | VOID ScanDriver(); -------------------------------------------------------------------------------- /MemScanner/Import.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | NTSYSAPI 6 | NTSTATUS 7 | NTAPI 8 | ZwQuerySystemInformation( 9 | IN ULONG SystemInformationClass, 10 | OUT PVOID SystemInformation, 11 | IN ULONG SystemInformationLength, 12 | OUT PULONG ReturnLength); 13 | 14 | NTSYSAPI 15 | PIMAGE_NT_HEADERS 16 | NTAPI 17 | RtlImageNtHeader(PVOID Base); 18 | -------------------------------------------------------------------------------- /MemScanner/MemScanner.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 | {A03B3488-ABEB-4D77-8C35-CEBFFC44699E} 39 | {dd38f7fc-d7bd-488b-9242-7d8754cde80d} 40 | v4.5 41 | 12.0 42 | Debug 43 | Win32 44 | MemScanner 45 | 46 | 47 | 48 | Windows10 49 | true 50 | WindowsKernelModeDriver10.0 51 | Driver 52 | WDM 53 | 54 | 55 | Windows10 56 | false 57 | WindowsKernelModeDriver10.0 58 | Driver 59 | WDM 60 | 61 | 62 | Windows7 63 | true 64 | WindowsKernelModeDriver10.0 65 | Driver 66 | WDM 67 | 68 | 69 | Windows10 70 | false 71 | WindowsKernelModeDriver10.0 72 | Driver 73 | WDM 74 | 75 | 76 | Windows10 77 | true 78 | WindowsKernelModeDriver10.0 79 | Driver 80 | WDM 81 | 82 | 83 | Windows10 84 | false 85 | WindowsKernelModeDriver10.0 86 | Driver 87 | WDM 88 | 89 | 90 | Windows10 91 | true 92 | WindowsKernelModeDriver10.0 93 | Driver 94 | WDM 95 | 96 | 97 | Windows10 98 | false 99 | WindowsKernelModeDriver10.0 100 | Driver 101 | WDM 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | DbgengKernelDebugger 113 | 114 | 115 | DbgengKernelDebugger 116 | 117 | 118 | DbgengKernelDebugger 119 | 120 | 121 | DbgengKernelDebugger 122 | 123 | 124 | DbgengKernelDebugger 125 | 126 | 127 | DbgengKernelDebugger 128 | 129 | 130 | DbgengKernelDebugger 131 | 132 | 133 | DbgengKernelDebugger 134 | 135 | 136 | 137 | Level2 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /MemScanner/MemScanner.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 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | 38 | 39 | Header Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | Header Files 46 | 47 | 48 | Header Files 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | -------------------------------------------------------------------------------- /MemScanner/NativeStruct.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | #define SEC_IMAGE 0x01000000 7 | 8 | typedef struct _SYSTEM_BASIC_INFORMATION { 9 | ULONG Reserved; 10 | ULONG TimerResolution; 11 | ULONG PageSize; 12 | ULONG NumberOfPhysicalPages; 13 | ULONG LowestPhysicalPageNumber; 14 | ULONG HighestPhysicalPageNumber; 15 | ULONG AllocationGranularity; 16 | ULONG_PTR MinimumUserModeAddress; 17 | ULONG_PTR MaximumUserModeAddress; 18 | ULONG_PTR ActiveProcessorsAffinityMask; 19 | CCHAR NumberOfProcessors; 20 | } SYSTEM_BASIC_INFORMATION, * PSYSTEM_BASIC_INFORMATION; 21 | 22 | 23 | typedef struct _SYSTEM_MODULE_ENTRY 24 | { 25 | HANDLE Section; 26 | PVOID MappedBase; 27 | PVOID Base; 28 | ULONG Size; 29 | ULONG Flags; 30 | USHORT LoadOrderIndex; 31 | USHORT InitOrderIndex; 32 | USHORT LoadCount; 33 | USHORT OffsetToFileName; 34 | UCHAR ImageName[256]; 35 | } SYSTEM_MODULE_ENTRY, * PSYSTEM_MODULE_ENTRY; 36 | 37 | 38 | typedef struct _SYSTEM_MODULE_INFORMATION 39 | { 40 | ULONG Count; 41 | SYSTEM_MODULE_ENTRY Modules[ANYSIZE_ARRAY]; 42 | } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; 43 | 44 | typedef struct _SYSTEM_BIGPOOL_ENTRY 45 | { 46 | union { 47 | PVOID VirtualAddress; 48 | ULONG_PTR NonPaged : 1; 49 | }; 50 | 51 | ULONG_PTR SizeInBytes; 52 | 53 | union { 54 | UCHAR Tag[4]; 55 | ULONG TagUlong; 56 | }; 57 | 58 | } SYSTEM_BIGPOOL_ENTRY, * PSYSTEM_BIGPOOL_ENTRY; 59 | 60 | typedef struct _SYSTEM_BIGPOOL_INFORMATION 61 | { 62 | ULONG Count; 63 | SYSTEM_BIGPOOL_ENTRY AllocatedInfo[ANYSIZE_ARRAY]; 64 | } SYSTEM_BIGPOOL_INFORMATION, * PSYSTEM_BIGPOOL_INFORMATION; 65 | 66 | 67 | typedef enum _SYSTEM_INFORMATION_CLASS { 68 | SystemBasicInformation, 69 | SystemProcessorInformation, 70 | SystemPerformanceInformation, 71 | SystemTimeOfDayInformation, 72 | SystemNotImplemented1, 73 | SystemProcessesInformation, 74 | SystemCallCounts, 75 | SystemConfigurationInformation, 76 | SystemProcessorTimes, 77 | SystemGlobalFlag, 78 | SystemNotImplemented2, 79 | SystemModuleInformation, 80 | SystemLockInformation, 81 | SystemNotImplemented3, 82 | SystemNotImplemented4, 83 | SystemNotImplemented5, 84 | SystemHandleInformation, 85 | SystemObjectInformation, 86 | SystemPagefileInformation, 87 | SystemInstructionEmulationCounts, 88 | SystemInvalidInfoClass1, 89 | SystemCacheInformation, 90 | SystemPoolTagInformation, 91 | SystemProcessorStatistics, 92 | SystemDpcInformation, 93 | SystemNotImplemented6, 94 | SystemLoadImage, 95 | SystemUnloadImage, 96 | SystemTimeAdjustment, 97 | SystemNotImplemented7, 98 | SystemNotImplemented8, 99 | SystemNotImplemented9, 100 | SystemCrashDumpInformation, 101 | SystemExceptionInformation, 102 | SystemCrashDumpStateInformation, 103 | SystemKernelDebuggerInformation, 104 | SystemContextSwitchInformation, 105 | SystemRegistryQuotaInformation, 106 | SystemLoadAndCallImage, 107 | SystemPrioritySeparation, 108 | SystemNotImplemented10, 109 | SystemNotImplemented11, 110 | SystemInvalidInfoClass2, 111 | SystemInvalidInfoClass3, 112 | SystemCurrentTimeZoneInformation, 113 | SystemLookasideInformation, 114 | SystemSetTimeSlipEvent, 115 | SystemCreateSession, 116 | SystemDeleteSession, 117 | SystemInvalidInfoClass4, 118 | SystemRangeStartInformation, 119 | SystemVerifierInformation, 120 | SystemAddVerifier, 121 | SystemSessionProcessesInformation, 122 | SystemLoadGdiDriverInSystemSpace = 0x0036, 123 | SystemNumaProcessorMap = 0x0037, 124 | SystemPrefetcherInformation = 0x0038, 125 | SystemExtendedProcessInformation = 0x0039, 126 | SystemRecommendedSharedDataAlignment = 0x003A, 127 | SystemComPlusPackage = 0x003B, 128 | SystemNumaAvailableMemory = 0x003C, 129 | SystemProcessorPowerInformation = 0x003D, 130 | SystemEmulationBasicInformation = 0x003E, 131 | SystemEmulationProcessorInformation = 0x003F, 132 | SystemExtendedHandleInformation = 0x0040, 133 | SystemLostDelayedWriteInformation = 0x0041, 134 | SystemBigPoolInformation = 0x0042, 135 | SystemSessionPoolTagInformation = 0x0043, 136 | SystemSessionMappedViewInformation = 0x0044, 137 | SystemHotpatchInformation = 0x0045, 138 | SystemObjectSecurityMode = 0x0046, 139 | SystemWatchdogTimerHandler = 0x0047, 140 | SystemWatchdogTimerInformation = 0x0048, 141 | SystemLogicalProcessorInformation = 0x0049, 142 | SystemWow64SharedInformationObsolete = 0x004A, 143 | SystemRegisterFirmwareTableInformationHandler = 0x004B, 144 | SystemFirmwareTableInformation = 0x004C, 145 | SystemModuleInformationEx = 0x004D, 146 | SystemVerifierTriageInformation = 0x004E, 147 | SystemSuperfetchInformation = 0x004F, 148 | SystemMemoryListInformation = 0x0050, 149 | SystemFileCacheInformationEx = 0x0051, 150 | SystemThreadPriorityClientIdInformation = 0x0052, 151 | SystemProcessorIdleCycleTimeInformation = 0x0053, 152 | SystemVerifierCancellationInformation = 0x0054, 153 | SystemProcessorPowerInformationEx = 0x0055, 154 | SystemRefTraceInformation = 0x0056, 155 | SystemSpecialPoolInformation = 0x0057, 156 | SystemProcessIdInformation = 0x0058, 157 | SystemErrorPortInformation = 0x0059, 158 | SystemBootEnvironmentInformation = 0x005A, 159 | SystemHypervisorInformation = 0x005B, 160 | SystemVerifierInformationEx = 0x005C, 161 | SystemTimeZoneInformation = 0x005D, 162 | SystemImageFileExecutionOptionsInformation = 0x005E, 163 | SystemCoverageInformation = 0x005F, 164 | SystemPrefetchPatchInformation = 0x0060, 165 | SystemVerifierFaultsInformation = 0x0061, 166 | SystemSystemPartitionInformation = 0x0062, 167 | SystemSystemDiskInformation = 0x0063, 168 | SystemProcessorPerformanceDistribution = 0x0064, 169 | SystemNumaProximityNodeInformation = 0x0065, 170 | SystemDynamicTimeZoneInformation = 0x0066, 171 | SystemCodeIntegrityInformation = 0x0067, 172 | SystemProcessorMicrocodeUpdateInformation = 0x0068, 173 | SystemProcessorBrandString = 0x0069, 174 | SystemVirtualAddressInformation = 0x006A, 175 | SystemLogicalProcessorAndGroupInformation = 0x006B, 176 | SystemProcessorCycleTimeInformation = 0x006C, 177 | SystemStoreInformation = 0x006D, 178 | SystemRegistryAppendString = 0x006E, 179 | SystemAitSamplingValue = 0x006F, 180 | SystemVhdBootInformation = 0x0070, 181 | SystemCpuQuotaInformation = 0x0071, 182 | SystemNativeBasicInformation = 0x0072, 183 | SystemErrorPortTimeouts = 0x0073, 184 | SystemLowPriorityIoInformation = 0x0074, 185 | SystemBootEntropyInformation = 0x0075, 186 | SystemVerifierCountersInformation = 0x0076, 187 | SystemPagedPoolInformationEx = 0x0077, 188 | SystemSystemPtesInformationEx = 0x0078, 189 | SystemNodeDistanceInformation = 0x0079, 190 | SystemAcpiAuditInformation = 0x007A, 191 | SystemBasicPerformanceInformation = 0x007B, 192 | SystemQueryPerformanceCounterInformation = 0x007C, 193 | SystemSessionBigPoolInformation = 0x007D, 194 | SystemBootGraphicsInformation = 0x007E, 195 | SystemScrubPhysicalMemoryInformation = 0x007F, 196 | SystemBadPageInformation = 0x0080, 197 | SystemProcessorProfileControlArea = 0x0081, 198 | SystemCombinePhysicalMemoryInformation = 0x0082, 199 | SystemEntropyInterruptTimingInformation = 0x0083, 200 | SystemConsoleInformation = 0x0084, 201 | SystemPlatformBinaryInformation = 0x0085, 202 | SystemThrottleNotificationInformation = 0x0086, 203 | SystemHypervisorProcessorCountInformation = 0x0087, 204 | SystemDeviceDataInformation = 0x0088, 205 | SystemDeviceDataEnumerationInformation = 0x0089, 206 | SystemMemoryTopologyInformation = 0x008A, 207 | SystemMemoryChannelInformation = 0x008B, 208 | SystemBootLogoInformation = 0x008C, 209 | SystemProcessorPerformanceInformationEx = 0x008D, 210 | SystemSpare0 = 0x008E, 211 | SystemSecureBootPolicyInformation = 0x008F, 212 | SystemPageFileInformationEx = 0x0090, 213 | SystemSecureBootInformation = 0x0091, 214 | SystemEntropyInterruptTimingRawInformation = 0x0092, 215 | SystemPortableWorkspaceEfiLauncherInformation = 0x0093, 216 | SystemFullProcessInformation = 0x0094, 217 | MaxSystemInfoClass = 0x0095 218 | 219 | } SYSTEM_INFORMATION_CLASS, * PSYSTEM_INFORMATION_CLASS; 220 | 221 | typedef struct _LDR_DATA_TABLE_ENTRY64 222 | { 223 | LIST_ENTRY InLoadOrderModuleList; 224 | LIST_ENTRY InMemoryOrderModuleList; 225 | LIST_ENTRY InInitializationOrderModuleList; 226 | PVOID DllBase; 227 | PVOID EntryPoint; 228 | ULONG SizeOfImage; 229 | UNICODE_STRING FullDllName; 230 | UNICODE_STRING BaseDllName; 231 | ULONG Flags; 232 | USHORT LoadCount; 233 | USHORT TlsIndex; 234 | union 235 | { 236 | LIST_ENTRY HashLinks; 237 | struct 238 | { 239 | PVOID SectionPointer; 240 | ULONG CheckSum; 241 | }; 242 | }; 243 | union 244 | { 245 | ULONG TimeDateStamp; 246 | PVOID LoadedImports; 247 | }; 248 | PVOID EntryPointActivationContext; 249 | PVOID PatchInformation; 250 | LIST_ENTRY ForwarderLinks; 251 | LIST_ENTRY ServiceTagLinks; 252 | LIST_ENTRY StaticLinks; 253 | } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; 254 | 255 | typedef struct _LDR_DATA_TABLE_ENTRY32 { 256 | LIST_ENTRY32 InLoadOrderModuleList; 257 | LIST_ENTRY32 InMemoryOrderModuleList; 258 | LIST_ENTRY32 InInitializationOrderModuleList; 259 | ULONG DllBase; 260 | ULONG EntryPoint; 261 | ULONG SizeOfImage; 262 | UNICODE_STRING32 FullDllName; 263 | UNICODE_STRING32 BaseDllName; 264 | ULONG Flags; 265 | USHORT LoadCount; 266 | USHORT TlsIndex; 267 | union { 268 | LIST_ENTRY32 HashLinks; 269 | struct { 270 | ULONG SectionPointer; 271 | ULONG CheckSum; 272 | }; 273 | }; 274 | union { 275 | struct { 276 | ULONG TimeDateStamp; 277 | }; 278 | struct { 279 | ULONG LoadedImports; 280 | }; 281 | }; 282 | 283 | ULONG EntryPointActivationContext; 284 | ULONG PatchInformation; 285 | LIST_ENTRY32 ForwarderLinks; 286 | LIST_ENTRY32 ServiceTagLinks; 287 | LIST_ENTRY32 StaticLinks; 288 | 289 | } LDR_DATA_TABLE_ENTRY32, * PLDR_DATA_TABLE_ENTRY32; 290 | 291 | typedef struct _KLDR_DATA_TABLE_ENTRY 292 | { 293 | struct _LIST_ENTRY InLoadOrderLinks; //0x0 294 | VOID* ExceptionTable; //0x10 295 | ULONG ExceptionTableSize; //0x18 296 | VOID* GpValue; //0x20 297 | struct _NON_PAGED_DEBUG_INFO* NonPagedDebugInfo; //0x28 298 | VOID* DllBase; //0x30 299 | VOID* EntryPoint; //0x38 300 | ULONG SizeOfImage; //0x40 301 | struct _UNICODE_STRING FullDllName; //0x48 302 | struct _UNICODE_STRING BaseDllName; //0x58 303 | ULONG Flags; //0x68 304 | USHORT LoadCount; //0x6c 305 | union 306 | { 307 | USHORT SignatureLevel : 4; //0x6e 308 | USHORT SignatureType : 3; //0x6e 309 | USHORT Unused : 9; //0x6e 310 | USHORT EntireField; //0x6e 311 | } u1; //0x6e 312 | VOID* SectionPointer; //0x70 313 | ULONG CheckSum; //0x78 314 | ULONG CoverageSectionSize; //0x7c 315 | VOID* CoverageSection; //0x80 316 | VOID* LoadedImports; //0x88 317 | VOID* Spare; //0x90 318 | ULONG SizeOfImageNotRounded; //0x98 319 | ULONG TimeDateStamp; //0x9c 320 | 321 | } KLDR_DATA_TABLE_ENTRY, * PKLDR_DATA_TABLE_ENTRY; 322 | 323 | typedef struct _POOL_HEADER { 324 | union { 325 | struct { 326 | USHORT PreviousSize : 9; 327 | USHORT PoolIndex : 7; 328 | USHORT BlockSize : 9; 329 | USHORT PoolType : 7; 330 | }; 331 | ULONG Ulong1; // used for InterlockedCompareExchange required by Alpha 332 | }; 333 | #if defined (_WIN64) 334 | ULONG PoolTag; 335 | #endif 336 | union { 337 | PEPROCESS ProcessBilled; 338 | #if !defined (_WIN64) 339 | ULONG PoolTag; 340 | #endif 341 | struct { 342 | USHORT AllocatorBackTraceIndex; 343 | USHORT PoolTagHash; 344 | }; 345 | }; 346 | } POOL_HEADER, * PPOOL_HEADER; 347 | 348 | struct _EX_PUSH_LOCK 349 | { 350 | union 351 | { 352 | struct 353 | { 354 | ULONGLONG Locked : 1; //0x0 355 | ULONGLONG Waiting : 1; //0x0 356 | ULONGLONG Waking : 1; //0x0 357 | ULONGLONG MultipleShared : 1; //0x0 358 | ULONGLONG Shared : 60; //0x0 359 | }; 360 | ULONGLONG Value; //0x0 361 | VOID* Ptr; //0x0 362 | }; 363 | }; 364 | 365 | //0x40 bytes (sizeof) 366 | typedef struct _OBJECT_CREATE_INFORMATION 367 | { 368 | ULONG Attributes; //0x0 369 | VOID* RootDirectory; //0x8 370 | CHAR ProbeMode; //0x10 371 | ULONG PagedPoolCharge; //0x14 372 | ULONG NonPagedPoolCharge; //0x18 373 | ULONG SecurityDescriptorCharge; //0x1c 374 | VOID* SecurityDescriptor; //0x20 375 | struct _SECURITY_QUALITY_OF_SERVICE* SecurityQos; //0x28 376 | struct _SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService; //0x30 377 | } OBJECT_CREATE_INFORMATION, *POBJECT_CREATE_INFORMATION; 378 | 379 | 380 | typedef struct _OBJECT_HEADER 381 | { 382 | LONGLONG PointerCount; //0x0 383 | union 384 | { 385 | LONGLONG HandleCount; //0x8 386 | VOID* NextToFree; //0x8 387 | }; 388 | struct _EX_PUSH_LOCK Lock; //0x10 389 | UCHAR TypeIndex; //0x18 390 | union 391 | { 392 | UCHAR TraceFlags; //0x19 393 | struct 394 | { 395 | UCHAR DbgRefTrace : 1; //0x19 396 | UCHAR DbgTracePermanent : 1; //0x19 397 | }; 398 | }; 399 | UCHAR InfoMask; //0x1a 400 | union 401 | { 402 | UCHAR Flags; //0x1b 403 | struct 404 | { 405 | UCHAR NewObject : 1; //0x1b 406 | UCHAR KernelObject : 1; //0x1b 407 | UCHAR KernelOnlyAccess : 1; //0x1b 408 | UCHAR ExclusiveObject : 1; //0x1b 409 | UCHAR PermanentObject : 1; //0x1b 410 | UCHAR DefaultSecurityQuota : 1; //0x1b 411 | UCHAR SingleHandleEntry : 1; //0x1b 412 | UCHAR DeletedInline : 1; //0x1b 413 | }; 414 | }; 415 | ULONG Reserved; //0x1c 416 | union 417 | { 418 | struct _OBJECT_CREATE_INFORMATION* ObjectCreateInfo; //0x20 419 | VOID* QuotaBlockCharged; //0x20 420 | }; 421 | VOID* SecurityDescriptor; //0x28 422 | struct _QUAD Body; //0x30 423 | } OBJECT_HEADER, * POBJECT_HEADER; 424 | 425 | 426 | typedef struct _MMVIEW_WIN7 // 0x30 427 | { 428 | ULONGLONG Entry; // +0x0(0x8) 429 | ULONGLONG Writable; // +0x8(0x8) 430 | struct CONTROL_AREA* ControlArea; // +0x8(0x8) 431 | LIST_ENTRY ViewLinks; // +0x10(0x10) 432 | PVOID SessionViewVa; // +0x20(0x8) 433 | ULONG SessionId; // +0x28(0x4) 434 | 435 | } MMVIEW_WIN7, * PMMVIEW_WIN7; 436 | 437 | typedef struct _MMSESSION_WIN7 // 0x58 438 | { 439 | KGUARDED_MUTEX SystemSpaceViewLock; // +0x0(0x38) 440 | KGUARDED_MUTEX* SystemSpaceViewLockPointer; // +0x38(0x8) 441 | MMVIEW_WIN7* SystemSpaceViewTable; // +0x40(0x8) 442 | ULONG SystemSpaceHashSize; // +0x48(0x4) 443 | ULONG SystemSpaceHashEntries; // +0x4c(0x4) 444 | ULONG SystemSpaceHashKey; // +0x50(0x4) 445 | ULONG BitmapFailures; // +0x54(0x4) 446 | 447 | } MMSESSION_WIN7, * PMMSESSION_WIN7; 448 | 449 | 450 | typedef struct _MMVIEW_WIN10 451 | { 452 | RTL_BALANCED_NODE SectionNode; 453 | ULONG64 Unkown1; // +0x18 454 | ULONG_PTR ViewSize; // +0x20 455 | ULONG_PTR Unkown2; // +0x28 456 | PVOID ControlArea; // +0x30 457 | PVOID FileObject; // +0x38 458 | ULONG_PTR Unknown3; // +0x40 459 | ULONG_PTR Unknown4; // +0x48 460 | PVOID SessionViewVa; // +0x50 461 | ULONG Unknown5; 462 | ULONG Unknown6; 463 | 464 | } MMVIEW_WIN10, * PMMVIEW_WIN10; 465 | 466 | typedef struct _MMVIEW_WIN10_NEW 467 | { 468 | RTL_BALANCED_NODE SectionNode; 469 | ULONG64 Unkown1; // +0x18 470 | ULONG_PTR ViewSize; // +0x20 471 | ULONG_PTR Unkown2; // +0x28 472 | PVOID ControlArea; // +0x30 473 | ULONG ControlAreaFlag; // +0x38 474 | PVOID FileObject; // +0x40 475 | ULONG_PTR Unknown3; // +0x48 476 | ULONG_PTR Unknown4; // +0x50 477 | PVOID SessionViewVa; // +0x58 478 | ULONG Unknown5; 479 | ULONG Unknown6; 480 | 481 | } MMVIEW_WIN10_NEW, * PMMVIEW_WIN10_NEW; 482 | 483 | typedef struct _RTL_AVL_TREE 484 | { 485 | PRTL_BALANCED_NODE Root; // +0x0(0x8) 486 | 487 | } RTL_AVL_TREE, * PRTL_AVL_TREE; 488 | 489 | typedef struct _MMSESSION_WIN10 490 | { 491 | EX_PUSH_LOCK SystemSpaceViewLock; 492 | PEX_PUSH_LOCK SystemSpaceViewLockPointer; 493 | RTL_AVL_TREE ViewRoot; 494 | ULONG ViewCount; 495 | ULONG BitmapFailures; 496 | 497 | }MMSESSION_WIN10, * PMMSESSION_WIN10; 498 | 499 | typedef struct _MI_SYSTEM_VA_ASSIGNMENT 500 | { 501 | VOID* BaseAddress; //0x0 502 | ULONGLONG NumberOfBytes; //0x8 503 | } MI_SYSTEM_VA_ASSIGNMENT, * PMI_SYSTEM_VA_ASSIGNMENT; 504 | 505 | enum _MI_ASSIGNED_REGION_TYPES 506 | { 507 | AssignedRegionNonPagedPool = 0, 508 | AssignedRegionPagedPool = 1, 509 | AssignedRegionSystemCache = 2, 510 | AssignedRegionSystemPtes = 3, 511 | AssignedRegionUltraZero = 4, 512 | AssignedRegionPfnDatabase = 5, 513 | AssignedRegionCfg = 6, 514 | AssignedRegionHyperSpace = 7, 515 | AssignedRegionKernelStacks = 8, 516 | AssignedRegionPageTables = 9, 517 | AssignedRegionSession = 10, 518 | AssignedRegionSecureNonPagedPool = 11, 519 | AssignedRegionSystemImages = 12, 520 | AssignedRegionMaximum = 13 521 | }; 522 | 523 | #pragma warning(disable : 4214) 524 | typedef struct _MMPTE_HARDWARE64 525 | { 526 | ULONGLONG Valid : 1; 527 | ULONGLONG Dirty1 : 1; 528 | ULONGLONG Owner : 1; 529 | ULONGLONG WriteThrough : 1; 530 | ULONGLONG CacheDisable : 1; 531 | ULONGLONG Accessed : 1; 532 | ULONGLONG Dirty : 1; 533 | ULONGLONG LargePage : 1; 534 | ULONGLONG Global : 1; 535 | ULONGLONG CopyOnWrite : 1; 536 | ULONGLONG Unused : 1; 537 | ULONGLONG Write : 1; 538 | ULONGLONG PageFrameNumber : 36; 539 | ULONGLONG reserved1 : 4; 540 | ULONGLONG SoftwareWsIndex : 11; 541 | ULONGLONG NoExecute : 1; 542 | } MMPTE_HARDWARE64, * PMMPTE_HARDWARE64; 543 | 544 | typedef struct _MMPTE 545 | { 546 | union 547 | { 548 | ULONG_PTR Long; 549 | MMPTE_HARDWARE64 Hard; 550 | } u; 551 | } MMPTE; 552 | typedef MMPTE* PMMPTE; 553 | 554 | // 555 | // This structure is used by the debugger for all targets 556 | // It is the same size as DBGKD_DATA_HEADER on all systems 557 | // 558 | typedef struct _DBGKD_DEBUG_DATA_HEADER64 { 559 | 560 | // 561 | // Link to other blocks 562 | // 563 | 564 | LIST_ENTRY64 List; 565 | 566 | // 567 | // This is a unique tag to identify the owner of the block. 568 | // If your component only uses one pool tag, use it for this, too. 569 | // 570 | 571 | ULONG OwnerTag; 572 | 573 | // 574 | // This must be initialized to the size of the data block, 575 | // including this structure. 576 | // 577 | 578 | ULONG Size; 579 | 580 | } DBGKD_DEBUG_DATA_HEADER64, * PDBGKD_DEBUG_DATA_HEADER64; 581 | 582 | 583 | // 584 | // This structure is the same size on all systems. The only field 585 | // which must be translated by the debugger is Header.List. 586 | // 587 | 588 | // 589 | // DO NOT ADD OR REMOVE FIELDS FROM THE MIDDLE OF THIS STRUCTURE!!! 590 | // 591 | // If you remove a field, replace it with an "unused" placeholder. 592 | // Do not reuse fields until there has been enough time for old debuggers 593 | // and extensions to age out. 594 | // 595 | typedef struct _KDDEBUGGER_DATA64 { 596 | 597 | DBGKD_DEBUG_DATA_HEADER64 Header; 598 | 599 | // 600 | // Base address of kernel image 601 | // 602 | 603 | ULONG64 KernBase; 604 | 605 | // 606 | // DbgBreakPointWithStatus is a function which takes an argument 607 | // and hits a breakpoint. This field contains the address of the 608 | // breakpoint instruction. When the debugger sees a breakpoint 609 | // at this address, it may retrieve the argument from the first 610 | // argument register, or on x86 the eax register. 611 | // 612 | 613 | ULONG64 BreakpointWithStatus; // address of breakpoint 614 | 615 | // 616 | // Address of the saved context record during a bugcheck 617 | // 618 | // N.B. This is an automatic in KeBugcheckEx's frame, and 619 | // is only valid after a bugcheck. 620 | // 621 | 622 | ULONG64 SavedContext; 623 | 624 | // 625 | // help for walking stacks with user callbacks: 626 | // 627 | 628 | // 629 | // The address of the thread structure is provided in the 630 | // WAIT_STATE_CHANGE packet. This is the offset from the base of 631 | // the thread structure to the pointer to the kernel stack frame 632 | // for the currently active usermode callback. 633 | // 634 | 635 | USHORT ThCallbackStack; // offset in thread data 636 | 637 | // 638 | // these values are offsets into that frame: 639 | // 640 | 641 | USHORT NextCallback; // saved pointer to next callback frame 642 | USHORT FramePointer; // saved frame pointer 643 | 644 | // 645 | // pad to a quad boundary 646 | // 647 | USHORT PaeEnabled; 648 | 649 | // 650 | // Address of the kernel callout routine. 651 | // 652 | 653 | ULONG64 KiCallUserMode; // kernel routine 654 | 655 | // 656 | // Address of the usermode entry point for callbacks. 657 | // 658 | 659 | ULONG64 KeUserCallbackDispatcher; // address in ntdll 660 | 661 | 662 | // 663 | // Addresses of various kernel data structures and lists 664 | // that are of interest to the kernel debugger. 665 | // 666 | 667 | ULONG64 PsLoadedModuleList; 668 | ULONG64 PsActiveProcessHead; 669 | ULONG64 PspCidTable; 670 | 671 | ULONG64 ExpSystemResourcesList; 672 | ULONG64 ExpPagedPoolDescriptor; 673 | ULONG64 ExpNumberOfPagedPools; 674 | 675 | ULONG64 KeTimeIncrement; 676 | ULONG64 KeBugCheckCallbackListHead; 677 | ULONG64 KiBugcheckData; 678 | 679 | ULONG64 IopErrorLogListHead; 680 | 681 | ULONG64 ObpRootDirectoryObject; 682 | ULONG64 ObpTypeObjectType; 683 | 684 | ULONG64 MmSystemCacheStart; 685 | ULONG64 MmSystemCacheEnd; 686 | ULONG64 MmSystemCacheWs; 687 | 688 | ULONG64 MmPfnDatabase; 689 | ULONG64 MmSystemPtesStart; 690 | ULONG64 MmSystemPtesEnd; 691 | ULONG64 MmSubsectionBase; 692 | ULONG64 MmNumberOfPagingFiles; 693 | 694 | ULONG64 MmLowestPhysicalPage; 695 | ULONG64 MmHighestPhysicalPage; 696 | ULONG64 MmNumberOfPhysicalPages; 697 | 698 | ULONG64 MmMaximumNonPagedPoolInBytes; 699 | ULONG64 MmNonPagedSystemStart; 700 | ULONG64 MmNonPagedPoolStart; 701 | ULONG64 MmNonPagedPoolEnd; 702 | 703 | ULONG64 MmPagedPoolStart; 704 | ULONG64 MmPagedPoolEnd; 705 | ULONG64 MmPagedPoolInformation; 706 | ULONG64 MmPageSize; 707 | 708 | ULONG64 MmSizeOfPagedPoolInBytes; 709 | 710 | ULONG64 MmTotalCommitLimit; 711 | ULONG64 MmTotalCommittedPages; 712 | ULONG64 MmSharedCommit; 713 | ULONG64 MmDriverCommit; 714 | ULONG64 MmProcessCommit; 715 | ULONG64 MmPagedPoolCommit; 716 | ULONG64 MmExtendedCommit; 717 | 718 | ULONG64 MmZeroedPageListHead; 719 | ULONG64 MmFreePageListHead; 720 | ULONG64 MmStandbyPageListHead; 721 | ULONG64 MmModifiedPageListHead; 722 | ULONG64 MmModifiedNoWritePageListHead; 723 | ULONG64 MmAvailablePages; 724 | ULONG64 MmResidentAvailablePages; 725 | 726 | ULONG64 PoolTrackTable; 727 | ULONG64 NonPagedPoolDescriptor; 728 | 729 | ULONG64 MmHighestUserAddress; 730 | ULONG64 MmSystemRangeStart; 731 | ULONG64 MmUserProbeAddress; 732 | 733 | ULONG64 KdPrintCircularBuffer; 734 | ULONG64 KdPrintCircularBufferEnd; 735 | ULONG64 KdPrintWritePointer; 736 | ULONG64 KdPrintRolloverCount; 737 | 738 | ULONG64 MmLoadedUserImageList; 739 | 740 | // NT 5.1 Addition 741 | 742 | ULONG64 NtBuildLab; 743 | ULONG64 KiNormalSystemCall; 744 | 745 | // NT 5.0 hotfix addition 746 | 747 | ULONG64 KiProcessorBlock; 748 | ULONG64 MmUnloadedDrivers; 749 | ULONG64 MmLastUnloadedDriver; 750 | ULONG64 MmTriageActionTaken; 751 | ULONG64 MmSpecialPoolTag; 752 | ULONG64 KernelVerifier; 753 | ULONG64 MmVerifierData; 754 | ULONG64 MmAllocatedNonPagedPool; 755 | ULONG64 MmPeakCommitment; 756 | ULONG64 MmTotalCommitLimitMaximum; 757 | ULONG64 CmNtCSDVersion; 758 | 759 | // NT 5.1 Addition 760 | 761 | ULONG64 MmPhysicalMemoryBlock; 762 | ULONG64 MmSessionBase; 763 | ULONG64 MmSessionSize; 764 | ULONG64 MmSystemParentTablePage; 765 | 766 | // Server 2003 addition 767 | 768 | ULONG64 MmVirtualTranslationBase; 769 | 770 | USHORT OffsetKThreadNextProcessor; 771 | USHORT OffsetKThreadTeb; 772 | USHORT OffsetKThreadKernelStack; 773 | USHORT OffsetKThreadInitialStack; 774 | 775 | USHORT OffsetKThreadApcProcess; 776 | USHORT OffsetKThreadState; 777 | USHORT OffsetKThreadBStore; 778 | USHORT OffsetKThreadBStoreLimit; 779 | 780 | USHORT SizeEProcess; 781 | USHORT OffsetEprocessPeb; 782 | USHORT OffsetEprocessParentCID; 783 | USHORT OffsetEprocessDirectoryTableBase; 784 | 785 | USHORT SizePrcb; 786 | USHORT OffsetPrcbDpcRoutine; 787 | USHORT OffsetPrcbCurrentThread; 788 | USHORT OffsetPrcbMhz; 789 | 790 | USHORT OffsetPrcbCpuType; 791 | USHORT OffsetPrcbVendorString; 792 | USHORT OffsetPrcbProcStateContext; 793 | USHORT OffsetPrcbNumber; 794 | 795 | USHORT SizeEThread; 796 | 797 | ULONG64 KdPrintCircularBufferPtr; 798 | ULONG64 KdPrintBufferSize; 799 | 800 | ULONG64 KeLoaderBlock; 801 | 802 | USHORT SizePcr; 803 | USHORT OffsetPcrSelfPcr; 804 | USHORT OffsetPcrCurrentPrcb; 805 | USHORT OffsetPcrContainedPrcb; 806 | 807 | USHORT OffsetPcrInitialBStore; 808 | USHORT OffsetPcrBStoreLimit; 809 | USHORT OffsetPcrInitialStack; 810 | USHORT OffsetPcrStackLimit; 811 | 812 | USHORT OffsetPrcbPcrPage; 813 | USHORT OffsetPrcbProcStateSpecialReg; 814 | USHORT GdtR0Code; 815 | USHORT GdtR0Data; 816 | 817 | USHORT GdtR0Pcr; 818 | USHORT GdtR3Code; 819 | USHORT GdtR3Data; 820 | USHORT GdtR3Teb; 821 | 822 | USHORT GdtLdt; 823 | USHORT GdtTss; 824 | USHORT Gdt64R3CmCode; 825 | USHORT Gdt64R3CmTeb; 826 | 827 | ULONG64 IopNumTriageDumpDataBlocks; 828 | ULONG64 IopTriageDumpDataBlocks; 829 | 830 | // Longhorn addition 831 | 832 | ULONG64 VfCrashDataBlock; 833 | ULONG64 MmBadPagesDetected; 834 | ULONG64 MmZeroedPageSingleBitErrorsDetected; 835 | 836 | // Windows 7 addition 837 | 838 | ULONG64 EtwpDebuggerData; 839 | USHORT OffsetPrcbContext; 840 | 841 | // Windows 8 addition 842 | 843 | USHORT OffsetPrcbMaxBreakpoints; 844 | USHORT OffsetPrcbMaxWatchpoints; 845 | 846 | ULONG OffsetKThreadStackLimit; 847 | ULONG OffsetKThreadStackBase; 848 | ULONG OffsetKThreadQueueListEntry; 849 | ULONG OffsetEThreadIrpList; 850 | 851 | USHORT OffsetPrcbIdleThread; 852 | USHORT OffsetPrcbNormalDpcState; 853 | USHORT OffsetPrcbDpcStack; 854 | USHORT OffsetPrcbIsrStack; 855 | 856 | USHORT SizeKDPC_STACK_FRAME; 857 | 858 | // Windows 8.1 Addition 859 | 860 | USHORT OffsetKPriQueueThreadListHead; 861 | USHORT OffsetKThreadWaitReason; 862 | 863 | // Windows 10 RS1 Addition 864 | 865 | USHORT Padding; 866 | ULONG64 PteBase; 867 | 868 | // Windows 10 RS5 Addition 869 | 870 | ULONG64 RetpolineStubFunctionTable; 871 | ULONG RetpolineStubFunctionTableSize; 872 | ULONG RetpolineStubOffset; 873 | ULONG RetpolineStubSize; 874 | 875 | } KDDEBUGGER_DATA64, * PKDDEBUGGER_DATA64; 876 | 877 | 878 | typedef struct _DUMP_HEADER 879 | { 880 | ULONG Signature; 881 | ULONG ValidDump; 882 | ULONG MajorVersion; 883 | ULONG MinorVersion; 884 | ULONG_PTR DirectoryTableBase; 885 | ULONG_PTR PfnDataBase; 886 | PLIST_ENTRY PsLoadedModuleList; 887 | PLIST_ENTRY PsActiveProcessHead; 888 | ULONG MachineImageType; 889 | ULONG NumberProcessors; 890 | ULONG BugCheckCode; 891 | ULONG_PTR BugCheckParameter1; 892 | ULONG_PTR BugCheckParameter2; 893 | ULONG_PTR BugCheckParameter3; 894 | ULONG_PTR BugCheckParameter4; 895 | CHAR VersionUser[32]; 896 | struct _KDDEBUGGER_DATA64* KdDebuggerDataBlock; 897 | } DUMP_HEADER, * PDUMP_HEADER; 898 | 899 | //0x4 bytes (sizeof) 900 | typedef struct _MMSECTION_FLAGS 901 | { 902 | ULONG BeingDeleted : 1; //0x0 903 | ULONG BeingCreated : 1; //0x0 904 | ULONG BeingPurged : 1; //0x0 905 | ULONG NoModifiedWriting : 1; //0x0 906 | ULONG FailAllIo : 1; //0x0 907 | ULONG Image : 1; //0x0 908 | ULONG Based : 1; //0x0 909 | ULONG File : 1; //0x0 910 | ULONG AttemptingDelete : 1; //0x0 911 | ULONG PrefetchCreated : 1; //0x0 912 | ULONG PhysicalMemory : 1; //0x0 913 | ULONG ImageControlAreaOnRemovableMedia : 1; //0x0 914 | ULONG Reserve : 1; //0x0 915 | ULONG Commit : 1; //0x0 916 | ULONG NoChange : 1; //0x0 917 | ULONG WasPurged : 1; //0x0 918 | ULONG UserReference : 1; //0x0 919 | ULONG GlobalMemory : 1; //0x0 920 | ULONG DeleteOnClose : 1; //0x0 921 | ULONG FilePointerNull : 1; //0x0 922 | ULONG PreferredNode : 6; //0x0 923 | ULONG GlobalOnlyPerSession : 1; //0x0 924 | ULONG UserWritable : 1; //0x0 925 | ULONG SystemVaAllocated : 1; //0x0 926 | ULONG PreferredFsCompressionBoundary : 1; //0x0 927 | ULONG UsingFileExtents : 1; //0x0 928 | ULONG PageSize64K : 1; //0x0 929 | } MMSECTION_FLAGS, *PMMSECTION_FLAGS; 930 | 931 | struct _MMSECTION_FLAGS2 932 | { 933 | USHORT PartitionId : 10; //0x0 934 | UCHAR NoCrossPartitionAccess : 1; //0x2 935 | UCHAR SubsectionCrossPartitionReferenceOverflow : 1; //0x2 936 | }; 937 | 938 | //0x8 bytes (sizeof) 939 | struct _EX_FAST_REF 940 | { 941 | union 942 | { 943 | VOID* Object; //0x0 944 | ULONGLONG RefCnt : 4; //0x0 945 | ULONGLONG Value; //0x0 946 | }; 947 | }; 948 | 949 | //0x28 bytes (sizeof) 950 | struct _MI_CONTROL_AREA_WAIT_BLOCK 951 | { 952 | struct _MI_CONTROL_AREA_WAIT_BLOCK* Next; //0x0 953 | ULONG WaitReason; //0x8 954 | ULONG WaitResponse; //0xc 955 | struct _KGATE Gate; //0x10 956 | }; 957 | 958 | //0x4 bytes (sizeof) 959 | struct _SEGMENT_FLAGS 960 | { 961 | union 962 | { 963 | struct 964 | { 965 | USHORT TotalNumberOfPtes4132 : 10; //0x0 966 | USHORT Spare0 : 1; //0x0 967 | USHORT SessionDriverProtos : 1; //0x0 968 | USHORT LargePages : 1; //0x0 969 | USHORT DebugSymbolsLoaded : 1; //0x0 970 | USHORT WriteCombined : 1; //0x0 971 | USHORT NoCache : 1; //0x0 972 | }; 973 | USHORT Short0; //0x0 974 | }; 975 | union 976 | { 977 | struct 978 | { 979 | UCHAR ImageCetShadowStacksReady : 1; //0x2 980 | UCHAR DefaultProtectionMask : 5; //0x2 981 | UCHAR Binary32 : 1; //0x2 982 | UCHAR ContainsDebug : 1; //0x2 983 | }; 984 | UCHAR UChar1; //0x2 985 | }; 986 | union 987 | { 988 | struct 989 | { 990 | UCHAR ForceCollision : 1; //0x3 991 | UCHAR ImageSigningType : 3; //0x3 992 | UCHAR ImageSigningLevel : 4; //0x3 993 | }; 994 | UCHAR UChar2; //0x3 995 | }; 996 | }; 997 | 998 | //0x10 bytes (sizeof) 999 | typedef struct _MMEXTEND_INFO 1000 | { 1001 | ULONGLONG CommittedSize; //0x0 1002 | ULONG ReferenceCount; //0x8 1003 | } MMEXTEND_INFO, *PMMEXTEND_INFO; 1004 | 1005 | //0x40 bytes (sizeof) 1006 | typedef struct _SECTION_IMAGE_INFORMATION 1007 | { 1008 | VOID* TransferAddress; //0x0 1009 | ULONG ZeroBits; //0x8 1010 | ULONGLONG MaximumStackSize; //0x10 1011 | ULONGLONG CommittedStackSize; //0x18 1012 | ULONG SubSystemType; //0x20 1013 | union 1014 | { 1015 | struct 1016 | { 1017 | USHORT SubSystemMinorVersion; //0x24 1018 | USHORT SubSystemMajorVersion; //0x26 1019 | }; 1020 | ULONG SubSystemVersion; //0x24 1021 | }; 1022 | union 1023 | { 1024 | struct 1025 | { 1026 | USHORT MajorOperatingSystemVersion; //0x28 1027 | USHORT MinorOperatingSystemVersion; //0x2a 1028 | }; 1029 | ULONG OperatingSystemVersion; //0x28 1030 | }; 1031 | USHORT ImageCharacteristics; //0x2c 1032 | USHORT DllCharacteristics; //0x2e 1033 | USHORT Machine; //0x30 1034 | UCHAR ImageContainsCode; //0x32 1035 | union 1036 | { 1037 | UCHAR ImageFlags; //0x33 1038 | struct 1039 | { 1040 | UCHAR ComPlusNativeReady : 1; //0x33 1041 | UCHAR ComPlusILOnly : 1; //0x33 1042 | UCHAR ImageDynamicallyRelocated : 1; //0x33 1043 | UCHAR ImageMappedFlat : 1; //0x33 1044 | UCHAR BaseBelow4gb : 1; //0x33 1045 | UCHAR ComPlusPrefer32bit : 1; //0x33 1046 | UCHAR Reserved : 2; //0x33 1047 | }; 1048 | }; 1049 | ULONG LoaderFlags; //0x34 1050 | ULONG ImageFileSize; //0x38 1051 | ULONG CheckSum; //0x3c 1052 | } SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION; 1053 | 1054 | //0xc bytes (sizeof) 1055 | typedef struct _MI_EXTRA_IMAGE_INFORMATION 1056 | { 1057 | ULONG SizeOfHeaders; //0x0 1058 | ULONG SizeOfImage; //0x4 1059 | ULONG TimeDateStamp; //0x8 1060 | } MI_EXTRA_IMAGE_INFORMATION, *PMI_EXTRA_IMAGE_INFORMATION; 1061 | 1062 | //0x50 bytes (sizeof) 1063 | typedef struct _MI_SECTION_IMAGE_INFORMATION 1064 | { 1065 | struct _SECTION_IMAGE_INFORMATION ExportedImageInformation; //0x0 1066 | struct _MI_EXTRA_IMAGE_INFORMATION InternalImageInformation; //0x40 1067 | } MI_SECTION_IMAGE_INFORMATION, *PMI_SECTION_IMAGE_INFORMATION; 1068 | 1069 | //0x48 bytes (sizeof) 1070 | typedef struct _SEGMENT 1071 | { 1072 | struct _CONTROL_AREA* ControlArea; //0x0 1073 | ULONG TotalNumberOfPtes; //0x8 1074 | struct _SEGMENT_FLAGS SegmentFlags; //0xc 1075 | ULONGLONG NumberOfCommittedPages; //0x10 1076 | ULONGLONG SizeOfSegment; //0x18 1077 | union 1078 | { 1079 | struct _MMEXTEND_INFO* ExtendInfo; //0x20 1080 | VOID* BasedAddress; //0x20 1081 | }; 1082 | struct _EX_PUSH_LOCK SegmentLock; //0x28 1083 | union 1084 | { 1085 | ULONGLONG ImageCommitment; //0x30 1086 | ULONG CreatingProcessId; //0x30 1087 | } u1; //0x30 1088 | union 1089 | { 1090 | struct _MI_SECTION_IMAGE_INFORMATION* ImageInformation; //0x38 1091 | VOID* FirstMappedVa; //0x38 1092 | } u2; //0x38 1093 | struct _MMPTE* PrototypePte; //0x40 1094 | } SEGMENT, *PSEGMENT; 1095 | 1096 | //0x20 bytes (sizeof) 1097 | typedef struct _MI_PROTOTYPE_PTES_NODE 1098 | { 1099 | struct _RTL_BALANCED_NODE Node; //0x0 1100 | union 1101 | { 1102 | struct 1103 | { 1104 | ULONGLONG AllocationType : 3; //0x18 1105 | ULONGLONG Inserted : 1; //0x18 1106 | } e1; //0x18 1107 | struct 1108 | { 1109 | ULONGLONG PrototypePtesFlags; //0x18 1110 | } e2; //0x18 1111 | } u1; //0x18 1112 | } MI_PROTOTYPE_PTES_NODE, *PMI_PROTOTYPE_PTES_NODE; 1113 | 1114 | //0x8 bytes (sizeof) 1115 | typedef struct _IMAGE_SECURITY_CONTEXT 1116 | { 1117 | union 1118 | { 1119 | VOID* PageHashes; //0x0 1120 | ULONGLONG Value; //0x0 1121 | struct 1122 | { 1123 | ULONGLONG SecurityBeingCreated : 2; //0x0 1124 | ULONGLONG SecurityMandatory : 1; //0x0 1125 | ULONGLONG PageHashPointer : 61; //0x0 1126 | }; 1127 | }; 1128 | } IMAGE_SECURITY_CONTEXT, *PIMAGE_SECURITY_CONTEXT; 1129 | 1130 | //0x40 bytes (sizeof) 1131 | typedef struct _MI_IMAGE_SECURITY_REFERENCE 1132 | { 1133 | struct _MI_PROTOTYPE_PTES_NODE ProtosNode; //0x0 1134 | VOID* DynamicRelocations; //0x20 1135 | struct _IMAGE_SECURITY_CONTEXT SecurityContext; //0x28 1136 | union 1137 | { 1138 | VOID* ImageFileExtents; //0x30 1139 | ULONGLONG ImageFileExtentsUlongPtr; //0x30 1140 | ULONGLONG FilesystemWantsRva : 1; //0x30 1141 | ULONGLONG Spare : 3; //0x30 1142 | } u1; //0x30 1143 | ULONGLONG StrongImageReference; //0x38 1144 | } MI_IMAGE_SECURITY_REFERENCE, *PMI_IMAGE_SECURITY_REFERENCE; 1145 | 1146 | typedef struct _CONTROL_AREA 1147 | { 1148 | struct _SEGMENT* Segment; //0x0 1149 | union 1150 | { 1151 | struct _LIST_ENTRY ListHead; //0x8 1152 | VOID* AweContext; //0x8 1153 | }; 1154 | ULONGLONG NumberOfSectionReferences; //0x18 1155 | ULONGLONG NumberOfPfnReferences; //0x20 1156 | ULONGLONG NumberOfMappedViews; //0x28 1157 | ULONGLONG NumberOfUserReferences; //0x30 1158 | union 1159 | { 1160 | ULONG LongFlags; //0x38 1161 | struct _MMSECTION_FLAGS Flags; //0x38 1162 | } u; //0x38 1163 | union 1164 | { 1165 | ULONG LongFlags; //0x3c 1166 | struct _MMSECTION_FLAGS2 Flags; //0x3c 1167 | } u1; //0x3c 1168 | struct _EX_FAST_REF FilePointer; //0x40 1169 | volatile LONG ControlAreaLock; //0x48 1170 | ULONG ModifiedWriteCount; //0x4c 1171 | struct _MI_CONTROL_AREA_WAIT_BLOCK* WaitList; //0x50 1172 | union 1173 | { 1174 | struct 1175 | { 1176 | union 1177 | { 1178 | ULONG NumberOfSystemCacheViews; //0x58 1179 | ULONG ImageRelocationStartBit; //0x58 1180 | }; 1181 | union 1182 | { 1183 | volatile LONG WritableUserReferences; //0x5c 1184 | struct 1185 | { 1186 | ULONG ImageRelocationSizeIn64k : 16; //0x5c 1187 | ULONG SystemImage : 1; //0x5c 1188 | ULONG CantMove : 1; //0x5c 1189 | ULONG StrongCode : 2; //0x5c 1190 | ULONG BitMap : 2; //0x5c 1191 | ULONG ImageActive : 1; //0x5c 1192 | ULONG ImageBaseOkToReuse : 1; //0x5c 1193 | }; 1194 | }; 1195 | union 1196 | { 1197 | ULONG FlushInProgressCount; //0x60 1198 | ULONG NumberOfSubsections; //0x60 1199 | struct _MI_IMAGE_SECURITY_REFERENCE* SeImageStub; //0x60 1200 | }; 1201 | } e2; //0x58 1202 | } u2; //0x58 1203 | struct _EX_PUSH_LOCK FileObjectLock; //0x68 1204 | volatile ULONGLONG LockedPages; //0x70 1205 | union 1206 | { 1207 | ULONGLONG IoAttributionContext : 61; //0x78 1208 | ULONGLONG Spare : 3; //0x78 1209 | ULONGLONG ImageCrossPartitionCharge; //0x78 1210 | ULONGLONG CommittedPageCount : 36; //0x78 1211 | } u3; //0x78 1212 | } CONTROL_AREA, * PCONTROL_AREA; 1213 | 1214 | // Win10 1215 | typedef struct _SECTION 1216 | { 1217 | struct _RTL_BALANCED_NODE SectionNode; //0x0 1218 | ULONGLONG StartingVpn; //0x18 1219 | ULONGLONG EndingVpn; //0x20 1220 | union 1221 | { 1222 | struct _CONTROL_AREA* ControlArea; //0x28 1223 | struct _FILE_OBJECT* FileObject; //0x28 1224 | ULONGLONG RemoteImageFileObject : 1; //0x28 1225 | ULONGLONG RemoteDataFileObject : 1; //0x28 1226 | } u1; //0x28 1227 | ULONGLONG SizeOfSection; //0x30 1228 | union 1229 | { 1230 | ULONG LongFlags; //0x38 1231 | struct _MMSECTION_FLAGS Flags; //0x38 1232 | } u; //0x38 1233 | ULONG InitialPageProtection : 12; //0x3c 1234 | ULONG SessionId : 19; //0x3c 1235 | ULONG NoValidationNeeded : 1; //0x3c 1236 | 1237 | } SECTION, * PSECTION; 1238 | 1239 | 1240 | //0x4 bytes (sizeof) 1241 | typedef struct _MMSUBSECTION_FLAGS 1242 | { 1243 | USHORT SubsectionAccessed : 1; //0x0 1244 | USHORT Protection : 5; //0x0 1245 | USHORT StartingSector4132 : 10; //0x0 1246 | USHORT SubsectionStatic : 1; //0x2 1247 | USHORT GlobalMemory : 1; //0x2 1248 | USHORT DirtyPages : 1; //0x2 1249 | USHORT OnDereferenceList : 1; //0x2 1250 | USHORT SectorEndOffset : 12; //0x2 1251 | } MMSUBSECTION_FLAGS, *PMMSUBSECTION_FLAGS; 1252 | 1253 | //0x38 bytes (sizeof) 1254 | typedef struct _SUBSECTION 1255 | { 1256 | struct _CONTROL_AREA* ControlArea; //0x0 1257 | struct _MMPTE* SubsectionBase; //0x8 1258 | struct _SUBSECTION* NextSubsection; //0x10 1259 | ULONG PtesInSubsection; //0x18 1260 | union 1261 | { 1262 | ULONG UnusedPtes; //0x20 1263 | struct _RTL_AVL_TREE GlobalPerSessionHead; //0x20 1264 | }; 1265 | union 1266 | { 1267 | ULONG LongFlags; //0x28 1268 | struct _MMSUBSECTION_FLAGS SubsectionFlags; //0x28 1269 | } u; //0x28 1270 | ULONG StartingSector; //0x2c 1271 | ULONG NumberOfFullSectors; //0x30 1272 | } SUBSECTION, *PSUBSECTION; 1273 | 1274 | //0x40 bytes (sizeof) 1275 | typedef struct _SEGMENT_OBJECT 1276 | { 1277 | VOID* BaseAddress; //0x0 1278 | ULONG TotalNumberOfPtes; //0x8 1279 | union _LARGE_INTEGER SizeOfSegment; //0x10 1280 | ULONG NonExtendedPtes; //0x18 1281 | ULONG ImageCommitment; //0x1c 1282 | struct _CONTROL_AREA* ControlArea; //0x20 1283 | struct _SUBSECTION* Subsection; //0x28 1284 | struct _MMSECTION_FLAGS* MmSectionFlags; //0x30 1285 | struct _MMSUBSECTION_FLAGS* MmSubSectionFlags; //0x38 1286 | } SEGMENT_OBJECT, *PSEGMENT_OBJECT; 1287 | 1288 | //0x30 bytes (sizeof) 1289 | typedef struct _SECTION_OBJECT 1290 | { 1291 | VOID* StartingVa; //0x0 1292 | VOID* EndingVa; //0x8 1293 | VOID* Parent; //0x10 1294 | VOID* LeftChild; //0x18 1295 | VOID* RightChild; //0x20 1296 | struct _SEGMENT* Segment; //0x28 1297 | } SECTION_OBJECT, *PSECTION_OBJECT; 1298 | -------------------------------------------------------------------------------- /MemScanner/Private.c: -------------------------------------------------------------------------------- 1 | #include "Private.h" 2 | #include "NativeStruct.h" 3 | #include "import.h" 4 | 5 | 6 | 7 | NTSYSAPI 8 | ULONG 9 | NTAPI 10 | KeCapturePersistentThreadState( 11 | IN PCONTEXT Context, 12 | IN PKTHREAD Thread, 13 | IN ULONG BugCheckCode, 14 | IN ULONG BugCheckParameter1, 15 | IN ULONG BugCheckParameter2, 16 | IN ULONG BugCheckParameter3, 17 | IN ULONG BugCheckParameter4, 18 | OUT PVOID VirtualAddress 19 | ); 20 | 21 | //-------------------------------------------------------------------------------------------------------------- 22 | extern DYNAMIC_DATA g_dynData; 23 | //-------------------------------------------------------------------------------------------------------------- 24 | PLIST_ENTRY PsLoadedModuleList; 25 | PVOID g_KernelBase = NULL; 26 | ULONG g_KernelSize = 0; 27 | KDDEBUGGER_DATA64 g_KdBlock = { 0 }; 28 | 29 | //-------------------------------------------------------------------------------------------------------------- 30 | VOID InitializeDebuggerBlock() 31 | { 32 | CONTEXT context = { 0 }; 33 | context.ContextFlags = CONTEXT_FULL; 34 | RtlCaptureContext(&context); 35 | 36 | PDUMP_HEADER dumpHeader = (PDUMP_HEADER)ExAllocatePoolWithTag(NonPagedPool, DUMP_BLOCK_SIZE, MMS_POOL_TAG); 37 | if (dumpHeader) 38 | { 39 | KeCapturePersistentThreadState(&context, NULL, 0, 0, 0, 0, 0, dumpHeader); 40 | RtlCopyMemory(&g_KdBlock, (PUCHAR)dumpHeader + KDDEBUGGER_DATA_OFFSET, sizeof(g_KdBlock)); 41 | 42 | ExFreePool(dumpHeader); 43 | } 44 | } 45 | //-------------------------------------------------------------------------------------------------------------- 46 | PVOID GetKernelBase(OUT PULONG pSize) 47 | { 48 | NTSTATUS status = STATUS_SUCCESS; 49 | ULONG bytes = 0; 50 | PSYSTEM_MODULE_INFORMATION pMods = NULL; 51 | PVOID checkPtr = NULL; 52 | UNICODE_STRING routineName; 53 | 54 | // Already found 55 | if (g_KernelBase != NULL) 56 | { 57 | if (pSize) 58 | { 59 | *pSize = g_KernelSize; 60 | } 61 | 62 | return g_KernelBase; 63 | } 64 | 65 | RtlInitUnicodeString(&routineName, L"NtOpenFile"); 66 | checkPtr = MmGetSystemRoutineAddress(&routineName); 67 | if (checkPtr == NULL) 68 | { 69 | return NULL; 70 | } 71 | 72 | // Protect from UserMode AV 73 | status = ZwQuerySystemInformation(SystemModuleInformation, 0, bytes, &bytes); 74 | if (bytes == 0) 75 | { 76 | DbgPrint("MemScanner: %s: Invalid SystemModuleInformation size\n", __FUNCTION__); 77 | return NULL; 78 | } 79 | 80 | pMods = (PSYSTEM_MODULE_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, bytes, MMS_POOL_TAG); 81 | if (!pMods) 82 | { 83 | return NULL; 84 | } 85 | 86 | RtlZeroMemory(pMods, bytes); 87 | 88 | status = ZwQuerySystemInformation(SystemModuleInformation, pMods, bytes, &bytes); 89 | 90 | if (NT_SUCCESS(status)) 91 | { 92 | PSYSTEM_MODULE_ENTRY pMod = pMods->Modules; 93 | 94 | for (ULONG i = 0; i < pMods->Count; i++) 95 | { 96 | // System routine is inside module 97 | if (checkPtr >= pMod[i].Base && 98 | checkPtr < (PVOID)((PUCHAR)pMod[i].Base + pMod[i].Size)) 99 | { 100 | g_KernelBase = pMod[i].Base; 101 | g_KernelSize = pMod[i].Size; 102 | if (pSize) 103 | { 104 | *pSize = g_KernelSize; 105 | } 106 | 107 | break; 108 | } 109 | } 110 | } 111 | 112 | if (pMods) 113 | { 114 | ExFreePoolWithTag(pMods, MMS_POOL_TAG); 115 | pMods = NULL; 116 | } 117 | 118 | return g_KernelBase; 119 | } 120 | //-------------------------------------------------------------------------------------------------------------- 121 | NTSTATUS MmsInitLdrData(IN PLDR_DATA_TABLE_ENTRY pThisModule) 122 | { 123 | PVOID kernelBase = GetKernelBase(NULL); 124 | if (kernelBase == NULL) 125 | { 126 | DbgPrint("MemScanner: %s: Failed to retrieve Kernel base address. Aborting\n", __FUNCTION__); 127 | return STATUS_NOT_FOUND; 128 | } 129 | 130 | for (PLIST_ENTRY pListEntry = pThisModule->InLoadOrderModuleList.Flink; pListEntry != &pThisModule->InLoadOrderModuleList; pListEntry = pListEntry->Flink) 131 | { 132 | PLDR_DATA_TABLE_ENTRY pEntry = CONTAINING_RECORD(pListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList); 133 | if (kernelBase == pEntry->DllBase) 134 | { 135 | if ((PVOID)pListEntry->Blink >= pEntry->DllBase && (PUCHAR)pListEntry->Blink < (PUCHAR)pEntry->DllBase + pEntry->SizeOfImage) 136 | { 137 | PsLoadedModuleList = pListEntry->Blink; 138 | break; 139 | } 140 | } 141 | } 142 | 143 | if (!PsLoadedModuleList) 144 | { 145 | DbgPrint("MemScanner: %s: Failed to retrieve PsLoadedModuleList address. Aborting\n", __FUNCTION__); 146 | return STATUS_NOT_FOUND; 147 | } 148 | 149 | return STATUS_SUCCESS; 150 | } 151 | //-------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------- /MemScanner/Private.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "NativeStruct.h" 5 | 6 | 7 | #ifndef _WIN64 8 | #define DUMP_BLOCK_SIZE 0x20000 9 | #else 10 | #define DUMP_BLOCK_SIZE 0x40000 11 | #endif 12 | 13 | #ifndef _WIN64 14 | #define KDDEBUGGER_DATA_OFFSET 0x1068 15 | #else 16 | #define KDDEBUGGER_DATA_OFFSET 0x2080 17 | #endif 18 | 19 | #define MMS_POOL_TAG 'cSmM' 20 | 21 | #define PHYSICAL_ADDRESS_BITS 40 22 | 23 | 24 | // 25 | // PTE protection values 26 | // 27 | #define MM_ZERO_ACCESS 0 28 | #define MM_READONLY 1 29 | #define MM_EXECUTE 2 30 | #define MM_EXECUTE_READ 3 31 | #define MM_READWRITE 4 32 | #define MM_WRITECOPY 5 33 | #define MM_EXECUTE_READWRITE 6 34 | #define MM_EXECUTE_WRITECOPY 7 35 | 36 | #define MM_PTE_VALID_MASK 0x1 37 | #define MM_PTE_WRITE_MASK 0x800 38 | #define MM_PTE_OWNER_MASK 0x4 39 | #define MM_PTE_WRITE_THROUGH_MASK 0x8 40 | #define MM_PTE_CACHE_DISABLE_MASK 0x10 41 | #define MM_PTE_ACCESS_MASK 0x20 42 | #define MM_PTE_DIRTY_MASK 0x42 43 | #define MM_PTE_LARGE_PAGE_MASK 0x80 44 | #define MM_PTE_GLOBAL_MASK 0x100 45 | #define MM_PTE_COPY_ON_WRITE_MASK 0x200 46 | #define MM_PTE_PROTOTYPE_MASK 0x400 47 | #define MM_PTE_TRANSITION_MASK 0x800 48 | 49 | 50 | #define MI_SYSTEM_RANGE_START (ULONG_PTR)(0xFFFF080000000000) // start of system space 51 | 52 | #define KI_USER_SHARED_DATA 0xFFFFF78000000000UI64 53 | 54 | #define SharedUserData ((KUSER_SHARED_DATA * const)KI_USER_SHARED_DATA) 55 | 56 | #ifndef PTE_SHIFT 57 | #define PTE_SHIFT 3 58 | #endif 59 | #ifndef PTI_SHIFT 60 | #define PTI_SHIFT 12 61 | #endif 62 | #ifndef PDI_SHIFT 63 | #define PDI_SHIFT 21 64 | #endif 65 | #ifndef PPI_SHIFT 66 | #define PPI_SHIFT 30 67 | #endif 68 | #ifndef PXI_SHIFT 69 | #define PXI_SHIFT 39 70 | #endif 71 | 72 | #ifndef PXE_BASE 73 | #define PXE_BASE 0xFFFFF6FB7DBED000UI64 74 | #endif 75 | #ifndef PXE_SELFMAP 76 | #define PXE_SELFMAP 0xFFFFF6FB7DBEDF68UI64 77 | #endif 78 | #ifndef PPE_BASE 79 | #define PPE_BASE 0xFFFFF6FB7DA00000UI64 80 | #endif 81 | #ifndef PDE_BASE 82 | #define PDE_BASE 0xFFFFF6FB40000000UI64 83 | #endif 84 | #ifndef PTE_BASE 85 | #define PTE_BASE 0xFFFFF68000000000UI64 86 | #endif 87 | 88 | #define VIRTUAL_ADDRESS_BITS 48 89 | #define VIRTUAL_ADDRESS_MASK ((((ULONG_PTR)1) << VIRTUAL_ADDRESS_BITS) - 1) 90 | 91 | #define PTE_PER_PAGE 512 92 | #define PDE_PER_PAGE 512 93 | #define PPE_PER_PAGE 512 94 | #define PXE_PER_PAGE 512 95 | 96 | #define PPI_MASK (PPE_PER_PAGE - 1) 97 | #define PXI_MASK (PXE_PER_PAGE - 1) 98 | 99 | #define MiGetPxeOffset(va) \ 100 | ((ULONG)(((ULONG_PTR)(va) >> PXI_SHIFT) & PXI_MASK)) 101 | 102 | #define MiGetPxeAddress(va) \ 103 | ((PMMPTE)PXE_BASE + MiGetPxeOffset(va)) 104 | 105 | #define MiGetPpeAddress(va) \ 106 | ((PMMPTE)(((((ULONG_PTR)(va) & VIRTUAL_ADDRESS_MASK) >> PPI_SHIFT) << PTE_SHIFT) + PPE_BASE)) 107 | 108 | #define MiGetPdeAddress(va) \ 109 | ((PMMPTE)(((((ULONG_PTR)(va) & VIRTUAL_ADDRESS_MASK) >> PDI_SHIFT) << PTE_SHIFT) + PDE_BASE)) 110 | 111 | #define MiGetPteAddress(va) \ 112 | ((PMMPTE)(((((ULONG_PTR)(va) & VIRTUAL_ADDRESS_MASK) >> PTI_SHIFT) << PTE_SHIFT) + PTE_BASE)) 113 | 114 | #define VA_SHIFT (63 - 47) // address sign extend shift count 115 | 116 | #define MiGetVirtualAddressMappedByPte(PTE) \ 117 | ((PVOID)((LONG_PTR)(((LONG_PTR)(PTE) - PTE_BASE) << (PAGE_SHIFT + VA_SHIFT - PTE_SHIFT)) >> VA_SHIFT)) 118 | 119 | #define MI_IS_PHYSICAL_ADDRESS(Va) \ 120 | ((MiGetPxeAddress(Va)->u.Hard.Valid == 1) && \ 121 | (MiGetPpeAddress(Va)->u.Hard.Valid == 1) && \ 122 | ((MiGetPdeAddress(Va)->u.Long & 0x81) == 0x81) || (MiGetPteAddress(Va)->u.Hard.Valid == 1)) 123 | 124 | 125 | 126 | typedef enum _WinVer 127 | { 128 | WINVER_7 = 0x0610, 129 | WINVER_7_SP1 = 0x0611, 130 | WINVER_8 = 0x0620, 131 | WINVER_81 = 0x0630, 132 | WINVER_10 = 0x0A00, 133 | WINVER_10_TH1 = 0x0A01, // 134 | WINVER_10_TH2 = 0x0A02, 135 | WINVER_10_RS1 = 0x0A03, // Anniversary update 136 | WINVER_10_RS2 = 0x0A04, // Creators update 137 | WINVER_10_RS3 = 0x0A05, // Fall creators update 138 | WINVER_10_RS4 = 0x0A06, // Spring creators update 139 | WINVER_10_RS5 = 0x0A07, // October 2018 update 140 | WINVER_10_19H1 = 0x0A08, // May 2019 update 19H1 141 | WINVER_10_19H2 = 0x0A09, // November 2019 update 19H2 142 | WINVER_10_20H1 = 0x0A0A, // April 2020 update 20H1 143 | 144 | } WinVer; 145 | 146 | typedef struct _DYNAMIC_DATA 147 | { 148 | WinVer ver; // OS version 149 | ULONG buildNo; // OS build revision 150 | 151 | PVOID MmPteSpaceStart; 152 | PVOID MmPteSpacecEnd; 153 | 154 | PVOID MmHyperSpaceStart; 155 | PVOID MmHyperSpaceEnd; 156 | 157 | PVOID MmSharedSystemPageStart; 158 | PVOID MmSharedSystemPageEnd; 159 | 160 | PVOID MmSystemCacheWorkingSetStart; 161 | PVOID MmSystemCacheWorkingSetEnd; 162 | 163 | PVOID MmSystemPtesStart; 164 | PVOID MmSystemPtesEnd; 165 | 166 | PVOID MmDriverImageStart; 167 | PVOID MmDriverImageEnd; 168 | 169 | PVOID MmPagedPoolStart; 170 | PVOID MmPagedPoolEnd; 171 | 172 | PVOID MmNonpagedPoolStart; 173 | PVOID MmNonpagedPoolEnd; 174 | 175 | PVOID MmSessionSpaceStart; 176 | PVOID MmSessionSpaceEnd; 177 | 178 | PVOID MmDynamicVASpaceStart; // MiVaSystemCache/MiVaSpecialPoolPaged/MiVaSpecialPoolNonPaged 179 | PVOID MmDynamicVASpaceEnd; 180 | 181 | PVOID MmSystemCacheStart; 182 | PVOID MmSystemCacheEnd; 183 | 184 | PVOID MmSpecialPoolStart; 185 | PVOID MmSpecialPoolEnd; 186 | 187 | PVOID MmPfnDatabaseStart; 188 | PVOID MmPfnDatabaseEnd; 189 | 190 | PVOID DYN_PDE_BASE; // Win10 AU+ relocated PDE base VA 191 | PVOID DYN_PTE_BASE; // Win10 AU+ relocated PTE base VA 192 | 193 | } DYNAMIC_DATA, * PDYNAMIC_DATA; 194 | 195 | PVOID GetKernelBase(OUT PULONG pSize); 196 | VOID InitializeDebuggerBlock(); 197 | NTSTATUS MmsInitLdrData(IN PLDR_DATA_TABLE_ENTRY pThisModule); 198 | 199 | extern KDDEBUGGER_DATA64 g_KdBlock; -------------------------------------------------------------------------------- /MemScanner/ProcessScanner.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FaEryICE/MemScanner/0d4e423f56af9480553c1b01c2d4380873a4dee1/MemScanner/ProcessScanner.c -------------------------------------------------------------------------------- /MemScanner/ProcessScanner.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | VOID ScanSection(); -------------------------------------------------------------------------------- /MemScanner/SectionScanner.c: -------------------------------------------------------------------------------- 1 | #include "SectionScanner.h" 2 | #include "Private.h" 3 | #include "Utils.h" 4 | 5 | //---------------------------------------------------------------------------------------------- 6 | extern POBJECT_TYPE* MmSectionObjectType; 7 | extern DYNAMIC_DATA g_dynData; 8 | //---------------------------------------------------------------------------------------------- 9 | VOID ScanImageFileObjectBySectionObjectMemory_Win7AndLater(PVOID lpStartAddr, SIZE_T ScanSize) 10 | { 11 | SIZE_T ulSize = 0; 12 | ULONG_PTR lpSearchAddr = 0; 13 | ULONG_PTR lpEndAddr = 0; 14 | ULONG ulEntrySize = 0; 15 | ULONG ulCurrentSize = 0; 16 | ULONG_PTR pSectionObject = 0; 17 | NTSTATUS status = STATUS_SUCCESS; 18 | 19 | lpSearchAddr = (ULONG_PTR)lpStartAddr; 20 | lpEndAddr = (ULONG_PTR)lpStartAddr + ScanSize - sizeof(SECTION_OBJECT); 21 | 22 | KdPrint(("[%s] lpSearchAddr:%p lpEndAddr:%p\n", __FUNCTION__, lpSearchAddr, lpEndAddr)); 23 | 24 | while (TRUE) 25 | { 26 | if (lpSearchAddr + PAGE_SIZE > lpEndAddr) 27 | { 28 | ulEntrySize = (ULONG)(lpEndAddr - lpSearchAddr); 29 | } 30 | else 31 | { 32 | ulEntrySize = PAGE_SIZE; 33 | } 34 | 35 | if (!MmsIsAddressValidLength((PVOID)lpSearchAddr, ulEntrySize)) 36 | { 37 | goto NextLoop; 38 | } 39 | 40 | pSectionObject = lpSearchAddr; 41 | 42 | ulCurrentSize = 0; 43 | ulEntrySize -= sizeof(SECTION_OBJECT); 44 | 45 | while (ulCurrentSize < ulEntrySize) 46 | { 47 | PSECTION_OBJECT pSection = (PSECTION_OBJECT)pSectionObject; 48 | if (MmsIsRealSectionObject(pSection)) 49 | { 50 | PCONTROL_AREA ControlArea = pSection->Segment->ControlArea; 51 | if (ControlArea->u.Flags.File && ControlArea->u.Flags.Image) 52 | { 53 | char szName[128] = { 0 }; 54 | PFILE_OBJECT FileObject = (PFILE_OBJECT)((ULONG_PTR)ControlArea->FilePointer.Value & ~0xF); 55 | 56 | if (MmsIsRealFileObject(FileObject)) 57 | { 58 | if (MmsGetObjectName(FileObject, szName, 128)) 59 | { 60 | KdPrint(("[%s] SectionObj:%p FileObj:%p FileName:%s\n", __FUNCTION__, pSection, FileObject, szName)); 61 | } 62 | } 63 | } 64 | 65 | ulCurrentSize += sizeof(SECTION_OBJECT); 66 | pSectionObject += sizeof(SECTION_OBJECT); 67 | } 68 | else 69 | { 70 | ulCurrentSize += sizeof(ULONG_PTR); 71 | pSectionObject += sizeof(ULONG_PTR); 72 | } 73 | } 74 | 75 | NextLoop: 76 | lpSearchAddr += PAGE_SIZE; 77 | if (lpSearchAddr >= lpEndAddr) 78 | { 79 | break; 80 | } 81 | } 82 | } 83 | //---------------------------------------------------------------------------------------------- 84 | VOID ScanImageFileObjectBySectionObjectMemory_Win10(PVOID lpStartAddr, SIZE_T ScanSize) 85 | { 86 | SIZE_T ulSize = 0; 87 | ULONG_PTR lpSearchAddr = 0; 88 | ULONG_PTR lpEndAddr = 0; 89 | ULONG ulEntrySize = 0; 90 | ULONG ulCurrentSize = 0; 91 | ULONG_PTR pSectionObject = 0; 92 | NTSTATUS status = STATUS_SUCCESS; 93 | 94 | 95 | lpSearchAddr = (ULONG_PTR)lpStartAddr; 96 | lpEndAddr = (ULONG_PTR)lpStartAddr + ScanSize - sizeof(SECTION); 97 | 98 | KdPrint(("[%s] lpSearchAddr:%p lpEndAddr:%p\n", __FUNCTION__, lpSearchAddr, lpEndAddr)); 99 | 100 | while (TRUE) 101 | { 102 | if (lpSearchAddr + PAGE_SIZE > lpEndAddr) 103 | { 104 | ulEntrySize = (ULONG)(lpEndAddr - lpSearchAddr); 105 | } 106 | else 107 | { 108 | ulEntrySize = PAGE_SIZE; 109 | } 110 | 111 | if (!MmsIsAddressValidLength((PVOID)lpSearchAddr, ulEntrySize)) 112 | { 113 | goto NextLoop; 114 | } 115 | 116 | pSectionObject = lpSearchAddr; 117 | 118 | ulCurrentSize = 0; 119 | ulEntrySize -= sizeof(SECTION); 120 | 121 | while (ulCurrentSize < ulEntrySize) 122 | { 123 | PSECTION pSection = (PSECTION)pSectionObject; 124 | if (MmsIsRealSectionObject2(pSection)) 125 | { 126 | if (pSection->u.Flags.File && pSection->u.Flags.Image) 127 | { 128 | char szName[128] = { 0 }; 129 | PCONTROL_AREA ControlArea = (PCONTROL_AREA)((ULONG_PTR)pSection->u1.ControlArea & ~3); 130 | PFILE_OBJECT FileObject = (PFILE_OBJECT)((ULONG_PTR)ControlArea->FilePointer.Value & ~0xF); 131 | 132 | if (MmsIsRealFileObject(FileObject)) 133 | { 134 | if (MmsGetObjectName(FileObject, szName, 128)) 135 | { 136 | KdPrint(("[%s] SectionObj:%p FileObj:%p FileName:%s\n", __FUNCTION__, pSection, FileObject, szName)); 137 | } 138 | } 139 | } 140 | 141 | ulCurrentSize += sizeof(SECTION); 142 | pSectionObject += sizeof(SECTION); 143 | } 144 | else 145 | { 146 | ulCurrentSize += sizeof(ULONG_PTR); 147 | pSectionObject += sizeof(ULONG_PTR); 148 | } 149 | } 150 | 151 | NextLoop: 152 | lpSearchAddr += PAGE_SIZE; 153 | if (lpSearchAddr >= lpEndAddr) 154 | { 155 | break; 156 | } 157 | } 158 | } 159 | //---------------------------------------------------------------------------------------------- 160 | VOID ScanImageFileObjectBySectionObjectMemory() 161 | { 162 | SIZE_T ulSize = 0; 163 | ULONG_PTR lpSearchAddr = 0; 164 | ULONG_PTR lpEndAddr = 0; 165 | ULONG ulEntrySize = 0; 166 | ULONG ulCurrentSize = 0; 167 | ULONG_PTR pSectionObject = 0; 168 | NTSTATUS status = STATUS_SUCCESS; 169 | 170 | if (g_dynData.ver >= WINVER_7 && g_dynData.ver <= WINVER_81) 171 | { 172 | ulSize = (ULONG_PTR)g_dynData.MmPagedPoolEnd - (ULONG_PTR)g_dynData.MmPagedPoolStart; 173 | ScanImageFileObjectBySectionObjectMemory_Win7AndLater(g_dynData.MmPagedPoolStart, ulSize); 174 | } 175 | else if (g_dynData.ver >= WINVER_10_TH1) 176 | { 177 | ulSize = (ULONG_PTR)g_dynData.MmPagedPoolEnd - (ULONG_PTR)g_dynData.MmPagedPoolStart; 178 | ScanImageFileObjectBySectionObjectMemory_Win10(g_dynData.MmPagedPoolStart, ulSize); 179 | } 180 | } 181 | //---------------------------------------------------------------------------------------------- 182 | VOID ScanSection() 183 | { 184 | ScanImageFileObjectBySectionObjectMemory(); 185 | } 186 | //---------------------------------------------------------------------------------------------- 187 | -------------------------------------------------------------------------------- /MemScanner/SectionScanner.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | VOID ScanSection(); -------------------------------------------------------------------------------- /MemScanner/Utils.c: -------------------------------------------------------------------------------- 1 | #include "Utils.h" 2 | #include "Private.h" 3 | 4 | //------------------------------------------------------------------------------------------------------------------------------------------------------------------- 5 | typedef 6 | POBJECT_TYPE 7 | (NTAPI* pfnObGetObjectType)( 8 | PVOID pObject 9 | ); 10 | //------------------------------------------------------------------------------------------------------------------------------------------------------------------- 11 | pfnObGetObjectType g_ObGetObjectType = NULL; 12 | 13 | extern POBJECT_TYPE* IoDriverObjectType; 14 | extern POBJECT_TYPE* IoDeviceObjectType; 15 | extern POBJECT_TYPE* MmSectionObjectType; 16 | //------------------------------------------------------------------------------------------------------------------------------------------------------------------- 17 | NTSTATUS MmsSearchPattern(IN PCUCHAR pattern, IN UCHAR wildcard, IN ULONG_PTR len, IN const VOID* base, IN ULONG_PTR size, OUT PVOID* ppFound) 18 | { 19 | ASSERT(ppFound != NULL && pattern != NULL && base != NULL); 20 | if (ppFound == NULL || pattern == NULL || base == NULL) 21 | { 22 | return STATUS_INVALID_PARAMETER; 23 | } 24 | 25 | for (ULONG_PTR i = 0; i < size - len; i++) 26 | { 27 | BOOLEAN found = TRUE; 28 | for (ULONG_PTR j = 0; j < len; j++) 29 | { 30 | if (pattern[j] != wildcard && pattern[j] != ((PCUCHAR)base)[i + j]) 31 | { 32 | found = FALSE; 33 | break; 34 | } 35 | } 36 | 37 | if (found != FALSE) 38 | { 39 | *ppFound = (PUCHAR)base + i; 40 | return STATUS_SUCCESS; 41 | } 42 | } 43 | 44 | return STATUS_NOT_FOUND; 45 | } 46 | //------------------------------------------------------------------------------------------------------------------------------------------------------------------- 47 | POBJECT_TYPE MmsGetObjectType(PVOID pObject) 48 | { 49 | UNICODE_STRING uniFuncName = { 0 }; 50 | 51 | if (!g_ObGetObjectType) 52 | { 53 | RtlInitUnicodeString(&uniFuncName, L"ObGetObjectType"); 54 | g_ObGetObjectType = (pfnObGetObjectType)MmGetSystemRoutineAddress(&uniFuncName); 55 | } 56 | 57 | if (g_ObGetObjectType) 58 | { 59 | return g_ObGetObjectType(pObject); 60 | } 61 | 62 | return NULL; 63 | } 64 | //------------------------------------------------------------------------------------------------------------------------------------------------------------------- 65 | ULONG MmsGetObjectName(PVOID Object, char* szBuffer, ULONG ulBufferSize) 66 | { 67 | ULONG ulRetLen = 0; 68 | ULONG ulRet = 0; 69 | PUNICODE_STRING lpUniObjectName = NULL; 70 | 71 | lpUniObjectName = (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool, 1024 + 2 * sizeof(OBJECT_NAME_INFORMATION), 'nOmM'); 72 | if (!lpUniObjectName) 73 | { 74 | return 0; 75 | } 76 | 77 | memset(lpUniObjectName, 0, 1024 + 2 * sizeof(OBJECT_NAME_INFORMATION)); 78 | lpUniObjectName->MaximumLength = 1024; 79 | 80 | if (NT_SUCCESS(ObQueryNameString(Object, (POBJECT_NAME_INFORMATION)lpUniObjectName, 1024, &ulRetLen))) 81 | { 82 | ULONG i, Len = lpUniObjectName->Length / 2; 83 | for (i = 0; i + 8 < Len && i + 1 < ulBufferSize; i++) 84 | { 85 | szBuffer[i] = (char)lpUniObjectName->Buffer[i + 8]; 86 | } 87 | 88 | szBuffer[i++] = 0; 89 | ulRet = i; 90 | } 91 | 92 | ExFreePool(lpUniObjectName); 93 | return ulRet; 94 | } 95 | //------------------------------------------------------------------------------------------------------------------------------------------------------------------- 96 | BOOLEAN MmsIsAddressValidLength(PVOID lpBuffer, ULONG Len) 97 | { 98 | ULONG_PTR AddrStart = 0; 99 | ULONG_PTR AddrEnd = 0; 100 | 101 | if (!MmIsAddressValid(lpBuffer)) 102 | { 103 | return FALSE; 104 | } 105 | 106 | AddrStart = (ULONG_PTR)lpBuffer; 107 | AddrEnd = AddrStart + Len; 108 | 109 | AddrStart = ALIGN_UP_BY(AddrStart, PAGE_SIZE); 110 | 111 | for (; AddrStart < AddrEnd; AddrStart += PAGE_SIZE) 112 | { 113 | if (!MmIsAddressValid((PVOID)AddrStart)) 114 | { 115 | return FALSE; 116 | } 117 | } 118 | 119 | return TRUE; 120 | } 121 | //------------------------------------------------------------------------------------------------------------------------------------------------------------------- 122 | BOOLEAN MmsIsRealDriverObject(PDRIVER_OBJECT DriverObject) 123 | { 124 | BOOLEAN bRet = FALSE; 125 | ULONG_PTR CurrentVirutalPage = 0; 126 | ULONG_PTR PreVirtualPage = 0; 127 | 128 | if (!DriverObject || !MmIsAddressValid(DriverObject)) 129 | { 130 | return FALSE; 131 | } 132 | 133 | if (DriverObject->Type != 4 || DriverObject->Size != sizeof(DRIVER_OBJECT)) 134 | { 135 | return FALSE; 136 | } 137 | 138 | CurrentVirutalPage = ALIGN_DOWN_BY(DriverObject, PAGE_SIZE); 139 | PreVirtualPage = ALIGN_DOWN_BY((ULONG_PTR)DriverObject - 0x30, PAGE_SIZE); // Win7 ~ Win10 sizeof(_object_header) == 0x30 140 | 141 | if (PreVirtualPage != CurrentVirutalPage) 142 | { 143 | if (PreVirtualPage + PAGE_SIZE != CurrentVirutalPage) 144 | { 145 | // Impossible; 146 | return FALSE; 147 | } 148 | else 149 | { 150 | if (!MmIsAddressValid((PVOID)PreVirtualPage)) 151 | { 152 | return FALSE; 153 | } 154 | } 155 | } 156 | 157 | // ObGetObjectType会访问到Object之前的内存空间,如果对象头内存与对象体内存不在一个页面,需要确保对象头所在页面也是有效的,正常情况绝不会不在同一个页面下 158 | if (MmsGetObjectType(DriverObject) != *IoDriverObjectType) 159 | { 160 | return FALSE; 161 | } 162 | 163 | if ((ULONG_PTR)DriverObject->DriverSection <= (ULONG_PTR)MmSystemRangeStart || 164 | !MmIsAddressValid(DriverObject->DriverSection) || 165 | (DriverObject->DriverSize & 0x1F) || 166 | (ULONG_PTR)DriverObject->DriverStart <= (ULONG_PTR)MmSystemRangeStart || 167 | ((ULONG_PTR)(DriverObject->DriverStart) & 0xFFF)) 168 | { 169 | return FALSE; 170 | } 171 | 172 | PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject; 173 | if (DeviceObject) 174 | { 175 | if (MmIsAddressValid(DeviceObject) && 176 | MmsGetObjectType(DeviceObject) == *IoDeviceObjectType && 177 | DeviceObject->Type == 3 && 178 | DeviceObject->Size >= sizeof(DEVICE_OBJECT)) 179 | { 180 | bRet = TRUE; 181 | } 182 | } 183 | else 184 | { 185 | bRet = TRUE; 186 | } 187 | 188 | return bRet; 189 | } 190 | //------------------------------------------------------------------------------------------------------------------------------------------------------------------- 191 | BOOLEAN MmsIsValidUnicodeString(PUNICODE_STRING lpuniStr) 192 | { 193 | if (!lpuniStr || 194 | !lpuniStr->Buffer || 195 | !lpuniStr->Length || 196 | lpuniStr->Length > lpuniStr->MaximumLength || 197 | !MmsIsAddressValidLength(lpuniStr->Buffer, lpuniStr->Length)) 198 | { 199 | return FALSE; 200 | } 201 | 202 | return TRUE; 203 | } 204 | //------------------------------------------------------------------------------------------------------------------------------------------------------------------- 205 | BOOLEAN MmsIsRealSectionObject(PSECTION_OBJECT SectionObject) 206 | { 207 | BOOLEAN bRet = FALSE; 208 | 209 | if (MmsIsAddressValidLength((PVOID)((ULONG_PTR)SectionObject - sizeof(OBJECT_HEADER)), sizeof(OBJECT_HEADER) + sizeof(SECTION_OBJECT)) && 210 | MmsGetObjectType(SectionObject) == *MmSectionObjectType && 211 | (ULONG_PTR)SectionObject->Segment > (ULONG_PTR)MmSystemRangeStart && 212 | MmsIsAddressValidLength((PVOID)((ULONG_PTR)SectionObject->Segment - sizeof(OBJECT_HEADER)), sizeof(OBJECT_HEADER) + sizeof(SEGMENT_OBJECT)) && 213 | SectionObject->Segment->SizeOfSegment > 0 && 214 | SectionObject->Segment->SizeOfSegment < (ULONG_PTR)MmSystemRangeStart && 215 | SectionObject->Segment->TotalNumberOfPtes > 0 && 216 | (ULONG_PTR)SectionObject->Segment->PrototypePte > (ULONG_PTR)MmSystemRangeStart) 217 | { 218 | PCONTROL_AREA ControlArea = (PCONTROL_AREA)SectionObject->Segment->ControlArea; 219 | if ((ULONG_PTR)ControlArea > (ULONG_PTR)MmSystemRangeStart && 220 | MmsIsAddressValidLength(ControlArea, sizeof(CONTROL_AREA)) && // sizeof(CONTROL_AREA) == 0x70/0x78/0x80 ... in all windows version 221 | !ControlArea->u.Flags.BeingCreated && 222 | !ControlArea->u.Flags.BeingDeleted) 223 | { 224 | return TRUE; 225 | } 226 | } 227 | 228 | return bRet; 229 | } 230 | //------------------------------------------------------------------------------------------------------------------------------------------------------------------- 231 | BOOLEAN MmsIsRealSectionObject2(PSECTION SectionObject) 232 | { 233 | BOOLEAN bRet = FALSE; 234 | 235 | if (MmsIsAddressValidLength((PVOID)((ULONG_PTR)SectionObject - sizeof(OBJECT_HEADER)), sizeof(OBJECT_HEADER) + sizeof(SECTION)) && 236 | MmsGetObjectType(SectionObject) == *MmSectionObjectType && 237 | SectionObject->SizeOfSection > 0 && 238 | SectionObject->SizeOfSection < (ULONG_PTR)MmSystemRangeStart && 239 | !SectionObject->u.Flags.BeingDeleted && 240 | !SectionObject->u.Flags.BeingCreated) 241 | { 242 | PCONTROL_AREA ControlArea = (PCONTROL_AREA)((ULONG_PTR)SectionObject->u1.ControlArea & ~3); 243 | if ((ULONG_PTR)ControlArea > (ULONG_PTR)MmSystemRangeStart && 244 | MmsIsAddressValidLength(ControlArea, sizeof(CONTROL_AREA))) 245 | { 246 | return TRUE; 247 | } 248 | } 249 | 250 | return bRet; 251 | } 252 | //------------------------------------------------------------------------------------------------------------------------------------------------------------------- 253 | BOOLEAN MmsIsRealFileObject(PFILE_OBJECT FileObject) 254 | { 255 | BOOLEAN bRet = FALSE; 256 | 257 | if (MmsIsAddressValidLength((PVOID)((ULONG_PTR)FileObject - sizeof(OBJECT_HEADER)), sizeof(OBJECT_HEADER) + sizeof(FILE_OBJECT)) && 258 | MmsGetObjectType(FileObject) == *IoFileObjectType && 259 | FileObject->Type == 5 && 260 | FileObject->Size == sizeof(FILE_OBJECT) && 261 | (ULONG_PTR)FileObject->DeviceObject > (ULONG_PTR)MmSystemRangeStart && 262 | (ULONG_PTR)FileObject->SectionObjectPointer > (ULONG_PTR)MmSystemRangeStart) 263 | { 264 | if ((ULONG_PTR)FileObject->DeviceObject) 265 | { 266 | if ((ULONG_PTR)FileObject->DeviceObject > (ULONG_PTR)MmSystemRangeStart && 267 | MmsIsAddressValidLength((PVOID)((ULONG_PTR)FileObject->DeviceObject - sizeof(OBJECT_HEADER)), sizeof(OBJECT_HEADER) + sizeof(DEVICE_OBJECT)) && 268 | MmsGetObjectType(FileObject->DeviceObject) == *IoDeviceObjectType) 269 | { 270 | bRet = TRUE; 271 | } 272 | else 273 | { 274 | bRet = FALSE; 275 | } 276 | } 277 | 278 | if ((ULONG_PTR)FileObject->Vpb) 279 | { 280 | if ((ULONG_PTR)FileObject->Vpb > (ULONG_PTR)MmSystemRangeStart && 281 | MmsIsAddressValidLength(FileObject->Vpb, sizeof(VPB)) && 282 | (ULONG_PTR)FileObject->Vpb->DeviceObject > (ULONG_PTR)MmSystemRangeStart && 283 | MmsIsAddressValidLength((PVOID)((ULONG_PTR)FileObject->Vpb->DeviceObject - sizeof(OBJECT_HEADER)), sizeof(OBJECT_HEADER) + sizeof(DEVICE_OBJECT)) && 284 | MmsGetObjectType(FileObject->Vpb->DeviceObject) == *IoDeviceObjectType) 285 | { 286 | bRet = TRUE; 287 | } 288 | else 289 | { 290 | bRet = FALSE; 291 | } 292 | } 293 | } 294 | 295 | return bRet; 296 | } 297 | //------------------------------------------------------------------------------------------------------------------------------------------------------------------- 298 | -------------------------------------------------------------------------------- /MemScanner/Utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "NativeStruct.h" 4 | 5 | NTSTATUS MmsSearchPattern(IN PCUCHAR pattern, IN UCHAR wildcard, IN ULONG_PTR len, IN const VOID* base, IN ULONG_PTR size, OUT PVOID* ppFound); 6 | POBJECT_TYPE MmsGetObjectType(PVOID pObject); 7 | ULONG MmsGetObjectName(PVOID Object, char* szBuffer, ULONG ulBufferSize); 8 | BOOLEAN MmsIsAddressValidLength(PVOID lpBuffer, ULONG Len); 9 | BOOLEAN MmsIsRealDriverObject(PVOID pObject); 10 | BOOLEAN MmsIsRealSectionObject(PSECTION_OBJECT SectionObject); 11 | BOOLEAN MmsIsRealSectionObject2(PSECTION SectionObject); 12 | BOOLEAN MmsIsRealFileObject(PFILE_OBJECT FileObject); 13 | BOOLEAN MmsIsValidUnicodeString(PUNICODE_STRING lpuniStr); -------------------------------------------------------------------------------- /MemScanner/main.c: -------------------------------------------------------------------------------- 1 | #include "NativeStruct.h" 2 | #include "Private.h" 3 | #include "Import.h" 4 | #include "Utils.h" 5 | #include "DriverScanner.h" 6 | #include "SectionScanner.h" 7 | #include 8 | 9 | 10 | 11 | KEVENT g_ScannerFinishEvent; 12 | 13 | // OS Dependant data 14 | DYNAMIC_DATA g_dynData = { 0 }; 15 | PDRIVER_OBJECT g_DriverObject = NULL; 16 | 17 | CHAR* g_szAssignedRegionNames[] = { 18 | "AssignedRegionNonPagedPool", 19 | "AssignedRegionPagedPool", 20 | "AssignedRegionSystemCache", 21 | "AssignedRegionSystemPtes", 22 | "AssignedRegionUltraZero", 23 | "AssignedRegionPfnDatabase", 24 | "AssignedRegionCfg", 25 | "AssignedRegionHyperSpace", 26 | "AssignedRegionKernelStacks", 27 | "AssignedRegionPageTables", 28 | "AssignedRegionSession", 29 | "AssignedRegionSecureNonPagedPool", 30 | "AssignedRegionSystemImages", 31 | "AssignedRegionMaximum" 32 | }; 33 | 34 | extern POBJECT_TYPE* MmSectionObjectType; 35 | 36 | extern PKDDEBUGGER_DATA64 g_KdDebuggerDataBlock; 37 | 38 | //--------------------------------------------------------------------------------------------------------- 39 | NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath); 40 | VOID DriverUnload(PDRIVER_OBJECT DriverObject); 41 | NTSTATUS MmsGetBuildNO(OUT PULONG pBuildNo); 42 | NTSTATUS MmsScanSection(IN PCCHAR section, IN PCUCHAR pattern, IN UCHAR wildcard, IN ULONG_PTR len, OUT PVOID* ppFound); 43 | NTSTATUS MmsInitDynamicData(IN OUT PDYNAMIC_DATA pData); 44 | NTSTATUS MmsInitMemoryLayoutForWin7AndWin8(IN OUT PDYNAMIC_DATA pData); 45 | NTSTATUS MmsInitMemoryLayoutForWin8_1ToWin10TH2(IN OUT PDYNAMIC_DATA pData); 46 | NTSTATUS MmsInitMemoryLayoutForWin10RS1AndLater(IN OUT PDYNAMIC_DATA pData); 47 | 48 | VOID MmsTestAllocateMemory(); 49 | VOID MmsScannerThread(IN PVOID StartContext); 50 | //--------------------------------------------------------------------------------------------------------- 51 | NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) 52 | { 53 | NTSTATUS Status = STATUS_SUCCESS; 54 | HANDLE ThreadHandle = NULL; 55 | 56 | UNREFERENCED_PARAMETER(RegistryPath); 57 | 58 | InitializeDebuggerBlock(); 59 | Status = MmsInitDynamicData(&g_dynData); 60 | if (!NT_SUCCESS(Status)) 61 | { 62 | return Status; 63 | } 64 | 65 | Status = MmsInitLdrData((PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection); 66 | if (!NT_SUCCESS(Status)) 67 | { 68 | return Status; 69 | } 70 | 71 | g_DriverObject = DriverObject; 72 | 73 | DriverObject->DriverUnload = DriverUnload; 74 | 75 | MmsTestAllocateMemory(); 76 | 77 | KeInitializeEvent(&g_ScannerFinishEvent, NotificationEvent, FALSE); 78 | PsCreateSystemThread(&ThreadHandle, 79 | 0, 80 | NULL, 81 | NtCurrentProcess(), 82 | NULL, 83 | MmsScannerThread, 84 | NULL); 85 | 86 | if (ThreadHandle) 87 | { 88 | ZwClose(ThreadHandle); 89 | } 90 | 91 | return STATUS_SUCCESS; 92 | } 93 | //--------------------------------------------------------------------------------------------------------- 94 | VOID MmsScannerThread(IN PVOID StartContext) 95 | { 96 | LARGE_INTEGER liDelayTime = { 0 }; 97 | 98 | liDelayTime.QuadPart = -1000 * 10000; 99 | KeDelayExecutionThread(KernelMode, FALSE, &liDelayTime); 100 | 101 | ScanDriver(); 102 | ScanSection(); 103 | 104 | KeSetEvent(&g_ScannerFinishEvent, IO_NO_INCREMENT, FALSE); 105 | 106 | PsTerminateSystemThread(STATUS_SUCCESS); 107 | } 108 | //--------------------------------------------------------------------------------------------------------- 109 | VOID DriverUnload(PDRIVER_OBJECT DriverObject) 110 | { 111 | UNREFERENCED_PARAMETER(DriverObject); 112 | 113 | DbgPrint("[%s] Unloading\n", __FUNCTION__); 114 | 115 | KeWaitForSingleObject(&g_ScannerFinishEvent, Executive, KernelMode, FALSE, NULL); 116 | 117 | DbgPrint("[%s] Unload Complete\n", __FUNCTION__); 118 | 119 | return; 120 | } 121 | //--------------------------------------------------------------------------------------------------------- 122 | NTSTATUS MmsScanSection(IN PCCHAR section, IN PCUCHAR pattern, IN UCHAR wildcard, IN ULONG_PTR len, OUT PVOID* ppFound) 123 | { 124 | ASSERT(ppFound != NULL); 125 | if (ppFound == NULL) 126 | return STATUS_INVALID_PARAMETER; 127 | 128 | PVOID base = GetKernelBase(NULL); 129 | if (!base) 130 | return STATUS_NOT_FOUND; 131 | 132 | PIMAGE_NT_HEADERS64 pHdr = RtlImageNtHeader(base); 133 | if (!pHdr) 134 | return STATUS_INVALID_IMAGE_FORMAT; 135 | 136 | PIMAGE_SECTION_HEADER pFirstSection = (PIMAGE_SECTION_HEADER)(pHdr + 1); 137 | for (PIMAGE_SECTION_HEADER pSection = pFirstSection; pSection < pFirstSection + pHdr->FileHeader.NumberOfSections; pSection++) 138 | { 139 | ANSI_STRING s1, s2; 140 | RtlInitAnsiString(&s1, section); 141 | RtlInitAnsiString(&s2, (PCCHAR)pSection->Name); 142 | if (RtlCompareString(&s1, &s2, TRUE) == 0) 143 | { 144 | PVOID ptr = NULL; 145 | NTSTATUS status = MmsSearchPattern(pattern, wildcard, len, (PUCHAR)base + pSection->VirtualAddress, pSection->Misc.VirtualSize, &ptr); 146 | if (NT_SUCCESS(status)) 147 | *ppFound = ptr; 148 | 149 | return status; 150 | } 151 | } 152 | 153 | return STATUS_NOT_FOUND; 154 | } 155 | //--------------------------------------------------------------------------------------------------------- 156 | NTSTATUS MmsGetBuildNO(OUT PULONG pBuildNo) 157 | { 158 | ASSERT(pBuildNo != NULL); 159 | if (pBuildNo == NULL) 160 | return STATUS_INVALID_PARAMETER; 161 | 162 | NTSTATUS status = STATUS_SUCCESS; 163 | UNICODE_STRING strRegKey = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion"); 164 | UNICODE_STRING strRegValue = RTL_CONSTANT_STRING(L"BuildLabEx"); 165 | UNICODE_STRING strRegValue10 = RTL_CONSTANT_STRING(L"UBR"); 166 | UNICODE_STRING strVerVal = { 0 }; 167 | HANDLE hKey = NULL; 168 | OBJECT_ATTRIBUTES keyAttr = { 0 }; 169 | 170 | InitializeObjectAttributes(&keyAttr, &strRegKey, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); 171 | 172 | status = ZwOpenKey(&hKey, KEY_READ, &keyAttr); 173 | if (NT_SUCCESS(status)) 174 | { 175 | PKEY_VALUE_FULL_INFORMATION pValueInfo = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, MMS_POOL_TAG); 176 | ULONG bytes = 0; 177 | 178 | if (pValueInfo) 179 | { 180 | // Try query UBR value 181 | status = ZwQueryValueKey(hKey, &strRegValue10, KeyValueFullInformation, pValueInfo, PAGE_SIZE, &bytes); 182 | if (NT_SUCCESS(status)) 183 | { 184 | *pBuildNo = *(PULONG)((PUCHAR)pValueInfo + pValueInfo->DataOffset); 185 | goto skip1; 186 | } 187 | 188 | status = ZwQueryValueKey(hKey, &strRegValue, KeyValueFullInformation, pValueInfo, PAGE_SIZE, &bytes); 189 | if (NT_SUCCESS(status)) 190 | { 191 | PWCHAR pData = (PWCHAR)((PUCHAR)pValueInfo->Name + pValueInfo->NameLength); 192 | for (ULONG i = 0; i < pValueInfo->DataLength; i++) 193 | { 194 | if (pData[i] == L'.') 195 | { 196 | for (ULONG j = i + 1; j < pValueInfo->DataLength; j++) 197 | { 198 | if (pData[j] == L'.') 199 | { 200 | strVerVal.Buffer = &pData[i] + 1; 201 | strVerVal.Length = strVerVal.MaximumLength = (USHORT)((j - i) * sizeof(WCHAR)); 202 | status = RtlUnicodeStringToInteger(&strVerVal, 10, pBuildNo); 203 | 204 | goto skip1; 205 | } 206 | } 207 | } 208 | } 209 | 210 | skip1:; 211 | } 212 | 213 | ExFreePoolWithTag(pValueInfo, MMS_POOL_TAG); 214 | } 215 | else 216 | status = STATUS_NO_MEMORY; 217 | 218 | ZwClose(hKey); 219 | } 220 | else 221 | DbgPrint("[%s] ZwOpenKey failed with status 0x%X\n", __FUNCTION__, status); 222 | 223 | return status; 224 | } 225 | //--------------------------------------------------------------------------------------------------------- 226 | NTSTATUS MmsInitDynamicData(IN OUT PDYNAMIC_DATA pData) 227 | { 228 | NTSTATUS status = STATUS_SUCCESS; 229 | RTL_OSVERSIONINFOEXW verInfo = { 0 }; 230 | 231 | if (pData == NULL) 232 | { 233 | return STATUS_INVALID_ADDRESS; 234 | } 235 | 236 | RtlZeroMemory(pData, sizeof(DYNAMIC_DATA)); 237 | pData->DYN_PDE_BASE = (PVOID)PDE_BASE; 238 | pData->DYN_PTE_BASE = (PVOID)PTE_BASE; 239 | 240 | verInfo.dwOSVersionInfoSize = sizeof(verInfo); 241 | status = RtlGetVersion((PRTL_OSVERSIONINFOW)&verInfo); 242 | 243 | if (status != STATUS_SUCCESS) 244 | { 245 | return status; 246 | } 247 | 248 | ULONG ver_short = (verInfo.dwMajorVersion << 8) | (verInfo.dwMinorVersion << 4) | verInfo.wServicePackMajor; 249 | pData->ver = (WinVer)ver_short; 250 | 251 | // Get kernel build number 252 | status = MmsGetBuildNO(&pData->buildNo); 253 | 254 | DbgPrint( 255 | "[%s] OS version %d.%d.%d.%d.%d - 0x%x\n", 256 | __FUNCTION__, 257 | verInfo.dwMajorVersion, 258 | verInfo.dwMinorVersion, 259 | verInfo.dwBuildNumber, 260 | verInfo.wServicePackMajor, 261 | pData->buildNo, 262 | ver_short 263 | ); 264 | 265 | switch (ver_short) 266 | { 267 | // Windows 7 268 | // Windows 7 SP1 269 | case WINVER_7: 270 | case WINVER_7_SP1: 271 | break; 272 | 273 | // Windows 8 274 | case WINVER_8: 275 | break; 276 | 277 | // Windows 8.1 278 | case WINVER_81: 279 | break; 280 | 281 | // Windows 10, build 16299/15063/14393/10586/10140 282 | case WINVER_10: 283 | 284 | if (verInfo.dwBuildNumber == 10240) 285 | { 286 | pData->ver = WINVER_10_TH1; 287 | break; 288 | } 289 | else if (verInfo.dwBuildNumber == 10586) 290 | { 291 | pData->ver = WINVER_10_TH2; 292 | break; 293 | } 294 | else if (verInfo.dwBuildNumber == 14393) 295 | { 296 | pData->ver = WINVER_10_RS1; 297 | break; 298 | } 299 | else if (verInfo.dwBuildNumber == 15063) 300 | { 301 | pData->ver = WINVER_10_RS2; 302 | break; 303 | } 304 | else if (verInfo.dwBuildNumber == 16299) 305 | { 306 | pData->ver = WINVER_10_RS3; 307 | break; 308 | } 309 | else if (verInfo.dwBuildNumber == 17134) 310 | { 311 | pData->ver = WINVER_10_RS4; 312 | break; 313 | } 314 | else if (verInfo.dwBuildNumber == 17763) 315 | { 316 | pData->ver = WINVER_10_RS5; 317 | break; 318 | } 319 | else if (verInfo.dwBuildNumber == 18362 || verInfo.dwBuildNumber == 18363) 320 | { 321 | pData->ver = verInfo.dwBuildNumber == 18362 ? WINVER_10_19H1 : WINVER_10_19H2; 322 | break; 323 | } 324 | else if (verInfo.dwBuildNumber == 19041) 325 | { 326 | pData->ver = WINVER_10_20H1; 327 | break; 328 | } 329 | else 330 | { 331 | return STATUS_NOT_SUPPORTED; 332 | } 333 | default: 334 | break; 335 | } 336 | 337 | if (pData->ver >= WINVER_7 && pData->ver <= WINVER_8) 338 | { 339 | status = MmsInitMemoryLayoutForWin7AndWin8(pData); 340 | } 341 | else if (pData->ver >= WINVER_81 && pData->ver <= WINVER_10_TH2) 342 | { 343 | status = MmsInitMemoryLayoutForWin8_1ToWin10TH2(pData); 344 | } 345 | else if (pData->ver >= WINVER_10_RS1) 346 | { 347 | status = MmsInitMemoryLayoutForWin10RS1AndLater(pData); 348 | 349 | DbgPrint("[%s] g_KdBlock->KernBase: %p, GetKernelBase() = 0x%p\n", __FUNCTION__, g_KdBlock.KernBase, GetKernelBase(NULL)); 350 | 351 | ULONGLONG mask = (1ll << (PHYSICAL_ADDRESS_BITS - 1)) - 1; 352 | g_dynData.DYN_PTE_BASE = (PVOID)g_KdBlock.PteBase; 353 | g_dynData.DYN_PDE_BASE = (PVOID)((g_KdBlock.PteBase & ~mask) | ((g_KdBlock.PteBase >> 9) & mask)); 354 | } 355 | 356 | DbgPrint("[%s] MmPagedPoolStart: 0x%p, MmPagedPoolEnd = 0x%p \n", __FUNCTION__, pData->MmPagedPoolStart, pData->MmPagedPoolEnd); 357 | DbgPrint("[%s] MmNonpagedPoolStart: 0x%p, MmNonpagedPoolEnd = 0x%p \n", __FUNCTION__, pData->MmNonpagedPoolStart, pData->MmNonpagedPoolEnd); 358 | DbgPrint("[%s] MmSystemPtesStart: 0x%p, MmSystemPtesEnd = 0x%p \n", __FUNCTION__, pData->MmSystemPtesStart, pData->MmSystemPtesEnd); 359 | DbgPrint("[%s] MmDriverImageStart: 0x%p, MmDriverImageEnd = 0x%p \n", __FUNCTION__, pData->MmDriverImageStart, pData->MmDriverImageEnd); 360 | DbgPrint("[%s] PDE_BASE: %p, PTE_BASE: %p\n", __FUNCTION__, pData->DYN_PDE_BASE, pData->DYN_PTE_BASE); 361 | 362 | if ((ULONG_PTR)pData->DYN_PDE_BASE < MI_SYSTEM_RANGE_START || (ULONG_PTR)pData->DYN_PTE_BASE < MI_SYSTEM_RANGE_START) 363 | { 364 | DbgPrint("[%s] Invalid PDE/PTE base, aborting\n", __FUNCTION__); 365 | return STATUS_UNSUCCESSFUL; 366 | } 367 | 368 | return status; 369 | 370 | } 371 | //--------------------------------------------------------------------------------------------------------- 372 | NTSTATUS MmsInitMemoryLayoutForWin7AndWin8(IN OUT PDYNAMIC_DATA pData) 373 | { 374 | if (!pData) 375 | { 376 | return STATUS_INVALID_ADDRESS; 377 | } 378 | 379 | if (!g_KdBlock.MmNonPagedPoolStart || !g_KdBlock.MmMaximumNonPagedPoolInBytes) 380 | { 381 | return STATUS_UNSUCCESSFUL; 382 | } 383 | 384 | // 可扩展区域 385 | pData->MmNonpagedPoolStart = *(PVOID*)g_KdBlock.MmNonPagedPoolStart; 386 | pData->MmNonpagedPoolEnd = (PVOID)((PUCHAR)pData->MmNonpagedPoolStart + *(PULONG_PTR)g_KdBlock.MmMaximumNonPagedPoolInBytes - 1); 387 | 388 | pData->MmPteSpaceStart = (PVOID)0xFFFFF68000000000; 389 | pData->MmPteSpacecEnd = (PVOID)0xFFFFF6FFFFFFFFFF; 390 | 391 | pData->MmHyperSpaceStart = (PVOID)0xFFFFF70000000000; 392 | pData->MmHyperSpaceEnd = (PVOID)0xFFFFF77FFFFFFFFF; 393 | 394 | pData->MmSharedSystemPageStart = (PVOID)0xFFFFF78000000000; 395 | pData->MmSharedSystemPageEnd = (PVOID)0xFFFFF78000000FFF; 396 | 397 | pData->MmSystemCacheWorkingSetStart = (PVOID)0xFFFFF78000001000; 398 | pData->MmSystemCacheWorkingSetEnd = (PVOID)0xFFFFF7FFFFFFFFFF; 399 | 400 | pData->MmDriverImageStart = (PVOID)0xFFFFF80000000000; 401 | pData->MmDriverImageEnd = (PVOID)0xFFFFF87FFFFFFFFF; 402 | 403 | pData->MmSystemPtesStart = (PVOID)0xFFFFF88000000000; 404 | pData->MmSystemPtesEnd = (PVOID)0xFFFFF89FFFFFFFFF; 405 | 406 | pData->MmPagedPoolStart = (PVOID)0xFFFFF8A000000000; 407 | pData->MmPagedPoolEnd = (PVOID)0xFFFFF8BFFFFFFFFF; 408 | 409 | pData->MmSessionSpaceStart = (PVOID)0xFFFFF90000000000; 410 | pData->MmSessionSpaceEnd = (PVOID)0xFFFFF97FFFFFFFFF; 411 | 412 | pData->MmDynamicVASpaceStart = (PVOID)0xFFFFF98000000000; 413 | pData->MmDynamicVASpaceEnd = (PVOID)0xFFFFFA70FFFFFFFF; 414 | 415 | pData->MmPfnDatabaseStart = (PVOID)0xFFFFFA8000000000; 416 | pData->MmPfnDatabaseEnd = (PVOID)((ULONG_PTR)pData->MmNonpagedPoolStart - 1); 417 | 418 | return STATUS_SUCCESS; 419 | } 420 | //--------------------------------------------------------------------------------------------------------- 421 | NTSTATUS MmsInitMemoryLayoutForWin8_1ToWin10TH2(IN OUT PDYNAMIC_DATA pData) 422 | { 423 | if (!pData) 424 | { 425 | return STATUS_INVALID_ADDRESS; 426 | } 427 | 428 | pData->MmPteSpaceStart = (PVOID)0xFFFFF68000000000; 429 | pData->MmPteSpacecEnd = (PVOID)0xFFFFF6FFFFFFFFFF; 430 | 431 | pData->MmHyperSpaceStart = (PVOID)0xFFFFF70000000000; 432 | pData->MmHyperSpaceEnd = (PVOID)0xFFFFF77FFFFFFFFF; 433 | 434 | pData->MmSharedSystemPageStart = (PVOID)0xFFFFF78000000000; 435 | pData->MmSharedSystemPageEnd = (PVOID)0xFFFFF78000000FFF; 436 | 437 | pData->MmSystemCacheStart = (PVOID)0xFFFFB00000000000; 438 | pData->MmSystemCacheEnd = (PVOID)0xFFFFBFFFFFFFFFFF; 439 | 440 | pData->MmPagedPoolStart = (PVOID)0xFFFFC00000000000; 441 | pData->MmPagedPoolEnd = (PVOID)0xFFFFCF7FFFFFFFFF; 442 | 443 | pData->MmSpecialPoolStart = (PVOID)0xFFFFCF8000000000; 444 | pData->MmSpecialPoolEnd = (PVOID)0xFFFFCFFFFFFFFFFF; 445 | 446 | pData->MmSystemPtesStart = (PVOID)0xFFFFD00000000000; 447 | pData->MmSystemPtesEnd = (PVOID)0xFFFFDFFFFFFFFFFF; 448 | 449 | pData->MmNonpagedPoolStart = (PVOID)0xFFFFE00000000000; 450 | pData->MmNonpagedPoolEnd = (PVOID)0xFFFFF00000000000;//等分成KeNumberNodes块 451 | 452 | pData->MmDriverImageStart = (PVOID)0xFFFFF80000000000; 453 | pData->MmDriverImageEnd = (PVOID)0xFFFFF87FFFFFFFFF; 454 | 455 | pData->MmSessionSpaceStart = (PVOID)0xFFFFF90000000000; 456 | pData->MmSessionSpaceEnd = (PVOID)0xFFFFF97FFFFFFFFF; 457 | 458 | pData->MmDynamicVASpaceStart = (PVOID)0xFFFFF98000000000; 459 | pData->MmDynamicVASpaceEnd = (PVOID)0xFFFFFA70FFFFFFFF; 460 | 461 | pData->MmPfnDatabaseStart = (PVOID)0xFFFFFA8000000000; 462 | pData->MmPfnDatabaseEnd = (PVOID)((ULONG_PTR)pData->MmNonpagedPoolStart - 1); 463 | 464 | return STATUS_SUCCESS; 465 | } 466 | //--------------------------------------------------------------------------------------------------------- 467 | NTSTATUS MmsInitMemoryLayoutForWin10RS1AndLater(IN OUT PDYNAMIC_DATA pData) 468 | { 469 | ULONG ulIndex = 0; 470 | PVOID lpTargetAddr = NULL; 471 | PMI_SYSTEM_VA_ASSIGNMENT lpMiSystemVaAssignment = NULL; 472 | 473 | if (!pData) 474 | { 475 | return STATUS_INVALID_ADDRESS; 476 | } 477 | 478 | MmsScanSection(".text", 479 | (PCUCHAR)"\x48\x63\xC1\x48\x8D\x0D\xCC\xCC\xCC\xCC\x48\x03\xC0\x48\x8B\x04\xC1\xC3", 480 | 0xCC, 481 | 18, 482 | (PVOID)&lpTargetAddr); 483 | 484 | if (!lpTargetAddr) 485 | { 486 | DbgPrint("[%s] MmsScanSection Failed\n", __FUNCTION__); 487 | return STATUS_NOT_FOUND; 488 | } 489 | 490 | lpMiSystemVaAssignment = (PMI_SYSTEM_VA_ASSIGNMENT)((PUCHAR)lpTargetAddr + *(PULONG)((PUCHAR)lpTargetAddr + 6) + 10); 491 | for (ulIndex = 0; ulIndex < AssignedRegionMaximum; ulIndex++) 492 | { 493 | DbgPrint("[%s] Names:%s, BaseAddr:%I64x, Size:%I64x\n", 494 | __FUNCTION__, 495 | g_szAssignedRegionNames[ulIndex], 496 | lpMiSystemVaAssignment[ulIndex].BaseAddress, 497 | lpMiSystemVaAssignment[ulIndex].NumberOfBytes); 498 | } 499 | 500 | pData->MmPteSpaceStart = (PVOID)lpMiSystemVaAssignment[AssignedRegionPageTables].BaseAddress; 501 | pData->MmPteSpacecEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[AssignedRegionPageTables].BaseAddress + lpMiSystemVaAssignment[AssignedRegionPageTables].NumberOfBytes - 1); 502 | 503 | pData->MmHyperSpaceStart = (PVOID)lpMiSystemVaAssignment[AssignedRegionHyperSpace].BaseAddress; 504 | pData->MmHyperSpaceEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[AssignedRegionHyperSpace].BaseAddress + lpMiSystemVaAssignment[AssignedRegionHyperSpace].NumberOfBytes - 1); 505 | 506 | pData->MmSharedSystemPageStart = (PVOID)0xFFFFF78000000000; 507 | pData->MmSharedSystemPageEnd = (PVOID)0xFFFFF78000000FFF; 508 | 509 | pData->MmSystemCacheStart = (PVOID)lpMiSystemVaAssignment[AssignedRegionSystemCache].BaseAddress; 510 | pData->MmSystemCacheEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[AssignedRegionSystemCache].BaseAddress + lpMiSystemVaAssignment[AssignedRegionSystemCache].NumberOfBytes - 1); 511 | 512 | pData->MmPagedPoolStart = (PVOID)lpMiSystemVaAssignment[AssignedRegionPagedPool].BaseAddress; 513 | pData->MmPagedPoolEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[AssignedRegionPagedPool].BaseAddress + lpMiSystemVaAssignment[AssignedRegionPagedPool].NumberOfBytes - 1); 514 | 515 | pData->MmSpecialPoolStart = (PVOID)NULL; 516 | pData->MmSpecialPoolEnd = (PVOID)NULL; 517 | 518 | pData->MmSystemPtesStart = (PVOID)lpMiSystemVaAssignment[AssignedRegionSystemPtes].BaseAddress; 519 | pData->MmSystemPtesEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[AssignedRegionSystemPtes].BaseAddress + lpMiSystemVaAssignment[AssignedRegionSystemPtes].NumberOfBytes - 1); 520 | 521 | pData->MmNonpagedPoolStart = (PVOID)lpMiSystemVaAssignment[AssignedRegionNonPagedPool].BaseAddress; 522 | pData->MmNonpagedPoolEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[AssignedRegionNonPagedPool].BaseAddress + lpMiSystemVaAssignment[AssignedRegionNonPagedPool].NumberOfBytes - 1);//等分成KeNumberNodes块 523 | 524 | if (pData->ver == WINVER_10_RS1) 525 | { 526 | pData->MmDriverImageStart = (PVOID)lpMiSystemVaAssignment[13].BaseAddress; 527 | pData->MmDriverImageEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[13].BaseAddress + lpMiSystemVaAssignment[13].NumberOfBytes - 1); 528 | 529 | pData->MmSessionSpaceStart = (PVOID)lpMiSystemVaAssignment[10].BaseAddress; 530 | pData->MmSessionSpaceEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[10].BaseAddress + lpMiSystemVaAssignment[10].NumberOfBytes - 1); 531 | } 532 | else if (pData->ver == WINVER_10_RS2) 533 | { 534 | pData->MmDriverImageStart = (PVOID)lpMiSystemVaAssignment[12].BaseAddress; 535 | pData->MmDriverImageEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[12].BaseAddress + lpMiSystemVaAssignment[12].NumberOfBytes - 1); 536 | 537 | pData->MmSessionSpaceStart = (PVOID)lpMiSystemVaAssignment[11].BaseAddress; 538 | pData->MmSessionSpaceEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[11].BaseAddress + lpMiSystemVaAssignment[11].NumberOfBytes - 1); 539 | } 540 | else if (pData->ver >= WINVER_10_RS3 && pData->ver <= WINVER_10_RS5) 541 | { 542 | pData->MmDriverImageStart = (PVOID)lpMiSystemVaAssignment[13].BaseAddress; 543 | pData->MmDriverImageEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[13].BaseAddress + lpMiSystemVaAssignment[13].NumberOfBytes - 1); 544 | 545 | pData->MmSessionSpaceStart = (PVOID)lpMiSystemVaAssignment[12].BaseAddress; 546 | pData->MmSessionSpaceEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[12].BaseAddress + lpMiSystemVaAssignment[12].NumberOfBytes - 1); 547 | } 548 | else if (pData->ver == WINVER_10_19H1 || pData->ver == WINVER_10_19H2) 549 | { 550 | pData->MmDriverImageStart = (PVOID)lpMiSystemVaAssignment[11].BaseAddress; 551 | pData->MmDriverImageEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[11].BaseAddress + lpMiSystemVaAssignment[11].NumberOfBytes - 1); 552 | 553 | pData->MmSessionSpaceStart = (PVOID)lpMiSystemVaAssignment[10].BaseAddress; 554 | pData->MmSessionSpaceEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[10].BaseAddress + lpMiSystemVaAssignment[10].NumberOfBytes - 1); 555 | } 556 | else if (pData->ver >= WINVER_10_20H1) 557 | { 558 | pData->MmDriverImageStart = (PVOID)lpMiSystemVaAssignment[AssignedRegionSystemImages].BaseAddress; 559 | pData->MmDriverImageEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[AssignedRegionSystemImages].BaseAddress + lpMiSystemVaAssignment[AssignedRegionSystemImages].NumberOfBytes - 1); 560 | 561 | pData->MmSessionSpaceStart = (PVOID)lpMiSystemVaAssignment[10].BaseAddress; 562 | pData->MmSessionSpaceEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[10].BaseAddress + lpMiSystemVaAssignment[10].NumberOfBytes - 1); 563 | } 564 | 565 | pData->MmDynamicVASpaceStart = (PVOID)NULL; 566 | pData->MmDynamicVASpaceEnd = (PVOID)NULL; 567 | 568 | pData->MmPfnDatabaseStart = (PVOID)lpMiSystemVaAssignment[AssignedRegionPfnDatabase].BaseAddress; 569 | pData->MmPfnDatabaseEnd = (PVOID)((PUCHAR)lpMiSystemVaAssignment[AssignedRegionPfnDatabase].BaseAddress + lpMiSystemVaAssignment[AssignedRegionPfnDatabase].NumberOfBytes - 1); 570 | 571 | return STATUS_SUCCESS; 572 | } 573 | //--------------------------------------------------------------------------------------------------------- 574 | VOID MmsTestAllocatePagedPoolMemory() 575 | { 576 | PVOID lpAddr = NULL; 577 | 578 | lpAddr = ExAllocatePoolWithTag(PagedPool, 256, MMS_POOL_TAG); 579 | if (lpAddr) 580 | { 581 | DbgPrint("[%s] AllocateAddress:%p\n", __FUNCTION__, lpAddr); 582 | ExFreePool(lpAddr); 583 | } 584 | } 585 | //--------------------------------------------------------------------------------------------------------- 586 | VOID MmsTestAllocateNonPagedPoolMemory() 587 | { 588 | PVOID lpAddr = NULL; 589 | 590 | lpAddr = ExAllocatePoolWithTag(NonPagedPool, 256, MMS_POOL_TAG); 591 | if (lpAddr) 592 | { 593 | DbgPrint("[%s] AllocateAddress:%p\n", __FUNCTION__, lpAddr); 594 | ExFreePool(lpAddr); 595 | } 596 | } 597 | //--------------------------------------------------------------------------------------------------------- 598 | VOID MmsTestAllocateMDLMemory() 599 | { 600 | PHYSICAL_ADDRESS Low = { 0 }; 601 | PHYSICAL_ADDRESS High = { 0 }; 602 | PHYSICAL_ADDRESS Skip = { 0 }; 603 | SIZE_T SizeOfBytes = 0x332000; 604 | 605 | High.QuadPart = 0x10000000000000; 606 | 607 | PMDL pMdl = MmAllocatePagesForMdl(Low, High, Skip, SizeOfBytes); 608 | if (pMdl) 609 | { 610 | PVOID lpMappedAddr = MmMapLockedPagesSpecifyCache(pMdl, KernelMode, MmNonCached, NULL, 0, 0); 611 | if (lpMappedAddr) 612 | { 613 | DbgPrint("[%s] AllocateAddress:%p\n", __FUNCTION__, lpMappedAddr); 614 | 615 | MmUnmapLockedPages(lpMappedAddr, pMdl); 616 | lpMappedAddr; 617 | } 618 | 619 | MmFreePagesFromMdl(pMdl); 620 | ExFreePool(pMdl); 621 | } 622 | } 623 | //--------------------------------------------------------------------------------------------------------- 624 | VOID MmsTestMapViewInSystemSpace() 625 | { 626 | OBJECT_ATTRIBUTES oa; 627 | NTSTATUS Status = STATUS_SUCCESS; 628 | UNICODE_STRING uniDllName = { 0 }; 629 | IO_STATUS_BLOCK IoStatusblock = { 0 }; 630 | HANDLE hFileHandle = NULL; 631 | HANDLE hSection = NULL; 632 | PVOID SectionObject = NULL; 633 | PVOID MappedAddr = NULL; 634 | SIZE_T MappedSize = 0; 635 | 636 | RtlInitUnicodeString(&uniDllName, L"\\SystemRoot\\System32\\ntdll.dll"); 637 | InitializeObjectAttributes(&oa, &uniDllName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); 638 | 639 | Status = ZwCreateFile(&hFileHandle, 640 | FILE_READ_ACCESS, 641 | &oa, 642 | &IoStatusblock, 643 | NULL, 644 | 0, 645 | FILE_SHARE_READ, 646 | FILE_OPEN, 647 | 0, 648 | NULL, 649 | 0); 650 | 651 | if (!NT_SUCCESS(Status)) 652 | { 653 | return; 654 | } 655 | 656 | InitializeObjectAttributes(&oa, NULL, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); 657 | Status = ZwCreateSection(&hSection, 658 | STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ, 659 | &oa, 660 | NULL, 661 | PAGE_READONLY, 662 | SEC_IMAGE, 663 | hFileHandle); 664 | 665 | if (!NT_SUCCESS(Status)) 666 | { 667 | goto Cleanup; 668 | } 669 | 670 | Status = ObReferenceObjectByHandle(hSection, 0, *MmSectionObjectType, KernelMode, &SectionObject, NULL); 671 | if (!NT_SUCCESS(Status)) 672 | { 673 | goto Cleanup; 674 | } 675 | 676 | MmMapViewInSystemSpace(SectionObject, &MappedAddr, &MappedSize); 677 | DbgPrint("[%s] MappedAddr:%p MappedSize:%x\n", __FUNCTION__, MappedAddr, MappedSize); 678 | 679 | Cleanup: 680 | 681 | if (MappedAddr) 682 | { 683 | MmUnmapViewInSystemSpace(MappedAddr); 684 | MappedAddr = NULL; 685 | } 686 | 687 | if (SectionObject) 688 | { 689 | ObDereferenceObject(SectionObject); 690 | SectionObject = NULL; 691 | } 692 | 693 | if (hSection) 694 | { 695 | ZwClose(hSection); 696 | hSection = NULL; 697 | } 698 | 699 | if (hFileHandle) 700 | { 701 | ZwClose(hFileHandle); 702 | hFileHandle = NULL; 703 | } 704 | 705 | return; 706 | } 707 | //--------------------------------------------------------------------------------------------------------- 708 | VOID MmsTestAllocateContiguousMemory() 709 | { 710 | PVOID lpVirtualAddr = NULL; 711 | PHYSICAL_ADDRESS HighestAcceptAddress = {0}; 712 | HighestAcceptAddress.QuadPart = 1000000000; 713 | 714 | // 申请连续的不可分页物理内存空间 并映射到系统空间 715 | lpVirtualAddr = MmAllocateContiguousMemory(PAGE_SIZE * 10, HighestAcceptAddress); 716 | if (lpVirtualAddr) 717 | { 718 | DbgPrint("[%s] lpVirtualAddr:%p\n", __FUNCTION__, lpVirtualAddr); 719 | MmFreeContiguousMemory(lpVirtualAddr); 720 | } 721 | } 722 | //--------------------------------------------------------------------------------------------------------- 723 | VOID MmsTestAllocateMemory() 724 | { 725 | MmsTestAllocatePagedPoolMemory(); 726 | MmsTestAllocateNonPagedPoolMemory(); 727 | MmsTestMapViewInSystemSpace(); 728 | MmsTestAllocateMDLMemory(); 729 | MmsTestAllocateContiguousMemory(); 730 | } 731 | //--------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MemScanner 2 | Analyze Windows x64 Kernel Memory Layout 3 | *** 4 | 5 | # Build 6 | Build with VS2019 + WDK 10.0.19041.0
7 | Support Windows 7 ~ Windows 10 20H1 x64, and Not support x86 Platform 8 | *** 9 | 10 | # Update 11 | 2020/11/19 Repair Bsod in Win7/8, and support Finding FileObject By Scanning SectionObject in Win7~Win10 12 | 2020/11/18 Support Find FileObject By Scanning SectionObject(PagedPool Memory) 13 | 2020/10/26 Support EnumDriver By Scanning DriverObject and LDR_DATA_TABLE_ENTRY(NonPagedPool Memory) 14 | *** 15 | 16 | # Conclusion 17 | - In Win7 DriverObject is not associated with FileObject, within the procedure of MmLoadSystemImage the SectionObject created and deleted immediately at the end; but in Win10 the life cycle of SectionObject is same to DriverObject. 18 | --------------------------------------------------------------------------------