首页 > WinDriver > WD-新建SSDT项通讯
2014七月7

WD-新建SSDT项通讯

以下仅针对32位系统,在XP下测试:
以下是XP在ring3的调用方式:

1
2
3
4
5
6
7
8
9
10
11
12
// xp
ntdll!NtReadFile:
7c92d9b0 b8b7000000      mov     eax,0B7h
7c92d9b5 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92d9ba ff12            call    dword ptr [edx]      ds:0023:7ffe0300={ntdll!KiFastSystemCall (7c92e4f0)}
7c92d9bc c22400          ret     24h
7c92d9bf 90              nop
 
 
ntdll!KiFastSystemCall:
7c92e4f0 8bd4            mov     edx,esp
7c92e4f2 0f34            sysenter

所以原理也比较简单了,仿写即可,注意SSDT要去掉写保护!
ring3:

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
#include "stdafx.h"
#include <Windows.h>
 
__declspec(naked) void MyKiFastSystemCall()
{
	__asm
	{
		mov  edx,esp;
		__emit 0x0f;
		__emit 0x34;
	}
};
 
__declspec(naked) NTSTATUS NTAPI
	IOSystemControl(
	IN ULONG IoCtrl,
	IN PVOID InputBuf,
	IN ULONG InputBufLen,
	OUT PVOID OutputBuf,
	IN ULONG OutputLen,
	OUT PULONG ReturnLen)
{
		__asm
		{
			mov eax, 11Ch;
			call MyKiFastSystemCall
			retn 0x18;
		}
}
 
int _tmain(int argc, _TCHAR* argv[])
{
	char szBuf[100] = {0};
	ULONG outlen = 0;
	IOSystemControl(0x12345678,"hgy413",strlen("hgy413"),szBuf,99,&outlen);
	printf("%s-%d\n",szBuf, outlen);
 
	getchar();
	return 0;
}

ring0:

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
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "main.h"
// def
typedef struct _KSERVICE_TABLE_DESCRIPTOR 
{
	PULONG ServiceTableBase;//SSTD基地址
	PULONG Count;				//包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新
	ULONG TableSize;			//由 ServiceTableBase 描述的服务的数目
	PUCHAR ArgumentTable;		//包含每个系统服务参数字节数表的基地址-系统服务参数表 每个表项是一个UCHAR,表示一个函数参数长度
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
 
//ssdt表已经导出了,这里例行公事下
extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;
KSERVICE_TABLE_DESCRIPTOR ssdt_copy;
ULONG NewSsdtServiceTableBase[1024] = {0};
UCHAR NewSsdtServiceTableNumber[1024] = {0};
 
NTSTATUS
IoSystemControl(IN ULONG ControlCode,
					 IN PVOID InputBuffer OPTIONAL,
					 IN ULONG InputBufferLength,
					 OUT PVOID OutputBuffer OPTIONAL,
					 IN ULONG OutputBufferLength,
					 OUT PULONG ReturnLength OPTIONAL
					 )
{
	NTSTATUS Status = STATUS_SUCCESS;
 
	if (OutputBuffer&&MmIsAddressValid(OutputBuffer))
	{
		KdPrint(("%s\r\n",InputBuffer));
		memset(OutputBuffer, 0x41, OutputBufferLength);//传出buf变为AAAAA...
		if (ReturnLength&& MmIsAddressValid(ReturnLength))
		{
			*ReturnLength = 10; //传出size随便设置为10
		}
	}
	return Status;
}
 
 
void  NtosAddSsdtServiceTable(
							  PVOID NewFunction,
							  ULONG NewNumber
							  )
{
	NTSTATUS Status = STATUS_SUCCESS;
	PEPROCESS Process;
 
	//禁止写保护,不然蓝屏
	__asm
	{
		MOV    EAX, CR0;        
		OR    EAX, 10000H;            
		MOV    CR0, EAX;              
		STI;                    
	}
 
	//复制原始服务表
	//把原始表复制到我们的数组
	memcpy(
		NewSsdtServiceTableBase, 
		KeServiceDescriptorTable->ServiceTableBase, 
		KeServiceDescriptorTable->TableSize * 4
		);
 
	//原始函数个数
	memcpy(
		NewSsdtServiceTableNumber, 
		KeServiceDescriptorTable->ArgumentTable, 
		KeServiceDescriptorTable->TableSize
		);
 
	//修改SSDT表添加服务函数
	NewSsdtServiceTableBase[ssdt_copy.TableSize] = NewFunction;
	NewSsdtServiceTableNumber[ssdt_copy.TableSize] = NewNumber;
 
	//更新内存里面导出 KeServiceDescriptorTable Ssdt 表
	KeServiceDescriptorTable->ServiceTableBase = NewSsdtServiceTableBase;
	KeServiceDescriptorTable->ArgumentTable = NewSsdtServiceTableNumber;
	KeServiceDescriptorTable->TableSize = ssdt_copy.TableSize + 1;
 
	//恢复写保护
	__asm
	{
		MOV    EAX, CR0;        
		OR    EAX, 10000H;            
		MOV    CR0, EAX;              
		STI;                    
	}
}
 
VOID DDKUnload (IN PDRIVER_OBJECT pDriverObject) 
{
	KdPrint(("[DDKUnload]-start\n"));
 
	//恢复原始的
	KeServiceDescriptorTable->ServiceTableBase = ssdt_copy.ServiceTableBase;
	KeServiceDescriptorTable->Count = ssdt_copy.Count;
	KeServiceDescriptorTable->TableSize = ssdt_copy.TableSize;
	KeServiceDescriptorTable->ArgumentTable = ssdt_copy.ArgumentTable;
 
	KdPrint(("[DDKUnload]-end\n"));
}
 
NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject,
					  IN PUNICODE_STRING pRegistryPath) 
{
	KdPrint(("[DriverEntry]-start\n"));
	pDriverObject->DriverUnload = DDKUnload;
 
	// 保存原始的
	ssdt_copy.ServiceTableBase = KeServiceDescriptorTable->ServiceTableBase;
	ssdt_copy.Count = KeServiceDescriptorTable->Count;
	ssdt_copy.TableSize = KeServiceDescriptorTable->TableSize;
	ssdt_copy.ArgumentTable = KeServiceDescriptorTable->ArgumentTable;
 
	//我们调用自定义函数,往SSDT表添加内存
	NtosAddSsdtServiceTable(IoSystemControl, 24);
 
	KdPrint(("[DriverEntry]-end\n"));
	return STATUS_SUCCESS;
}

在驱动加载后,可以看到:
newssdt
运行ring3小程序,可以看到outbuf为AAAAA..,大小为10:
createssdt

文章作者:hgy413
本文地址:https://hgy413.com/1514.html
版权所有 © 转载时必须以链接形式注明作者和原始出处!

本文的评论功能被关闭了.