EasyHook for systemcall hooking

Created By Saddam Abu Ghaida and Nicolai Tufar

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 Open source 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 doesn’t require .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);

4. 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*/  }
Share Me
Posted in Programming and tagged , , , , , , , , . Bookmark the permalink. RSS feed for this post. Leave a trackback.

3 Responses to EasyHook for systemcall hooking

  1. Pingback: Transparent Encryption Layer using EasyHook | My Blog

  2. Dan says:

    Did your code work?
    I tried to use insafe code in the dll to be injected, but once injected, the hooked process crashed.

Leave a Reply

Your email address will not be published. Required fields are marked *


× 1 = six

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 

Swedish Greys - a WordPress theme from Nordic Themepark.