Hello.
I quickly developped a API Hook class to hook an API on current process.
I used it to intercept WriteProcessMemory calls and get the lpBuffer parameter on malware to defeat RunPE technique (run PE in memory).
Anyway, you can use it in several cases.
The code is really tiny, but with the error handling, the code is more heavy 
APIHook.cs:
Code:
/// <summary>
/// APIHook Class.
/// </summary>
public class APIHook {
#region <Constructor>
/// <summary>
/// Initialize APIHook Class.
/// </summary>
/// <param name="process">Process to hook.</param>
/// <param name="dll">DLL of the procedure to hook.</param>
/// <param name="procedure">Procedure to hook.</param>
/// <param name="callback">Managed alternative procedure (callback).</param>
public APIHook(Process process, string dll, string procedure, Delegate callback) {
this.Process = process;
this.DLL = dll;
this.Procedure = procedure;
this.Callback = callback;
this.Address = IntPtr.Zero;
this.Old = null;
}
#endregion
#region <Functions>
/// <summary>
/// Hook the procedure.
/// </summary>
public void Hook() {
if (this.Process == null || this.DLL == null || this.Procedure == null|| this.Callback == null)
throw new ArgumentNullException();
if (this.Address != IntPtr.Zero || this.Old != null)
throw new InvalidOperationException();
if (this.Process.HasExited)
throw new InvalidOperationException();
IntPtr bytes = IntPtr.Zero;
byte[] asm = new byte[] {
0xB8, 0x00, 0x00, 0x00, 0x00, // MOV EAX, addr
0xFF, 0xE0 // JMP EAX
};
IntPtr handle = OpenProcess(ProcessAccessFlags.All, false, this.Process.Id);
if (handle == IntPtr.Zero)
throw new ApplicationException();
IntPtr hModule = GetModuleHandle(this.DLL);
if (hModule == IntPtr.Zero)
throw new ApplicationException();
this.Address = GetProcAddress(hModule, this.Procedure);
if (this.Address == IntPtr.Zero)
throw new ApplicationException();
this.Old = new byte[asm.Length];
Array.Copy(BitConverter.GetBytes((uint)Marshal.GetFunctionPointerForDelegate(this.Callback)), 0, asm, 1, 4);
if (!ReadProcessMemory(handle, this.Address, this.Old, this.Old.Length, out bytes))
throw new ApplicationException();
if (this.Old.Length != (int)bytes)
throw new ApplicationException();
if (!WriteProcessMemory(handle, this.Address, asm, asm.Length, out bytes))
throw new ApplicationException();
if (asm.Length != (int)bytes)
throw new ApplicationException();
if (!CloseHandle(handle))
throw new ApplicationException();
}
/// <summary>
/// Clear the hook previously set.
/// </summary>
public void UnHook() {
if (this.Process == null)
throw new ArgumentNullException();
if (this.Address == IntPtr.Zero || this.Old == null)
throw new InvalidOperationException();
if (this.Process.HasExited)
throw new InvalidOperationException();
IntPtr bytes = IntPtr.Zero;
IntPtr handle = OpenProcess(ProcessAccessFlags.All, false, this.Process.Id);
if (handle == IntPtr.Zero)
throw new ApplicationException();
if (!WriteProcessMemory(handle, this.Address, this.Old, this.Old.Length, out bytes))
throw new ApplicationException();
if (this.Old.Length != (int)bytes)
throw new ApplicationException();
if (!CloseHandle(handle))
throw new ApplicationException();
this.Address = IntPtr.Zero;
this.Old = null;
}
#endregion
#region <Properties>
/// <summary>
/// Process to hook.
/// </summary>
public Process Process { get; set; }
/// <summary>
/// DLL of the procedure to hook.
/// </summary>
public string DLL { get; set; }
/// <summary>
/// Procedure to hook.
/// </summary>
public string Procedure { get; set; }
/// <summary>
/// Managed alternative procedure (callback)
/// </summary>
public Delegate Callback { get; set; }
/// <summary>
/// Address of the hooked procedure.
/// </summary>
public IntPtr Address { get; set; }
/// <summary>
/// Old opcodes of the hooked procedure.
/// </summary>
public byte[] Old { get; set; }
#endregion
#region <API>
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll")]
public static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int dwSize, out IntPtr lpNumberOfBytesRead);
[DllImport("kernel32.dll")]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, out IntPtr lpNumberOfBytesWritten);
[Flags]
public enum ProcessAccessFlags : uint {
All = 0x001F0FFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VMOperation = 0x00000008,
VMRead = 0x00000010,
VMWrite = 0x00000020,
DupHandle = 0x00000040,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
Synchronize = 0x00100000
}
#endregion
}
Example:
Code:
public static APIHook hook;
public static void Main() {
hook = new APIHook(Process.GetCurrentProcess(), "kernel32.dll", "Beep", new BeepDelegate(BeepCallback));
Beep(750, 300);
hook.Hook();
Beep(750, 300);
}
public static bool BeepCallback(uint dwFreq, uint dwDuration) {
Debug.WriteLine("Beep hooked!");
hook.UnHook();
return Beep(dwFreq, dwDuration);
}
public delegate bool BeepDelegate(uint dwFreq, uint dwDuration);
[DllImport("kernel32.dll")]
public static extern bool Beep(uint dwFreq, uint dwDuration);
Xartrick.