基于TDI驱动的个人防火墙程序设计与实现

基于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 核心组件

  1. TDI过滤驱动:内核层网络数据包拦截与过滤
  2. 用户态控制程序:提供用户界面和规则管理
  3. 规则引擎:实现访问控制策略
  4. 日志系统:记录网络活动和安全事件
  5. 配置管理:保存和加载防火墙配置

三、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 核心功能

  1. 数据包过滤

    • 基于源/目标IP地址
    • 基于源/目标端口
    • 基于协议类型(TCP/UDP/ICMP)
    • 基于方向(入站/出站)
  2. 规则管理

    • 添加/删除规则
    • 启用/禁用规则
    • 规则优先级管理
    • 规则导入/导出
  3. 日志记录

    • 记录被阻止的连接
    • 记录允许的连接
    • 记录系统事件
    • 日志查询和过滤
  4. 系统控制

    • 启用/禁用防火墙
    • 重置统计信息
    • 更新规则集
    • 系统托盘图标

5.2 安全特性

  1. 防IP欺骗:验证源IP地址有效性
  2. 防端口扫描:检测异常连接请求
  3. DDoS防护:限制连接频率
  4. 应用层过滤:集成应用识别引擎
  5. 加密通信:保护管理通道

六、编译与部署

6.1 环境要求

6.2 编译步骤

  1. 安装WDK和Visual Studio

  2. 创建KMDF项目

  3. 添加TdiFirewall.c和TdiHook.c到项目

  4. 配置项目属性:

    • 目标平台:Windows 7+
    • 配置类型:驱动程序
    • 签名:测试签名
  5. 编译驱动程序

  6. 编译用户态控制程序

6.3 安装步骤

  1. 以管理员身份运行命令提示符

  2. 使用sc命令安装驱动:

    sc create TdiFirewall binPath= "C:\Path\To\TdiFirewall.sys" type= kernel start= demand
    sc start TdiFirewall
    
  3. 运行用户态控制程序

  4. 配置防火墙规则

七、使用说明

7.1 基本操作

  1. 添加规则

    • 点击"添加规则"按钮
    • 填写协议、方向、IP地址、端口
    • 选择允许或阻止
    • 保存规则
  2. 管理规则

    • 在规则列表中查看所有规则
    • 右键点击规则进行编辑/删除
    • 拖放规则调整优先级
  3. 查看日志

    • 在日志窗口查看所有事件
    • 使用筛选器查找特定事件
    • 导出日志到文件
  4. 系统控制

    • 使用工具栏按钮启用/禁用防火墙
    • 配置自动启动选项
    • 更新病毒库和规则库

7.2 高级功能

  1. 规则模板

    • 预定义常用规则(Web访问、邮件等)
    • 一键应用模板
  2. 时间计划

    • 设置规则生效时间段
    • 按日期安排规则
  3. 应用控制

    • 按应用程序设置规则
    • 监控应用网络活动
  4. 网络监控

    • 实时显示网络连接
    • 流量统计和分析

八、性能优化

8.1 驱动层优化

  1. 规则匹配算法

    • 使用哈希表加速规则查找
    • 实现多级过滤(IP→端口→协议)
    • 规则分组和索引
  2. 内存管理

    • 使用内存池减少分配开销
    • 预分配数据包缓冲区
    • 零拷贝技术
  3. 并发处理

    • 多核负载均衡
    • 无锁数据结构
    • 批处理网络事件

8.2 用户态优化

  1. 异步IO

    • 使用IO完成端口
    • 异步规则更新
    • 后台日志处理
  2. UI优化

    • 虚拟列表显示大量规则
    • 增量日志更新
    • 数据缓存
  3. 配置管理

    • 增量规则更新
    • 配置版本控制
    • 自动备份

九、安全考虑

9.1 驱动安全

  1. 防篡改

    • 驱动代码签名
    • 内存保护机制
    • 反调试技术
  2. 稳定性

    • 异常处理机制
    • 资源泄漏检测
    • 压力测试
  3. 兼容性

    • 多版本Windows支持
    • 不同网络环境适配
    • 硬件兼容性测试

9.2 用户态安全

  1. 权限控制

    • 管理员权限要求
    • 操作确认机制
    • 敏感操作审计
  2. 数据安全

    • 规则加密存储
    • 通信加密
    • 防篡改机制
  3. 隐私保护

    • 匿名日志选项
    • 数据最小化原则
    • 用户数据控制

十、项目总结

本TDI个人防火墙程序实现了以下关键功能:

  1. 内核级网络过滤

    • 通过TDI驱动拦截网络数据包
    • 实现高效的规则匹配算法
    • 提供细粒度的访问控制
  2. 用户友好的管理界面

    • 直观的规则管理
    • 实时的日志监控
    • 灵活的系统配置
  3. 全面的日志系统

    • 详细记录网络活动
    • 支持日志分析和过滤
    • 提供安全事件告警
  4. 可扩展的架构

    • 模块化设计
    • 插件式规则引擎
    • 开放的API接口

技术挑战与解决方案

  1. TDI驱动开发复杂性

    • 使用WDK示例作为基础
    • 分阶段实现功能
    • 严格的测试流程
  2. 性能与安全的平衡

    • 优化规则匹配算法
    • 使用高效的数据结构
    • 实现智能过滤机制
  3. 系统兼容性问题

    • 多版本Windows测试
    • 不同网络环境适配
    • 用户反馈驱动改进

专注于matlab/simulink,电子电路,编程