简单的API挂钩可以防止文件删除?

时间:2013-12-28 13:52:33

标签: .net vb.net winapi hook easyhook

当用户通过挂钩所需的API函数来删除任何目录中的文件时,我想拦截,并且可以在消息框中询问一个简单的布尔问题" Really Would you like to Delete this file?&#34 ;,这个问题是一个表示我希望控制文件,删除文件或防止删除的例子。

我的操作系统是Windows 8 x64,但我想在其他Windows操作系统和它们的arquitechtures中编写一种通用方法(如果这样做不会让人头疼更难)。

在这个问题中我已经读过,最好的选择是通过我看到存在名为{{1的WinAPI函数的方式来挂钩NtSetFileInformation函数Intercept FIleSytemCall for Deletion。还有界面DeleteFile而且我不知道它们之间的差异,但无论如何我真的不知道如何开始这样做......

  

我想澄清一下,我正在寻找一个VBNET解决方案,我很头疼   因为这些API-Hooking库没有任何VBNET代码示例超过Google,   当涉及到复杂的代码时,对VBNET的C#代码转换非常错误。

编辑: 我找到了一个ICopyHook库关于EasyHook的示例,它似乎完全符合我的需求,但它是C#代码,我试图翻译它没有成功:Hooking NtCreateFile API from ntdll.dll with EasyHook (c#)

所以,我已经用NtSetFileInformation库2.6尝试了这个,但什么也没做:

Deviare

基本上上面的代码与此处hooking another program's calls to winapi functions in vb.net回答的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指令中抛弃了我。

此外,我已经使用库_hook.Attach(_mgr.Processes)尝试了此操作,但当我从Explorer.exe或CMD中删除文件时再没有做任何操作,代码是此C#代码的翻译http://www.codeproject.com/Questions/528094/DeleteFileplushookingpluswithplusEasyHookplussucce

EasyHook

3 个答案:

答案 0 :(得分:2)

如果是我,我会重新审视我的架构,看看我是否真的需要阻止任何和所有文件删除。可能你只需要防止几个敏感目录中的删除(可能只是这些目录中的一些敏感文件)。这应该是一个不那么讨厌的用户界面。

答案 1 :(得分:2)

前几天我写这种方法暂时解决了这个问题,但我并不是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

答案 2 :(得分:1)

您需要的是目录观察者。 Visual Studio内置了功能。 请尝试以下代码:

Imports System.IO

Module Watcher

Const DirectoryName As String = "C:\Database\2010Admin Updated"

Private intCreated As Integer



Sub Main()

Dim Watcher As New FileSystemWatcher(DirectoryName)

Try

' Add delegates for events

AddHandler Watcher.Created, New FileSystemEventHandler(AddressOf Watcher_Created)

AddHandler Watcher.Changed, New FileSystemEventHandler(AddressOf Watcher_Changed)

AddHandler Watcher.Deleted, New FileSystemEventHandler(AddressOf Watcher_Deleted)

AddHandler Watcher.Renamed, New RenamedEventHandler(AddressOf Watcher_Renamed)

' Must do this

Watcher.EnableRaisingEvents = True

' Display instructions and wait to exit

Console.WriteLine("Make changes to the " & DirectoryName & "directory.")

Console.WriteLine("You will see the events generated.")

Console.WriteLine("Press ENTER to exit.")

Console.ReadLine()

Finally

Watcher.Dispose()

End Try

End Sub

Private Sub Watcher_Created(ByVal sender As Object, ByVal e As FileSystemEventArgs)

Dim objWriter As New System.IO.StreamWriter("C:\dbupdated.txt", True)

Console.WriteLine("Event: File {0} {1}", e.FullPath, e.ChangeType)

objWriter.WriteLine(Now() & "Event: File {0} {1}", e.FullPath, e.ChangeType)

objWriter.WriteLine()

objWriter.Close()

intCreated += 1

If intCreated Mod 2 = 0 Then

MsgBox("File Created: " & e.FullPath)

End If

End Sub

Private Sub Watcher_Changed(ByVal sender As Object, ByVal e As FileSystemEventArgs)

Dim objWriter As New System.IO.StreamWriter("C:\dbupdated.txt", True)

Console.WriteLine("Event: File {0} {1}", e.FullPath, e.ChangeType)

objWriter.WriteLine(Now() & "Event: File {0} {1}", e.FullPath, e.ChangeType)

objWriter.WriteLine()

objWriter.Close()

End Sub

Private Sub Watcher_Deleted(ByVal sender As Object, ByVal e As FileSystemEventArgs)

Dim objWriter As New System.IO.StreamWriter("C:\dbupdated.txt", True)

Console.WriteLine("Event: File {0} {1}", e.FullPath, e.ChangeType)

objWriter.WriteLine(Now() & "Event: File {0} {1}", e.FullPath, e.ChangeType)

objWriter.WriteLine()

objWriter.Close()

End Sub

Private Sub Watcher_Renamed(ByVal sender As Object, ByVal e As RenamedEventArgs)

Dim objWriter As New System.IO.StreamWriter("C:\dbupdated.txt", True)

Console.WriteLine("Event: File {0} {1} to {2}", e.OldFullPath, e.ChangeType, e.FullPath)

objWriter.WriteLine(Now() & "Event: File {0} {1} to {2}", e.OldFullPath, e.ChangeType, e.FullPath)

objWriter.WriteLine()

objWriter.Close()

End Sub



End Module

尝试运行它(作为控制台应用程序)。