.NET 运行时
.NET: 基于 .NET 软件框架的 Microsoft 技术。运行时: 运行未编译为机器语言的应用所需的环境。
58 个问题
public void MonitorProcess(int pid, string processPath, int monitorSeconds = 10)
{
Console.WriteLine($"[ProcessMonitor] 启动 ETW 监控, PID={pid},进程路径={processPath},时长={monitorSeconds}s");
try
{
string connStr = $"Data Source={dbPath};Version=3;Synchronous=Normal;Journal Mode=WAL;";
using (var dbConn = new SQLiteConnection(connStr))
{
dbConn.Open();
EnsureSyscallsTable(dbConn);
// 获取进程可执行文件路径
//string processPath = GetProcessPath(pid);
Console.WriteLine($"[ProcessMonitor] 进程 {pid} 可执行文件路径: {processPath}");
// 启动 ETW 会话
using (var session = new TraceEventSession("ProcMonitorETWSession_" + pid))
{
// 订阅文件操作事件 (文件 I/O)
session.EnableKernelProvider(KernelTraceEventParser.Keywords.FileIOInit | KernelTraceEventParser.Keywords.FileIO);
// 注册文件事件回调
session.Source.Kernel.FileIORead += data => HandleFileEvent(data, "FileRead", dbConn, pid, processPath);
session.Source.Kernel.FileIOWrite += data => HandleFileEvent(data, "FileWrite", dbConn, pid, processPath);
session.Source.Kernel.FileIOCreate += data => HandleFileEvent(data, "FileCreate", dbConn, pid, processPath);
session.Source.Kernel.FileIODelete += data => HandleFileEvent(data, "FileDelete", dbConn, pid, processPath);
// 启动事件处理线程
Thread etwThread = new Thread(() => session.Source.Process());
etwThread.Start();
// 将会话加入活动监控会话列表
lock (SessionLock)
{
ActiveSessions[pid] = session;
}
// 监控进程并在结束后停止
int elapsedTime = 0;
while (elapsedTime < monitorSeconds)
{
if (!IsProcessAlive(pid)) // 检查进程是否仍然存活
{
Console.WriteLine($"[ProcessMonitor] 进程 {pid} 已结束,停止监控。");
break;
}
Thread.Sleep(1000); // 每秒检查一次进程存活状态
elapsedTime++;
}
// 结束监控
session.Source.StopProcessing();
etwThread.Join();
}
dbConn.Close();
}
}
catch (Exception ex)
{
Console.Error.WriteLine($"[ProcessMonitor] 监控期间发生异常: {ex.Message}");
}
Console.WriteLine("[ProcessMonitor] 监控结束。");
lock (SessionLock)
{
ActiveSessions.Remove(pid);
}
SuspiciousProcessList.RemoveProcess(pid); // ✅ 移除已监控的进程
StopMonitoring(pid);
Console.WriteLine($"[ProcessMonitor] 停止对进程 {pid} 的监控");
}
private void HandleFileEvent(TraceEvent data, string syscall, SQLiteConnection dbConn, int targetPid, string processPath)
{
if (data.ProcessID != targetPid) return;
string fileName = null;
// **统一处理不同类型的 File I/O 事件**
if (data is FileIOReadWriteTraceData ioData)
{
fileName = ioData.FileName;
Console.WriteLine($"1-FileIOReadWriteTraceData文件名:{ioData.FileName},filekey:{ioData.FileKey},FileObject:{ioData.FileObject}");
}
else if (data is FileIOCreateTraceData createData)
{
fileName = createData.FileName;
Console.WriteLine($"2-FileIOCreateTraceData文件名:{createData.FileName},FileObject:{createData.FileObject}");
}
else if (data is FileIOInfoTraceData infoData)
{
fileName = infoData.FileName;
Console.WriteLine($"3-FileIOInfoTraceData文件名:{infoData.FileName},filekey:{infoData.FileKey},FileObject:{infoData.FileObject}");
}
if (!string.IsNullOrEmpty(fileName))
{
InsertSyscall(dbConn, syscall, data.ProcessID, data.ProcessName, processPath, fileName);
}
}
public sealed class FileIOCreateTraceData : TraceEvent
{
private KernelTraceEventParserState state;
public ulong IrpPtr => GetAddressAt(0);
public ulong FileObject => GetAddressAt((LayoutVersion <= 2) ? HostOffset(8, 2) : HostOffset(4, 1));
//
// 摘要:
// See the Windows CreateFile API CreateOptions for this
public CreateOptions CreateOptions => (CreateOptions)(GetInt32At((LayoutVersion <= 2) ? HostOffset(12, 3) : HostOffset(12, 2)) & 0xFFFFFF);
//
// 摘要:
// See Windows CreateFile API CreateDisposition for this.
public CreateDisposition CreateDisposition => (CreateDisposition)GetByteAt((LayoutVersion <= 2) ? HostOffset(15, 3) : HostOffset(15, 2));
//
// 摘要:
// See Windows CreateFile API ShareMode parameter
public FileAttributes FileAttributes => (FileAttributes)GetInt32At((LayoutVersion <= 2) ? HostOffset(16, 3) : HostOffset(16, 2));
//
// 摘要:
// See windows CreateFile API ShareMode parameter
public FileShare ShareAccess => (FileShare)GetInt32At((LayoutVersion <= 2) ? HostOffset(20, 3) : HostOffset(20, 2));
public string FileName => state.KernelToUser(GetUnicodeStringAt((LayoutVersion <= 2) ? HostOffset(24, 3) : HostOffset(24, 2)));
}
The above is part of the code. In the console output, I don’t know why the same file exists but the file path is lowercase,like the following
上面是部分代码,在控制台的输出结果中,不知道为什么会存在同一文件但是文件路径被小写化了,就像下面
2-FileIOReadWriteTraceData文件名:E:\MyProject\DBA\test\test01\01.txt,FileObject:18446640743780695280
2-FileIOReadWriteTraceData文件名:E:\myproject\dba\test\test01\01.txt,FileObject:18446640743780698480
2-FileIOReadWriteTraceData文件名:E:\myproject\dba\test\test01\01.txt,FileObject:18446640743780706880
2-FileIOReadWriteTraceData文件名:E:\MyProject\DBA\test\test01\01.txt,FileObject:18446640743780682080
2-FileIOReadWriteTraceData文件名:E:\MyProject\DBA\test\test01\02.txt,FileObject:18446640743780713280
2-FileIOReadWriteTraceData文件名:E:\myproject\dba\test\test01\02.txt,FileObject:18446640743780715280
2-FileIOReadWriteTraceData文件名:E:\myproject\dba\test\test01\02.txt,FileObject:18446640743780706080
2-FileIOReadWriteTraceData文件名:E:\MyProject\DBA\test\test01\02.txt,FileObject:18446640743780714480