//基於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