#include <ntddk.h>
#define TERMINATEPROCESSINDEX 0x101 //系统服务号TerminateProcess函数
#define NAME "notepad.exe"
typedef struct _ServicedescriptorTable {
PVOID ServiceTableBase;
PVOID ServiceCouterTable;
DWORD32 NumberOfServices;
PVOID ParamTableBase;
}KServicedescriptorTable,PKServicedescriptorTable;
typedef struct _SERVICE_DESCRIPTOR_TABLE{
KServicedescriptorTable ntoskrnel; //ntoskrnl.exe的服务函数 (Kernel32.dll)
KServicedescriptorTable win32k; //win32k.sys的服务函数,(gdi.dll/user.dll的内核支持)
KServicedescriptorTable NotUsed1;
KServicedescriptorTable NotUsed2;
}KSERVICE_TABLE_DESCRIPTOR, PKSERVICE_TABLE_DESCRIPTOR;
typedef NTSTATUS(NTAPI ZWTerminateProcess)(HANDLE ProcessHandle,NTSTATUS ExitStatus);
NTSTATUS NTAPI MyTerminateProcess( HANDLE ProcessHandle, NTSTATUS ExitStatus); //钩子函数申明
extern POBJECT_TYPE PsProcessType;
extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;
ZWTerminateProcess NewTerminateProcess = MyTerminateProcess; //钩子函数地址
ZWTerminateProcess OldTerminateProcess =NULL; //原函数地址
NTKERNELAPI UCHAR *PsGetProcessImageFileName(PEPROCESS Process);
/关闭进程的时候这个NtTerminateProcess函数貌似会被执行二次或多次/
NTSTATUS NTAPI MyTerminateProcess( HANDLE ProcessHandle, NTSTATUS ExitStatus) { //第一个是要终止进程的句柄
NTSTATUS status = STATUS_SUCCESS;
PEPROCESS process = { 0 };
UCHAR ProcessName = NULL;
UCHAR ProcessName1 = NULL;
status=ObReferenceObjectByHandle(ProcessHandle, 0, *PsProcessType, KernelMode, &process, NULL);
if ( !NT_SUCCESS(status)) {
DbgPrint("第一次执行!\n");
return status;
}
ProcessName = (UCHAR*)((DWORD32)process + 0x174); //如果关闭的是我们保护的进程
ProcessName1 = PsGetProcessImageFileName(process);
if (!_stricmp(PsGetProcessImageFileName(process), NAME) || !_stricmp(PsGetProcessImageFileName(process), "calc.exe")){
//执行这个里了就卡死
return STATUS_ACCESS_DENIED;
}
DbgPrint("ProceeName %s\n", ProcessName);
return OldTerminateProcess(ProcessHandle, ExitStatus);
}
VOID RestPageAttr() {
asm {
mov eax, cr0
and eax, 0xFFFEFFFF
mov cr0, eax
sti
}
}
VOID SetPageAttr() {
asm {
cli
mov eax, cr0
or eax,0x10000
mov cr0,eax
}
}
NTSTATUS HookTerminateProcess() {
/这样的不能重复加载,否在第二次HOOK OldTerminateProcess保存的是第一个hook的自己函数的地址直接蓝屏 应为我们写入内核中的数据不会自动删除/
DWORD32 Index=(DWORD32)(KeServiceDescriptorTable->ntoskrnel.ServiceTableBase)+ TERMINATEPROCESSINDEX4; //ZwTerminateProcess 在SSDT中的位置
DbgPrint("Address1=%p\n", Index);
OldTerminateProcess = (ZWTerminateProcess)((DWORD32)Index); //获取原函数地址
DbgPrint("Address2=%p\n", OldTerminateProcess);
(DWORD32)Index = (DWORD32)MyTerminateProcess;
DbgPrint("MyTerminateProcess=%p\n", MyTerminateProcess);
DbgPrint("HOOK Yes!\n");
return STATUS_SUCCESS;
}
NTSTATUS UnloadkTerminateProcessHook() {
DWORD32 Index = (DWORD32)(KeServiceDescriptorTable->ntoskrnel.ServiceTableBase) + TERMINATEPROCESSINDEX 4;
(DWORD32)Index = (DWORD32)OldTerminateProcess;
return STATUS_SUCCESS;
}
NTSTATUS DriverUnload(PDRIVER_OBJECT Pobject) {
/如果卸载之前没有还原直接Over 挂了我好几个小时/
SetPageAttr();
UnloadkTerminateProcessHook();
RestPageAttr();
DbgPrint("Unload Hook Yes!\n"); //卸载之前一定要换还原
DbgPrint("驱动卸载成功!\n"); //卸载之前一定要换还原
return STATUS_SUCCESS;
}
NTSTATUS DirverEntry(PDRIVER_OBJECT Pobject, PUNICODE_STRING RegPath) {
DbgPrint("驱动加载成功!\n");
DbgPrint("PKServicedescriptorTable=%p\n", KeServiceDescriptorTable->ntoskrnel.ServiceTableBase);
SetPageAttr();
HookTerminateProcess();
RestPageAttr();
Pobject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
关闭其他进程打印的信息都没得任何问题,找了一下午不知道为啥卡死,而不蓝屏求教
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课