I would like to intercept when the user deletes a file on ANY directory by hooking the needed API function(s) with the availability of asking a simple boolean question in a mesagebox "Really Would you like to Delete this file?
", the question is an example to express that I would like to have control on the file, to delete it or to prevent deletion.
My OS Is Windows 8 x64
, but I would like to write a method for generic usage in other Windows OS and their arquitechtures (if this don't suppose harder headaches to do it).
In this SO question I've read that the best choice is to hook the NtSetFileInformation
function Intercept FIleSytemCall for Deletion by the way I've seen that exists a WinAPI function named DeleteFile
and also the interface ICopyHook
and I don't know the differente between these, but anyways I really don't know how to start doing this...
I would like to clarify that I'm looking for a VBNET solution, I've headaches because the absence of any VBNET Code example from these API-Hooking libraries over Google, and C# code translations to VBNET goes really wrong when a complex code is involved.
EDIT: I've found a EasyHook
library Example about NtSetFileInformation
which seems to be perfect for my needs, but it is C# code and I've tried to translate it without success: Hooking NtCreateFile API from ntdll.dll with EasyHook (c#)
So, I've tried this with Deviare
library 2.6, but does nothing:
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
Basically the code above is the same as @mazoula
answered here hooking another program's calls to winapi functions in vb.net ,he says that the code worked for him, but I've tried it as is (without doiing my modifications above) and throwed me an exception at the _hook.Attach(_mgr.Processes)
instruction.
Also I've tried this with the library EasyHook
but again does nothing when I delete a file from Explorer.exe or from CMD, the code is a translation of this C# code 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
few days ago I've write this approach to temporally resolve the problem, but I'm not 100% secure that the method will work properly in all the scenarios (for example the user can press ctrl+z to restore a file deletion and my method logic uses the datetime property of the files to try to pick the last deleted which I'm not 100% secure), this works by now, but I would like to learn how to API hook instead of doing this.
Also obviously this will not work with a permanent file deletion.