#include <ntifs.h>
#include <ntddk.h>
NTKERNELAPI UCHAR * PsGetProcessImageFileName(__in PEPROCESS Process);
#pragma pack(1)
typedef struct _SystemServiceEntry
{
ULONG *ServiceTableBase;
ULONG *ServiceCounterTableBase;
ULONG NumberOfServices;
ULONG *ParamTableBase;
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
#pragma pack()
extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;
#define GetServiceIndex(_Function) (*(PULONG)((PUCHAR)_Function+1))
#define HOOK_SSDT(_Function, _Hook,_MappedSSDTBase)\
InterlockedExchange ((PLONG)&_MappedSSDTBase [GetServiceIndex(_Function)], (LONG)_Hook)
#define UNHOOK_SSDT(_Function, _Orig, _MappedSSDTBase)\
InterlockedExchange((PLONG) &_MappedSSDTBase[GetServiceIndex(_Function)], (LONG)_Orig)
NTSTATUS MyOpenProcess(OUT PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId);
typedef NTSTATUS(*_NtOpenProcess)(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId);
_NtOpenProcess Old_ZwOpenProcess;
//获取进程ProcesId
ULONG GetProcesId(char* pProcessName);
NTSTATUS Hook_SSDT_MDL(ULONG_PTR HookFunAddr, ULONG_PTR NewFunAddr, PULONG_PTR pOldFunAddr);
NTSTATUS Resume_SSDT_MDL(ULONG_PTR src, ULONG_PTR OldFunAdd);
ULONG g_pid;
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
Resume_SSDT_MDL(ZwOpenProcess, Old_ZwOpenProcess);
return;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
DriverObject->DriverUnload = DriverUnload;
//请先运行notepad.exe在加载驱动 explorer.exe
g_pid = GetProcesId("explorer.exe");
if (g_pid == 0)g_pid = 1234;
Hook_SSDT_MDL(ZwOpenProcess, MyOpenProcess, &Old_ZwOpenProcess);
return STATUS_SUCCESS;
}
NTSTATUS MyOpenProcess(OUT PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId)
{
NTSTATUS Status = STATUS_SUCCESS;
if (ClientId->UniqueProcess == (HANDLE)g_pid)
{
ProcessHandle = NULL;
return STATUS_ACCESS_DENIED;
}
return Old_ZwOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
}
NTSTATUS Hook_SSDT_MDL(ULONG_PTR HookFunAddr, ULONG_PTR NewFunAddr, PULONG_PTR pOldFunAddr)
{
//定义变量
PMDL pMdlSSDT = NULL; // 用来创建原始的 SSDT 地址, 映射到我们的域中, 来达到解除页面保护
PVOID *MappedSSDTBase = 0; // 存放解除页面保护后指向的 SSDT 首地址的指针
//参数效验
if (KeServiceDescriptorTable == NULL || pOldFunAddr == NULL || HookFunAddr == NULL || NewFunAddr == NULL)return STATUS_UNSUCCESSFUL;
//调用 MmCreateMdl 创建一个映射 SSDT 的 MDL 结构的虚拟内存空间
pMdlSSDT = MmCreateMdl(NULL, KeServiceDescriptorTable->ServiceTableBase, KeServiceDescriptorTable->NumberOfServices * 4);
if (pMdlSSDT == NULL)return STATUS_UNSUCCESSFUL;
MmBuildMdlForNonPagedPool(pMdlSSDT);
//改变 MDL 的标记来实现可读写
pMdlSSDT->MdlFlags = pMdlSSDT->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
//锁定此 MDL 的虚拟内存空间, 以防止其他进程来访问, 并返回指向此 MDL 首地址的指针
MappedSSDTBase = (PVOID *)MmMapLockedPages(pMdlSSDT, KernelMode);
//检测返回首地址的指针是否成功, 成功便对 SSDT 进行 Hook
if (MappedSSDTBase == 0)return STATUS_UNSUCCESSFUL;
//HOOK
*pOldFunAddr = KeServiceDescriptorTable->ServiceTableBase[GetServiceIndex(HookFunAddr)];
HOOK_SSDT(HookFunAddr, NewFunAddr, MappedSSDTBase);
// 对 MDL 分配的内存空间进行释放
if (pMdlSSDT != NULL)
{
MmUnmapLockedPages(MappedSSDTBase, pMdlSSDT);
IoFreeMdl(pMdlSSDT);
}
return STATUS_SUCCESS;
}
// 用于解除 SSDT 的页面保护. 并恢复 被 Hook 的 SSDT
NTSTATUS Resume_SSDT_MDL(ULONG_PTR src, ULONG_PTR OldFunAdd)
{
PMDL pMdlSSDT = NULL; // 用来创建原始的 SSDT 地址, 映射到我们的域中, 来达到解除页面保护
PVOID *MappedSSDTBase = 0; // 存放解除页面保护后指向的 SSDT 首地址的指针
//参数效验
if (KeServiceDescriptorTable == NULL || src == NULL || OldFunAdd == NULL)return STATUS_UNSUCCESSFUL;
//调用 MmCreateMdl 创建一个映射 SSDT 的 MDL 结构的虚拟内存空间
pMdlSSDT = MmCreateMdl(NULL, KeServiceDescriptorTable->ServiceTableBase, KeServiceDescriptorTable->NumberOfServices * 4);
if (pMdlSSDT == NULL)return STATUS_UNSUCCESSFUL;
//将上面创建的 MDL 分配在非分页内存中, 因为 SSDT 在非分页内存中
MmBuildMdlForNonPagedPool(pMdlSSDT);
//改变 MDL 的标记来实现可读写
pMdlSSDT->MdlFlags = pMdlSSDT->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
//锁定此 MDL 的虚拟内存空间, 以防止其他进程来访问, 并返回指向此 MDL 首地址的指针
MappedSSDTBase = (PVOID *)MmMapLockedPages(pMdlSSDT, KernelMode);
if (MappedSSDTBase == NULL)
{
IoFreeMdl(pMdlSSDT);
return STATUS_UNSUCCESSFUL;
}
UNHOOK_SSDT(src, OldFunAdd, MappedSSDTBase);
// 对 MDL 分配的内存空间进行释放
if (pMdlSSDT != NULL)
{
MmUnmapLockedPages(MappedSSDTBase, pMdlSSDT);
IoFreeMdl(pMdlSSDT);
}
return STATUS_SUCCESS;
}
//获取进程ProcesId
ULONG GetProcesId(char* pProcessName)
{
//参数效验
if (pProcessName == NULL)return NULL;
if (MmIsAddressValid(pProcessName) == FALSE)return NULL;
//定义变量
PEPROCESS pEprocess = NULL;
NTSTATUS ntstatus = STATUS_SUCCESS;
UCHAR *szProcessName = NULL;
for (int i = 4; i < 10000; i = i + 4) //一般来说没有超过100000的PID和TID
{
//进程ID和返回一个引用指针的过程EPROCESS结构
ntstatus = PsLookupProcessByProcessId((HANDLE)i, &pEprocess);
if (NT_SUCCESS(ntstatus))//STATUS_INVALID_CID
{
ObfDereferenceObject(pEprocess);
if (pEprocess != NULL)
{
//比较进程名
szProcessName = PsGetProcessImageFileName(pEprocess);
if (szProcessName)
{
if (_stricmp((char*)szProcessName, pProcessName) == 0)
{
return (HANDLE)i;
}
}
}
}
}
return NULL;
}
SSDT HOOK
最新推荐文章于 2024-04-17 11:45:00 发布