[C#] APIHook Class menu

User Tag List

Results 1 to 5 of 5
  1. #1
    Xartrick's Avatar Active Member
    Reputation
    24
    Join Date
    May 2011
    Posts
    29
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [C#] APIHook Class

    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.
    Last edited by Xartrick; 12-29-2013 at 10:23 AM.

    [C#] APIHook Class
  2. #2
    Bananenbrot's Avatar Contributor
    Reputation
    153
    Join Date
    Nov 2009
    Posts
    384
    Thanks G/R
    1/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I typically need to change page protection flags for it in order to work... See https://github.com/Bananenbrot/Banan...cture/Patch.cs.
    Also, don't inherit from ApplicationException. It's not recommended (anymore), see the remarks on MSDN.

    Edit: Your Hook should implement IDisposable and have the appropriate finalizer too. If the code before hook.Unhook() throws, you never get to clean up the mess you caused and your host process will most likely crash.
    Last edited by Bananenbrot; 07-25-2013 at 09:48 AM.

  3. #3
    Xartrick's Avatar Active Member
    Reputation
    24
    Join Date
    May 2011
    Posts
    29
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Bananenbrot View Post
    I typically need to change page protection flags for it in order to work... See https://github.com/Bananenbrot/Banan...cture/Patch.cs.
    I used VirtualProtect(Ex) to do it, but in my case, I don't need it, for other case, maybe.

    Originally Posted by Bananenbrot View Post
    Also, don't inherit from ApplicationException. It's not recommended (anymore), see the remarks on MSDN.
    I din't see anything about it, can you send me a link?

    Originally Posted by Bananenbrot View Post
    Edit: Your Hook should implement IDisposable and have the appropriate finalizer too. If the code before hook.Unhook() throws, you never get to clean up the mess you caused and your host process will most likely crash.
    I tried to be as simple as possible, I didn't handle all crash posibilities, but you're right, should implement it.

  4. #4
    Bananenbrot's Avatar Contributor
    Reputation
    153
    Join Date
    Nov 2009
    Posts
    384
    Thanks G/R
    1/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This SO answer cites the respective MDSN page: c# - What is ApplicationException for in .NET? - Stack Overflow

  5. #5
    Xartrick's Avatar Active Member
    Reputation
    24
    Join Date
    May 2011
    Posts
    29
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Bananenbrot View Post
    This SO answer cites the respective MDSN page: c# - What is ApplicationException for in .NET? - Stack Overflow
    After many re-read, I understand, I sometimes read too quickly and don't understand the whole thing.
    English isn't my native language.

Similar Threads

  1. What class do you play as?
    By janzi9 in forum Community Chat
    Replies: 28
    Last Post: 11-13-2006, 04:03 PM
  2. Whats your favorite class?
    By Bossman4 in forum World of Warcraft General
    Replies: 32
    Last Post: 11-07-2006, 09:48 AM
  3. Guide for your class in an instance!
    By Bossman4 in forum World of Warcraft Guides
    Replies: 5
    Last Post: 10-28-2006, 03:39 PM
  4. Full Guide for Dungeon Set 1 items (all classes)
    By Cush in forum World of Warcraft Guides
    Replies: 13
    Last Post: 09-07-2006, 03:07 PM
  5. priest own any class
    By bigbaz in forum World of Warcraft Exploits
    Replies: 4
    Last Post: 06-10-2006, 01:13 AM
All times are GMT -5. The time now is 09:10 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search