模块回调
模块回调
1. 模块加载的监控
[!NOTE] Note
模块加载的监控
// 模块加载回调
VOID ImageMonitorRoutine(
PUNICODE_STRING FullImageName,
HANDLE ProcessId,
PIMAGE_INFO ImageInfo
)
{
PEPROCESS dwProcess;
if (ProcessId == 0) // 则是驱动加载
{
PsLookupProcessByProcessId(ProcessId, &dwProcess);
DbgPrint("驱动进程ID: %d, 驱动进程名称: %s, 驱动路径: %wZ\n",
ProcessId, PsGetProcessImageFileName(dwProcess), FullImageName);
}
else
{
PsLookupProcessByProcessId(ProcessId, &dwProcess);
DbgPrint("模块进程ID: %d, 驱动进程名称: %s, 驱动路径: %wZ\n",
ProcessId, PsGetProcessImageFileName(dwProcess), FullImageName);
}
}
// 模块加载的监控
NTSTATUS LgHeaderClass::CreateMoudleMonitor()
{
// 注册加载模块,卸载模块通知函数
NTSTATUS dwStatus = PsSetLoadImageNotifyRoutine(ImageMonitorRoutine);
return dwStatus;
}
// 取消模块加载监控
VOID LgHeaderClass::DeleteMoudleMonitor()
{
// 取消加载模块,卸载模块通知函数
PsRemoveLoadImageNotifyRoutine(ImageMonitorRoutine);
}
然后我们在主函数中调用
LgHeaderClass * dwLg;
EXTERN_C VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
KdPrint(("驱动卸载\r\n"));
//dwLg->DeleteProcessMonitor();
dwLg->DeleteMoudleMonitor();
delete dwLg;
}
EXTERN_C NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING pReg)
{
KdPrint(("驱动加载\r\n"));
NTSTATUS dwStatus = STATUS_SUCCESS;
DriverObject->DriverUnload = DriverUnload;
dwLg = new LgHeaderClass();
//dwStatus = dwLg->CreateProcessMonitor();
dwStatus = dwLg->CreateMoudleMonitor();
return dwStatus;
}
调用成功

2. 模块加载衍生的拦截操作
[!NOTE] Note
模块加载衍生的驱动拦截操作
// 获取进程名称, 因为这个函数导出却未在头文件中声明,所以需要自己定义
PCHAR PsGetProcessImageFileName(IN PEPROCESS Process);
NTSTATUS MmUnmapViewOfSection(IN PEPROCESS Process, PVOID pLoadImageBase);
// 阻止指定驱动加载
BOOLEAN DenyLoadDriver(PVOID pLoadImageBase)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pLoadImageBase;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PCHAR)pDosHeader + pDosHeader->e_lfanew);
// 获取 OEP
PVOID pAddressOfEntryPoint = (PVOID)((PCHAR)pDosHeader + pNtHeader->OptionalHeader.AddressOfEntryPoint);
// 使用 MDL 方式写入
ULONG dwShellCodeSize = 6;
UCHAR pShellCode[6] = {
0xB8, 0x22, 0x00, 0x00, 0xC0, // mov eax, 0xC0000022
0xC3 // ret
};
// 建立与目标地址物理内存的映射
PMDL pMdl = MmCreateMdl(NULL, pAddressOfEntryPoint, dwShellCodeSize);
if (pMdl == NULL)
{
KdPrint(("MmCreateMdl Error!!!"));
return FALSE;
}
// 更新 MDL 对物理内存的描述
MmBuildMdlForNonPagedPool(pMdl);
// 将 MDL 中描述的物理页面映射到虚拟内存中,并返回映射的虚拟内存地址
PVOID pNewAddress = MmMapLockedPages(pMdl, KernelMode);
if (pNewAddress == NULL)
{
IoFreeMdl(pMdl);
return FALSE;
}
// 写入数据
RtlCopyMemory(pNewAddress, pShellCode, dwShellCodeSize);
// 释放 MDL 映射的虚拟内存地址
MmUnmapLockedPages(pNewAddress, pMdl);
IoFreeMdl(pMdl);
return TRUE;
}
// 阻止指定DLL加载
BOOLEAN DenyLoadDll(HANDLE ProcessId, PVOID pLoadImageBase)
{
NTSTATUS dwStatus = STATUS_SUCCESS;
PEPROCESS dwpErocess = NULL;
dwStatus = PsLookupProcessByProcessId(ProcessId, &dwpErocess);
if (!NT_SUCCESS(dwStatus))
{
KdPrint(("PsLookupProcessByProcessId Error:%X\n", dwStatus));
return FALSE;
}
// 卸载模块
dwStatus = MmUnmapViewOfSection(dwpErocess, pLoadImageBase);
if (!NT_SUCCESS(dwStatus))
{
KdPrint(("MmUnmapViewOfSection Error:%X\n", dwStatus));
return FALSE;
}
return TRUE;
}

浙公网安备 33010602011771号