//基于SSDT Hook
//Hook ZwTerminateProcess对传入的进程进行检查,如果匹配,则返回拒绝访问
#include <ntddk.h>
#include <windef.h>
#include "SSDTHook.h"
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemBasicInformation,
SystemProcessorInformation,
SystemPerformanceInformation,
SystemTimeOfDayInformation,
SystemPathInformation,
SystemProcessInformation,
SystemCallCountInformation,
SystemDeviceInformation,
SystemProcessorPerformanceInformation,
SystemFlagsInformation,
SystemCallTimeInformation,
SystemModuleInformation,
SystemLocksInformation,
SystemStackTraceInformation,
SystemPagedPoolInformation,
SystemNonPagedPoolInformation,
SystemHandleInformation,
SystemObjectInformation,
SystemPageFileInformation,
SystemVdmInstemulInformation,
SystemVdmBopInformation,
SystemFileCacheInformation,
SystemPoolTagInformation,
SystemInterruptInformation,
SystemDpcBehaviorInformation,
SystemFullMemoryInformation,
SystemLoadGdiDriverInformation,
SystemUnloadGdiDriverInformation,
SystemTimeAdjustmentInformation,
SystemSummaryMemoryInformation,
SystemNextEventIdInformation,
SystemEventIdsInformation,
SystemCrashDumpInformation,
SystemExceptionInformation,
SystemCrashDumpStateInformation,
SystemKernelDebuggerInformation,
SystemContextSwitchInformation,
SystemRegistryQuotaInformation,
SystemExtendServiceTableInformation,
SystemPrioritySeperation,
SystemPlugPlayBusInformation,
SystemDockInformation,
//SystemPowerInformation,
SystemProcessorSpeedInformation,
SystemCurrentTimeZoneInformation,
SystemLookasideInformation
} SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS;
typedef struct _SYSTEM_THREAD {
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
LONG BasePriority;
ULONG ContextSwitchCount;
ULONG State;
KWAIT_REASON WaitReason;
} SYSTEM_THREAD, *PSYSTEM_THREAD;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER SpareLi1;
LARGE_INTEGER SpareLi2;
LARGE_INTEGER SpareLi3;
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG_PTR PageDirectoryBase;
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
UCHAR * PsGetProcessImageFileName(__in PEPROCESS Process);
NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(
__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
__out_bcount_opt(SystemInformationLength) PVOID SystemInformation,
__in ULONG SystemInformationLength,
__out_opt PULONG ReturnLength
);
NTSTATUS HookNtQuerySystemInformation(
__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
__out_bcount_opt(SystemInformationLength) PVOID SystemInformation,
__in ULONG SystemInformationLength,
__out_opt PULONG ReturnLength
);
typedef NTSTATUS(*NTQUERYSYSTEMINFORMATION)(
__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
__out_bcount_opt(SystemInformationLength) PVOID SystemInformation,
__in ULONG SystemInformationLength,
__out_opt PULONG ReturnLength
);
typedef NTSTATUS(*NTTERMINATEPROCESS)(
__in_opt HANDLE ProcessHandle,
__in NTSTATUS ExitStatus
);
NTSTATUS HookNtTerminateProcess(
__in_opt HANDLE ProcessHandle,
__in NTSTATUS ExitStatus
);
NTTERMINATEPROCESS pOldNtTerminateProcess=NULL;
BOOLEAN NPUnicodeStringToChar(PUNICODE_STRING UniName, char Name[])
{
ANSI_STRING AnsiName;
NTSTATUS ntstatus;
char* nameptr;
__try {
ntstatus = RtlUnicodeStringToAnsiString(&AnsiName, UniName, TRUE);
if (AnsiName.Length < 260) {
nameptr = (PCHAR)AnsiName.Buffer;
//strcpy(Name, _strupr(nameptr)); //将字符串转换成大写形式
strcpy(Name, nameptr);//
}
RtlFreeAnsiString(&AnsiName);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
DbgPrint("NPUnicodeStringToChar EXCEPTION_EXECUTE_HANDLER\n");
return FALSE;
}
return TRUE;
}
NTSTATUS Unload(PDRIVER_OBJECT driver)
{
DbgPrint("unloaded!");
UnInstallSysServiceHook((ULONG)ZwQuerySystemInformation);
UnInstallSysServiceHook((ULONG)ZwTerminateProcess);
return STATUS_SUCCESS;
}
NTSTATUS HookNtTerminateProcess(
__in_opt HANDLE ProcessHandle,
__in NTSTATUS ExitStatus
)
{
ULONG uPID;
NTSTATUS rtStatus;
PCHAR pStrProcName;
PEPROCESS pEProcess;
ANSI_STRING strProcName;
//通过进程句柄来获得该进程所对应的 FileObject 对象,由于这里是进程对象,自然获得的是 EPROCESS 对象
rtStatus = ObReferenceObjectByHandle(ProcessHandle,FILE_READ_DATA, NULL, KernelMode, &pEProcess, NULL);
if (!NT_SUCCESS(rtStatus))
{
return rtStatus;
}
//保存 SSDT 中原来的 NtTerminateProcess 地址
pOldNtTerminateProcess = (NTTERMINATEPROCESS)oldSysServiceAddr[SYSCALL_INDEX(ZwTerminateProcess)];
//通过该函数可以获取到进程名称和进程 ID,该函数在内核中实质是导出的(在 WRK 中可以看到)
//但是 ntddk.h 中并没有到处,所以需要自己声明才能使用
uPID = (ULONG)PsGetProcessId(pEProcess);
pStrProcName = (PCHAR)PsGetProcessImageFileName(pEProcess);
DbgPrint("TerimateProcess:%s\n", pStrProcName);
//通过进程名来初始化一个 ASCII 字符串
RtlInitAnsiString(&strProcName, pStrProcName);
if (strstr(pStrProcName, "notepad.exe"))//保护notepad.exe进程
{
//如果该进程是所保护的的进程的话,则返回权限不够的异常即可
return STATUS_ACCESS_DENIED;
}
//对于非保护的进程可以直接调用原来 SSDT 中的 NtTerminateProcess 来结束进程
rtStatus = pOldNtTerminateProcess(ProcessHandle, ExitStatus);
return rtStatus;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
DbgPrint("Driver Entry");
BackupSysServicesTable();
driver->DriverUnload = Unload;
InstallSysServiceHook((ULONG)ZwTerminateProcess, (ULONG)HookNtTerminateProcess);
return STATUS_SUCCESS;
}
源代码:https://pan.baidu.com/s/14GY1wwvbpws3nNQy02GIbQ