using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Threading;
namespace DirectoryGuardPro
{
class Program
{
// 配置區(qū)
private static readonly string[] AllowedProcesses = { "TrustedApp.exe", "BackupTool.exe" }; // 白名單程序
private static readonly string ProtectedDirectory = @"C:\MissionCritical"; // 受保護目錄
// 內(nèi)核API聲明
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess,
FileShare dwShareMode,
IntPtr lpSecurityAttributes,
FileMode dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr hObject);
static void Main()
{
if (!IsAdmin())
{
Console.WriteLine("[錯誤] 必須使用管理員權(quán)限運行!");
return;
}
// 啟動實時監(jiān)控線程
Thread monitorThread = new Thread(FileAccessMonitor);
monitorThread.IsBackground = true;
monitorThread.Start();
Console.WriteLine($"防護已啟用,保護目錄:{ProtectedDirectory}");
Console.WriteLine("白名單程序:" + string.Join(", ", AllowedProcesses));
Console.WriteLine("按 Ctrl+C 退出...");
while (true) Thread.Sleep(1000);
}
// 核心監(jiān)控邏輯
private static void FileAccessMonitor()
{
using (var watcher = new FileSystemWatcher(ProtectedDirectory))
{
watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName
| NotifyFilters.Size | NotifyFilters.LastWrite;
watcher.IncludeSubdirectories = true;
// 綁定事件(使用高優(yōu)先級響應(yīng))
watcher.Created += (sender, e) => ValidateProcess(e.FullPath);
watcher.Changed += (sender, e) => ValidateProcess(e.FullPath);
watcher.Renamed += (sender, e) => ValidateProcess(e.FullPath);
watcher.Deleted += (sender, e) => ValidateProcess(e.FullPath);
watcher.EnableRaisingEvents = true;
while (true) Thread.Sleep(10); // 保持線程活躍
}
}
// 驗證進程合法性
private static void ValidateProcess(string filePath)
{
int processId = GetFileLockingProcessId(filePath);
if (processId == -1) return;
var process = Process.GetProcessById(processId);
string processName = process.ProcessName.ToLower();
bool isAllowed = AllowedProcesses.Any(p =>
p.Equals(processName, StringComparison.OrdinalIgnoreCase));
if (!isAllowed)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"[攔截] 非法訪問!進程:{processName} (PID: {processId}) 文件:{filePath}");
Console.ResetColor();
try
{
process.Kill();
BlockFurtherAccess(filePath); // 阻止殘留操作
}
catch (Exception ex)
{
Console.WriteLine($"[警告] 終止進程失敗:{ex.Message}");
}
}
}
// 使用內(nèi)核句柄檢測文件鎖定進程
private static int GetFileLockingProcessId(string filePath)
{
IntPtr handle = CreateFile(
filePath,
0x80000000, // GENERIC_READ
FileShare.ReadWrite,
IntPtr.Zero,
FileMode.Open,
0x80, // FILE_FLAG_BACKUP_SEMANTICS
IntPtr.Zero);
if (handle.ToInt32() == -1)
{
int errorCode = Marshal.GetLastWin32Error();
// 錯誤碼 32 表示文件被占用
return (errorCode == 32) ? QueryProcessUsingHandle(filePath) : -1;
}
CloseHandle(handle);
return -1;
}
// 調(diào)用系統(tǒng)命令查詢進程ID
private static int QueryProcessUsingHandle(string filePath)
{
var cmd = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "handle64.exe", // 需提前部署Sysinternals Handle工具
Arguments = $"/accepteula -nobanner \"{filePath}\"",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
cmd.Start();
string output = cmd.StandardOutput.ReadToEnd();
cmd.WaitForExit();
// 解析輸出,例如:"wininit.exe pid: 508 type: File"
var line = output.Split('\n').FirstOrDefault(l => l.Contains("pid:"));
if (line != null && int.TryParse(line.Split(' ')[3], out int pid))
return pid;
return -1;
}
// 強制解除文件鎖定
private static void BlockFurtherAccess(string filePath)
{
try
{
using (var fs = new FileStream(filePath, FileMode.Open,
FileAccess.ReadWrite, FileShare.None))
{
fs.Lock(0, fs.Length); // 獨占鎖定文件
}
}
catch { /* 無需處理 */ }
}
// 管理員權(quán)限檢查
private static bool IsAdmin() =>
new WindowsPrincipal(WindowsIdentity.GetCurrent())
.IsInRole(WindowsBuiltInRole.Administrator);
}
}