在筆者上一篇文章《驅動開發:核心特徵碼搜尋函數封裝》
中為了定位特徵的方便我們封裝實現了一個可以傳入陣列實現的SearchSpecialCode
定位函數,該定位函數其實還不能算的上簡單,本章LyShark
將對特徵碼定位進行簡化,讓定位變得更簡單,並運用定位程式碼實現掃描核心PE的.text
程式碼段,並從程式碼段中得到某個特徵所在記憶體位置。
老樣子為了後續教學能夠繼續,先來定義一個lyshark.h
標頭檔案,該標頭檔案中包含了我們本篇文章所必須要使用到的結構體定義,這些定義的函數如果不懂請去看LyShark
以前的文章,這裡就不羅嗦了。
#include <ntifs.h>
#include <ntimage.h>
typedef struct _KLDR_DATA_TABLE_ENTRY
{
LIST_ENTRY64 InLoadOrderLinks;
ULONG64 __Undefined1;
ULONG64 __Undefined2;
ULONG64 __Undefined3;
ULONG64 NonPagedDebugInfo;
ULONG64 DllBase;
ULONG64 EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT __Undefined5;
ULONG64 __Undefined6;
ULONG CheckSum;
ULONG __padding1;
ULONG TimeDateStamp;
ULONG __padding2;
}KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;
typedef struct _RTL_PROCESS_MODULE_INFORMATION
{
HANDLE Section;
PVOID MappedBase;
PVOID ImageBase;
ULONG ImageSize;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT OffsetToFileName;
UCHAR FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;
typedef struct _RTL_PROCESS_MODULES
{
ULONG NumberOfModules;
RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemBasicInformation = 0x0,
SystemProcessorInformation = 0x1,
SystemPerformanceInformation = 0x2,
SystemTimeOfDayInformation = 0x3,
SystemPathInformation = 0x4,
SystemProcessInformation = 0x5,
SystemCallCountInformation = 0x6,
SystemDeviceInformation = 0x7,
SystemProcessorPerformanceInformation = 0x8,
SystemFlagsInformation = 0x9,
SystemCallTimeInformation = 0xa,
SystemModuleInformation = 0xb,
SystemLocksInformation = 0xc,
SystemStackTraceInformation = 0xd,
SystemPagedPoolInformation = 0xe,
SystemNonPagedPoolInformation = 0xf,
SystemHandleInformation = 0x10,
SystemObjectInformation = 0x11,
SystemPageFileInformation = 0x12,
SystemVdmInstemulInformation = 0x13,
SystemVdmBopInformation = 0x14,
SystemFileCacheInformation = 0x15,
SystemPoolTagInformation = 0x16,
SystemInterruptInformation = 0x17,
SystemDpcBehaviorInformation = 0x18,
SystemFullMemoryInformation = 0x19,
SystemLoadGdiDriverInformation = 0x1a,
SystemUnloadGdiDriverInformation = 0x1b,
SystemTimeAdjustmentInformation = 0x1c,
SystemSummaryMemoryInformation = 0x1d,
SystemMirrorMemoryInformation = 0x1e,
SystemPerformanceTraceInformation = 0x1f,
SystemObsolete0 = 0x20,
SystemExceptionInformation = 0x21,
SystemCrashDumpStateInformation = 0x22,
SystemKernelDebuggerInformation = 0x23,
SystemContextSwitchInformation = 0x24,
SystemRegistryQuotaInformation = 0x25,
SystemExtendServiceTableInformation = 0x26,
SystemPrioritySeperation = 0x27,
SystemVerifierAddDriverInformation = 0x28,
SystemVerifierRemoveDriverInformation = 0x29,
SystemProcessorIdleInformation = 0x2a,
SystemLegacyDriverInformation = 0x2b,
SystemCurrentTimeZoneInformation = 0x2c,
SystemLookasideInformation = 0x2d,
SystemTimeSlipNotification = 0x2e,
SystemSessionCreate = 0x2f,
SystemSessionDetach = 0x30,
SystemSessionInformation = 0x31,
SystemRangeStartInformation = 0x32,
SystemVerifierInformation = 0x33,
SystemVerifierThunkExtend = 0x34,
SystemSessionProcessInformation = 0x35,
SystemLoadGdiDriverInSystemSpace = 0x36,
SystemNumaProcessorMap = 0x37,
SystemPrefetcherInformation = 0x38,
SystemExtendedProcessInformation = 0x39,
SystemRecommendedSharedDataAlignment = 0x3a,
SystemComPlusPackage = 0x3b,
SystemNumaAvailableMemory = 0x3c,
SystemProcessorPowerInformation = 0x3d,
SystemEmulationBasicInformation = 0x3e,
SystemEmulationProcessorInformation = 0x3f,
SystemExtendedHandleInformation = 0x40,
SystemLostDelayedWriteInformation = 0x41,
SystemBigPoolInformation = 0x42,
SystemSessionPoolTagInformation = 0x43,
SystemSessionMappedViewInformation = 0x44,
SystemHotpatchInformation = 0x45,
SystemObjectSecurityMode = 0x46,
SystemWatchdogTimerHandler = 0x47,
SystemWatchdogTimerInformation = 0x48,
SystemLogicalProcessorInformation = 0x49,
SystemWow64SharedInformationObsolete = 0x4a,
SystemRegisterFirmwareTableInformationHandler = 0x4b,
SystemFirmwareTableInformation = 0x4c,
SystemModuleInformationEx = 0x4d,
SystemVerifierTriageInformation = 0x4e,
SystemSuperfetchInformation = 0x4f,
SystemMemoryListInformation = 0x50,
SystemFileCacheInformationEx = 0x51,
SystemThreadPriorityClientIdInformation = 0x52,
SystemProcessorIdleCycleTimeInformation = 0x53,
SystemVerifierCancellationInformation = 0x54,
SystemProcessorPowerInformationEx = 0x55,
SystemRefTraceInformation = 0x56,
SystemSpecialPoolInformation = 0x57,
SystemProcessIdInformation = 0x58,
SystemErrorPortInformation = 0x59,
SystemBootEnvironmentInformation = 0x5a,
SystemHypervisorInformation = 0x5b,
SystemVerifierInformationEx = 0x5c,
SystemTimeZoneInformation = 0x5d,
SystemImageFileExecutionOptionsInformation = 0x5e,
SystemCoverageInformation = 0x5f,
SystemPrefetchPatchInformation = 0x60,
SystemVerifierFaultsInformation = 0x61,
SystemSystemPartitionInformation = 0x62,
SystemSystemDiskInformation = 0x63,
SystemProcessorPerformanceDistribution = 0x64,
SystemNumaProximityNodeInformation = 0x65,
SystemDynamicTimeZoneInformation = 0x66,
SystemCodeIntegrityInformation = 0x67,
SystemProcessorMicrocodeUpdateInformation = 0x68,
SystemProcessorBrandString = 0x69,
SystemVirtualAddressInformation = 0x6a,
SystemLogicalProcessorAndGroupInformation = 0x6b,
SystemProcessorCycleTimeInformation = 0x6c,
SystemStoreInformation = 0x6d,
SystemRegistryAppendString = 0x6e,
SystemAitSamplingValue = 0x6f,
SystemVhdBootInformation = 0x70,
SystemCpuQuotaInformation = 0x71,
SystemNativeBasicInformation = 0x72,
SystemErrorPortTimeouts = 0x73,
SystemLowPriorityIoInformation = 0x74,
SystemBootEntropyInformation = 0x75,
SystemVerifierCountersInformation = 0x76,
SystemPagedPoolInformationEx = 0x77,
SystemSystemPtesInformationEx = 0x78,
SystemNodeDistanceInformation = 0x79,
SystemAcpiAuditInformation = 0x7a,
SystemBasicPerformanceInformation = 0x7b,
SystemQueryPerformanceCounterInformation = 0x7c,
SystemSessionBigPoolInformation = 0x7d,
SystemBootGraphicsInformation = 0x7e,
SystemScrubPhysicalMemoryInformation = 0x7f,
SystemBadPageInformation = 0x80,
SystemProcessorProfileControlArea = 0x81,
SystemCombinePhysicalMemoryInformation = 0x82,
SystemEntropyInterruptTimingInformation = 0x83,
SystemConsoleInformation = 0x84,
SystemPlatformBinaryInformation = 0x85,
SystemThrottleNotificationInformation = 0x86,
SystemHypervisorProcessorCountInformation = 0x87,
SystemDeviceDataInformation = 0x88,
SystemDeviceDataEnumerationInformation = 0x89,
SystemMemoryTopologyInformation = 0x8a,
SystemMemoryChannelInformation = 0x8b,
SystemBootLogoInformation = 0x8c,
SystemProcessorPerformanceInformationEx = 0x8d,
SystemSpare0 = 0x8e,
SystemSecureBootPolicyInformation = 0x8f,
SystemPageFileInformationEx = 0x90,
SystemSecureBootInformation = 0x91,
SystemEntropyInterruptTimingRawInformation = 0x92,
SystemPortableWorkspaceEfiLauncherInformation = 0x93,
SystemFullProcessInformation = 0x94,
SystemKernelDebuggerInformationEx = 0x95,
SystemBootMetadataInformation = 0x96,
SystemSoftRebootInformation = 0x97,
SystemElamCertificateInformation = 0x98,
SystemOfflineDumpConfigInformation = 0x99,
SystemProcessorFeaturesInformation = 0x9a,
SystemRegistryReconciliationInformation = 0x9b,
MaxSystemInfoClass = 0x9c,
} SYSTEM_INFORMATION_CLASS;
// 宣告函數
// By: Lyshark.com
NTSYSAPI PIMAGE_NT_HEADERS NTAPI RtlImageNtHeader(_In_ PVOID Base);
NTSTATUS NTAPI ZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);
typedef VOID(__cdecl *PMiProcessLoaderEntry)(PKLDR_DATA_TABLE_ENTRY section, IN LOGICAL Insert);
typedef NTSTATUS(*NTQUERYSYSTEMINFORMATION)(IN ULONG SystemInformationClass, OUT PVOID SystemInformation, IN ULONG_PTR SystemInformationLength, OUT PULONG_PTR ReturnLength OPTIONAL);
我們繼續,首先實現特徵碼字串的解析與掃描實現此處UtilLySharkSearchPattern
函數就是LyShark
封裝過的,這裡依次介紹一下引數傳遞的含義。
(以\x開頭)
(除去\x後的長度)
這段程式碼該如何使用,如下我們以定位IoInitializeTimer
為例,演示UtilLySharkSearchPattern
如何定位特徵的,如下程式碼pattern
變數中就是我們需要定位的特徵值,pattern_size
則是需要定位的特徵碼長度,在address
地址位置向下掃描128
位元組,找到則返回到find_address
變數內。
// 署名
// PowerBy: LyShark
// Email: [email protected]
#include "lyshark.h"
PVOID GetIoInitializeTimerAddress()
{
PVOID VariableAddress = 0;
UNICODE_STRING uioiTime = { 0 };
RtlInitUnicodeString(&uioiTime, L"IoInitializeTimer");
VariableAddress = (PVOID)MmGetSystemRoutineAddress(&uioiTime);
if (VariableAddress != 0)
{
return VariableAddress;
}
return 0;
}
// 對指定記憶體執行特徵碼掃描
NTSTATUS UtilLySharkSearchPattern(IN PUCHAR pattern, IN ULONG_PTR len, IN const VOID* base, IN ULONG_PTR size, OUT PVOID* ppFound)
{
// 計算匹配長度
// LyShark.com 特徵碼掃描
NT_ASSERT(ppFound != 0 && pattern != 0 && base != 0);
if (ppFound == 0 || pattern == 0 || base == 0)
{
return STATUS_INVALID_PARAMETER;
}
__try
{
for (ULONG_PTR i = 0; i < size - len; i++)
{
BOOLEAN found = TRUE;
for (ULONG_PTR j = 0; j < len; j++)
{
if (pattern[j] != ((PUCHAR)base)[i + j])
{
found = FALSE;
break;
}
}
if (found != FALSE)
{
*ppFound = (PUCHAR)base + i;
DbgPrint("[LyShark.com] 特徵碼匹配地址: %p \n", (PUCHAR)base + i);
return STATUS_SUCCESS;
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return STATUS_UNHANDLED_EXCEPTION;
}
return STATUS_NOT_FOUND;
}
VOID UnDriver(PDRIVER_OBJECT driver)
{
DbgPrint(("Uninstall Driver Is OK \n"));
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
DbgPrint(("hello lyshark.com \n"));
// 返回匹配長度5
CHAR pattern[] = "\x48\x89\x6c\x24\x10";
PVOID *find_address = NULL;
int pattern_size = sizeof(pattern) - 1;
DbgPrint("匹配長度: %d \n", pattern_size);
// 得到基地址
PVOID address = GetIoInitializeTimerAddress();
// 掃描特徵
NTSTATUS nt = UtilLySharkSearchPattern((PUCHAR)pattern, pattern_size, address, 128, &find_address);
DbgPrint("[LyShark 返回地址 => ] 0x%p \n", (ULONG64)find_address);
Driver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}
執行驅動程式完成特徵定位,並對比定位效果。
如上述所示定位函數我們已經封裝好了,相信你也能感受到這種方式要比使用陣列更方便,為了能定位到核心PE結構我們需要使用RtlImageNtHeader
來解析,這個核心函數專門用來得到核心程式的PE頭部結構的,在下方案例中首先我們使用封裝過的LySharkToolsUtilKernelBase
函數拿到核心基址,如果你不懂函數實現細節請閱讀《驅動開發:核心取ntoskrnl模組基地址》
這篇文章,拿到基址以後可以直接使用RtlImageNtHeader
對其PE頭部進行解析,如下所示。
// 署名
// PowerBy: LyShark
// Email: [email protected]
#include "lyshark.h"
// 定義全域性變數
static PVOID g_KernelBase = 0;
static ULONG g_KernelSize = 0;
// 得到KernelBase基地址
// lyshark.com
PVOID LySharkToolsUtilKernelBase(OUT PULONG pSize)
{
NTSTATUS status = STATUS_SUCCESS;
ULONG bytes = 0;
PRTL_PROCESS_MODULES pMods = 0;
PVOID checkPtr = 0;
UNICODE_STRING routineName;
if (g_KernelBase != 0)
{
if (pSize)
{
*pSize = g_KernelSize;
}
return g_KernelBase;
}
RtlInitUnicodeString(&routineName, L"NtOpenFile");
checkPtr = MmGetSystemRoutineAddress(&routineName);
if (checkPtr == 0)
return 0;
__try
{
status = ZwQuerySystemInformation(SystemModuleInformation, 0, bytes, &bytes);
if (bytes == 0)
{
return 0;
}
pMods = (PRTL_PROCESS_MODULES)ExAllocatePoolWithTag(NonPagedPoolNx, bytes, L"LyShark");
RtlZeroMemory(pMods, bytes);
status = ZwQuerySystemInformation(SystemModuleInformation, pMods, bytes, &bytes);
if (NT_SUCCESS(status))
{
PRTL_PROCESS_MODULE_INFORMATION pMod = pMods->Modules;
for (ULONG i = 0; i < pMods->NumberOfModules; i++)
{
if (checkPtr >= pMod[i].ImageBase && checkPtr < (PVOID)((PUCHAR)pMod[i].ImageBase + pMod[i].ImageSize))
{
g_KernelBase = pMod[i].ImageBase;
g_KernelSize = pMod[i].ImageSize;
if (pSize)
{
*pSize = g_KernelSize;
}
break;
}
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return 0;
}
if (pMods)
{
ExFreePoolWithTag(pMods, L"LyShark");
}
DbgPrint("KernelBase = > %p \n", g_KernelBase);
return g_KernelBase;
}
VOID UnDriver(PDRIVER_OBJECT driver)
{
DbgPrint(("Uninstall Driver Is OK \n"));
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
DbgPrint(("hello lyshark.com \n"));
// 獲取核心第一個模組的基地址
PVOID base = LySharkToolsUtilKernelBase(0);
if (!base)
return STATUS_NOT_FOUND;
// 得到NT頭部PE32+結構
// lyshark.com
PIMAGE_NT_HEADERS64 pHdr = RtlImageNtHeader(base);
if (!pHdr)
return STATUS_INVALID_IMAGE_FORMAT;
// 首先尋找程式碼段
PIMAGE_SECTION_HEADER pFirstSection = (PIMAGE_SECTION_HEADER)(pHdr + 1);
for (PIMAGE_SECTION_HEADER pSection = pFirstSection; pSection < pFirstSection + pHdr->FileHeader.NumberOfSections; pSection++)
{
ANSI_STRING LySharkSection, LySharkName;
RtlInitAnsiString(&LySharkSection, ".text");
RtlInitAnsiString(&LySharkName, (PCCHAR)pSection->Name);
DbgPrint("[LyShark.PE] 名字: %Z | 地址: %p | 長度: %d \n", LySharkName, (PUCHAR)base + pSection->VirtualAddress, pSection->Misc.VirtualSize);
}
Driver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}
執行這段驅動程式,你會得到當前核心
的所有PE節
資訊,列舉效果如下所示。
既然能夠得到PE頭部資料了,那麼我們只需要掃描這段空間並得到匹配到的資料即可,其實很容易實現,如下程式碼所示。
// 署名
// PowerBy: LyShark
// Email: [email protected]
#include "lyshark.h"
// 定義全域性變數
static PVOID g_KernelBase = 0;
static ULONG g_KernelSize = 0;
// 得到KernelBase基地址
// lyshark.com
PVOID LySharkToolsUtilKernelBase(OUT PULONG pSize)
{
NTSTATUS status = STATUS_SUCCESS;
ULONG bytes = 0;
PRTL_PROCESS_MODULES pMods = 0;
PVOID checkPtr = 0;
UNICODE_STRING routineName;
if (g_KernelBase != 0)
{
if (pSize)
{
*pSize = g_KernelSize;
}
return g_KernelBase;
}
RtlInitUnicodeString(&routineName, L"NtOpenFile");
checkPtr = MmGetSystemRoutineAddress(&routineName);
if (checkPtr == 0)
return 0;
__try
{
status = ZwQuerySystemInformation(SystemModuleInformation, 0, bytes, &bytes);
if (bytes == 0)
{
return 0;
}
pMods = (PRTL_PROCESS_MODULES)ExAllocatePoolWithTag(NonPagedPoolNx, bytes, L"LyShark");
RtlZeroMemory(pMods, bytes);
status = ZwQuerySystemInformation(SystemModuleInformation, pMods, bytes, &bytes);
if (NT_SUCCESS(status))
{
PRTL_PROCESS_MODULE_INFORMATION pMod = pMods->Modules;
for (ULONG i = 0; i < pMods->NumberOfModules; i++)
{
if (checkPtr >= pMod[i].ImageBase && checkPtr < (PVOID)((PUCHAR)pMod[i].ImageBase + pMod[i].ImageSize))
{
g_KernelBase = pMod[i].ImageBase;
g_KernelSize = pMod[i].ImageSize;
if (pSize)
{
*pSize = g_KernelSize;
}
break;
}
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return 0;
}
if (pMods)
{
ExFreePoolWithTag(pMods, L"LyShark");
}
DbgPrint("KernelBase = > %p \n", g_KernelBase);
return g_KernelBase;
}
// 對指定記憶體執行特徵碼掃描
NTSTATUS UtilLySharkSearchPattern(IN PUCHAR pattern, IN UCHAR wildcard, IN ULONG_PTR len, IN const VOID* base, IN ULONG_PTR size, OUT PVOID* ppFound)
{
NT_ASSERT(ppFound != 0 && pattern != 0 && base != 0);
if (ppFound == 0 || pattern == 0 || base == 0)
{
return STATUS_INVALID_PARAMETER;
}
__try
{
for (ULONG_PTR i = 0; i < size - len; i++)
{
BOOLEAN found = TRUE;
for (ULONG_PTR j = 0; j < len; j++)
{
if (pattern[j] != wildcard && pattern[j] != ((PUCHAR)base)[i + j])
{
found = FALSE;
break;
}
}
if (found != FALSE)
{
*ppFound = (PUCHAR)base + i;
DbgPrint("[LyShark] 特徵碼匹配地址: %p \n", (PUCHAR)base + i);
return STATUS_SUCCESS;
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return STATUS_UNHANDLED_EXCEPTION;
}
return STATUS_NOT_FOUND;
}
// 掃描程式碼段中的指令片段
NTSTATUS ByLySharkComUtilScanSection(IN PCCHAR section, IN PUCHAR pattern, IN UCHAR wildcard, IN ULONG_PTR len, OUT PVOID* ppFound)
{
NT_ASSERT(ppFound != 0);
if (ppFound == 0)
return STATUS_INVALID_PARAMETER;
// 獲取核心第一個模組的基地址
PVOID base = LySharkToolsUtilKernelBase(0);
if (!base)
return STATUS_NOT_FOUND;
// 得到NT頭部PE32+結構
PIMAGE_NT_HEADERS64 pHdr = RtlImageNtHeader(base);
if (!pHdr)
return STATUS_INVALID_IMAGE_FORMAT;
// 首先尋找程式碼段
PIMAGE_SECTION_HEADER pFirstSection = (PIMAGE_SECTION_HEADER)(pHdr + 1);
for (PIMAGE_SECTION_HEADER pSection = pFirstSection; pSection < pFirstSection + pHdr->FileHeader.NumberOfSections; pSection++)
{
ANSI_STRING LySharkSection, LySharkText;
RtlInitAnsiString(&LySharkSection, section);
RtlInitAnsiString(&LySharkText, (PCCHAR)pSection->Name);
// 判斷是不是我們要找的.text節
if (RtlCompareString(&LySharkSection, &LySharkText, TRUE) == 0)
{
// 如果是則開始匹配特徵碼
return UtilLySharkSearchPattern(pattern, wildcard, len, (PUCHAR)base + pSection->VirtualAddress, pSection->Misc.VirtualSize, ppFound);
}
}
return STATUS_NOT_FOUND;
}
VOID UnDriver(PDRIVER_OBJECT driver)
{
DbgPrint(("Uninstall Driver Is OK \n"));
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
DbgPrint("hello lyshark.com \n");
PMiProcessLoaderEntry m_MiProcessLoaderEntry = NULL;
RTL_OSVERSIONINFOW Version = { 0 };
Version.dwOSVersionInfoSize = sizeof(Version);
RtlGetVersion(&Version);
//獲取核心版本號
DbgPrint("主版本: %d -->次版本: %d --> 編譯版本: %d", Version.dwMajorVersion, Version.dwMinorVersion, Version.dwBuildNumber);
if (Version.dwMajorVersion == 10)
{
// 如果是 win10 18363 則匹配特徵
if (Version.dwBuildNumber == 18363)
{
CHAR pattern[] = "\x48\x89\x5c\x24\x08";
int pattern_size = sizeof(pattern) - 1;
ByLySharkComUtilScanSection(".text", (PUCHAR)pattern, 0xCC, pattern_size, (PVOID *)&m_MiProcessLoaderEntry);
DbgPrint("[LyShark] 輸出首地址: %p", m_MiProcessLoaderEntry);
}
}
Driver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}
程式碼中首先判斷系統主版本windows 10 18363
如果是則執行匹配,只匹配.text
也就是程式碼段中的資料,當遇到0xcc
時則取消繼續,否則繼續執行列舉,程式輸出效果如下所示。
在WinDBG中輸入命令!dh 0xfffff8007f600000
解析出核心PE頭資料,可以看到如下所示,對比無誤。