Joe1sn's Cabin

windows内核驱动 11-设备TDI过滤

加油,坚持

从内核捕获TCP连接并打印

1
ioctl --irp--> device

CreateFile:打开自己的设备

1
socket -> afd.sys -> Build_irp ----> tcp--> 物理网卡

Build_irp:tdi编程,生成一个设备,然后绑定在设备上,从而拦截irp

附加设备

主要功能实现

IoAttachDevice 例程将调用方的设备对象附加到命名的目标设备对象,以便首先将绑定到目标设备的 I/O 请求路由到调用方。

1
2
3
4
5
NTSTATUS IoAttachDevice(
[in] PDEVICE_OBJECT SourceDevice,
[in] PUNICODE_STRING TargetDevice,
[out] PDEVICE_OBJECT *AttachedDevice
);
1
[in] SourceDevice

指向调用方创建的设备对象的指针。

1
[in] TargetDevice

指向一个缓冲区的指针,该缓冲区包含要附加到的指定 SourceDevice 的设备对象的名称。

1
[out] AttachedDevice

指向指针的调用方分配存储的指针。 返回时,如果附件成功,则包含指向目标设备对象的指针。

由于Windows Vista过后重新封装了驱动,所以找不到\Device\Tcp

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
#include <ntifs.h>
#include <windef.h>

PDRIVER_OBJECT pFilterDevObj = NULL;
PDEVICE_OBJECT pDevObj = NULL;

//传递不关心的irp请求给下一层
NTSTATUS NotSupported(PDEVICE_OBJECT pDevice, PIRP pIrp) {
IoSkipCurrentIrpStackLocation(pIrp);
return IoCallDriver(pDevice, pIrp);
}

//
NTSTATUS MyDispatch(PDEVICE_OBJECT pDevice, PIRP pIrp) {
if (pDevice == pFilterDevObj) {
DbgPrint("this is filter\n");
}

IoSkipCurrentIrpStackLocation(pIrp);
return IoCallDriver(pDevice, pIrp);
}

VOID
DriverUnload(PDRIVER_OBJECT DriverObject)
{
DbgPrint("Driver Stopping -> %wZ\n", &DriverObject->DriverName);
IoDetachDevice(pDevObj); //解绑设备
IoDeleteDevice(pFilterDevObj); //删除设备
}

NTSTATUS
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
UNREFERENCED_PARAMETER(RegistryPath);

DbgPrint("Driver Running -> %wZ\n", &DriverObject->DriverName);
DriverObject->DriverUnload = DriverUnload;

NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING deviceName = { 0 };

// 1. 生成设备
status = IoCreateDevice(DriverObject, 0, NULL, FILE_DEVICE_NETWORK, FILE_DEVICE_SECURE_OPEN, FALSE, &pFilterDevObj);
if (!NT_SUCCESS(status)) {
DbgPrint("allocate device failed: %x\n", status);
return status;
}
DbgPrint("allocated device success\n");


// 2. 设置分发函数
for (size_t i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction[i] = NotSupported;
}
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = MyDispatch;

RtlInitUnicodeString(&deviceName, L"\\Device\\Tcp");
status = IoAttachDevice(pFilterDevObj, &deviceName, &pDevObj);
if (!NT_SUCCESS(status)) {
DbgPrint("attach device failed: %x\n", status);
IoDeleteDevice(pFilterDevObj);
return status;
}

return status;
}

最后可以从irp stack中提取出有用的ip相关信息