HOOK SSDT NtOpenProcess 保护进程

原创 2013年12月03日 11:31:32

感谢众大神分享的技术,因为几乎没直接用别人的源码,所以就标题原创

但是因为这个技术肯定是前辈们搞出来的,所以就特意说明下,此乃转载耶

模板用的张帆大牛的

记录一下,以后备用

有些许疑惑,不过都解决了:http://blog.csdn.net/u012410612/article/details/17096597

//本来只是测试MmGetSystemRoutineAddresss函数的,然后发现直接用函数名就可以得到这个地址
//然后就像SSDT HOOK简单测试一下函数地址,
//然后HOOK之后就想简单的实现进程保护
//就这样越多了

#ifdef _cplusplus
extern "C"
{
#endif
#include <ntddk.h>
#ifdef _cplusplus
}
#endif

//定义代码段分页标志
#define PAGEDCODE	code_seg("PAGE")
#define LOCKEDCODE	code_seg()
#define INITCODE	code_seg("INIT")

//定义数据段分页标志
#define PAGEDDATA	code_seg("PAGE")
#define LOCKEDDATA	code_seg()
#define INITDATA	code_seg("INIT")

//定义求数组个数的宏定义
#define arraysize(p)	(sizeof(p) / sizeof((p)[0]))

//定义设备扩展
typedef struct _DEVICE_EXTENSION{
	PDEVICE_OBJECT pDevice;
	UNICODE_STRING ustrDeviceName;		//设备名称
	UNICODE_STRING ustrSymLinkName;		//符号链接名
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;

//函数声明//
//初始化时创建设备和符号
NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject);
//驱动卸载例程
VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject);
//驱动默认分派例程
NTSTATUS DispatchRoutine(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp);

typedef NTSTATUS ( *pfnNtOpenProcess)(
			PHANDLE,
			ACCESS_MASK,
			POBJECT_ATTRIBUTES,
			PCLIENT_ID);
pfnNtOpenProcess OldNtOpenProcess;

NTSTATUS MyNtOpenProcess(
			OUT PHANDLE ProcessHandle,
			IN ACCESS_MASK DesireAccess,
			IN POBJECT_ATTRIBUTES ObjectAttributes,
			PCLIENT_ID ClientID);
			
typedef struct _SERVICE_DESCRIPTOR_TABLE {
	PVOID 	ServiceTableBase;//System Service Dispatch Table 的基地址
	PVOID 	ServiceCounterTableBase;//包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新
	ULONG	NumberOfServices;//由 ServiceTableBase 描述的服务的数目
	PUCHAR	ParamTableBase;//包含每个系统服务参数字节数表的基地址-系统服务参数表
}SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;

extern "C"{
__declspec(dllimport) SERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
}


//看了下调用MmGetSystemRoutineAddress查看函数地址
//顺便SSDT HOOK NtOpenProcess
//注释全是测试用
//貌似标准做法是在DriverEntry中int 3
//然后再下断点双机调试
//以后不能用这个打印查看了。。。说不定一下就看见蓝精灵了

#include "Driver.h"

NTSTATUS MyNtOpenProcess(
			OUT PHANDLE ProcessHandle,
			IN ACCESS_MASK DesireAccess,
			IN POBJECT_ATTRIBUTES ObjectAttributes,
			PCLIENT_ID ClientID)
{
	//在这了实现进程保护的吧, 话说本来打算根据ObjectName来判断进程名的,但是貌似全是null值
	//只能用pid了
	//KdPrint(("SSDT HOOK NtOpenProcess Successful!"));
	NTSTATUS status = STATUS_SUCCESS;
	//要保护的进程PID
	LONG pid = 3780;
	//KdPrint(("ClientID->UniqueProcess = %ld\n", ClientID->UniqueProcess));
	//PsLookupProcessByProcessId(IN HANDLE ProcessId, OUT PEPROCESS *Process)可获得EPROCESS结构
	if((long)ClientID->UniqueProcess == pid)
	{
		//KdPrint(("Protected PID: %ld\n", pid));
		return STATUS_ACCESS_DENIED;
	}
	//UNICODE_STRING szProtect;
	//RtlInitUnicodeString(&szProtect, L"1.exe");
	//PUNICODE_STRING szProtect = (PUNICODE_STRING)ExAllocatePool(PagedPool,sizeof(UNICODE_STRING));
	//RtlInitUnicodeString(szProtect, L"1.exe");
	//_asm int 3;
	//__try
	//{
		//ProbeForRead(ObjectAttributes->ObjectName, sizeof(UNICODE_STRING), 4);
		//KdPrint(("%wZ\n", ObjectAttributes->ObjectName));
		//if(!RtlCompareUnicodeString(ObjectAttributes->ObjectName, &szProtect, FALSE))
		//{	//ExFreePool(((PVOID)szProtect));
		//	return STATUS_UNSUCCESSFUL;
		//}
	//}
	//__except(EXCEPTION_EXECUTE_HANDLER)
	//{
		status = OldNtOpenProcess(ProcessHandle, DesireAccess, ObjectAttributes, ClientID);
	//}
	return status;
	//ExFreePool((PVOID)szProtect);
}
//禁用写保护,wp=0
VOID PROTECT()
{
	__asm
	{
		cli ;
		mov eax, cr0
		and  eax, ~0x10000
		mov cr0, eax
	}
}
//启用写保护,wp=1
VOID UN_PROTECT()
{
	__asm
	{
		mov  eax, cr0
		or     eax, 0x10000
		mov  cr0, eax
		sti ;
	}
}

PVOID HookSSDTFunction(PVOID OldFunction, PVOID HookFunction)
{
	KdPrint(("Enter HookSSDTFunction\n"));
	//KdPrint(("KeServiceDescriptorTable.ServiceTableBase=0x%X\n",KeServiceDescriptorTable.ServiceTableBase));
	//KdPrint(("KeServiceDescriptorTable.NumberOfServices=0x%X\n",KeServiceDescriptorTable.NumberOfServices));
	//PROTECT();	It is sure that if we use PROTECT function, we must change other code too;
	//我勒个去,我也用英语装逼一下,O(∩_∩)O哈哈~
	PMDL pMdl = MmCreateMdl(
					NULL, 
					KeServiceDescriptorTable.ServiceTableBase, 
					KeServiceDescriptorTable.NumberOfServices*4);
	if(!pMdl)
	{
		KdPrint(("Hook SSDT Failed!\n"));
		return 0;
	}
	MmBuildMdlForNonPagedPool(pMdl);
	pMdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;
	PLONG pMdlLocked = (PLONG)MmMapLockedPages(pMdl, KernelMode);
	//KdPrint(("ServiceTableBase Locked page 0X%X", pMdlLocked));
	//网上HOOK 系列都是用的这个来获得和修改地址,原因见下
	//OldZwOpenProcess = (ZWOPENPROCESS)(KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PBYTE)ZwOpenProcess+1)])
	//lkd> u ZwOpenProcess
	//nt!ZwOpenProcess:
	//805016b4 b87a000000      mov     eax,7Ah
	//805016b9 8d542404        lea     edx,[esp+4]
	for(ULONG i = 0; i<KeServiceDescriptorTable.NumberOfServices; i++)
	{
		if((LONG)pMdlLocked[i] == (LONG)OldFunction)
		{
			//KdPrint(("修改前: HOOK Func addr=0X%X", (LONG)HookFunction));
			//KdPrint(("修改前: Need Hook addr=0X%X", (LONG)pMdlLocked[i]));
			InterlockedExchange(&pMdlLocked[i], (LONG)HookFunction);
			//KdPrint(("修改后: Need Hook addr=0X%X", (LONG)pMdlLocked[i]));
			break;
		}
	}
	MmUnmapLockedPages(pMdlLocked, pMdl);
	IoFreeMdl(pMdl);
	//UN_PROTECT()
	KdPrint(("Leave HookSSDTFunction\n"));
	return OldFunction;
}

VOID Test(PCWSTR sz)
{
	UNICODE_STRING strToFind;
	RtlInitUnicodeString(&strToFind, sz);
	PVOID AddrToFind = MmGetSystemRoutineAddress(&strToFind);
	if (!AddrToFind);
		//KdPrint(("MmGetSystemRoutineAddress: %S address is not fount\n", sz));
	else;
		//KdPrint(("Hook之前调用MmGetSystemRoutineAddress: 0x%X\n", AddrToFind));
	KdPrint(("Hook之后直接用NtOpenProcess名 %X\n", NtOpenProcess));
	//直接用函数名获得的NtOpenProcess的地址和用MmGetSystemRoutineAddress获得的地址一样
	//HookSSDTFunction(AddrToFind, MyNtOpenProcess);
	OldNtOpenProcess = (pfnNtOpenProcess)HookSSDTFunction(NtOpenProcess, MyNtOpenProcess);
	AddrToFind = MmGetSystemRoutineAddress(&strToFind);
	//KdPrint(("Hook之后调用MmGetSystemRoutineAddress: 0x%X\n", AddrToFind));
	//KdPrint(("Hook之后直接用NtOpenProcess名 %X\n", NtOpenProcess));
}

/************************************************************************
* 函数名称:DriverEntry
* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象
* 参数列表:
      pDriverObject:从I/O管理器中传进来的驱动对象
      pRegistryPath:驱动程序在注册表的中的路径
* 返回 值:返回初始化驱动状态
*************************************************************************/
#pragma INITCODE
extern "C" NTSTATUS DriverEntry(
		IN PDRIVER_OBJECT pDriverObject, 
		IN PUNICODE_STRING pRegistryPath)
{
	NTSTATUS status;
	KdPrint(("Enter DriverEntry\n"));
	//注册其他驱动调用函数
	pDriverObject->DriverUnload = DriverUnload;
	
	status = CreateDevice(pDriverObject);

	Test(L"NtOpenProcess");
	
	KdPrint(("Leave DriverEntry\n"));
	return status;
}

/************************************************************************
* 函数名称:CreateDevice
* 功能描述:初始化设备对象
* 参数列表:
      pDriverObject:从I/O管理器中传进来的驱动对象
* 返回 值:返回初始化状态
*************************************************************************/
#pragma INITCODE
NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject)
{
	NTSTATUS status;
	PDEVICE_OBJECT pDevObj;
	PDEVICE_EXTENSION pDevExt;
	
	//创建设备名称
	UNICODE_STRING devName;
	UNICODE_STRING symLinkName;
	RtlInitUnicodeString(&devName, L"\\Device\\MyDDKDevice");
	
	//创建设备
	status = IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENSION),
					&devName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj);
	if(!NT_SUCCESS(status))
		return status;
	pDevObj->Flags |= DO_BUFFERED_IO;
	pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
	pDevExt->pDevice = pDevObj;
	pDevExt->ustrDeviceName = devName;
	//创建符号链接
	RtlInitUnicodeString(&symLinkName, L"\\??\\MyDDKDevice");
	pDevExt->ustrSymLinkName = symLinkName;
	status = IoCreateSymbolicLink(&symLinkName, &devName);
	if(!NT_SUCCESS(status))
	{
		IoDeleteDevice(pDevObj);
		return status;
	}
	
	return status;
}

/************************************************************************
* 函数名称:DriverUnload
* 功能描述:负责驱动程序的卸载操作
* 参数列表:
      pDriverObject:驱动对象
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject)
{
	KdPrint(("Enter DriverUnload"));
	PDEVICE_OBJECT pNextObj;
	KdPrint(("Enter DriverUnload"));
	pNextObj = pDriverObject->DeviceObject;
	while(pNextObj != NULL)
	{
		PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pNextObj->DeviceExtension;
		
		//删除符号链接
		UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
		IoDeleteSymbolicLink(&pLinkName);
		pNextObj = pNextObj->NextDevice;
		IoDeleteDevice(pDevExt->pDevice);
	}
	KdPrint(("Leave DriverUnload"));
	
	HookSSDTFunction(MyNtOpenProcess, OldNtOpenProcess);
	KdPrint(("Leave DriverUnload"));
}

/************************************************************************
* 函数名称:DispatchRoutine
* 功能描述:对读IRP进行处理
* 参数列表:
      pDevObj:功能设备对象
      pIrp:从IO请求包
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS DispatchRoutine(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
{
	NTSTATUS status = STATUS_SUCCESS;
	KdPrint(("Enter DispatchRoutine"));
	pIrp->IoStatus.Status = status;
	pIrp->IoStatus.Information = 0;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	KdPrint(("Leave DispatchRoutine"));
	return status;
}



dbgview

Enter DriverEntry
Hook之前调用MmGetSystemRoutineAddress: 0x805CC3FC
Hook之后直接用NtOpenProcess名 805CC3FC
Enter HookSSDTFunction
修改前: HOOK Func addr=0XF7CC2490
修改前: Need Hook addr=0X805CC3FC
修改后: Need Hook addr=0XF7CC2490
Leave HookSSDTFunction
Hook之后调用MmGetSystemRoutineAddress: 0x805CC3FC
Hook之后直接用NtOpenProcess名 805CC3FC
Leave DriverEntry
Enter DriverUnload
Enter DriverUnload
Leave DriverUnload
Enter HookSSDTFunction
修改前: HOOK Func addr=0X805CC3FC
修改前: Need Hook addr=0XF7CC2490
修改后: Need Hook addr=0X805CC3FC
Leave HookSSDTFunction
Leave DriverUnload


得出的结论就是貌似只有调用Zw*函数才会用SSDT表哎。。。。Nt*号函数都是直接用的地址来着

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

针对 NtOpenProcess服务函数HOOK SSDT示例代码,保护记事本进程

#include ////////////////////////////////////////////////////////////////////////// //函数声明 NTSTA...

内核编程之SSDTHook(2)Hook NtOpenProcess实现进程保护

本博文由CSDN博主zuishikonghuan所作,版权归zuishikonghuan所有,转载请注明出处: 上一篇博文“内核编程之SSDTHook(1)原理(地址:)”中,介绍了SSDTHook的...

Hook SSDT NtOpenProcess的完整代码

以下是通过Hook SSDT NtOpenProcess保护进程的完整代码,对喜欢HOOK的初学者帮助很大 驱动代码Protect.C: #include "ntddk.h" ...

进程隐藏与进程保护(SSDT Hook 实现)(一)

转载自  Zachary.XiaoZhen - 梦想的天空 进程隐藏与进程保护(SSDT Hook 实现)(一) 文章目录:           ...

进程隐藏与进程保护(SSDT Hook 实现)(一)

转载自  Zachary.XiaoZhen - 梦想的天空 文章目录:                 ...

进程隐藏与进程保护(SSDT Hook 实现)(一)

文章目录:                   1. 引子 – Hook 技术: 2. SSDT 简介: 3. 应用层调...

进程隐藏与进程保护(SSDT Hook 实现)(一)

转载自  Zachary.XiaoZhen - 梦想的天空 lian

读取无保护的SSDT表中的NtOpenProcess函数的当前地址

// 无技术含量,是抄来的,驱动已入门的请飘过 /**********************************************************************...

进程隐藏与进程保护(SSDT Hook 实现)(一)

文章目录:                   1. 引子 – Hook 技术: 2. SSDT 简介:...

进程隐藏与进程保护(SSDT Hook 实现)(二)

Zachary.XiaoZhen - 梦想的天空 进程隐藏与进程保护(SSDT Hook 实现)(二) 文章目录:              ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)