#include "SSDTHook32.h"
PVOID __ServiceTableBase = NULL;
ULONG32 __NtOpenProcessIndex = 0;
PVOID __OldNtOpenProcess = NULL;
BOOLEAN __IsHook = FALSE;
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
{
NTSTATUS Status = STATUS_SUCCESS;
ULONG32 v1 = 0;
char FunctionName[] = "NtOpenProcess"; //要钩的函数名
DriverObject->DriverUnload = Unload;
__NtOpenProcessIndex = 0x0be;
/*
ntdll!ZwOpenProcess:
77585dc8 b8be000000 mov eax,0BEh
77585dcd ba0003fe7f mov edx,offset SharedUserData!SystemCallStub (7ffe0300)
77585dd2 ff12 call dword ptr [edx]
77585dd4 c21000 ret 10h
77585dd7 90 nop
*/
//这里我们得知函数索引为0be
//并且直接得到了SSDT地址即 extern PSERVER_SERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
if (KeServiceDescriptorTable == NULL)
{
return Status;
}
//base首地址 SSDT第一成员
__ServiceTableBase = ((PSERVER_SERVICE_DESCRIPTOR_TABLE)KeServiceDescriptorTable)->Unknow0;
//需要的函数(直接地址)
__OldNtOpenProcess = ((PULONG32)__ServiceTableBase)[__NtOpenProcessIndex];
//直接更改函数地址
HookSSDT(__ServiceTableBase, __NtOpenProcessIndex, FakeOpenProcess);
return Status;
}
VOID HookSSDT(PVOID ServiceTableBase, ULONG32 SSDTFunctionIndex, PVOID FakeFunctionAddress)
{
ULONG32 v1 = 0;
WPOFF();
((PULONG32)__ServiceTableBase)[__NtOpenProcessIndex] = FakeFunctionAddress;
WPON();
__IsHook = TRUE;
}
VOID UnHookSSDT()
{
WPOFF();
((PULONG32)__ServiceTableBase)[__NtOpenProcessIndex] = __OldNtOpenProcess;
WPON();
}
VOID WPOFF()
{
_disable();
__writecr0(__readcr0() & (~(0x10000)));
}
VOID WPON()
{
__writecr0(__readcr0() ^ 0x10000);
_enable();
}
VOID Unload(PDRIVER_OBJECT DriverObject)
{
DbgPrint("ByeByeDriver\r\n");
if (__IsHook)
{
UnHookSSDT();
__IsHook = FALSE;
}
}
NTSTATUS FakeOpenProcess(
_Out_ PHANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_opt_ PCLIENT_ID ClientID)
{
PEPROCESS EProcess = PsGetCurrentProcess(); //进程上下背景文
if (EProcess != NULL&&MmIsAddressValid(EProcess))
{
//通过EProcess 获得进程名称
char *ProcessImageName = PsGetProcessImageFileName(EProcess); //0x2e0
if (strstr(ProcessImageName, "EnumProcess") != 0)
{
return STATUS_ACCESS_DENIED; //黑名单
}
}
((pfnNtOpenProcess)__OldNtOpenProcess)(ProcessHandle, DesiredAccess, ObjectAttributes, ClientID); //白名单
}
//以上为代码实现
运行环境为win7(32)
#pragma once
#include <ntddk.h>
typedef struct _SERVER_SERVICE_DESCRIPTOR_TABLE_
{
PVOID Unknow0;
PVOID Unknow1;
PVOID Unknow2;
PVOID Unknow3;
}SERVER_SERVICE_DESCRIPTOR_TABLE, *PSERVER_SERVICE_DESCRIPTOR_TABLE;
VOID Unload(PDRIVER_OBJECT DriverObject);
VOID HookSSDT(PVOID ServiceTableBase, ULONG32 SSDTFunctionIndex, PVOID FakeFunctionAddress);
VOID UnHookSSDT();
VOID WPOFF();
VOID WPON();
NTSTATUS FakeOpenProcess(
_Out_ PHANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_opt_ PCLIENT_ID ClientID);
extern PSERVER_SERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
extern
char* PsGetProcessImageFileName(PEPROCESS EProcess);
typedef
NTSTATUS(*pfnNtOpenProcess)(
_Out_ PHANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_opt_ PCLIENT_ID ClientID);
//以上为SSDTHook32.h的头文件
//其实原理非常简单 就是获取SSDT地址 然后更改目标函数地址(因为32位下SSDT存入的是函数的直接地址)
//获取SSDT方法在代码批注里有所说明
//如何得到目标函数的索引 可以从Ntdll中查找相关函数的调用 具体可以通过调试得到
//此例函数索引中为windbg7(32)中得到的