驱动开发:内核特征码扫描PE代码段( 三 )

运行这段驱动程序,你会得到当前内核的所有PE节信息,枚举效果如下所示 。

驱动开发:内核特征码扫描PE代码段

文章插图
既然能够得到PE头部数据了,那么我们只需要扫描这段空间并得到匹配到的数据即可 , 其实很容易实现,如下代码所示 。
// 署名// PowerBy: LyShark// Email: me@lyshark.com#include "lyshark.h"// 定义全局变量static PVOID g_KernelBase = 0;static ULONG g_KernelSize = 0;// 得到KernelBase基地址// lyshark.comPVOID 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;}

推荐阅读