Friday, May 20, 2011

EasyHook for systemcall hooking

i was researching the web couple of months a go regarding a library which can provide a hooking functionality to windows system calls in order to be able to create transparent encryption layer for Fucked up databases such as FoxPro, i came across to two libraries . the first one is Windows Detours and the other one is  called EasyHook.

first i tried to work With Windows Detours and encounters 1 million problem form installation to compiling to packaging the encryption library, so i said to my self why not give EasyHook a try since i love Opensource projects and i support them with all my heart.  and what i like about it the most that it supports extending (hooking) unmanaged code (APIs) with pure managed ones like C# for 32 and 64 kernels, and it provides unmanaged API which not requires .Net Framework

below i will show who to start working with EasyHook local hooking from managed code "Quick and dirty" but i prefer if you are looking for more don't relay on my code. Go and read the documentation.


1. first you need to initialize the Hook as a parameters you need to pass the DLL filename and the function implemented by that DLL, and you need to provide the function wrapper and your function as an argument below i will initialize IO related functions


CreateWHook = LocalHook.Create(LocalHook.GetProcAddress("kernel32.dll", "CreateFileW"), new DCreateFileW(CreateFileWHook), this);
                CreateWHook.ThreadACL.SetExclusiveACL(new Int32[0]);

                CreateAHook = LocalHook.Create(LocalHook.GetProcAddress("kernel32.dll", "CreateFileA"), new DCreateFileA(CreateFileAHook), this);
                CreateAHook.ThreadACL.SetExclusiveACL(new Int32[0]);

                ReadHook = LocalHook.Create(LocalHook.GetProcAddress("kernel32.dll", "ReadFile"), new DReadFile(ReadFileHook), this);
                ReadHook.ThreadACL.SetExclusiveACL(new Int32[0]);

                WriteHook = LocalHook.Create(LocalHook.GetProcAddress("kernel32.dll", "WriteFile"), new DWriteFile(WriteFileHook), this);
                WriteHook.ThreadACL.SetExclusiveACL(new Int32[0]);

                CloseHook = LocalHook.Create(LocalHook.GetProcAddress("kernel32.dll", "CloseHandle"), new DCloseHandle(CloseHandleHook), this);
                CloseHook.ThreadACL.SetExclusiveACL(new Int32[0]);



  MoveAHook = LocalHook.Create(LocalHook.GetProcAddress("kernel32.dll", "MoveFileA"), new DMoveFileA(MoveFileAHook), this);
                MoveAHook.ThreadACL.SetExclusiveACL(new Int32[0]);

                MoveWHook = LocalHook.Create(LocalHook.GetProcAddress("kernel32.dll", "MoveFileW"), new DMoveFileW(MoveFileWHook), this);
                MoveWHook.ThreadACL.SetExclusiveACL(new Int32[0]);

                DeleteAHook = LocalHook.Create(LocalHook.GetProcAddress("kernel32.dll", "DeleteFileA"), new DDeleteFileA(DeleteFileAHook), this);
                DeleteAHook.ThreadACL.SetExclusiveACL(new Int32[0]);

                DeleteWHook = LocalHook.Create(LocalHook.GetProcAddress("kernel32.dll", "DeleteFileW"), new DDeleteFileW(DeleteFileWHook), this);
                DeleteWHook.ThreadACL.SetExclusiveACL(new Int32[0]);


2. create wrappers


  [UnmanagedFunctionPointer(CallingConvention.StdCall,
            CharSet = CharSet.Unicode, SetLastError = true)]

        delegate IntPtr DCreateFileW(String InFileName, UInt32 InDesiredAccess, UInt32 InShareMode,
                                     IntPtr InSecurityAttributes, UInt32 InCreationDisposition,
                                     UInt32 InFlagsAndAttributes, IntPtr InTemplateFile);


  [UnmanagedFunctionPointer(CallingConvention.StdCall,
                 CharSet = CharSet.Ansi, SetLastError = true)]

        delegate IntPtr DCreateFileA(String InFileName, UInt32 InDesiredAccess, UInt32 InShareMode,
                                     IntPtr InSecurityAttributes, UInt32 InCreationDisposition,
                                     UInt32 InFlagsAndAttributes, IntPtr InTemplateFile);



        [UnmanagedFunctionPointer(CallingConvention.StdCall,
            CharSet = CharSet.Ansi, SetLastError = true)]

        unsafe delegate bool DReadFile(IntPtr hFile, void* pBuffer, int NumberOfBytesToRead,
                                        int* pNumberOfBytesRead, int Overlapped);



 [UnmanagedFunctionPointer(CallingConvention.StdCall,
            CharSet = CharSet.Unicode, SetLastError = true)]

        delegate bool DWriteFile(IntPtr hFile, void* lpBuffer, uint nNumberOfBytesToWrite,
                                  out uint lpNumberOfBytesWritten, [In]
                                  ref System.Threading.NativeOverlapped lpOverlapped);


 [UnmanagedFunctionPointer(CallingConvention.StdCall,
            CharSet = CharSet.Unicode, SetLastError = true)]

        delegate bool DCloseHandle(IntPtr hObject);


 [UnmanagedFunctionPointer(CallingConvention.StdCall,
            CharSet = CharSet.Ansi, SetLastError = true)]
        delegate int DMoveFileA(String lpExistingFileName, String lpNewFileName);


 [UnmanagedFunctionPointer(CallingConvention.StdCall,
            CharSet = CharSet.Unicode, SetLastError = true)]
        delegate int DMoveFileW(String lpExistingFileName, String lpNewFileName);


 [UnmanagedFunctionPointer(CallingConvention.StdCall,
            CharSet = CharSet.Ansi, SetLastError = true)]
        delegate bool DDeleteFileA(string path);


 [UnmanagedFunctionPointer(CallingConvention.StdCall,
            CharSet = CharSet.Unicode, SetLastError = true)]
        delegate bool DDeleteFileW(string path);

3. define the functions to be externalized


[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true,
            CallingConvention = CallingConvention.StdCall)]

        static extern IntPtr CreateFileW(String InFileName, UInt32 InDesiredAccess, UInt32 InShareMode,
                                         IntPtr InSecurityAttributes, UInt32 InCreationDisposition,
                                         UInt32 InFlagsAndAttributes, IntPtr InTemplateFile);


  [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true,
            CallingConvention = CallingConvention.StdCall)]

        static extern IntPtr CreateFileA(String InFileName, UInt32 InDesiredAccess, UInt32 InShareMode,
                                         IntPtr InSecurityAttributes, UInt32 InCreationDisposition,
                                         UInt32 InFlagsAndAttributes, IntPtr InTemplateFile);


   [DllImport("kernel32", SetLastError = true)]

        static extern unsafe bool ReadFile(IntPtr hFile, void* pBuffer, int NumberOfBytesToRead,
                                             int* pNumberOfBytesRead, int Overlapped);

  [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true,
            CallingConvention = CallingConvention.StdCall)]

        static extern bool WriteFile(IntPtr hFile, void* lpBuffer, uint nNumberOfBytesToWrite,
                                      out uint lpNumberOfBytesWritten,
                                     [In] ref System.Threading.NativeOverlapped lpOverlapped);

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true,
            CallingConvention = CallingConvention.StdCall)]
        static extern bool CloseHandle(IntPtr hObject);

 [DllImport("kernel32", CharSet = CharSet.Ansi, SetLastError = true)]
        internal static extern int MoveFileA(String lpExistingFileName, String lpNewFileName);

 [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
        internal static extern int MoveFileW(String lpExistingFileName, String lpNewFileName);

[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
        static extern bool DeleteFileA(string path);
  [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        static extern bool DeleteFileW(string path);

3. Implement your functions


protected static unsafe IntPtr CreateFileWHook(String InFileName, UInt32 InDesiredAccess,
                                                    UInt32 InShareMode, IntPtr InSecurityAttributes,
                                                    UInt32 InCreationDisposition, UInt32 InFlagsAndAttributes,
                                                    IntPtr InTemplateFile)
        {  /*your implementation goes here */  }


protected static unsafe IntPtr CreateFileAHook(String InFileName, UInt32 InDesiredAccess,
                                                    UInt32 InShareMode, IntPtr InSecurityAttributes,
                                                    UInt32 InCreationDisposition, UInt32 InFlagsAndAttributes,
                                                    IntPtr InTemplateFile)
      {  /*your implementation goes here */  }


protected unsafe bool ReadFileHook(IntPtr hFile, void* pBuffer, int NumberOfBytesToRead,
                                                int* pNumberOfBytesRead, int Overlapped)
      {  /*your implementation goes here */  }


protected bool WriteFileHook(IntPtr hFile, void* lpBuffer, uint nNumberOfBytesToWrite,
                                          out uint lpNumberOfBytesWritten,
                                          [In] ref System.Threading.NativeOverlapped lpOverlapped)
       {  /*your implementation goes here */  }

protected bool CloseHandleHook(IntPtr hObject)
       {  /*your implementation goes here */  }


 protected int MoveFileAHook(String lpExistingFileName, String lpNewFileName)
       {  /*your implementation goes here*/  }

protected int MoveFileWHook(String lpExistingFileName, String lpNewFileName)
       {  /*your implementation goes here */  }

protected bool DeleteFileAHook(string path)
       {  /*your implementation goes here*/  }

protected bool DeleteFileWHook(string path)
       {  /*your implementation goes here*/  }

note the unsafe definition ; why ?

and thats it. see how easy as in EasyHook .

No comments:

Post a Comment