在應(yīng)用層,枚舉進(jìn)程及其通信端口一般可以用iphlpapi.dll中提供的函數(shù)來(lái)獲取。如獲取Tcp連接,則調(diào)用GetTcpTable或者AllocateAndGetTcpTableFromStack來(lái)查詢(xún)。這些API都是通過(guò)調(diào)用NtDeviceIoControlFile這個(gè)NativeAPI來(lái)進(jìn)入內(nèi)核查詢(xún)信息的,如果在內(nèi)核用SSDT Hook來(lái)掛鉤此函數(shù),從而隱藏特定的IP、端口信息的話,那么在應(yīng)用層,常規(guī)的查詢(xún)方法就查不到隱藏的端口了。
本文通過(guò)直接向設(shè)備對(duì)象\Device\Tcp發(fā)送IOCTL Code=IOCTL_TCP_QUERY_INFORMATION_EX的命令,直接獲取進(jìn)程,端口信息。本文也同時(shí)實(shí)現(xiàn)了UDP端口的查詢(xún)。
具體請(qǐng)參考下面的代碼,使用WinDDK 6001.18001編譯。
1
#include <ntddk.h>
2
#include <tdiinfo.h>
3
#include <tdistat.h>
4
5
#define DD_TCP_DEVICE_NAME L"\\Device\\Tcp"
6
#define DD_UDP_DEVICE_NAME L"\\Device\\Udp"
7
8
#define TCP_MIB_ADDRTABLE_ENTRY_EX_ID 0x102
9
10
/**//* TCP/UDP/RawIP IOCTL code definitions */
11
12
#define FSCTL_TCP_BASE FILE_DEVICE_NETWORK
13
14
#define _TCP_CTL_CODE(function, method, access) \
15
CTL_CODE(FSCTL_TCP_BASE, function, method, access)
16
17
#define IOCTL_TCP_QUERY_INFORMATION_EX \
18
_TCP_CTL_CODE(0, METHOD_NEITHER, FILE_ANY_ACCESS)
19
20
#define ntohs(s) \
21
(((s >> 8) & 0x00FF) | \
22
((s << 8) & 0xFF00))
23
24
enum
{TCPPORT, UDPPORT};
25
26
typedef ULONG DWORD;
27
28
typedef struct _MIB_TCPROW_OWNER_PID
29

{
30
DWORD dwState;
31
DWORD dwLocalAddr;
32
DWORD dwLocalPort;
33
DWORD dwRemoteAddr;
34
DWORD dwRemotePort;
35
DWORD dwOwningPid;
36
} MIB_TCPROW_OWNER_PID, *PMIB_TCPROW_OWNER_PID;
37
38
/**//////////////////////////////////////////////////////////////////////////////////// 39
//
40
// 功能實(shí)現(xiàn):根據(jù)設(shè)備名獲取文件句柄或文件對(duì)象指針
41
// 輸入?yún)?shù):FileHandle是要輸出的文件句柄指針;
42
// FileObject是要輸出的文件對(duì)象指針
43
// DeviceName是要獲取設(shè)備的設(shè)備名
44
// 輸出參數(shù):返回NTSTATUS類(lèi)型的值
45
//
46
/**//////////////////////////////////////////////////////////////////////////////////// 47
NTSTATUS
48
GetObjectByName(OUT HANDLE *FileHandle, OUT PFILE_OBJECT *FileObject, IN WCHAR *DeviceName)
49

{
50
UNICODE_STRING deviceTCPUnicodeString;
51
OBJECT_ATTRIBUTES TCP_object_attr;
52
NTSTATUS status;
53
IO_STATUS_BLOCK IoStatus;
54
55
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
56
RtlInitUnicodeString(&deviceTCPUnicodeString, DeviceName);
57
InitializeObjectAttributes(&TCP_object_attr,
58
&deviceTCPUnicodeString,
59
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
60
0,
61
0);
62
status = ZwCreateFile(FileHandle,
63
GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,
64
&TCP_object_attr,
65
&IoStatus,
66
0,
67
FILE_ATTRIBUTE_NORMAL,
68
FILE_SHARE_READ,
69
FILE_OPEN,
70
0,
71
0,
72
0);
73
if(!NT_SUCCESS(status))
74
{
75
KdPrint(("Failed to open"));
76
return STATUS_UNSUCCESSFUL;
77
}
78
status = ObReferenceObjectByHandle(*FileHandle,
79
FILE_ANY_ACCESS,
80
0,
81
KernelMode,
82
(PVOID*)FileObject,
83
NULL);
84
85
return status;
86
}
87
88
/**//////////////////////////////////////////////////////////////////////////////////// 89
//
90
// 功能實(shí)現(xiàn):枚舉網(wǎng)絡(luò)連接端口信息
91
// 輸入?yún)?shù):OutLength為輸出緩沖區(qū)的大小
92
// PortType為要枚舉的端口類(lèi)型
93
// TCPPORT-TCP端口
94
// UDPPORT-UDP端口
95
// 輸出參數(shù):輸出端口信息,在函數(shù)內(nèi)部分配空間,需要在外部釋放
96
//
97
/**//////////////////////////////////////////////////////////////////////////////////// 98
PVOID
99
EnumPortInformation(OUT PULONG OutLength, IN USHORT PortType)
100

{
101
ULONG BufLen = PAGE_SIZE;
102
PVOID pInputBuff=NULL;
103
PVOID pOutputBuff=NULL;
104
PVOID pOutBuf=NULL;
105
NTSTATUS status = STATUS_SUCCESS;
106
HANDLE FileHandle=NULL;
107
UNICODE_STRING DeviceName;
108
PFILE_OBJECT pFileObject=NULL;
109
PDEVICE_OBJECT pDeviceObject=NULL;
110
KEVENT Event ;
111
IO_STATUS_BLOCK StatusBlock;
112
PIRP pIrp;
113
PIO_STACK_LOCATION StackLocation ;
114
ULONG NumOutputBuffers;
115
ULONG i;
116
TCP_REQUEST_QUERY_INFORMATION_EX TdiId;
117
118
RtlZeroMemory(&TdiId, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
119
120
if(TCPPORT == PortType)
121
{
122
TdiId.ID.toi_entity.tei_entity = CO_TL_ENTITY;
123
}
124
else if(UDPPORT == PortType)
125
{
126
TdiId.ID.toi_entity.tei_entity = CL_TL_ENTITY;
127
}
128
else
129
{
130
KdPrint(("需要獲取的端口類(lèi)型無(wú)效\n"));
131
return NULL;
132
}
133
134
TdiId.ID.toi_entity.tei_instance = ENTITY_LIST_ID;
135
TdiId.ID.toi_class = INFO_CLASS_PROTOCOL;
136
TdiId.ID.toi_type = INFO_TYPE_PROVIDER;
137
TdiId.ID.toi_id = TCP_MIB_ADDRTABLE_ENTRY_EX_ID;
138
139
pInputBuff = (PVOID)&TdiId;
140
141
__try
142
{
143
if(UDPPORT == PortType)
144
{
145
BufLen *= 3;
146
}
147
pOutputBuff = ExAllocatePool(NonPagedPool, BufLen);
148
if(NULL == pOutputBuff)
149
{
150
KdPrint(("輸出緩沖區(qū)內(nèi)存分配失敗!\n"));
151
*OutLength = 0;
152
__leave;
153
}
154
155
if(TCPPORT == PortType)
156
{
157
status = GetObjectByName(&FileHandle, &pFileObject, DD_TCP_DEVICE_NAME);
158
}
159
else if(UDPPORT == PortType)
160
{
161
status = GetObjectByName(&FileHandle, &pFileObject, DD_UDP_DEVICE_NAME);
162
}
163
if (!NT_SUCCESS(status))
164
{
165
KdPrint(("獲取設(shè)備名失敗!\n"));
166
*OutLength = 0;
167
__leave;
168
}
169
170
pDeviceObject = IoGetRelatedDeviceObject(pFileObject);
171
if (NULL == pDeviceObject)
172
{
173
KdPrint(("獲取設(shè)備對(duì)象失敗!\n"));
174
*OutLength = 0;
175
__leave;
176
}
177
178
KdPrint(("Tcpip Driver Object:%08lX\n", pDeviceObject->DriverObject));
179
180
KeInitializeEvent(&Event, NotificationEvent, FALSE);
181
182
pIrp = IoBuildDeviceIoControlRequest(IOCTL_TCP_QUERY_INFORMATION_EX, \
183
pDeviceObject, pInputBuff, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX), \
184
pOutputBuff, BufLen, FALSE, &Event, &StatusBlock);
185
if (NULL == pIrp)
186
{
187
KdPrint(("IRP生成失敗!\n"));
188
*OutLength = 0;
189
__leave;
190
}
191
192
StackLocation = IoGetNextIrpStackLocation(pIrp);
193
StackLocation->FileObject = pFileObject;//不設(shè)置這里會(huì)藍(lán)屏
194
StackLocation->DeviceObject = pDeviceObject;
195
196
status = IoCallDriver(pDeviceObject, pIrp);
197
198
KdPrint(("STATUS:%08lX\n", status));
199
200
if (STATUS_BUFFER_OVERFLOW == status)
201
{
202
KdPrint(("緩沖區(qū)太小!%d\n",StatusBlock.Information));
203
}
204
205
if (STATUS_PENDING == status)
206
{
207
KdPrint(("STATUS_PENDING"));
208
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
209
status = StatusBlock.Status;
210
}
211
212
if(STATUS_CANCELLED == status)
213
{
214
KdPrint(("STATUS_CANCELLED"));
215
}
216
217
if(status == STATUS_SUCCESS)
218
{
219
*OutLength = StatusBlock.Information;
220
pOutBuf = pOutputBuff;
221
}
222
}
223
__finally
224
{
225
ObDereferenceObject(pFileObject);
226
if(FileHandle)
227
{
228
ZwClose(FileHandle);
229
}
230
}
231
return pOutBuf;
232
}
233
234
NTSTATUS DriverUnload(PDRIVER_OBJECT pDrvObj)
235

{
236
DbgPrint("DriverUnload\n");
237
return STATUS_SUCCESS;
238
}
239
240
NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
241

{
242
PVOID pTcpBuf = NULL;
243
ULONG ulTcpBuf = 0;
244
245
DbgPrint("DriverEntry\n");
246
247
pDrvObj->DriverUnload = DriverUnload;
248
249
pTcpBuf = EnumPortInformation(&ulTcpBuf, TCPPORT);
250
251
if (pTcpBuf != NULL)
252
{
253
PMIB_TCPROW_OWNER_PID pTcpInfo = NULL;
254
// 打印tcp端口信息
255
pTcpInfo = (PMIB_TCPROW_OWNER_PID)pTcpBuf;
256
257
for(; pTcpInfo->dwOwningPid; pTcpInfo++)
258
{
259
KdPrint(("Pid:%d,Port:%d\n", pTcpInfo->dwOwningPid, ntohs(pTcpInfo->dwLocalPort)));
260
}
261
ExFreePool(pTcpBuf);
262
}
263
264
return STATUS_SUCCESS;
265
}
266
posted on 2010-07-09 18:28
水 閱讀(6000)
評(píng)論(3) 編輯 收藏 引用 所屬分類(lèi):
windows驅(qū)動(dòng)