用於防止文件刪除的簡單 API Hook?
我想在使用者刪除任何目錄上的文件時攔截,方法是將所需的 API 函式與在消息框“
Really Would you like to Delete this file?”中詢問簡單布爾問題的可用性掛鉤,這個問題是表達我想的一個例子控製文件,刪除它或防止刪除。我的作業系統是
Windows 8 x64,但我想為其他 Windows 作業系統及其架構中的通用用法編寫一種方法(如果這不認為更難做到的話)。在這個 SO question 中,我讀到最好的選擇是掛鉤
NtSetFileInformation函式Intercept FIleSytemCall 進行刪除,因為我看到存在一個名為 WinAPI 的函式DeleteFile以及介面ICopyHook,但我不知道它們之間的區別,但是無論如何我真的不知道如何開始這樣做……我想澄清一下,我正在尋找一個 VBNET 解決方案,我很頭疼,因為這些 API-Hooking 庫通過 Google 沒有任何 VBNET 程式碼範例,並且當複雜的程式碼是涉及。
***編輯:***我找到了一個
EasyHook庫範例,NtSetFileInformation它似乎非常適合我的需求,但它是 C# 程式碼,我試圖翻譯它但沒有成功: Hooking NtCreateFile API from ntdll.dll with EasyHook (c#)所以,我已經用圖書館 2.6 試過這個
Deviare,但什麼也沒做:Public Class Form1 Private _mgr As Deviare2.NktSpyMgr = Nothing Private WithEvents _hook As Deviare2.NktHook = Nothing Private _proc As Deviare2.INktProcess = Nothing Private Shadows Sub Shown() Handles MyBase.Shown _mgr = New Deviare2.NktSpyMgr() _hook = _mgr.CreateHook("ntdll.dll!NtSetFileInformation", Nothing) _hook.Hook() End Sub Private Sub OnFunctionCalled(ByVal proc As Deviare2.INktProcess, ByVal callInfo As Deviare2.INktHookCallInfo, ByVal rCall As Deviare.IRemoteCall) Handles _hook.OnFunctionCalled MsgBox("Caught function call in " & proc.Name) End Sub End Class
@mazoula基本上上面的程式碼與這裡回答的相同,在 vb.net 中掛鉤另一個程序對 winapi 函式的呼叫,他說該程式碼對他有用,但我已經按原樣嘗試過(沒有進行上面的修改)並向我扔了一個_hook.Attach(_mgr.Processes)指令中的異常。我也試過這個庫
EasyHook但是當我從 Explorer.exe 或 CMD 中刪除一個文件時再次沒有做任何事情,程式碼是這個 C# 程式碼的翻譯http://www.codeproject.com/Questions/528094/DeleteFileplushookingpluswithplusEasyHookplussucce:Imports System.Runtime.InteropServices Imports EasyHook Public Class Form1 <DllImport("kernel32.dll", CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.StdCall)> Private Shared Function DeleteFile(filename As String) As Integer End Function <UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet:=CharSet.Unicode)> Private Delegate Function DeleteFileHandler(filename As String) As Integer Private Shared deleted As Boolean = False public Function DeleteFileHookInstance(filename As String) As Integer MsgBox("works?") If deleted Then deleted = False Return 1 End If If MessageBox.Show((Convert.ToString("Do you really want to delete file ") & filename) + "?", "Confirm delete file", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes Then deleted = True Return DeleteFile(filename) Else Return 1 End If 'Assume the call is successfull End Function Public Sub Run() Dim hook As EasyHook.LocalHook Try MsgBox("Creating...") hook = LocalHook.Create(LocalHook.GetProcAddress("kernel32.dll", "DeleteFileW"), New DeleteFileHandler(AddressOf DeleteFileHookInstance), Me) 'It stops here, the main interface receives the reported status 'Creating...' seemly forever, I understand that is for the unexpected restarting of explorer.exe MsgBox("Completing...") hook.ThreadACL.SetExclusiveACL(New Integer() {0}) RemoteHooking.WakeUpProcess() MsgBox("OK") Catch ex As Exception MsgBox("CreateHook failed: " + ex.Message) System.Diagnostics.Process.GetCurrentProcess().Kill() End Try While True Application.DoEvents() End While End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Run() End Sub End Class
幾天前我寫了這個方法來臨時解決問題,但我不是 100% 確保該方法在所有場景中都能正常工作(例如,使用者可以按
ctrl+z恢復文件刪除和我的方法邏輯使用文件的 datetime 屬性來嘗試選擇我不是 100% 安全的最後刪除的文件),這現在有效,但我想學習如何使用 API 掛鉤而不是這樣做。同樣顯然這不適用於永久文件刪除。
Imports System.IO Imports Shell32 Public Class Test Private SH As New Shell Private RecycleBin As Folder = SH.NameSpace(ShellSpecialFolderConstants.ssfBITBUCKET) Private WithEvents FSW As New FileSystemWatcher Private Shadows Sub Load() _ Handles MyBase.Load With FSW .Path = "C:\Test" .IncludeSubdirectories = True .Filter = "*" .NotifyFilter = NotifyFilters.FileName Or NotifyFilters.DirectoryName .EnableRaisingEvents = True End With End Sub Private Sub OnItemDeleted(sender As FileSystemWatcher, e As FileSystemEventArgs) _ Handles FSW.Deleted Dim DeletedItems As IEnumerable(Of FolderItem) = RecycleBin.Items.Cast(Of FolderItem). Where(Function(Item) Item.Name = e.Name). OrderBy(Function(Item) Item.ModifyDate) Dim LastDeletedItem As Shell32.FolderItem = DeletedItems.LastOrDefault If LastDeletedItem IsNot Nothing Then If (LastDeletedItem.IsFolder AndAlso Directory.Exists(e.FullPath)) _ OrElse (Not LastDeletedItem.IsFolder AndAlso File.Exists(e.FullPath)) Then Throw New Exception(String.Format("¿ Item has been restored ?: {0}", e.FullPath)) Exit Sub End If LastDeletedItem.InvokeVerb("undelete") End If End Sub End Class
如果是我,我會重新審視我的架構,看看我是否真的需要防止任何和所有文件刪除。可能您只需要防止刪除一些敏感目錄(可能只是這些目錄中的一些敏感文件)。這應該可以減少煩人的 UI。