This is the first time I'm trying to connect the windows API. My goal is to control all the files that the process is going to create / open / read / write. To be more detailed, I decided to connect the ntdll.dll API, such as NtCreateFile () and NtOpenFile (). So, in order to achieve this goal, I went for EasyHook, which seems simple and reliable. I carefully followed the FileMon example, modifying what I really wanted: the hooked function. When I try to read information about a file that will be opened, I try to read information from the OBJECT_ATTRIBUTES structure, such as ObjectName. These are integer pointers, so I expected to use the Marshal.PtrToStringAuto (attributes.objectName) function to get a string value. However, as a result, I can only have bad lines without any meaning. Also, file access does not seem to work. I think there is something wrong with this code, possibly in the DllImport signatures. Be careful, I had to replace SafeHandle with IntPtr, because EasyHook complained about their marshaling. Can anybody help me?
Here is my special nested DLL code:
Here is the code of the launch method
public void Run(RemoteHooking.IContext InContext, String inChannelName) { // First of all, install all the hooks try { // NtCreateFile fileCreationHook = LocalHook.Create( LocalHook.GetProcAddress("ntdll.dll", "NtCreateFile"), new CreateFileDelegate(CreateFile_Hooked), this ); fileCreationHook = LocalHook.Create( LocalHook.GetProcAddress("ntdll.dll", "NtOpenFile"), new OpenFileDelegate(OpenFile_Hooked), this ); fileCreationHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 }); remoteIf.Log("File creation Hook correctly installed on pid "+RemoteHooking.GetCurrentProcessId()); } catch (Exception e) { remoteIf.Log(e.Message); remoteIf.Log(e.StackTrace); return; } // Wake up the process remoteIf.Log("Waiking up process..."); RemoteHooking.WakeUpProcess(); while (true) { Thread.Sleep(500); if (queue.Count > 0) { String[] package = null; lock (queue) { package = queue.ToArray(); queue.Clear(); } remoteIf.OnCreateFile(RemoteHooking.GetCurrentProcessId(), package); } else remoteIf.Ping(); } }
Here's the constructor code:
public InjectedDLL(RemoteHooking.IContext InContext, String inChannelName) {
There is a Hook delegate here and a hook function
public delegate int CreateFileDelegate(out IntPtr handle, System.IO.FileAccess access, ref OBJECT_ATTRIBUTES objectAttributes, out IO_STATUS_BLOCK ioStatus, ref long allocSize, uint fileAttributes, System.IO.FileShare share, uint createDisposition, uint createOptions, IntPtr eaBuffer, uint eaLength); public int CreateFile_Hooked( out IntPtr handle, System.IO.FileAccess access, ref OBJECT_ATTRIBUTES objectAttributes, out IO_STATUS_BLOCK ioStatus, ref long allocSize, uint fileAttributes, System.IO.FileShare share, uint createDisposition, uint createOptions, IntPtr eaBuffer, uint eaLength) {
There are built-in NtDll.Dll functions here:
[DllImport("ntdll.dll", ExactSpelling = true, SetLastError = true)] public static extern int NtCreateFile( out IntPtr handle, System.IO.FileAccess access, ref OBJECT_ATTRIBUTES objectAttributes, out IO_STATUS_BLOCK ioStatus, ref long allocSize, uint fileAttributes, System.IO.FileShare share, uint createDisposition, uint createOptions, IntPtr eaBuffer, uint eaLength); [DllImport("ntdll.dll", ExactSpelling = true, SetLastError = true)] public static extern int NtOpenFile( out IntPtr handle, System.IO.FileAccess access, ref OBJECT_ATTRIBUTES objectAttributes, out IO_STATUS_BLOCK ioStatus, System.IO.FileShare share, uint openOptions ); [StructLayout(LayoutKind.Sequential, Pack = 0)] public struct OBJECT_ATTRIBUTES { public Int32 Length; public IntPtr RootDirectory; public IntPtr ObjectName; public uint Attributes; public IntPtr SecurityDescriptor; public IntPtr SecurityQualityOfService; } [StructLayout(LayoutKind.Sequential, Pack = 0)] public struct IO_STATUS_BLOCK { public uint status; public IntPtr information; }