InlineHook与UnHook

分享一个多核下的InlineHook与UnHook。XP SP3测试通过。如有朋友有问题,欢迎提出共同解决。

.h文件

#ifndef _INLINEHOOK_H_
#define _INLINEHOOK_H_

#include <ntddk.h>

#pragma pack(1)
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
	unsigned int *ServiceTableBase;
	unsigned int *ServiceCounterTableBase; //仅适用于checked build版本
	unsigned int NumberOfServices;
	unsigned char *ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE; 
#pragma pack()

//变量及函数定义如下:
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;

UCHAR * PsGetProcessImageFileName(__in PEPROCESS Process);
#define PsGetCurrentProcessImageFileName() PsGetProcessImageFileName(PsGetCurrentProcess())

ULONG NumberOfRaisedCPU;
ULONG AllCPURaised;
PKDPC g_basePKDPC;

VOID CloseProtect()
{
	__asm
	{
		cli
			push eax
			mov eax,cr0
			and eax,not 10000h
			mov cr0,eax
			pop eax
	}
}

VOID OpenProtect()
{
	__asm
	{
		push eax
			mov eax,cr0
			or eax,10000h
			mov cr0,eax
			pop eax
			sti
	}
}

VOID RaiseCPUIrqlAndWait(
						 IN PKDPC Dpc,
						 IN PVOID DeferredContext,
						 IN PVOID SystemArgument1,
						 IN PVOID SystemArgument2
						 )
{
	InterlockedIncrement(&NumberOfRaisedCPU);
	while (!InterlockedCompareExchange(&AllCPURaised, 1, 1))
	{
		__asm nop;
	}
	InterlockedDecrement(&NumberOfRaisedCPU);
}

void ReleaseExclusivity()
{
	InterlockedIncrement(&AllCPURaised);
	while (InterlockedCompareExchange(&NumberOfRaisedCPU, 0, 0))
	{
		__asm nop;
	}
	if (NULL != g_basePKDPC)
	{
		ExFreePool((PVOID)g_basePKDPC);
		g_basePKDPC = NULL;
	}
	return;
}

BOOLEAN GainExlusivity(VOID)
{
	NTSTATUS ntStatus;
	ULONG u_currentCPU;
	CCHAR i;
	PKDPC pKdpc, temp_pkdpc;

	if (DISPATCH_LEVEL != KeGetCurrentIrql())
	{
		return FALSE;
	}

	InterlockedAnd(&NumberOfRaisedCPU, 0);
	InterlockedAnd(&AllCPURaised, 0);

	temp_pkdpc = (PKDPC)ExAllocatePoolWithTag(NonPagedPool, KeNumberProcessors * sizeof(KDPC),'xian');
	if (NULL == temp_pkdpc)
	{
		return FALSE;
	}
	g_basePKDPC = temp_pkdpc;
	u_currentCPU = KeGetCurrentProcessorNumber();
	for (i = 0; i < KeNumberProcessors; i++, *temp_pkdpc++)
	{
		if (i != u_currentCPU)
		{
			KeInitializeDpc(temp_pkdpc, RaiseCPUIrqlAndWait, NULL);
			KeSetTargetProcessorDpc(temp_pkdpc, i);
			KeInsertQueueDpc(temp_pkdpc, NULL, NULL);
		}
	}

	while (KeNumberProcessors - 1 != InterlockedCompareExchange(&NumberOfRaisedCPU, KeNumberProcessors - 1, KeNumberProcessors - 1))
	{
		__asm nop;
	}
	return TRUE;
}

void __stdcall SetWp()
{
	CloseProtect();
	ReleaseExclusivity();
}

void __stdcall ClearWp()
{
	GainExlusivity();
	OpenProtect();
}

/************************************************************************/
/*	函数名:SK_UnInlineHook

	参数:	IN ULONG OldFunction,		原函数地址
			IN ULONG HookCodeLength,	需要恢复的字节长度
			IN PVOID pOldFunctionCode	需要恢复的字节内容
*/
/************************************************************************/
NTSTATUS SK_UnInlineHook(IN ULONG OldFunction,IN ULONG HookCodeLength,IN PVOID pOldFunctionCode)
{
	NTSTATUS status = STATUS_SUCCESS;
	KIRQL OldIrql;

	SetWp();
	__try
	{
		RtlCopyMemory((PULONG)OldFunction,pOldFunctionCode,HookCodeLength);
	}
	__except(1)
	{
		status = STATUS_UNSUCCESSFUL;
	}
	ClearWp();
	return status;
}
/************************************************************************/
/*	函数名:SK_InlineHook

	参数:	IN ULONG OldFunction,		需要hook的函数
			IN ULONG MyFunction,		跳转到我们自己的函数
			IN ULONG HookCodeLength,	需要hook的长度
			OUT PULONG JmpBackAddress,	跳回原函数的地址
			OUT PVOID pOldFunctionCode	保存原函数被hook的字节
*/
/************************************************************************/
NTSTATUS SK_InlineHook(IN ULONG OldFunction,IN ULONG MyFunction,IN ULONG HookCodeLength,OUT PULONG JmpBackAddress,OUT PVOID pOldFunctionCode)
{
	NTSTATUS status = STATUS_SUCCESS;
	KIRQL OldIrql;
	UCHAR Jmp[0x10];

	SetWp();
	__try
	{
		memset(Jmp,0x90,0x10);
		RtlCopyMemory(pOldFunctionCode,(PULONG)OldFunction,HookCodeLength);
		*(PUCHAR)Jmp = 0xe9;
		*(PULONG)((PUCHAR)Jmp + 1) = (ULONG)MyFunction - (ULONG)OldFunction - HookCodeLength;
		*JmpBackAddress = (ULONG)OldFunction + HookCodeLength;
		RtlCopyMemory((PULONG)OldFunction,Jmp,HookCodeLength);
	}
	__except(1)
	{
		status = STATUS_UNSUCCESSFUL;
	}
	
	ClearWp();

	return status;
}

#endif


.c 文件

#include "InlineHookTest.h"

UCHAR g_OldCode[5] = {0x90};
ULONG g_JmpBackAddress = 0;

__declspec(naked)VOID MyOpenProcess()
{
	KdPrint(("%s 调用了NtOpenProcess!\n",PsGetCurrentProcessImageFileName()));
	__asm
	{
		push 0xC4
		jmp [g_JmpBackAddress]
	}
}

VOID UnloadDriver(PDRIVER_OBJECT pDriver)
{
	SK_UnInlineHook((ULONG)(KeServiceDescriptorTable->ServiceTableBase[122]),5,g_OldCode);
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver,PUNICODE_STRING pRegt)
{
	pDriver->DriverUnload = UnloadDriver;

	SK_InlineHook((ULONG)(KeServiceDescriptorTable->ServiceTableBase[122]),(ULONG)MyOpenProcess,5,&g_JmpBackAddress,g_OldCode);

	return STATUS_SUCCESS;
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值