A:剩余代码提交
This commit is contained in:
1 parent
50f50cb604
commit
117a6d783a
18 files changed
+1793
-1
No files matched your search
@@ -19,6 +19,7 @@
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMonitor_002Ecs_002Fl_003AC_0021_003FUsers_003Fcharlatans_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F211e6f3b24fa438a92f1815153647ce2c8f908_003Fb5_003F0c446809_003FMonitor_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANetworkInterface_002Ecs_002Fl_003AC_0021_003FUsers_003Fcharlatans_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F9c72a65889eb40ae9d8e0f130d1572e0268a0_003F34_003F49f5e6ff_003FNetworkInterface_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AProcess_002Ecs_002Fl_003AC_0021_003FUsers_003Fcharlatans_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4a26a752ec6249c4a090905d31c0cdfa528a0_003F8f_003F7037e590_003FProcess_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AQueue_00601_002Ecs_002Fl_003AC_0021_003FUsers_003Fcharlatans_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F211e6f3b24fa438a92f1815153647ce2c8f908_003Fa1_003F352e385c_003FQueue_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AReaderWriterLockSlim_002Ecs_002Fl_003AC_0021_003FUsers_003Fcharlatans_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F211e6f3b24fa438a92f1815153647ce2c8f908_003Fb5_003Fa78f431c_003FReaderWriterLockSlim_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AReadOnlyCollectionBase_002Ecs_002Fl_003AC_0021_003FUsers_003Fcharlatans_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4c1fd115dbe5414db1b4da1de3e96c5819910_003F04_003Fcae9fe22_003FReadOnlyCollectionBase_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASemaphoreSlim_002Ecs_002Fl_003AC_0021_003FUsers_003Fcharlatans_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F211e6f3b24fa438a92f1815153647ce2c8f908_003Fe9_003F4d4110fd_003FSemaphoreSlim_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
|
||||
@@ -36,8 +36,14 @@ public partial class WebPanel : UserControl
|
||||
webSocketManager.RegisterHandler("etwNetworkManger", async (cmd, socket) =>
|
||||
{
|
||||
Console.WriteLine("开始测试");
|
||||
|
||||
// 创建监听实例
|
||||
var etwNetworkManger = new EtwNetworkManger();
|
||||
etwNetworkManger.SetupETWHandlers();
|
||||
|
||||
// 设置 ETW 监听
|
||||
etwNetworkManger.SetupEtwHandlers();
|
||||
|
||||
// 开始监听
|
||||
etwNetworkManger.StartCapture();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace Utils.ETW.Test;
|
||||
|
||||
public class Tests
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test1()
|
||||
{
|
||||
Class1.Main();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
|
||||
<PackageReference Include="NUnit" Version="3.14.0"/>
|
||||
<PackageReference Include="NUnit.Analyzers" Version="3.9.0"/>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="NUnit.Framework"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Utils.ETW\Utils.ETW.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,119 @@
|
||||
using Microsoft.Diagnostics.Tracing.Parsers;
|
||||
using Microsoft.Diagnostics.Tracing.Session;
|
||||
|
||||
namespace Utils.ETW;
|
||||
|
||||
public static class Class1
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
Console.WriteLine($"这是ue安徽委会aweifawejiofawoi");
|
||||
|
||||
// if (TraceEventSession.IsElevated() == true)
|
||||
// {
|
||||
// Console.WriteLine("请以管理员身份运行此程序!");
|
||||
// return;
|
||||
// }
|
||||
|
||||
using (var session = new TraceEventSession("MyNetSession"))
|
||||
{
|
||||
// 启用网络内核事件(包括 TCP/UDP)
|
||||
session.EnableKernelProvider(KernelTraceEventParser.Keywords.NetworkTCPIP);
|
||||
|
||||
session.Source.Kernel.TcpIpRecv += data =>
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"[RECV] PID: {data.ProcessID} {data.saddr}:{data.sport} → {data.daddr}:{data.dport} {data.size} bytes");
|
||||
};
|
||||
|
||||
session.Source.Kernel.TcpIpSend += data =>
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"[SEND] PID: {data.ProcessID} {data.saddr}:{data.sport} → {data.daddr}:{data.dport} {data.size} bytes");
|
||||
};
|
||||
|
||||
Console.WriteLine("监听中... 按 Ctrl+C 退出");
|
||||
session.Source.Process(); // 开始监听事件(阻塞)
|
||||
}
|
||||
}
|
||||
|
||||
public static void Main2()
|
||||
{
|
||||
// Create real-time user session
|
||||
using (var session = new TraceEventSession("MyKernelSession"))
|
||||
{
|
||||
// Enable Kernel Network events
|
||||
session.EnableKernelProvider(
|
||||
KernelTraceEventParser.Keywords.NetworkTCPIP |
|
||||
KernelTraceEventParser.Keywords.Process |
|
||||
KernelTraceEventParser.Keywords.ImageLoad);
|
||||
|
||||
// Hook into real-time events
|
||||
session.Source.Kernel.TcpIpRecv += data =>
|
||||
{
|
||||
Console.WriteLine(
|
||||
$">>> TCP RECV: {data.ProcessID} -> {data.daddr}:{data.dport} [{data.size} bytes]");
|
||||
};
|
||||
|
||||
session.Source.Kernel.TcpIpSend += data =>
|
||||
{
|
||||
Console.WriteLine(
|
||||
$">>> TCP SEND: {data.ProcessID} -> {data.daddr}:{data.dport} [{data.size} bytes]");
|
||||
};
|
||||
|
||||
session.Source.Kernel.UdpIpRecv += data =>
|
||||
{
|
||||
Console.WriteLine(
|
||||
$">>> UDP RECV: {data.ProcessID} -> {data.daddr}:{data.dport} [{data.size} bytes]");
|
||||
};
|
||||
|
||||
session.Source.Kernel.UdpIpSend += data =>
|
||||
{
|
||||
Console.WriteLine(
|
||||
$">>> UDP SEND: {data.ProcessID} -> {data.daddr}:{data.dport} [{data.size} bytes]");
|
||||
};
|
||||
|
||||
/*
|
||||
* 当 新进程启动 时触发。
|
||||
🔧 事件信息:
|
||||
data.ProcessID:启动的进程 ID。
|
||||
data.ImageFileName:可执行文件的名称(例如 chrome.exe)。
|
||||
data.CommandLine:启动进程时使用的完整命令行参数。
|
||||
*/
|
||||
session.Source.Kernel.ProcessStart += data =>
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"[PROCESS START] PID={data.ProcessID} Name={data.ImageFileName} Cmd={data.CommandLine}");
|
||||
};
|
||||
/*
|
||||
* 当 进程结束 时触发。
|
||||
🔧 事件信息:
|
||||
data.ProcessID:终止的进程 ID。
|
||||
data.ImageFileName:进程对应的可执行文件名。
|
||||
✅ 应用场景:
|
||||
用于记录进程的退出事件,可以用来做进程生命周期分析。
|
||||
*/
|
||||
session.Source.Kernel.ProcessStop += data =>
|
||||
{
|
||||
Console.WriteLine($"[PROCESS STOP] PID={data.ProcessID} Name={data.ImageFileName}");
|
||||
};
|
||||
|
||||
/*
|
||||
当某个模块(例如 DLL 或 EXE)被加载到某个进程时触发。
|
||||
🔧 事件信息:
|
||||
data.ProcessID:加载模块的进程 ID。
|
||||
data.FileName:被加载的模块路径(例如 C:\Windows\System32\kernel32.dll)。
|
||||
✅ 应用场景:
|
||||
可以监控某些敏感模块是否被加载,如某些反调试或注入行为。
|
||||
*/
|
||||
session.Source.Kernel.ImageLoad += data =>
|
||||
{
|
||||
Console.WriteLine($"[MODULE LOAD] PID={data.ProcessID} Image={data.FileName}");
|
||||
};
|
||||
|
||||
Console.CancelKeyPress += (o, e) => session.Dispose();
|
||||
|
||||
session.Source.Process();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,463 @@
|
||||
using Microsoft.Diagnostics.Tracing;
|
||||
using Microsoft.Diagnostics.Tracing.Parsers;
|
||||
using Microsoft.Diagnostics.Tracing.Session;
|
||||
using Utils.ETW.Models;
|
||||
|
||||
namespace Utils.ETW.Core;
|
||||
|
||||
|
||||
// ETW网络事件处理器
|
||||
public class EtwNetworkCapture(string sessionName = "NetworkETWSession") : IDisposable
|
||||
{
|
||||
private readonly TraceEventSession _session = new(sessionName);
|
||||
private readonly ETWTraceEventSource _source = new(sessionName, TraceEventSourceType.Session);
|
||||
|
||||
/// <summary>
|
||||
/// 是否正在监听
|
||||
/// </summary>
|
||||
private bool _isCapturing = false;
|
||||
|
||||
// 事件处理委托
|
||||
public delegate void NetworkEventHandler(NetworkEventData eventData);
|
||||
|
||||
public delegate void TcpConnectionEventHandler(TcpConnectionEventData eventData);
|
||||
|
||||
public delegate void UdpPacketEventHandler(UdpPacketEventData eventData);
|
||||
|
||||
public delegate void DnsEventHandler(DnsEventData eventData);
|
||||
|
||||
public delegate void HttpEventHandler(HttpEventData eventData);
|
||||
|
||||
public delegate void NetworkInterfaceEventHandler(NetworkInterfaceEventData eventData);
|
||||
|
||||
public delegate void NetworkErrorEventHandler(NetworkErrorEventData eventData);
|
||||
|
||||
// 事件处理器
|
||||
|
||||
/// <summary>
|
||||
/// 通用网络事件处理,所有的网络事件都会进入该函数
|
||||
/// </summary>
|
||||
public event NetworkEventHandler? OnNetworkEvent;
|
||||
public event TcpConnectionEventHandler? OnTcpConnectionEvent;
|
||||
public event UdpPacketEventHandler? OnUdpPacketEvent;
|
||||
public event DnsEventHandler? OnDnsEvent;
|
||||
public event HttpEventHandler? OnHttpEvent;
|
||||
public event NetworkInterfaceEventHandler? OnNetworkInterfaceEvent;
|
||||
public event NetworkErrorEventHandler? OnNetworkErrorEvent;
|
||||
|
||||
/// <summary>
|
||||
/// 开始监听
|
||||
/// </summary>
|
||||
public void StartCapture()
|
||||
{
|
||||
if (_isCapturing) return;
|
||||
|
||||
try
|
||||
{
|
||||
// 启用网络相关的ETW提供程序
|
||||
EnableNetworkProviders();
|
||||
|
||||
// 设置事件处理器
|
||||
SetupEventHandlers();
|
||||
|
||||
_isCapturing = true;
|
||||
|
||||
// 开始处理事件(这是阻塞调用)
|
||||
Task.Run(() => { _source.Process(); });
|
||||
|
||||
Console.WriteLine("ETW网络捕获已启动...");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"启动ETW捕获失败: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置监听的 Providers
|
||||
/// </summary>
|
||||
private void EnableNetworkProviders()
|
||||
{
|
||||
// 启用内核网络事件
|
||||
_session.EnableKernelProvider(
|
||||
KernelTraceEventParser.Keywords.NetworkTCPIP
|
||||
);
|
||||
|
||||
|
||||
// 启用TCP/IP提供程序
|
||||
_session.EnableProvider("Microsoft-Windows-TCPIP",
|
||||
TraceEventLevel.Informational);
|
||||
|
||||
// 启用Winsock AFD提供程序
|
||||
/*
|
||||
*哪个进程创建了 socket
|
||||
每个 socket 的本地/远程地址、端口
|
||||
Socket 错误、阻塞、超时
|
||||
发送/接收的字节数
|
||||
使用了什么协议(TCP/UDP)
|
||||
*
|
||||
*/
|
||||
_session.EnableProvider("Microsoft-Windows-Winsock-AFD",
|
||||
TraceEventLevel.Informational);
|
||||
|
||||
// 启用DNS客户端提供程序
|
||||
_session.EnableProvider("Microsoft-Windows-DNS-Client",
|
||||
TraceEventLevel.Informational);
|
||||
|
||||
// 启用HTTP服务提供程序
|
||||
_session.EnableProvider("Microsoft-Windows-HttpService",
|
||||
TraceEventLevel.Informational);
|
||||
|
||||
// 启用网络配置文件提供程序
|
||||
_session.EnableProvider("Microsoft-Windows-NetworkProfile",
|
||||
TraceEventLevel.Informational);
|
||||
|
||||
// 监控 DNS 查询行为
|
||||
_session.EnableProvider("Microsoft-Windows-DNS-Client",
|
||||
TraceEventLevel.Informational);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置监听事件
|
||||
/// </summary>
|
||||
private void SetupEventHandlers()
|
||||
{
|
||||
var parser = new KernelTraceEventParser(_source);
|
||||
|
||||
// TCP连接事件
|
||||
parser.TcpIpConnect += data =>
|
||||
{
|
||||
var tcpEvent = new TcpConnectionEventData
|
||||
{
|
||||
Timestamp = data.TimeStamp,
|
||||
EventType = "TcpConnect",
|
||||
ProcessId = data.ProcessID,
|
||||
ThreadId = data.ThreadID,
|
||||
ProcessName = data.ProcessName,
|
||||
SourceIp = data.saddr,
|
||||
DestinationIp = data.daddr,
|
||||
SourcePort = data.sport,
|
||||
DestinationPort = data.dport,
|
||||
Protocol = "TCP",
|
||||
ConnectionState = "ESTABLISHED",
|
||||
Direction = TrafficDirection.Outbound
|
||||
};
|
||||
|
||||
OnTcpConnectionEvent?.Invoke(tcpEvent);
|
||||
OnNetworkEvent?.Invoke(tcpEvent);
|
||||
};
|
||||
|
||||
// TCP断开连接事件
|
||||
parser.TcpIpDisconnect += data =>
|
||||
{
|
||||
var tcpEvent = new TcpConnectionEventData
|
||||
{
|
||||
Timestamp = data.TimeStamp,
|
||||
EventType = "TcpDisconnect",
|
||||
ProcessId = data.ProcessID,
|
||||
ThreadId = data.ThreadID,
|
||||
ProcessName = data.ProcessName,
|
||||
SourceIp = data.saddr,
|
||||
DestinationIp = data.daddr,
|
||||
SourcePort = data.sport,
|
||||
DestinationPort = data.dport,
|
||||
Protocol = "TCP",
|
||||
ConnectionState = "CLOSED",
|
||||
Direction = TrafficDirection.Outbound
|
||||
};
|
||||
|
||||
OnTcpConnectionEvent?.Invoke(tcpEvent);
|
||||
OnNetworkEvent?.Invoke(tcpEvent);
|
||||
};
|
||||
|
||||
// TCP数据发送事件
|
||||
parser.TcpIpSend += data =>
|
||||
{
|
||||
var tcpEvent = new TcpConnectionEventData
|
||||
{
|
||||
Timestamp = data.TimeStamp,
|
||||
EventType = "TcpSend",
|
||||
ProcessId = data.ProcessID,
|
||||
ThreadId = data.ThreadID,
|
||||
ProcessName = data.ProcessName,
|
||||
SourceIp = data.saddr,
|
||||
DestinationIp = data.daddr,
|
||||
SourcePort = data.sport,
|
||||
DestinationPort = data.dport,
|
||||
Protocol = "TCP",
|
||||
DataLength = data.size,
|
||||
SequenceNumber = data.seqnum,
|
||||
Direction = TrafficDirection.Outbound
|
||||
};
|
||||
|
||||
OnTcpConnectionEvent?.Invoke(tcpEvent);
|
||||
OnNetworkEvent?.Invoke(tcpEvent);
|
||||
};
|
||||
|
||||
// TCP数据接收事件
|
||||
parser.TcpIpRecv += data =>
|
||||
{
|
||||
var tcpEvent = new TcpConnectionEventData
|
||||
{
|
||||
Timestamp = data.TimeStamp,
|
||||
EventType = "TcpReceive",
|
||||
ProcessId = data.ProcessID,
|
||||
ThreadId = data.ThreadID,
|
||||
ProcessName = data.ProcessName,
|
||||
SourceIp = data.saddr,
|
||||
DestinationIp = data.daddr,
|
||||
SourcePort = data.sport,
|
||||
DestinationPort = data.dport,
|
||||
Protocol = "TCP",
|
||||
DataLength = data.size,
|
||||
SequenceNumber = data.seqnum,
|
||||
Direction = TrafficDirection.Inbound
|
||||
};
|
||||
|
||||
OnTcpConnectionEvent?.Invoke(tcpEvent);
|
||||
OnNetworkEvent?.Invoke(tcpEvent);
|
||||
};
|
||||
|
||||
// UDP发送事件
|
||||
parser.UdpIpSend += data =>
|
||||
{
|
||||
var udpEvent = new UdpPacketEventData
|
||||
{
|
||||
Timestamp = data.TimeStamp,
|
||||
EventType = "UdpSend",
|
||||
ProcessId = data.ProcessID,
|
||||
ThreadId = data.ThreadID,
|
||||
ProcessName = data.ProcessName,
|
||||
SourceIp = data.saddr,
|
||||
DestinationIp = data.daddr,
|
||||
SourcePort = data.sport,
|
||||
DestinationPort = data.dport,
|
||||
Protocol = "UDP",
|
||||
DataLength = data.size,
|
||||
UdpLength = data.size,
|
||||
Direction = TrafficDirection.Outbound
|
||||
};
|
||||
|
||||
OnUdpPacketEvent?.Invoke(udpEvent);
|
||||
OnNetworkEvent?.Invoke(udpEvent);
|
||||
};
|
||||
|
||||
// UDP接收事件
|
||||
parser.UdpIpRecv += data =>
|
||||
{
|
||||
var udpEvent = new UdpPacketEventData
|
||||
{
|
||||
Timestamp = data.TimeStamp,
|
||||
EventType = "UdpReceive",
|
||||
ProcessId = data.ProcessID,
|
||||
ThreadId = data.ThreadID,
|
||||
ProcessName = data.ProcessName,
|
||||
SourceIp = data.saddr,
|
||||
DestinationIp = data.daddr,
|
||||
SourcePort = data.sport,
|
||||
DestinationPort = data.dport,
|
||||
Protocol = "UDP",
|
||||
DataLength = data.size,
|
||||
UdpLength = data.size,
|
||||
Direction = TrafficDirection.Inbound
|
||||
};
|
||||
|
||||
OnUdpPacketEvent?.Invoke(udpEvent);
|
||||
OnNetworkEvent?.Invoke(udpEvent);
|
||||
};
|
||||
|
||||
// 通用事件处理器,用于其他网络事件
|
||||
_source.Dynamic.All += data =>
|
||||
{
|
||||
// 处理DNS、HTTP等其他网络事件
|
||||
ProcessDynamicEvent(data);
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通用事件处理器,用于其他网络事件
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
private void ProcessDynamicEvent(TraceEvent data)
|
||||
{
|
||||
// 根据提供程序名称和事件ID处理不同类型的网络事件
|
||||
switch (data.ProviderName)
|
||||
{
|
||||
case "Microsoft-Windows-DNS-Client":
|
||||
ProcessDnsEvent(data);
|
||||
break;
|
||||
case "Microsoft-Windows-HttpService":
|
||||
ProcessHttpEvent(data);
|
||||
break;
|
||||
case "Microsoft-Windows-NetworkProfile":
|
||||
ProcessNetworkInterfaceEvent(data);
|
||||
break;
|
||||
// 负责 TCP/IP 协议栈事件,如连接、发送、接收、断开、重传等
|
||||
// 用于监控 TCP 会话生命周期,是连接追踪的核心
|
||||
case "Microsoft-Windows-TCPIP":
|
||||
// AFD(Ancillary Function Driver for WinSock)是 Winsock API 的核心内核模块
|
||||
// 常用于检测哪一个进程创建了 socket,socket 和 TCP 会话的关联
|
||||
case "Microsoft-Windows-Winsock-AFD":
|
||||
// 也叫 Kernel-Network
|
||||
case "MSNT_SystemTrace":
|
||||
break;
|
||||
default:
|
||||
// 处理其他网络事件
|
||||
ProcessGenericNetworkEvent(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessDnsEvent(TraceEvent data)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dnsEvent = new DnsEventData
|
||||
{
|
||||
Timestamp = data.TimeStamp,
|
||||
EventType = "DnsQuery",
|
||||
ProcessId = data.ProcessID,
|
||||
ThreadId = data.ThreadID,
|
||||
ProcessName = data.ProcessName,
|
||||
Protocol = "DNS"
|
||||
};
|
||||
|
||||
// 从事件数据中提取DNS特定信息
|
||||
if (data.PayloadNames.Contains("QueryName"))
|
||||
dnsEvent.QueryName = data.PayloadStringByName("QueryName");
|
||||
if (data.PayloadNames.Contains("QueryType"))
|
||||
dnsEvent.QueryType = data.PayloadStringByName("QueryType");
|
||||
|
||||
OnDnsEvent?.Invoke(dnsEvent);
|
||||
OnNetworkEvent?.Invoke(dnsEvent);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"处理DNS事件时出错: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessHttpEvent(TraceEvent data)
|
||||
{
|
||||
try
|
||||
{
|
||||
var httpEvent = new HttpEventData
|
||||
{
|
||||
Timestamp = data.TimeStamp,
|
||||
EventType = "HttpRequest",
|
||||
ProcessId = data.ProcessID,
|
||||
ThreadId = data.ThreadID,
|
||||
ProcessName = data.ProcessName,
|
||||
Protocol = "HTTP"
|
||||
};
|
||||
|
||||
// 从事件数据中提取HTTP特定信息
|
||||
if (data.PayloadNames.Contains("Url"))
|
||||
httpEvent.Url = data.PayloadStringByName("Url");
|
||||
if (data.PayloadNames.Contains("Method"))
|
||||
httpEvent.HttpMethod = data.PayloadStringByName("Method");
|
||||
|
||||
OnHttpEvent?.Invoke(httpEvent);
|
||||
OnNetworkEvent?.Invoke(httpEvent);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"处理HTTP事件时出错: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络配置发生变化
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
private void ProcessNetworkInterfaceEvent(TraceEvent data)
|
||||
{
|
||||
try
|
||||
{
|
||||
var interfaceEvent = new NetworkInterfaceEventData
|
||||
{
|
||||
Timestamp = data.TimeStamp,
|
||||
EventType = "NetworkInterface",
|
||||
ProcessId = data.ProcessID,
|
||||
ThreadId = data.ThreadID,
|
||||
ProcessName = data.ProcessName
|
||||
};
|
||||
|
||||
// 从事件数据中提取网络接口信息
|
||||
if (data.PayloadNames.Contains("InterfaceName"))
|
||||
interfaceEvent.InterfaceName = data.PayloadStringByName("InterfaceName");
|
||||
|
||||
OnNetworkInterfaceEvent?.Invoke(interfaceEvent);
|
||||
OnNetworkEvent?.Invoke(interfaceEvent);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"处理网络接口事件时出错: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理其他网络事件
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
private void ProcessGenericNetworkEvent(TraceEvent data)
|
||||
{
|
||||
try
|
||||
{
|
||||
var networkEvent = new NetworkEventData
|
||||
{
|
||||
Timestamp = data.TimeStamp,
|
||||
EventType = data.EventName,
|
||||
ProcessId = data.ProcessID,
|
||||
ThreadId = data.ThreadID,
|
||||
ProcessName = data.ProcessName
|
||||
};
|
||||
Console.WriteLine($"data.PayloadName :=> {data.ProviderName}");
|
||||
|
||||
// 提取通用网络信息
|
||||
foreach (var payloadName in data.PayloadNames)
|
||||
{
|
||||
try
|
||||
{
|
||||
var value = data.PayloadByName(payloadName);
|
||||
networkEvent.AdditionalProperties[payloadName] = value;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 忽略无法获取的字段
|
||||
}
|
||||
}
|
||||
|
||||
OnNetworkEvent?.Invoke(networkEvent);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"处理通用网络事件时出错: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public void StopCapture()
|
||||
{
|
||||
if (!_isCapturing) return;
|
||||
|
||||
try
|
||||
{
|
||||
_isCapturing = false;
|
||||
_session.Stop();
|
||||
_source.Dispose();
|
||||
Console.WriteLine("ETW网络捕获已停止");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"停止ETW捕获时出错: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
StopCapture();
|
||||
_session.Dispose();
|
||||
_source.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Utils.ETW.EtwTracker;
|
||||
using Utils.ETW.Models;
|
||||
|
||||
namespace Utils.ETW.Core;
|
||||
|
||||
public class DnsTracker : INetTracker
|
||||
{
|
||||
public void SetupEtwHandlers(EtwNetworkCapture networkCapture)
|
||||
{
|
||||
networkCapture.OnDnsEvent += dnsEvent =>
|
||||
{
|
||||
Console.WriteLine($"[DNS] 查询: {dnsEvent.QueryName} ({dnsEvent.QueryType})");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class HttpTracker : INetTracker
|
||||
{
|
||||
public void SetupEtwHandlers(EtwNetworkCapture networkCapture)
|
||||
{
|
||||
networkCapture.OnHttpEvent += httpEvent =>
|
||||
{
|
||||
Console.WriteLine($"[HTTP] {httpEvent.HttpMethod} {httpEvent.Url}");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class NetworkProfileTracker : INetTracker
|
||||
{
|
||||
public void SetupEtwHandlers(EtwNetworkCapture networkCapture)
|
||||
{
|
||||
networkCapture.OnNetworkInterfaceEvent += interfaceEvent =>
|
||||
{
|
||||
Console.WriteLine($"[Interface] {interfaceEvent.InterfaceName}: {interfaceEvent.InterfaceState}");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class NetworkTracker : INetTracker
|
||||
{
|
||||
/// <summary>
|
||||
/// 捕获的事件量
|
||||
/// </summary>
|
||||
private List<NetworkEventData> capturedEvents = new List<NetworkEventData>();
|
||||
|
||||
public void SetupEtwHandlers(EtwNetworkCapture networkCapture)
|
||||
{
|
||||
networkCapture.OnNetworkEvent += networkEvent => { capturedEvents.Add(networkEvent); };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class EtwNetworkManger
|
||||
{
|
||||
private UdpTracker udpTracker = new UdpTracker();
|
||||
private DnsTracker dnsTracker = new DnsTracker();
|
||||
private HttpTracker httpTracker = new HttpTracker();
|
||||
private NetworkProfileTracker networkProfileTracker = new NetworkProfileTracker();
|
||||
private NetworkTracker networkTracker = new NetworkTracker();
|
||||
private readonly TcpTracker _tcpTracker = new TcpTracker();
|
||||
|
||||
private EtwNetworkCapture networkCapture = new EtwNetworkCapture();
|
||||
|
||||
/// <summary>
|
||||
/// 设置信息处理器
|
||||
/// </summary>
|
||||
public void SetupEtwHandlers()
|
||||
{
|
||||
udpTracker.SetupEtwHandlers(networkCapture);
|
||||
// dnsTracker.SetupEtwHandlers(networkCapture);
|
||||
// httpTracker.SetupEtwHandlers(networkCapture);
|
||||
// networkProfileTracker.SetupEtwHandlers(networkCapture);
|
||||
// networkTracker.SetupEtwHandlers(networkCapture);
|
||||
|
||||
// _tcpTracker.SetupEtwHandlers(networkCapture);
|
||||
}
|
||||
|
||||
public void StartCapture()
|
||||
{
|
||||
networkCapture.StartCapture();
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
networkCapture.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using Utils.ETW.Models;
|
||||
|
||||
namespace Utils.ETW.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 网络信息缓存【全局 TCP、UDP 等连接信息存储】
|
||||
/// </summary>
|
||||
public sealed class NetworkCache
|
||||
{
|
||||
private static readonly Lazy<NetworkCache> _instance = new(() => new NetworkCache());
|
||||
|
||||
public static NetworkCache Instance => _instance.Value;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化字典大小 避免频繁扩容
|
||||
/// </summary>
|
||||
private static readonly int InitCapacity = 1_000;
|
||||
|
||||
// 私有构造函数,禁止外部创建实例
|
||||
private NetworkCache()
|
||||
{
|
||||
// 初始化缓存等操作
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 缓存字典
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, NetworkModel> _cache = new(InitCapacity);
|
||||
|
||||
// 设置缓存
|
||||
public void Set(string key, NetworkModel value)
|
||||
{
|
||||
lock (_cache)
|
||||
{
|
||||
_cache[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public NetworkModel? Get(string key)
|
||||
{
|
||||
lock (_cache)
|
||||
{
|
||||
return _cache.GetValueOrDefault(key);
|
||||
}
|
||||
}
|
||||
|
||||
// 移除缓存
|
||||
public void Remove(string key)
|
||||
{
|
||||
lock (_cache)
|
||||
{
|
||||
_cache.Remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net;
|
||||
using Utils.ETW.Models;
|
||||
|
||||
namespace Utils.ETW.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 网络信息管理【网络活动记录】
|
||||
/// </summary>
|
||||
public sealed class NetworkInfoManger
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络日志
|
||||
/// </summary>
|
||||
Queue<string> networkEvents = new();
|
||||
|
||||
/// <summary>
|
||||
/// 最大日志记录条数
|
||||
/// </summary>
|
||||
public int NetworkEventsMaxSize = 1_000;
|
||||
|
||||
/// <summary>
|
||||
/// 活跃的 TCP 连接
|
||||
/// </summary>
|
||||
private readonly ConcurrentDictionary<string, NetworkModel> _activeTcpSessions = new();
|
||||
|
||||
/// <summary>
|
||||
/// 活跃的 UDP 连接
|
||||
/// </summary>
|
||||
private readonly ConcurrentDictionary<string, NetworkModel> _activeUdpSessions = new();
|
||||
|
||||
private static readonly Lazy<NetworkInfoManger> _instance = new(() => new NetworkInfoManger());
|
||||
|
||||
/// <summary>
|
||||
/// 端口流量记录
|
||||
/// </summary>
|
||||
public readonly Dictionary<int, ulong> PortTrafficSent = new();
|
||||
public readonly Dictionary<int, ulong> PortTrafficReceived = new();
|
||||
|
||||
/// <summary>
|
||||
/// IP 流量记录
|
||||
/// </summary>
|
||||
public readonly Dictionary<IPAddress, ulong> SourceTrafficSent = new();
|
||||
public readonly Dictionary<IPAddress, ulong> SourceTrafficReceived = new();
|
||||
|
||||
public static NetworkInfoManger Instance => _instance.Value;
|
||||
|
||||
private NetworkInfoManger()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#region TCP 缓存信息
|
||||
|
||||
public void SetTcpCache(string key, NetworkModel value)
|
||||
{
|
||||
_activeTcpSessions[key] = value;
|
||||
}
|
||||
public void SetTcpCache(NetworkModel value)
|
||||
{
|
||||
_activeTcpSessions[value.GetKey()] = value;
|
||||
}
|
||||
public (bool tryRemove, NetworkModel? session) RemoveTcpCache(NetworkModel value)
|
||||
{
|
||||
return RemoveTcpCache(value.GetKey());
|
||||
}
|
||||
public (bool tryRemove, NetworkModel? session) RemoveTcpCache(string str)
|
||||
{
|
||||
var tryRemove = _activeTcpSessions.TryRemove(str, out var session);
|
||||
return (tryRemove, session);
|
||||
}
|
||||
public int GetTcpSize()
|
||||
=> _activeTcpSessions.Count;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region UDP 缓存信息
|
||||
|
||||
public void SetUdpCache(string key, NetworkModel value)
|
||||
{
|
||||
_activeUdpSessions[key] = value;
|
||||
}
|
||||
public void SetUdpCache(NetworkModel value)
|
||||
{
|
||||
_activeUdpSessions[value.GetKey()] = value;
|
||||
}
|
||||
public (bool tryRemove, NetworkModel? session) RemoveUdpCache(NetworkModel value)
|
||||
{
|
||||
return RemoveUdpCache(value.GetKey());
|
||||
}
|
||||
public (bool tryRemove, NetworkModel? session) RemoveUdpCache(string str)
|
||||
{
|
||||
var tryRemove = _activeUdpSessions.TryRemove(str, out var session);
|
||||
return (tryRemove, session);
|
||||
}
|
||||
public int GetUdpSize()
|
||||
=> _activeUdpSessions.Count;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 记录动作
|
||||
/// </summary>
|
||||
/// <param name="eventStr"></param>
|
||||
public void RecordEvent(string eventStr)
|
||||
{
|
||||
if (networkEvents.Count >= NetworkEventsMaxSize)
|
||||
networkEvents.Dequeue(); // 超出最大长度时,移除旧数据
|
||||
|
||||
networkEvents.Enqueue(eventStr);
|
||||
}
|
||||
|
||||
// todo: 2025年6月2日 22点00分 统计每个连接的时长、流量 (检测是否是僵尸进程【长连接,但低流量】);统计当前活跃连接
|
||||
// todo: 2025年6月2日 22点01分 按照 端口、IP 统计流量
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
using System.Net;
|
||||
using Utils.ETW.EtwTracker;
|
||||
using Utils.ETW.Models;
|
||||
|
||||
namespace Utils.ETW.Core;
|
||||
|
||||
public class UdpTracker : INetTracker
|
||||
{
|
||||
private Dictionary<int, int> portTraffic = new();
|
||||
private Dictionary<IPAddress, int> sourceTraffic = new();
|
||||
|
||||
public void SetupEtwHandlers(EtwNetworkCapture networkCapture)
|
||||
{
|
||||
networkCapture.OnUdpPacketEvent += (udpEvent) =>
|
||||
{
|
||||
Console.WriteLine($"[UDP] {udpEvent.EventType}: {udpEvent.SourceIp}:{udpEvent.SourcePort} -> " +
|
||||
$"{udpEvent.DestinationIp}:{udpEvent.DestinationPort} ({udpEvent.DataLength} bytes)");
|
||||
|
||||
// UDP处理主要关注数据包本身,而不是连接状态
|
||||
UpdateTrafficStats(udpEvent);
|
||||
|
||||
// 根据端口进行专门处理
|
||||
switch (udpEvent.DestinationPort)
|
||||
{
|
||||
case 53: // DNS
|
||||
ProcessDnsPacket(udpEvent);
|
||||
break;
|
||||
case 123: // NTP
|
||||
ProcessNtpPacket(udpEvent);
|
||||
break;
|
||||
case 67:
|
||||
case 68: // DHCP
|
||||
ProcessDhcpPacket(udpEvent);
|
||||
break;
|
||||
default:
|
||||
ProcessGenericUdpPacket(udpEvent);
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void UpdateTrafficStats(UdpPacketEventData udpEvent)
|
||||
{
|
||||
// 统计端口流量
|
||||
if (!portTraffic.ContainsKey(udpEvent.DestinationPort))
|
||||
portTraffic[udpEvent.DestinationPort] = 0;
|
||||
portTraffic[udpEvent.DestinationPort] += udpEvent.DataLength;
|
||||
|
||||
// 统计源IP流量
|
||||
if (!sourceTraffic.ContainsKey(udpEvent.SourceIp))
|
||||
sourceTraffic[udpEvent.SourceIp] = 0;
|
||||
sourceTraffic[udpEvent.SourceIp] += udpEvent.DataLength;
|
||||
}
|
||||
|
||||
private void ProcessDnsPacket(UdpPacketEventData udpEvent)
|
||||
{
|
||||
// 连接建立时间
|
||||
var lastSeenTime = DateTime.Now;
|
||||
|
||||
var networkModel = new NetworkModel
|
||||
{
|
||||
ConnectType = ProtocolType.UDP,
|
||||
ProcessId = udpEvent.ProcessId,
|
||||
ThreadId = udpEvent.ThreadId,
|
||||
ProcessName = udpEvent.ProcessName,
|
||||
SourceIp = udpEvent.SourceIp,
|
||||
DestinationIp = udpEvent.DestinationIp,
|
||||
LastSeenTime = lastSeenTime,
|
||||
BytesSent = 0,
|
||||
BytesReceived = 0,
|
||||
State = ConnectionState.Connecting,
|
||||
SourcePort = udpEvent.SourcePort,
|
||||
DestinationPort = udpEvent.DestinationPort,
|
||||
StartTime = lastSeenTime,
|
||||
Direction = udpEvent.Direction,
|
||||
RecordTime = lastSeenTime,
|
||||
IsPartialConnection = true,
|
||||
};
|
||||
|
||||
NetworkInfoManger.Instance.SetUdpCache(networkModel);
|
||||
|
||||
string str = $"连接建立: {networkModel.DestinationIp}:{networkModel.DestinationPort} ," +
|
||||
$"地址: {networkModel.SourceIp}:{networkModel.SourcePort}";
|
||||
NetworkInfoManger.Instance.RecordEvent(str);
|
||||
}
|
||||
|
||||
private void ProcessNtpPacket(UdpPacketEventData udpEvent)
|
||||
{
|
||||
// 连接建立时间
|
||||
var lastSeenTime = DateTime.Now;
|
||||
|
||||
var networkModel = new NetworkModel
|
||||
{
|
||||
ConnectType = ProtocolType.UDP,
|
||||
ProcessId = udpEvent.ProcessId,
|
||||
ThreadId = udpEvent.ThreadId,
|
||||
ProcessName = udpEvent.ProcessName,
|
||||
SourceIp = udpEvent.SourceIp,
|
||||
DestinationIp = udpEvent.DestinationIp,
|
||||
LastSeenTime = lastSeenTime,
|
||||
BytesSent = 0,
|
||||
BytesReceived = 0,
|
||||
State = ConnectionState.Connecting,
|
||||
SourcePort = udpEvent.SourcePort,
|
||||
DestinationPort = udpEvent.DestinationPort,
|
||||
StartTime = lastSeenTime,
|
||||
Direction = udpEvent.Direction,
|
||||
RecordTime = lastSeenTime,
|
||||
IsPartialConnection = true,
|
||||
};
|
||||
|
||||
NetworkInfoManger.Instance.SetUdpCache(networkModel);
|
||||
|
||||
string str = $"连接建立: {networkModel.DestinationIp}:{networkModel.DestinationPort} ," +
|
||||
$"地址: {networkModel.SourceIp}:{networkModel.SourcePort}";
|
||||
NetworkInfoManger.Instance.RecordEvent(str);
|
||||
|
||||
}
|
||||
|
||||
private void ProcessDhcpPacket(UdpPacketEventData udpEvent)
|
||||
{
|
||||
Console.WriteLine($"[DHCP] DHCP通信: {udpEvent.SourceIp} <-> {udpEvent.DestinationIp}");
|
||||
}
|
||||
|
||||
private void ProcessGenericUdpPacket(UdpPacketEventData udpEvent)
|
||||
{
|
||||
// 对于未知UDP流量,主要进行安全检查
|
||||
if (udpEvent.DataLength > 1024 * 64) // 64KB
|
||||
{
|
||||
Console.WriteLine($"[UDP警告] 大型UDP数据包: {udpEvent.ProcessName} " +
|
||||
$"发送 {udpEvent.DataLength} 字节到 {udpEvent.DestinationIp}:{udpEvent.DestinationPort}");
|
||||
}
|
||||
}
|
||||
|
||||
public void PrintTrafficSummary()
|
||||
{
|
||||
Console.WriteLine("\n=== UDP流量统计 ===");
|
||||
Console.WriteLine("端口流量TOP 10:");
|
||||
foreach (var item in portTraffic.OrderByDescending(x => x.Value).Take(10))
|
||||
{
|
||||
Console.WriteLine($" 端口 {item.Key}: {item.Value / 1024}KB");
|
||||
}
|
||||
|
||||
Console.WriteLine("\n源IP流量TOP 10:");
|
||||
foreach (var item in sourceTraffic.OrderByDescending(x => x.Value).Take(10))
|
||||
{
|
||||
Console.WriteLine($" {item.Key}: {item.Value / 1024}KB");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Utils.ETW;
|
||||
|
||||
public enum Enums
|
||||
{
|
||||
TcpConnect,
|
||||
TcpDisconnect,
|
||||
TcpSend,
|
||||
TcpReceive,
|
||||
UdpSend,
|
||||
UdpReceive,
|
||||
DnsQuery,
|
||||
HttpRequest,
|
||||
NetworkInterface,
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using Utils.ETW.Core;
|
||||
|
||||
namespace Utils.ETW.EtwTracker;
|
||||
|
||||
public interface INetTracker
|
||||
{
|
||||
/// <summary>
|
||||
/// 设置处理方式
|
||||
/// </summary>
|
||||
/// <param name="networkCapture">ETW 连接对象</param>
|
||||
void SetupEtwHandlers(EtwNetworkCapture networkCapture);
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net;
|
||||
using Common.Logger;
|
||||
using Utils.ETW.Core;
|
||||
using Utils.ETW.Models;
|
||||
|
||||
namespace Utils.ETW.EtwTracker;
|
||||
|
||||
/// <summary>
|
||||
/// TCP连接追踪器
|
||||
/// </summary>
|
||||
public class TcpTracker : INetTracker
|
||||
{
|
||||
/// <summary>
|
||||
/// 最大连接数
|
||||
/// </summary>
|
||||
private readonly int _maxConnections = 10_000;
|
||||
|
||||
/// <summary>
|
||||
/// 活跃会话
|
||||
/// </summary>
|
||||
private readonly ConcurrentDictionary<long, TcpConnectionSession> _activeSessions = new();
|
||||
|
||||
public void SetupEtwHandlers(EtwNetworkCapture networkCapture)
|
||||
{
|
||||
// TCP事件需要单独详细处理
|
||||
networkCapture.OnTcpConnectionEvent += tcpEvent =>
|
||||
{
|
||||
ProcessTcpEvent(tcpEvent);
|
||||
|
||||
// 额外的TCP特定检查
|
||||
CheckTcpSecurity(tcpEvent);
|
||||
MonitorTcpPerformance(tcpEvent);
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 安全性检查
|
||||
/// </summary>
|
||||
/// <param name="tcpEvent"></param>
|
||||
private void CheckTcpSecurity(TcpConnectionEventData tcpEvent)
|
||||
{
|
||||
// TCP安全检查
|
||||
if (tcpEvent.EventType == "TcpConnect")
|
||||
{
|
||||
// 检测端口扫描
|
||||
// 检测恶意外连
|
||||
// 检测异常连接模式
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 性能监视
|
||||
/// </summary>
|
||||
/// <param name="tcpEvent"></param>
|
||||
private void MonitorTcpPerformance(TcpConnectionEventData tcpEvent)
|
||||
{
|
||||
// TCP性能监控
|
||||
// 重传检测
|
||||
// 窗口大小分析
|
||||
// 连接建立延迟
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 不同连接状态事件
|
||||
/// </summary>
|
||||
/// <param name="tcpEvent"></param>
|
||||
public void ProcessTcpEvent(TcpConnectionEventData tcpEvent)
|
||||
{
|
||||
Console.WriteLine($"[TCP] {tcpEvent.EventType}: {tcpEvent.SourceIp}:{tcpEvent.SourcePort} -> " +
|
||||
$"{tcpEvent.DestinationIp}:{tcpEvent.DestinationPort} ({tcpEvent.ProcessName})");
|
||||
|
||||
switch (tcpEvent.EventType)
|
||||
{
|
||||
// 连接建立 - 需要记录连接开始时间
|
||||
case "TcpConnect":
|
||||
StartSession(tcpEvent);
|
||||
break;
|
||||
// 连接断开 - 计算连接持续时间,统计传输数据量
|
||||
case "TcpDisconnect":
|
||||
EndSession(tcpEvent);
|
||||
break;
|
||||
// 数据传输 - 累计传输字节数,检测异常流量
|
||||
case "TcpSend":
|
||||
UpdateSentData(tcpEvent);
|
||||
break;
|
||||
case "TcpReceive":
|
||||
UpdateReceivedData(tcpEvent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始监听
|
||||
/// </summary>
|
||||
/// <param name="tcpEvent"></param>
|
||||
private void StartSession(TcpConnectionEventData tcpEvent)
|
||||
{
|
||||
// 连接建立时间
|
||||
var lastSeenTime = DateTime.Now;
|
||||
|
||||
var networkModel = new NetworkModel
|
||||
{
|
||||
ConnectType = ProtocolType.TCP,
|
||||
ProcessId = tcpEvent.ProcessId,
|
||||
ThreadId = tcpEvent.ThreadId,
|
||||
ProcessName = tcpEvent.ProcessName,
|
||||
SourceIp = tcpEvent.SourceIp,
|
||||
DestinationIp = tcpEvent.DestinationIp,
|
||||
LastSeenTime = lastSeenTime,
|
||||
BytesSent = 0,
|
||||
BytesReceived = 0,
|
||||
State = ConnectionState.Connecting,
|
||||
SourcePort = tcpEvent.SourcePort,
|
||||
DestinationPort = tcpEvent.DestinationPort,
|
||||
StartTime = lastSeenTime,
|
||||
Direction = tcpEvent.Direction,
|
||||
RecordTime = lastSeenTime,
|
||||
IsPartialConnection = true,
|
||||
};
|
||||
|
||||
var session = new TcpConnectionSession
|
||||
{
|
||||
ConnectionId = tcpEvent.ConnectionId,
|
||||
StartTime = tcpEvent.Timestamp,
|
||||
SourceIp = tcpEvent.SourceIp,
|
||||
DestinationIp = tcpEvent.DestinationIp,
|
||||
SourcePort = tcpEvent.SourcePort,
|
||||
DestinationPort = tcpEvent.DestinationPort,
|
||||
ProcessName = tcpEvent.ProcessName
|
||||
};
|
||||
NetworkInfoManger.Instance.SetTcpCache(networkModel);
|
||||
|
||||
string str = $"连接建立: {networkModel.DestinationIp}:{networkModel.DestinationPort} ," +
|
||||
$"地址: {networkModel.SourceIp}:{networkModel.SourcePort}";
|
||||
NetworkInfoManger.Instance.RecordEvent(str);
|
||||
|
||||
// 业务逻辑处理
|
||||
AnalyzeNewConnection(session);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 结束会话
|
||||
/// </summary>
|
||||
/// <param name="tcpEvent"></param>
|
||||
private void EndSession(TcpConnectionEventData tcpEvent)
|
||||
{
|
||||
var key = NetworkModel.GetKey(
|
||||
tcpEvent.SourceIp,
|
||||
tcpEvent.SourcePort,
|
||||
tcpEvent.DestinationIp,
|
||||
tcpEvent.DestinationPort,
|
||||
tcpEvent.ProcessId,
|
||||
ProtocolType.TCP,
|
||||
tcpEvent.Timestamp
|
||||
);
|
||||
|
||||
var removeTcpCache = NetworkInfoManger.Instance.RemoveTcpCache(key);
|
||||
|
||||
if (removeTcpCache.tryRemove)
|
||||
{
|
||||
if (removeTcpCache.session == null)
|
||||
{
|
||||
Log.Warning("移除成功,但获取数据为 Null !");
|
||||
return;
|
||||
}
|
||||
|
||||
removeTcpCache.session.EndTime = tcpEvent.Timestamp;
|
||||
removeTcpCache.session.State = ConnectionState.Disconnected;
|
||||
|
||||
string str = $"连接断开: {removeTcpCache.session.DestinationIp}:{removeTcpCache.session.DestinationPort} ," +
|
||||
$"地址: {removeTcpCache.session.SourceIp}:{removeTcpCache.session.SourcePort}";
|
||||
|
||||
NetworkInfoManger.Instance.RecordEvent(str);
|
||||
// 连接结束时的分析
|
||||
// AnalyzeCompletedConnection(session);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新发送的数据量
|
||||
/// </summary>
|
||||
/// <param name="tcpEvent"></param>
|
||||
private void UpdateSentData(TcpConnectionEventData tcpEvent)
|
||||
{
|
||||
var key = NetworkModel.GetKey(
|
||||
tcpEvent.SourceIp,
|
||||
tcpEvent.SourcePort,
|
||||
tcpEvent.DestinationIp,
|
||||
tcpEvent.DestinationPort,
|
||||
tcpEvent.ProcessId,
|
||||
ProtocolType.TCP,
|
||||
tcpEvent.Timestamp
|
||||
);
|
||||
var (tryRemove, networkModel) = NetworkInfoManger.Instance.RemoveTcpCache(key);
|
||||
|
||||
if (tcpEvent.DataLength < 0)
|
||||
{
|
||||
throw new Exception("数据长度不可能为 0 !!");
|
||||
}
|
||||
|
||||
// 统计端口流量
|
||||
NetworkInfoManger.Instance.PortTrafficSent.TryAdd(tcpEvent.DestinationPort, 0);
|
||||
NetworkInfoManger.Instance.PortTrafficSent[tcpEvent.DestinationPort] += (ulong)tcpEvent.DataLength;
|
||||
|
||||
NetworkInfoManger.Instance.SourceTrafficSent.TryAdd(tcpEvent.SourceIp, 0);
|
||||
NetworkInfoManger.Instance.SourceTrafficSent[tcpEvent.SourceIp] += (ulong)tcpEvent.DataLength;
|
||||
|
||||
if (tryRemove)
|
||||
{
|
||||
if (networkModel == null)
|
||||
{
|
||||
Log.Warning("发送新数据, 但是数据获取为空 !");
|
||||
return;
|
||||
}
|
||||
|
||||
networkModel.BytesSent += tcpEvent.DataLength;
|
||||
networkModel.State = ConnectionState.Connected;
|
||||
networkModel.LastSeenTime = DateTime.Now;
|
||||
|
||||
// todo: 检测 1 分钟、10 分钟的数据传输量;统计 1 分钟、10 分钟平均速率
|
||||
|
||||
string str = $"发送: {networkModel.SourceIp}:{networkModel.SourcePort} {tcpEvent.DataLength} 字节";
|
||||
NetworkInfoManger.Instance.RecordEvent(str);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新接收的数据量
|
||||
/// </summary>
|
||||
/// <param name="tcpEvent"></param>
|
||||
private void UpdateReceivedData(TcpConnectionEventData tcpEvent)
|
||||
{
|
||||
var key = NetworkModel.GetKey(
|
||||
tcpEvent.SourceIp,
|
||||
tcpEvent.SourcePort,
|
||||
tcpEvent.DestinationIp,
|
||||
tcpEvent.DestinationPort,
|
||||
tcpEvent.ProcessId,
|
||||
ProtocolType.TCP,
|
||||
tcpEvent.Timestamp
|
||||
);
|
||||
var (tryRemove, networkModel) = NetworkInfoManger.Instance.RemoveTcpCache(key);
|
||||
|
||||
if (tcpEvent.DataLength < 0)
|
||||
{
|
||||
throw new Exception("数据长度不可能为 0 !!");
|
||||
}
|
||||
|
||||
// 统计端口流量
|
||||
NetworkInfoManger.Instance.PortTrafficReceived.TryAdd(tcpEvent.DestinationPort, 0);
|
||||
NetworkInfoManger.Instance.PortTrafficReceived[tcpEvent.DestinationPort] += (ulong)tcpEvent.DataLength;
|
||||
|
||||
NetworkInfoManger.Instance.SourceTrafficReceived.TryAdd(tcpEvent.SourceIp, 0);
|
||||
NetworkInfoManger.Instance.SourceTrafficReceived[tcpEvent.SourceIp] += (ulong)tcpEvent.DataLength;
|
||||
|
||||
if (tryRemove)
|
||||
{
|
||||
if (networkModel == null)
|
||||
{
|
||||
Log.Warning("发送新数据, 但是数据获取为空 !");
|
||||
return;
|
||||
}
|
||||
|
||||
networkModel.BytesReceived += tcpEvent.DataLength;
|
||||
networkModel.State = ConnectionState.Connected;
|
||||
networkModel.LastSeenTime = DateTime.Now;
|
||||
|
||||
string str = $"接收: {networkModel.SourceIp}:{networkModel.SourcePort} {tcpEvent.DataLength} 字节";
|
||||
NetworkInfoManger.Instance.RecordEvent(str);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分析新连接
|
||||
/// </summary>
|
||||
/// <param name="session"></param>
|
||||
private void AnalyzeNewConnection(TcpConnectionSession session)
|
||||
{
|
||||
// 1. 安全检查
|
||||
// if (IsExternalConnection(session.DestinationIp))
|
||||
// {
|
||||
// Console.WriteLine(
|
||||
// $"[SECURITY] 外部连接警告: {session.ProcessName} -> {session.DestinationIp}:{session.DestinationPort}");
|
||||
// }
|
||||
|
||||
// 2. 业务监控
|
||||
// if (IsBusinessCriticalPort(session.DestinationPort))
|
||||
// {
|
||||
// Console.WriteLine($"[BUSINESS] 关键业务连接: {session.ProcessName} -> {session.DestinationPort}");
|
||||
// }
|
||||
|
||||
// 3. 性能监控
|
||||
var tcpSize = NetworkInfoManger.Instance.GetTcpSize();
|
||||
if (tcpSize > 1000)
|
||||
{
|
||||
Console.WriteLine($"[PERFORMANCE] 连接数量警告: 当前活跃连接 {tcpSize}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是连接到外部
|
||||
/// </summary>
|
||||
/// <param name="ip"></param>
|
||||
/// <returns></returns>
|
||||
private bool IsExternalConnection(IPAddress ip)
|
||||
{
|
||||
// 简单检查是否为外部IP(实际应用中需要更复杂的逻辑)
|
||||
return !ip.ToString().StartsWith("192.168.") &&
|
||||
!ip.ToString().StartsWith("10.") &&
|
||||
!ip.ToString().StartsWith("172.") &&
|
||||
!IPAddress.IsLoopback(ip);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是业务端口
|
||||
/// </summary>
|
||||
/// <param name="port">要监测的端口号</param>
|
||||
/// <returns></returns>
|
||||
private bool IsBusinessCriticalPort(int port)
|
||||
{
|
||||
var businessPorts = new[]
|
||||
{ 80, 443, 3306, 5432, 1433, 6379 }; // HTTP, HTTPS, MySQL, PostgreSQL, SQL Server, Redis
|
||||
return businessPorts.Contains(port);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取活跃连接
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<TcpConnectionSession> GetActiveSessions()
|
||||
{
|
||||
return _activeSessions.Values.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取长连接的会话
|
||||
/// </summary>
|
||||
/// <param name="threshold">连接时长</param>
|
||||
/// <returns></returns>
|
||||
public List<TcpConnectionSession> GetLongRunningSessions(TimeSpan threshold)
|
||||
{
|
||||
return _activeSessions.Values
|
||||
.Where(s => s.Duration > threshold)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace Utils.ETW;
|
||||
|
||||
/// <summary>
|
||||
/// 全局网络信息
|
||||
/// </summary>
|
||||
public sealed class GlobalNet
|
||||
{
|
||||
private static readonly Lazy<GlobalNet> _instance = new Lazy<GlobalNet>(() => new GlobalNet());
|
||||
|
||||
public static GlobalNet Instance => _instance.Value;
|
||||
|
||||
|
||||
|
||||
// 私有构造函数,防止外部实例化
|
||||
private GlobalNet()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
using System.Net;
|
||||
|
||||
namespace Utils.ETW.Models;
|
||||
|
||||
// 网络事件数据结构定义
|
||||
public class NetworkEventData
|
||||
{
|
||||
/// <summary>
|
||||
/// 记录产生时间
|
||||
/// </summary>
|
||||
public DateTime Timestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 事件类型
|
||||
/// </summary>
|
||||
public string EventType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进程 ID
|
||||
/// </summary>
|
||||
public int ProcessId { get; set; }
|
||||
|
||||
public int ThreadId { get; set; }
|
||||
public string ProcessName { get; set; }
|
||||
public IPAddress SourceIp { get; set; }
|
||||
public IPAddress DestinationIp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 源端口
|
||||
/// </summary>
|
||||
public int SourcePort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标端口
|
||||
/// </summary>
|
||||
public int DestinationPort { get; set; }
|
||||
|
||||
public string Protocol { get; set; }
|
||||
public int DataLength { get; set; }
|
||||
public TrafficDirection Direction { get; set; } // Inbound/Outbound
|
||||
public Dictionary<string, object> AdditionalProperties { get; set; }
|
||||
|
||||
public NetworkEventData()
|
||||
{
|
||||
AdditionalProperties = new Dictionary<string, object>();
|
||||
}
|
||||
}
|
||||
|
||||
public class TcpConnectionSession : NetworkEventData
|
||||
{
|
||||
public long ConnectionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始时间
|
||||
/// </summary>
|
||||
public DateTime StartTime { get; set; }
|
||||
|
||||
public DateTime? EndTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发送的字节数
|
||||
/// </summary>
|
||||
public long BytesSent { get; set; }
|
||||
|
||||
public long BytesReceived { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 持续时间
|
||||
/// </summary>
|
||||
public TimeSpan Duration => (EndTime ?? DateTime.Now) - StartTime;
|
||||
|
||||
public List<string> Events { get; set; } = new List<string>();
|
||||
}
|
||||
|
||||
// TCP连接事件数据
|
||||
public class TcpConnectionEventData : NetworkEventData
|
||||
{
|
||||
/// <summary>
|
||||
/// 连接状态
|
||||
/// </summary>
|
||||
public string ConnectionState { get; set; } // ESTABLISHED, CLOSED, LISTEN等
|
||||
public long ConnectionId { get; set; }
|
||||
/// <summary>
|
||||
/// 顺序
|
||||
/// </summary>
|
||||
public int SequenceNumber { get; set; }
|
||||
public int AcknowledgmentNumber { get; set; }
|
||||
public int WindowSize { get; set; }
|
||||
public string TcpFlags { get; set; }
|
||||
}
|
||||
|
||||
// UDP数据包事件数据
|
||||
public class UdpPacketEventData : NetworkEventData
|
||||
{
|
||||
public int UdpLength { get; set; }
|
||||
public int Checksum { get; set; }
|
||||
}
|
||||
|
||||
// DNS查询事件数据
|
||||
public class DnsEventData : NetworkEventData
|
||||
{
|
||||
public string QueryName { get; set; }
|
||||
public string QueryType { get; set; }
|
||||
public string ResponseCode { get; set; }
|
||||
public List<string> ResolvedAddresses { get; set; }
|
||||
public int QueryId { get; set; }
|
||||
|
||||
public DnsEventData()
|
||||
{
|
||||
ResolvedAddresses = new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
// HTTP事件数据
|
||||
public class HttpEventData : NetworkEventData
|
||||
{
|
||||
public string HttpMethod { get; set; }
|
||||
public string Url { get; set; }
|
||||
public int StatusCode { get; set; }
|
||||
public string UserAgent { get; set; }
|
||||
public string Host { get; set; }
|
||||
public Dictionary<string, string> Headers { get; set; }
|
||||
public long ContentLength { get; set; }
|
||||
|
||||
public HttpEventData()
|
||||
{
|
||||
Headers = new Dictionary<string, string>();
|
||||
}
|
||||
}
|
||||
|
||||
// 网络接口事件数据
|
||||
public class NetworkInterfaceEventData : NetworkEventData
|
||||
{
|
||||
public string InterfaceName { get; set; }
|
||||
public string InterfaceType { get; set; }
|
||||
public string MacAddress { get; set; }
|
||||
public string InterfaceState { get; set; } // Up/Down
|
||||
public long BytesSent { get; set; }
|
||||
public long BytesReceived { get; set; }
|
||||
public long PacketsSent { get; set; }
|
||||
public long PacketsReceived { get; set; }
|
||||
}
|
||||
|
||||
// 网络错误事件数据
|
||||
public class NetworkErrorEventData : NetworkEventData
|
||||
{
|
||||
public int ErrorCode { get; set; }
|
||||
public string ErrorDescription { get; set; }
|
||||
public string ErrorCategory { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
using System.Net;
|
||||
|
||||
namespace Utils.ETW.Models;
|
||||
|
||||
/// <summary>
|
||||
/// 网络连接模型
|
||||
/// </summary>
|
||||
public class NetworkModel
|
||||
{
|
||||
// RemoteCountry 地理位置归属地,供安全分析
|
||||
|
||||
/// <summary>
|
||||
/// 进程 ID
|
||||
/// </summary>
|
||||
public required int ProcessId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 线程 ID
|
||||
/// </summary>
|
||||
public required int ThreadId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进程名称
|
||||
/// </summary>
|
||||
public required string ProcessName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 源地址
|
||||
/// </summary>
|
||||
public required IPAddress SourceIp { get; set; }
|
||||
|
||||
public required IPAddress DestinationIp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新活动时间
|
||||
/// </summary>
|
||||
public required DateTime LastSeenTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 记录产生时间
|
||||
/// </summary>
|
||||
public required DateTime RecordTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发送的数据量
|
||||
/// </summary>
|
||||
public long BytesSent { get; set; }
|
||||
|
||||
public long BytesReceived { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连接状态
|
||||
/// </summary>
|
||||
public required ConnectionState State { get; set; } // 如 ESTABLISHED, CLOSED, TIME_WAIT, 或 UDP/Unknown
|
||||
|
||||
/// <summary>
|
||||
/// 源端口
|
||||
/// </summary>
|
||||
public required int SourcePort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标端口
|
||||
/// </summary>
|
||||
public required int DestinationPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 连接类型
|
||||
/// </summary>
|
||||
public required ProtocolType ConnectType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始时间
|
||||
/// </summary>
|
||||
public DateTime? StartTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进站或是出站
|
||||
/// </summary>
|
||||
public TrafficDirection Direction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结束时间
|
||||
/// </summary>
|
||||
public DateTime? EndTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否是完整会话【如果在软件打开前会话已经创建则不认为是完整会话】
|
||||
/// </summary>
|
||||
public required bool IsPartialConnection { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 会话持续时间
|
||||
/// </summary>
|
||||
public TimeSpan Duration => (EndTime ?? DateTime.Now) - (StartTime ?? RecordTime);
|
||||
|
||||
// 近 1 分钟平均网速
|
||||
// 近 1 分钟流量统计
|
||||
// 近 10 分钟流量统计
|
||||
|
||||
public string GetKey()
|
||||
{
|
||||
return GetKey(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取唯一 ID
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetKey(NetworkModel networkModel)
|
||||
{
|
||||
return GetKey(networkModel.SourceIp,
|
||||
networkModel.SourcePort,
|
||||
networkModel.DestinationIp,
|
||||
networkModel.DestinationPort,
|
||||
networkModel.ProcessId,
|
||||
networkModel.ConnectType,
|
||||
networkModel.RecordTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取唯一 ID
|
||||
/// </summary>
|
||||
/// <param name="sourceIp">源 Ip</param>
|
||||
/// <param name="sourcePort">源端口</param>
|
||||
/// <param name="destinationIp">目标 Ip</param>
|
||||
/// <param name="destinationPort">目标端口</param>
|
||||
/// <param name="processId">进程 ID</param>
|
||||
/// <param name="connectType">连接类型</param>
|
||||
/// <param name="recordTime">记录时间</param>
|
||||
/// <returns></returns>
|
||||
public static string GetKey(
|
||||
IPAddress sourceIp,
|
||||
int sourcePort,
|
||||
IPAddress destinationIp,
|
||||
int destinationPort,
|
||||
int processId,
|
||||
ProtocolType connectType,
|
||||
DateTime recordTime)
|
||||
{
|
||||
var key =
|
||||
$"{sourceIp}:{sourcePort}-{destinationIp}:" +
|
||||
$"{destinationPort}-{processId}-{connectType}-" +
|
||||
$"{recordTime:yyyyMMddHHmmss}";
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ConnectionState
|
||||
{
|
||||
/// <summary>
|
||||
/// 正在尝试连接
|
||||
/// </summary>
|
||||
Connecting,
|
||||
Connected, // 当前连接活跃(发送/接收中)
|
||||
Disconnected, // 已断开或未活跃
|
||||
Listening, // 监听状态(如本地服务器)
|
||||
Unknown // 无法判断状态
|
||||
}
|
||||
|
||||
public enum ProtocolType
|
||||
{
|
||||
TCP,
|
||||
UDP,
|
||||
ICMP, // 可选
|
||||
Unknown
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 进出站类型
|
||||
/// </summary>
|
||||
public enum TrafficDirection
|
||||
{
|
||||
Inbound,
|
||||
Outbound,
|
||||
// Unknown
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.1.21" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Common\Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace Utils.ETW.Utils;
|
||||
|
||||
public static class SystemInfoHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 检查是否是管理员权限
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool IsRunAsAdministrator()
|
||||
{
|
||||
var identity = System.Security.Principal.WindowsIdentity.GetCurrent();
|
||||
var principal = new System.Security.Principal.WindowsPrincipal(identity);
|
||||
return principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user