x86下以ntopenprocess为例的SSDTHook

#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)中得到的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值