基于TDI驱动的个人防火墙程序设计与实现
一、项目概述
基于TDI(Transport Driver Interface)驱动的个人防火墙系统,能够在Windows内核层拦截网络数据包,实现访问控制、流量监控和安全防护功能。系统包含内核驱动程序和用户态控制程序两部分。
二、系统架构
2.1 整体架构
graph TD
A[用户态控制程序] -->|IOCTL| B[TDI过滤驱动]
B -->|拦截| C[网络协议栈]
C -->|数据包| B
B -->|处理结果| A
A -->|规则管理| D[规则数据库]
B -->|日志记录| E[日志系统]
2.2 核心组件
- TDI过滤驱动:内核层网络数据包拦截与过滤
- 用户态控制程序:提供用户界面和规则管理
- 规则引擎:实现访问控制策略
- 日志系统:记录网络活动和安全事件
- 配置管理:保存和加载防火墙配置
三、TDI过滤驱动实现
3.1 驱动入口 (TdiFirewall.c)
#include <ntddk.h>
#include <tdi.h>
#include <tdikrnl.h>
#include <netioapi.h>
#include <fwpmk.h>
// 设备对象名称
#define DEVICE_NAME L"\\Device\\TdiFirewall"
#define SYMBOLIC_LINK L"\\DosDevices\\TdiFirewall"
// IOCTL控制码
#define IOCTL_ADD_RULE CTL_CODE(FILE_DEVICE_NETWORK, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DEL_RULE CTL_CODE(FILE_DEVICE_NETWORK, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SET_MODE CTL_CODE(FILE_DEVICE_NETWORK, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
// 规则结构
typedef struct _FIREWALL_RULE {
ULONG RuleId;
ULONG Protocol; // TCP=6, UDP=17, ICMP=1
ULONG Direction; // 0=Inbound, 1=Outbound
ULONG SrcIp;
ULONG SrcPort;
ULONG DstIp;
ULONG DstPort;
ULONG Action; // 0=Block, 1=Allow
BOOLEAN Enabled;
} FIREWALL_RULE, *PFIREWALL_RULE;
// 全局变量
PDEVICE_OBJECT g_DeviceObject = NULL;
BOOLEAN g_FirewallEnabled = TRUE;
LIST_ENTRY g_RulesListHead;
KSPIN_LOCK g_RulesLock;
LONG g_NextRuleId = 1;
// 驱动卸载函数
VOID DriverUnload(PDRIVER_OBJECT DriverObject) {
UNICODE_STRING symbolicLink;
RtlInitUnicodeString(&symbolicLink, SYMBOLIC_LINK);
IoDeleteSymbolicLink(&symbolicLink);
IoDeleteDevice(g_DeviceObject);
KdPrint(("TdiFirewall: Driver unloaded\n"));
}
// 创建回调函数
NTSTATUS TdiCreateCallback(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
// 处理连接请求
// 检查规则,决定是否允许连接
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
// 接收回调函数
NTSTATUS TdiReceiveCallback(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
// 处理接收的数据包
// 检查规则,决定是否允许数据包通过
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
// 设备控制函数
NTSTATUS TdiDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_SUCCESS;
ULONG controlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
PVOID inputBuffer = Irp->AssociatedIrp.SystemBuffer;
ULONG inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
PVOID outputBuffer = Irp->AssociatedIrp.SystemBuffer;
ULONG outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
ULONG bytesReturned = 0;
switch (controlCode) {
case IOCTL_ADD_RULE:
if (inputBufferLength >= sizeof(FIREWALL_RULE)) {
PFIREWALL_RULE rule = (PFIREWALL_RULE)inputBuffer;
status = AddFirewallRule(rule);
if (NT_SUCCESS(status)) {
bytesReturned = sizeof(FIREWALL_RULE);
}
} else {
status = STATUS_INVALID_BUFFER_SIZE;
}
break;
case IOCTL_DEL_RULE:
if (inputBufferLength >= sizeof(ULONG)) {
ULONG ruleId = *(PULONG)inputBuffer;
status = DeleteFirewallRule(ruleId);
if (NT_SUCCESS(status)) {
bytesReturned = sizeof(ULONG);
}
} else {
status = STATUS_INVALID_BUFFER_SIZE;
}
break;
case IOCTL_SET_MODE:
if (inputBufferLength >= sizeof(BOOLEAN)) {
g_FirewallEnabled = *(PBOOLEAN)inputBuffer;
bytesReturned = sizeof(BOOLEAN);
} else {
status = STATUS_INVALID_BUFFER_SIZE;
}
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = bytesReturned;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
// 添加防火墙规则
NTSTATUS AddFirewallRule(PFIREWALL_RULE Rule) {
PFIREWALL_RULE newRule = ExAllocatePoolWithTag(NonPagedPool, sizeof(FIREWALL_RULE), 'FWLR');
if (!newRule) {
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory(newRule, Rule, sizeof(FIREWALL_RULE));
newRule->RuleId = InterlockedIncrement(&g_NextRuleId);
KIRQL oldIrql;
KeAcquireSpinLock(&g_RulesLock, &oldIrql);
InsertTailList(&g_RulesListHead, &newRule->ListEntry);
KeReleaseSpinLock(&g_RulesLock, oldIrql);
return STATUS_SUCCESS;
}
// 删除防火墙规则
NTSTATUS DeleteFirewallRule(ULONG RuleId) {
KIRQL oldIrql;
KeAcquireSpinLock(&g_RulesLock, &oldIrql);
PLIST_ENTRY entry;
for (entry = g_RulesListHead.Flink; entry != &g_RulesListHead; entry = entry->Flink) {
PFIREWALL_RULE rule = CONTAINING_RECORD(entry, FIREWALL_RULE, ListEntry);
if (rule->RuleId == RuleId) {
RemoveEntryList(entry);
ExFreePoolWithTag(rule, 'FWLR');
KeReleaseSpinLock(&g_RulesLock, oldIrql);
return STATUS_SUCCESS;
}
}
KeReleaseSpinLock(&g_RulesLock, oldIrql);
return STATUS_NOT_FOUND;
}
// 检查规则是否匹配
BOOLEAN CheckRuleMatch(PFIREWALL_RULE Rule, ULONG Protocol, ULONG SrcIp, ULONG SrcPort, ULONG DstIp, ULONG DstPort, ULONG Direction) {
if (!Rule->Enabled) return FALSE;
if (Rule->Protocol != 0 && Rule->Protocol != Protocol) return FALSE;
if (Rule->Direction != 2 && Rule->Direction != Direction) return FALSE;
if (Rule->SrcIp != 0 && Rule->SrcIp != SrcIp) return FALSE;
if (Rule->SrcPort != 0 && Rule->SrcPort != SrcPort) return FALSE;
if (Rule->DstIp != 0 && Rule->DstIp != DstIp) return FALSE;
if (Rule->DstPort != 0 && Rule->DstPort != DstPort) return FALSE;
return TRUE;
}
// 驱动入口点
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
UNICODE_STRING deviceName, symbolicLink;
NTSTATUS status;
// 初始化设备对象
RtlInitUnicodeString(&deviceName, DEVICE_NAME);
status = IoCreateDevice(DriverObject, 0, &deviceName, FILE_DEVICE_NETWORK, 0, FALSE, &g_DeviceObject);
if (!NT_SUCCESS(status)) {
return status;
}
// 创建符号链接
RtlInitUnicodeString(&symbolicLink, SYMBOLIC_LINK);
status = IoCreateSymbolicLink(&symbolicLink, &deviceName);
if (!NT_SUCCESS(status)) {
IoDeleteDevice(g_DeviceObject);
return status;
}
// 设置驱动函数
DriverObject->DriverUnload = DriverUnload;
for (ULONG i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
DriverObject->MajorFunction[i] = TdiDefaultDispatch;
}
DriverObject->MajorFunction[IRP_MJ_CREATE] = TdiCreateCallback;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TdiDeviceControl;
DriverObject->MajorFunction[IRP_MJ_READ] = TdiReceiveCallback;
// 初始化规则列表
InitializeListHead(&g_RulesListHead);
KeInitializeSpinLock(&g_RulesLock);
KdPrint(("TdiFirewall: Driver loaded successfully\n"));
return STATUS_SUCCESS;
}
3.2 TDI挂钩实现 (TdiHook.c)
#include <ntddk.h>
#include <tdi.h>
#include <tdikrnl.h>
// TDI函数指针
typedef NTSTATUS (*TdiOpenAddressFilePtr)(PVOID, PVOID, PVOID, PVOID);
typedef NTSTATUS (*TdiAssociateAddressPtr)(PVOID, PVOID);
typedef NTSTATUS (*TdiConnectPtr)(PVOID, PVOID, PVOID, PVOID);
TdiOpenAddressFilePtr OriginalTdiOpenAddressFile = NULL;
TdiAssociateAddressPtr OriginalTdiAssociateAddress = NULL;
TdiConnectPtr OriginalTdiConnect = NULL;
// 挂钩TDI函数
VOID HookTdiFunctions() {
UNICODE_STRING name;
PVOID address;
// 获取TdiOpenAddressFile地址
RtlInitUnicodeString(&name, L"\\SystemRoot\\system32\\tdinet.sys");
address = MmGetSystemRoutineAddress(&name);
if (address) {
OriginalTdiOpenAddressFile = (TdiOpenAddressFilePtr)((PUCHAR)address + 0x1234); // 实际偏移需计算
}
// 获取其他TDI函数地址...
}
// 过滤连接请求
NTSTATUS HookedTdiConnect(PVOID ConnectionContext, PVOID RequestContext, PVOID Buffer, PVOID Context) {
// 解析连接信息
PTDI_CONNECTION_INFORMATION connInfo = (PTDI_CONNECTION_INFORMATION)Buffer;
PTDI_ADDRESS_IP ipAddr = (PTDI_ADDRESS_IP)connInfo->RemoteAddress;
// 检查规则
if (ShouldBlockConnection(ipAddr->in_addr, ipAddr->sin_port)) {
KdPrint(("TdiFirewall: Blocked connection to %d.%d.%d.%d:%d\n",
(ipAddr->in_addr >> 24) & 0xFF, (ipAddr->in_addr >> 16) & 0xFF,
(ipAddr->in_addr >> 8) & 0xFF, ipAddr->in_addr & 0xFF,
ntohs(ipAddr->sin_port)));
return STATUS_ACCESS_DENIED;
}
// 调用原始函数
return OriginalTdiConnect(ConnectionContext, RequestContext, Buffer, Context);
}
// 判断是否阻止连接
BOOLEAN ShouldBlockConnection(ULONG ipAddress, USHORT port) {
if (!g_FirewallEnabled) return FALSE;
KIRQL oldIrql;
KeAcquireSpinLock(&g_RulesLock, &oldIrql);
PLIST_ENTRY entry;
for (entry = g_RulesListHead.Flink; entry != &g_RulesListHead; entry = entry->Flink) {
PFIREWALL_RULE rule = CONTAINING_RECORD(entry, FIREWALL_RULE, ListEntry);
if (CheckRuleMatch(rule, 0, 0, 0, ipAddress, port, 1)) { // 简化检查
KeReleaseSpinLock(&g_RulesLock, oldIrql);
return (rule->Action == 0); // 0=Block
}
}
KeReleaseSpinLock(&g_RulesLock, oldIrql);
return FALSE; // 默认允许
}
四、用户态控制程序
4.1 主程序 (FirewallUI.cpp)
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <commctrl.h>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "comctl32.lib")
#define DEVICE_NAME "\\\\.\\TdiFirewall"
#define WM_UPDATE_LOG (WM_USER + 100)
// 规则结构
struct FirewallRule {
DWORD id;
DWORD protocol;
DWORD direction;
DWORD srcIp;
DWORD srcPort;
DWORD dstIp;
DWORD dstPort;
DWORD action;
BOOL enabled;
};
// 全局变量
HWND hMainWnd;
HWND hRulesList;
HWND hLogList;
HANDLE hDevice;
std::vector<FirewallRule> rules;
std::vector<std::string> logEntries;
// 函数声明
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void AddRuleToList(const FirewallRule& rule);
void UpdateLogList();
void LoadRules();
void SaveRules();
void AddLogEntry(const char* message);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
// 初始化窗口
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = "TdiFirewallClass";
RegisterClassEx(&wc);
// 创建主窗口
hMainWnd = CreateWindow("TdiFirewallClass", "TDI Personal Firewall",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
800, 600, NULL, NULL, hInstance, NULL);
// 创建设备句柄
hDevice = CreateFile(DEVICE_NAME, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDevice == INVALID_HANDLE_VALUE) {
MessageBox(NULL, "Failed to open firewall device", "Error", MB_ICONERROR);
return 1;
}
// 加载规则
LoadRules();
// 显示窗口
ShowWindow(hMainWnd, nCmdShow);
UpdateWindow(hMainWnd);
// 消息循环
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
CloseHandle(hDevice);
return (int)msg.wParam;
}
// 窗口过程
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CREATE: {
// 创建工具栏
HWND hToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT,
0, 0, 0, 0, hWnd, NULL, NULL, NULL);
// 创建规则列表
hRulesList = CreateWindow(WC_LISTVIEW, "", WS_CHILD | WS_VISIBLE | LVS_REPORT,
10, 50, 780, 200, hWnd, NULL, NULL, NULL);
ListView_SetExtendedListViewStyle(hRulesList, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
// 添加列
LVCOLUMN lvc = {0};
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.iSubItem = 0; lvc.pszText = "ID"; lvc.cx = 40; ListView_InsertColumn(hRulesList, 0, &lvc);
lvc.iSubItem = 1; lvc.pszText = "协议"; lvc.cx = 60; ListView_InsertColumn(hRulesList, 1, &lvc);
lvc.iSubItem = 2; lvc.pszText = "方向"; lvc.cx = 60; ListView_InsertColumn(hRulesList, 2, &lvc);
lvc.iSubItem = 3; lvc.pszText = "源IP"; lvc.cx = 100; ListView_InsertColumn(hRulesList, 3, &lvc);
lvc.iSubItem = 4; lvc.pszText = "源端口"; lvc.cx = 60; ListView_InsertColumn(hRulesList, 4, &lvc);
lvc.iSubItem = 5; lvc.pszText = "目标IP"; lvc.cx = 100; ListView_InsertColumn(hRulesList, 5, &lvc);
lvc.iSubItem = 6; lvc.pszText = "目标端口"; lvc.cx = 60; ListView_InsertColumn(hRulesList, 6, &lvc);
lvc.iSubItem = 7; lvc.pszText = "动作"; lvc.cx = 60; ListView_InsertColumn(hRulesList, 7, &lvc);
lvc.iSubItem = 8; lvc.pszText = "状态"; lvc.cx = 60; ListView_InsertColumn(hRulesList, 8, &lvc);
// 创建日志列表
hLogList = CreateWindow(WC_LISTVIEW, "", WS_CHILD | WS_VISIBLE | LVS_REPORT,
10, 260, 780, 200, hWnd, NULL, NULL, NULL);
ListView_SetExtendedListViewStyle(hLogList, LVS_EX_FULLROWSELECT);
// 添加日志列
lvc.iSubItem = 0; lvc.pszText = "时间"; lvc.cx = 120; ListView_InsertColumn(hLogList, 0, &lvc);
lvc.iSubItem = 1; lvc.pszText = "事件"; lvc.cx = 650; ListView_InsertColumn(hLogList, 1, &lvc);
// 加载规则到列表
for (const auto& rule : rules) {
AddRuleToList(rule);
}
break;
}
case WM_COMMAND: {
switch (LOWORD(wParam)) {
case IDM_ADD_RULE: {
// 显示添加规则对话框
FirewallRule newRule = {0};
newRule.id = 0; // 由驱动分配
newRule.protocol = 6; // TCP
newRule.direction = 0; // Inbound
newRule.action = 1; // Allow
newRule.enabled = TRUE;
// 添加规则到驱动
DWORD bytesReturned;
BOOL success = DeviceIoControl(hDevice, IOCTL_ADD_RULE,
&newRule, sizeof(newRule),
NULL, 0, &bytesReturned, NULL);
if (success) {
rules.push_back(newRule);
AddRuleToList(newRule);
SaveRules();
AddLogEntry("添加新规则");
}
break;
}
case IDM_TOGGLE_FIREWALL: {
BOOL enabled = !g_FirewallEnabled;
DWORD bytesReturned;
DeviceIoControl(hDevice, IOCTL_SET_MODE,
&enabled, sizeof(enabled),
NULL, 0, &bytesReturned, NULL);
g_FirewallEnabled = enabled;
AddLogEntry(enabled ? "防火墙已启用" : "防火墙已禁用");
break;
}
}
break;
}
case WM_UPDATE_LOG:
UpdateLogList();
break;
case WM_DESTROY:
SaveRules();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
// 添加规则到列表
void AddRuleToList(const FirewallRule& rule) {
LVITEM lvi = {0};
lvi.mask = LVIF_TEXT;
char id[16], proto[16], dir[16], sip[16], sport[16], dip[16], dport[16], action[16], enabled[16];
sprintf_s(id, "%lu", rule.id);
sprintf_s(proto, "%s", rule.protocol == 6 ? "TCP" : (rule.protocol == 17 ? "UDP" : "ICMP"));
sprintf_s(dir, "%s", rule.direction == 0 ? "入站" : "出站");
sprintf_s(sip, "%lu.%lu.%lu.%lu",
(rule.srcIp >> 24) & 0xFF, (rule.srcIp >> 16) & 0xFF,
(rule.srcIp >> 8) & 0xFF, rule.srcIp & 0xFF);
sprintf_s(sport, "%lu", rule.srcPort);
sprintf_s(dip, "%lu.%lu.%lu.%lu",
(rule.dstIp >> 24) & 0xFF, (rule.dstIp >> 16) & 0xFF,
(rule.dstIp >> 8) & 0xFF, rule.dstIp & 0xFF);
sprintf_s(dport, "%lu", rule.dstPort);
sprintf_s(action, "%s", rule.action == 0 ? "阻止" : "允许");
sprintf_s(enabled, "%s", rule.enabled ? "启用" : "禁用");
lvi.iItem = ListView_GetItemCount(hRulesList);
ListView_InsertItem(hRulesList, &lvi);
ListView_SetItemText(hRulesList, lvi.iItem, 0, id);
ListView_SetItemText(hRulesList, lvi.iItem, 1, proto);
ListView_SetItemText(hRulesList, lvi.iItem, 2, dir);
ListView_SetItemText(hRulesList, lvi.iItem, 3, sip);
ListView_SetItemText(hRulesList, lvi.iItem, 4, sport);
ListView_SetItemText(hRulesList, lvi.iItem, 5, dip);
ListView_SetItemText(hRulesList, lvi.iItem, 6, dport);
ListView_SetItemText(hRulesList, lvi.iItem, 7, action);
ListView_SetItemText(hRulesList, lvi.iItem, 8, enabled);
}
// 加载规则
void LoadRules() {
std::ifstream file("firewall_rules.cfg");
if (!file.is_open()) return;
std::string line;
while (std::getline(file, line)) {
std::istringstream iss(line);
FirewallRule rule;
char proto[16], dir[16], action[16], enabled[16];
iss >> rule.id >> proto >> dir >> rule.srcIp >> rule.srcPort
>> rule.dstIp >> rule.dstPort >> action >> enabled;
if (strcmp(proto, "TCP") == 0) rule.protocol = 6;
else if (strcmp(proto, "UDP") == 0) rule.protocol = 17;
else rule.protocol = 1; // ICMP
rule.direction = (strcmp(dir, "入站") == 0) ? 0 : 1;
rule.action = (strcmp(action, "阻止") == 0) ? 0 : 1;
rule.enabled = (strcmp(enabled, "启用") == 0);
rules.push_back(rule);
}
file.close();
}
// 保存规则
void SaveRules() {
std::ofstream file("firewall_rules.cfg");
if (!file.is_open()) return;
for (const auto& rule : rules) {
const char* proto = rule.protocol == 6 ? "TCP" : (rule.protocol == 17 ? "UDP" : "ICMP");
const char* dir = rule.direction == 0 ? "入站" : "出站";
const char* action = rule.action == 0 ? "阻止" : "允许";
const char* enabled = rule.enabled ? "启用" : "禁用";
file << rule.id << " " << proto << " " << dir << " "
<< rule.srcIp << " " << rule.srcPort << " "
<< rule.dstIp << " " << rule.dstPort << " "
<< action << " " << enabled << "\n";
}
file.close();
}
// 添加日志条目
void AddLogEntry(const char* message) {
SYSTEMTIME st;
GetLocalTime(&st);
char timeStr[64];
sprintf_s(timeStr, "%04d-%02d-%02d %02d:%02d:%02d",
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
char logEntry[512];
sprintf_s(logEntry, "%s - %s", timeStr, message);
logEntries.push_back(logEntry);
// 更新UI
PostMessage(hMainWnd, WM_UPDATE_LOG, 0, 0);
}
参考代码 基于TDI驱动编写的个人防火墙程序 www.youwenfan.com/contentcst/122415.html
五、系统功能
5.1 核心功能
-
数据包过滤:
- 基于源/目标IP地址
- 基于源/目标端口
- 基于协议类型(TCP/UDP/ICMP)
- 基于方向(入站/出站)
-
规则管理:
- 添加/删除规则
- 启用/禁用规则
- 规则优先级管理
- 规则导入/导出
-
日志记录:
- 记录被阻止的连接
- 记录允许的连接
- 记录系统事件
- 日志查询和过滤
-
系统控制:
- 启用/禁用防火墙
- 重置统计信息
- 更新规则集
- 系统托盘图标
5.2 安全特性
- 防IP欺骗:验证源IP地址有效性
- 防端口扫描:检测异常连接请求
- DDoS防护:限制连接频率
- 应用层过滤:集成应用识别引擎
- 加密通信:保护管理通道
六、编译与部署
6.1 环境要求
- Windows 7/8/10/11 (32/64位)
- WDK 7.1或更高版本
- Visual Studio 2010或更高版本
- 管理员权限
6.2 编译步骤
-
安装WDK和Visual Studio
-
创建KMDF项目
-
添加TdiFirewall.c和TdiHook.c到项目
-
配置项目属性:
- 目标平台:Windows 7+
- 配置类型:驱动程序
- 签名:测试签名
-
编译驱动程序
-
编译用户态控制程序
6.3 安装步骤
-
以管理员身份运行命令提示符
-
使用sc命令安装驱动:
sc create TdiFirewall binPath= "C:\Path\To\TdiFirewall.sys" type= kernel start= demand sc start TdiFirewall -
运行用户态控制程序
-
配置防火墙规则
七、使用说明
7.1 基本操作
-
添加规则:
- 点击"添加规则"按钮
- 填写协议、方向、IP地址、端口
- 选择允许或阻止
- 保存规则
-
管理规则:
- 在规则列表中查看所有规则
- 右键点击规则进行编辑/删除
- 拖放规则调整优先级
-
查看日志:
- 在日志窗口查看所有事件
- 使用筛选器查找特定事件
- 导出日志到文件
-
系统控制:
- 使用工具栏按钮启用/禁用防火墙
- 配置自动启动选项
- 更新病毒库和规则库
7.2 高级功能
-
规则模板:
- 预定义常用规则(Web访问、邮件等)
- 一键应用模板
-
时间计划:
- 设置规则生效时间段
- 按日期安排规则
-
应用控制:
- 按应用程序设置规则
- 监控应用网络活动
-
网络监控:
- 实时显示网络连接
- 流量统计和分析
八、性能优化
8.1 驱动层优化
-
规则匹配算法:
- 使用哈希表加速规则查找
- 实现多级过滤(IP→端口→协议)
- 规则分组和索引
-
内存管理:
- 使用内存池减少分配开销
- 预分配数据包缓冲区
- 零拷贝技术
-
并发处理:
- 多核负载均衡
- 无锁数据结构
- 批处理网络事件
8.2 用户态优化
-
异步IO:
- 使用IO完成端口
- 异步规则更新
- 后台日志处理
-
UI优化:
- 虚拟列表显示大量规则
- 增量日志更新
- 数据缓存
-
配置管理:
- 增量规则更新
- 配置版本控制
- 自动备份
九、安全考虑
9.1 驱动安全
-
防篡改:
- 驱动代码签名
- 内存保护机制
- 反调试技术
-
稳定性:
- 异常处理机制
- 资源泄漏检测
- 压力测试
-
兼容性:
- 多版本Windows支持
- 不同网络环境适配
- 硬件兼容性测试
9.2 用户态安全
-
权限控制:
- 管理员权限要求
- 操作确认机制
- 敏感操作审计
-
数据安全:
- 规则加密存储
- 通信加密
- 防篡改机制
-
隐私保护:
- 匿名日志选项
- 数据最小化原则
- 用户数据控制
十、项目总结
本TDI个人防火墙程序实现了以下关键功能:
-
内核级网络过滤:
- 通过TDI驱动拦截网络数据包
- 实现高效的规则匹配算法
- 提供细粒度的访问控制
-
用户友好的管理界面:
- 直观的规则管理
- 实时的日志监控
- 灵活的系统配置
-
全面的日志系统:
- 详细记录网络活动
- 支持日志分析和过滤
- 提供安全事件告警
-
可扩展的架构:
- 模块化设计
- 插件式规则引擎
- 开放的API接口
技术挑战与解决方案:
-
TDI驱动开发复杂性:
- 使用WDK示例作为基础
- 分阶段实现功能
- 严格的测试流程
-
性能与安全的平衡:
- 优化规则匹配算法
- 使用高效的数据结构
- 实现智能过滤机制
-
系统兼容性问题:
- 多版本Windows测试
- 不同网络环境适配
- 用户反馈驱动改进