SSDT HOOK

#include <ntifs.h>
#include <ntddk.h>

NTKERNELAPI UCHAR * PsGetProcessImageFileName(__in PEPROCESS Process);


#pragma  pack(1) 
typedef  struct  _SystemServiceEntry 
{
	ULONG  *ServiceTableBase;         
	ULONG  *ServiceCounterTableBase;  
	ULONG  NumberOfServices;          
	ULONG  *ParamTableBase;
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
#pragma   pack()
extern  PKSERVICE_TABLE_DESCRIPTOR  KeServiceDescriptorTable;


#define   GetServiceIndex(_Function) (*(PULONG)((PUCHAR)_Function+1))

#define   HOOK_SSDT(_Function, _Hook,_MappedSSDTBase)\
InterlockedExchange ((PLONG)&_MappedSSDTBase [GetServiceIndex(_Function)], (LONG)_Hook)

#define  UNHOOK_SSDT(_Function, _Orig, _MappedSSDTBase)\
	InterlockedExchange((PLONG) &_MappedSSDTBase[GetServiceIndex(_Function)], (LONG)_Orig)

NTSTATUS  MyOpenProcess(OUT PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId);
typedef  NTSTATUS(*_NtOpenProcess)(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId);
_NtOpenProcess  Old_ZwOpenProcess;

//获取进程ProcesId
ULONG GetProcesId(char* pProcessName);


NTSTATUS  Hook_SSDT_MDL(ULONG_PTR HookFunAddr, ULONG_PTR NewFunAddr, PULONG_PTR pOldFunAddr);
NTSTATUS  Resume_SSDT_MDL(ULONG_PTR src, ULONG_PTR OldFunAdd);
ULONG g_pid;

VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
	Resume_SSDT_MDL(ZwOpenProcess, Old_ZwOpenProcess);
	return;
}




NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{

	DriverObject->DriverUnload = DriverUnload;

	//请先运行notepad.exe在加载驱动  explorer.exe
	g_pid = GetProcesId("explorer.exe");
	if (g_pid == 0)g_pid = 1234;

	Hook_SSDT_MDL(ZwOpenProcess, MyOpenProcess, &Old_ZwOpenProcess);
	return STATUS_SUCCESS;
}


NTSTATUS  MyOpenProcess(OUT PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId)
{
	NTSTATUS  Status = STATUS_SUCCESS;

	if (ClientId->UniqueProcess == (HANDLE)g_pid)
	{
		ProcessHandle = NULL;
		return  STATUS_ACCESS_DENIED;
	}

	return   Old_ZwOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
}


NTSTATUS  Hook_SSDT_MDL(ULONG_PTR HookFunAddr, ULONG_PTR NewFunAddr, PULONG_PTR pOldFunAddr)
{
	//定义变量
	PMDL   pMdlSSDT = NULL;      // 用来创建原始的 SSDT 地址, 映射到我们的域中, 来达到解除页面保护
	PVOID  *MappedSSDTBase = 0;  // 存放解除页面保护后指向的 SSDT 首地址的指针

								 //参数效验
	if (KeServiceDescriptorTable == NULL || pOldFunAddr == NULL || HookFunAddr == NULL || NewFunAddr == NULL)return STATUS_UNSUCCESSFUL;



	//调用 MmCreateMdl 创建一个映射 SSDT 的 MDL 结构的虚拟内存空间
	pMdlSSDT = MmCreateMdl(NULL, KeServiceDescriptorTable->ServiceTableBase, KeServiceDescriptorTable->NumberOfServices * 4);
	if (pMdlSSDT == NULL)return STATUS_UNSUCCESSFUL;
	MmBuildMdlForNonPagedPool(pMdlSSDT);

	//改变 MDL 的标记来实现可读写
	pMdlSSDT->MdlFlags = pMdlSSDT->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;

	//锁定此 MDL 的虚拟内存空间, 以防止其他进程来访问, 并返回指向此 MDL 首地址的指针
	MappedSSDTBase = (PVOID *)MmMapLockedPages(pMdlSSDT, KernelMode);

	//检测返回首地址的指针是否成功, 成功便对 SSDT 进行 Hook
	if (MappedSSDTBase == 0)return STATUS_UNSUCCESSFUL;


	//HOOK
	*pOldFunAddr = KeServiceDescriptorTable->ServiceTableBase[GetServiceIndex(HookFunAddr)];
	HOOK_SSDT(HookFunAddr, NewFunAddr, MappedSSDTBase);

	// 对 MDL 分配的内存空间进行释放
	if (pMdlSSDT != NULL)
	{
		MmUnmapLockedPages(MappedSSDTBase, pMdlSSDT);
		IoFreeMdl(pMdlSSDT);
	}

	return STATUS_SUCCESS;

}


// 用于解除 SSDT 的页面保护. 并恢复 被 Hook 的 SSDT
NTSTATUS  Resume_SSDT_MDL(ULONG_PTR src, ULONG_PTR OldFunAdd)
{

	PMDL   pMdlSSDT = NULL;      // 用来创建原始的 SSDT 地址, 映射到我们的域中, 来达到解除页面保护
	PVOID  *MappedSSDTBase = 0;  // 存放解除页面保护后指向的 SSDT 首地址的指针

								 //参数效验
	if (KeServiceDescriptorTable == NULL || src == NULL || OldFunAdd == NULL)return STATUS_UNSUCCESSFUL;

	//调用 MmCreateMdl 创建一个映射 SSDT 的 MDL 结构的虚拟内存空间
	pMdlSSDT = MmCreateMdl(NULL, KeServiceDescriptorTable->ServiceTableBase, KeServiceDescriptorTable->NumberOfServices * 4);
	if (pMdlSSDT == NULL)return STATUS_UNSUCCESSFUL;

	//将上面创建的 MDL 分配在非分页内存中, 因为 SSDT 在非分页内存中
	MmBuildMdlForNonPagedPool(pMdlSSDT);

	//改变 MDL 的标记来实现可读写
	pMdlSSDT->MdlFlags = pMdlSSDT->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;


	//锁定此 MDL 的虚拟内存空间, 以防止其他进程来访问, 并返回指向此 MDL 首地址的指针
	MappedSSDTBase = (PVOID *)MmMapLockedPages(pMdlSSDT, KernelMode);
	if (MappedSSDTBase == NULL)
	{
		IoFreeMdl(pMdlSSDT);
		return STATUS_UNSUCCESSFUL;
	}

	UNHOOK_SSDT(src, OldFunAdd, MappedSSDTBase);

	// 对 MDL 分配的内存空间进行释放
	if (pMdlSSDT != NULL)
	{
		MmUnmapLockedPages(MappedSSDTBase, pMdlSSDT);
		IoFreeMdl(pMdlSSDT);
	}

	return STATUS_SUCCESS;
}

//获取进程ProcesId
ULONG GetProcesId(char* pProcessName)
{
	//参数效验
	if (pProcessName == NULL)return NULL;
	if (MmIsAddressValid(pProcessName) == FALSE)return NULL;


	//定义变量
	PEPROCESS pEprocess = NULL;
	NTSTATUS ntstatus = STATUS_SUCCESS;
	UCHAR *szProcessName = NULL;

	for (int i = 4; i < 10000; i = i + 4) //一般来说没有超过100000的PID和TID
	{
		//进程ID和返回一个引用指针的过程EPROCESS结构
		ntstatus = PsLookupProcessByProcessId((HANDLE)i, &pEprocess);
		if (NT_SUCCESS(ntstatus))//STATUS_INVALID_CID
		{
			ObfDereferenceObject(pEprocess);
			if (pEprocess != NULL)
			{
				//比较进程名
				szProcessName = PsGetProcessImageFileName(pEprocess);
				if (szProcessName)
				{
					if (_stricmp((char*)szProcessName, pProcessName) == 0)
					{
						return (HANDLE)i;
					}
				}
			}
		}
	}

	return NULL;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值