驱动:HooK内核函数为自己的函数(来自网络)

hook不同的函数,需要定义相对应的函数原型,本例原型为NTOpenProcess

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <ntdef.h>
 
LONG preAddr,curAddr,writeAddr;
bool isHook;
 
//驱动入口
extern "C" NTSTATUS DriverEntry(
	PDRIVER_OBJECT pDriObj,
	PUNICODE_STRING pRegStr)
{
	isHook = false;                       //标示没有Hook
	DbgPrint("Driver Entry..\n");
 
	//linktest();
	UNICODE_STRING functionname;
	RtlInitUnicodeString(&functionname, L"NtOpenProcess");
 
	DbgPrint("%ws current address:%x \n",functionname.Buffer, curAddr = GetSSDTFunctionAddr(HOOKOFFSET));
    DbgPrint("%ws source address:%x \n",functionname.Buffer, preAddr = GetSystemRoutineAddr(&functionname));
	if(curAddr == preAddr){
		DbgPrint("program wasn't hook! but will be..");
	}
 
	SSDTWrite((LONG)HookFunction, HOOKOFFSET);
	isHook = true;
 
	pDriObj->DriverUnload = MyUnloadDriver;
	return STATUS_SUCCESS;
}
 
//卸载函数
VOID MyUnloadDriver(PDRIVER_OBJECT pDriObj)
{
	DbgPrint("Driver Unload!");
	if(isHook)SSDTWrite(preAddr,HOOKOFFSET);
}
 
 
/*
*获取SSDT表中functionname函数的当前地址
*/
LONG GetSSDTFunctionAddr(int pOffset)
{
	DbgPrint("In the SSDTWrite function..\n");
	LONG basePtr;
	int iOffset = pOffset*4;
	_asm{
		push eax
		push ebx
		mov  ebx, KeServiceDescriptorTable
		mov  ebx,[ebx]
		mov	 eax, iOffset
		add  ebx,eax
		mov writeAddr,eax            //将要写入jmp代码的地址
		mov ebx,[ebx]
		mov  basePtr,ebx            //现在该地址的代码
		pop	 ebx
		pop  eax
	}
	return basePtr;
}
 
/*
*获取SSDT表中functionname函数的原地址
*/
LONG GetSystemRoutineAddr(PUNICODE_STRING functionname)
{
	LONG ret = NULL;
	return ret = (LONG)MmGetSystemRoutineAddress(functionname);  //原地址的
}
 
 
/*
*用writeAddress地址,来代替SSDT表中相应函数的地址,其中iOffset是函数的偏移
*/
VOID SSDTWrite(const LONG writeAddress, int iOffset)
{
	DbgPrint(" \n HOOK  \n");
	LONG *SSDT_ADR,t_addr;
	t_addr = (LONG)KeServiceDescriptorTable->ServiceTableBase;
	SSDT_ADR = (PLONG)(t_addr+iOffset*4);
	PHookFunction = (MyFunction *)writeAddress;
	_asm{
		cli
		mov eax,cr0
		and eax,not 10000h
		mov cr0,eax
	}
	*SSDT_ADR = (ULONG)PHookFunction;
	_asm{
		mov eax,cr0
		mov ebx,10000h
		or eax,ebx
		mov cr0,eax
		sti
	}
}
 
//自己的函数用来代替内核函数
NTSTATUS HookFunction( 
			OUT     PHANDLE ProcessHandle, 
			IN     ACCESS_MASK DesiredAccess, 
			IN     POBJECT_ATTRIBUTES ObjectAttributes, 
			IN     PCLIENT_ID ClientId ) 
{
	DbgPrint("嘿嘿come here");
	ProcessHandle = NULL;
	return STATUS_ACCESS_DENIED;
}

头文件,其中122标示为SSDT表的第122个函数NTOpenProcess

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#ifdef __cplusplus
extern "C" {
#endif
#include "ntddk.h"
#ifdef __cplusplus
}
#endif
 
#define HOOKOFFSET 122
 
VOID MyUnloadDriver(PDRIVER_OBJECT pDriObj);
LONG GetSSDTFunctionAddr(int pOffset);
LONG GetSystemRoutineAddr(PUNICODE_STRING functionname);
VOID SSDTWrite(const LONG writeAddress, int iOffset);
 
extern "C" NTSTATUS __stdcall HookFunction( 
			 OUT     PHANDLE ProcessHandle, 
			 IN     ACCESS_MASK DesiredAccess, 
			 IN     POBJECT_ATTRIBUTES ObjectAttributes, 
			 IN     PCLIENT_ID ClientId ) ;
 
extern "C" typedef NTSTATUS __stdcall MyFunction( 
	OUT     PHANDLE ProcessHandle, 
	IN     ACCESS_MASK DesiredAccess, 
	IN     POBJECT_ATTRIBUTES ObjectAttributes, 
	IN     PCLIENT_ID ClientId ) ;
MyFunction * PHookFunction;
typedef struct _ServiceDescriptorTable {
	PVOID ServiceTableBase; //System Service Dispatch Table 的基地址  
	PVOID ServiceCounterTable;
	//包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。 
	unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。  
	PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表 
}*PServiceDescriptorTable;
 
extern "C" PServiceDescriptorTable  KeServiceDescriptorTable;
posted @ 2011-09-10 08:44  OnTimer  阅读(317)  评论(0)    收藏  举报