#include <ntddk.h>
//定义数据内存空间段
#define PAGECODE code_seg("PAGE")//可以用于虚拟内存
#define INITCODE code_seg("INIT")//代码运行在这块内存上,运行一次就释放
typedef struct _ServiceDescriptorTable {
PVOID ServiceTableBase; //System Service Dispatch Table 的基地址
PVOID ServiceCounterTable;
//包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。
unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。
PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表
}*PServiceDescriptorTable;
extern PServiceDescriptorTable KeServiceDescriptorTable;
VOID WPOFF()
{
__asm
{
cli
mov eax, cr0
and eax, not 10000h
mov cr0, eax
}
}
VOID WPON()
{
__asm
{
mov eax, cr0
or eax, 10000h
mov cr0, eax
sti
}
}
typedef NTSTATUS (__stdcall *ZWOPENPROCESS)(OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId
);
ZWOPENPROCESS RealZwOpenProcess;//声明了一个函数指针
NTSTATUS NewZwOPENPROCESS(OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId
)
{
return RealZwOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
}
VOID Cr0SSDTHook()
{
//保存原始地址
//(int*)KeServiceDescriptorTable->ServiceTableBase) 得到base地址
//+122*4相当于得到某个函数的变量地址
int addr = (int)(((int*)KeServiceDescriptorTable->ServiceTableBase) + 122);
DbgPrint("原始地址:%x\r\n",(*((int*)addr)));
DbgPrint("原始地址:%x\r\n",*(((int*)KeServiceDescriptorTable->ServiceTableBase)+122));
//把他转换成指针,然后在用*访问
//保存下原来的函数
RealZwOpenProcess = (ZWOPENPROCESS)(*((int*)addr));//原始函数地址
//关闭页面保护
WPOFF();
//在替换成我们的函数
*((int*)addr) = (int)NewZwOPENPROCESS;
DbgPrint("现在地址:%x\r\n",(*((int*)addr)));
//开启页面保护
WPON();
}
#pragma PAGECODE
VOID DriverUnLoad(IN PDRIVER_OBJECT DriverObject)
{
int addr;
DbgPrint("卸载成功");
addr = (int)(((int*)KeServiceDescriptorTable->ServiceTableBase) + 122);
//关闭页面保护
WPOFF();
*((int*)addr) = (int)RealZwOpenProcess;
//开启页面保护
WPON();
}
#pragma INITCODE
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING regStr)
{
DbgPrint("加载成功");
//添加卸载函数
pDriverObject->DriverUnload=DriverUnLoad;
//下面进行NTOPENPROCESS的HOOK,也就是说修改表
Cr0SSDTHook();//进行HOOK
return (1);
}