Skip to content

Instantly share code, notes, and snippets.

@rhotav
Last active January 16, 2021 14:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rhotav/4a9adeb322bdcf753eb3c46eb3546ca4 to your computer and use it in GitHub Desktop.
Save rhotav/4a9adeb322bdcf753eb3c46eb3546ca4 to your computer and use it in GitHub Desktop.
Windows API Hooking with C# (MessageBoxA)
using System;
using System.Runtime.InteropServices;
namespace Hook_Example
{
class HookManager
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize,
uint flNewProtect, out uint lpflOldProtect);
const int N_BYTES = 5;
IntPtr addr;
uint old;
byte[] src = new byte[5];
byte[] dst = new byte[5];
public HookManager(IntPtr source, IntPtr destination)
{
VirtualProtect(source, N_BYTES, 0x40, out old); //İzinleri düzenliyoruz. 0x40 kodu ile Yazma Okuma izni veriyoruz.
Marshal.Copy(source, src, 0, N_BYTES); //Gelen Source Adresindeki ilk 6 byte'ı alıyor ve src değişkenine yazdırıyor.
dst[0] = 0xE9; //jmp bytecode
var dx = BitConverter.GetBytes((int)destination - (int)source - N_BYTES);
Array.Copy(dx, 0, dst, 1, N_BYTES - 1);
addr = source;
}
public void Install()
{
Marshal.Copy(dst, 0, addr, N_BYTES); //sahte fonksiyonumuza yönlendiren kodları yazdırıyoruz.
}
public void Uninstall()
{
Marshal.Copy(src, 0, addr, N_BYTES); //Orjinal byte'ları tekrar yerine yazıyoruz.
}
}
}
using System;
using System.Runtime.InteropServices;
namespace Hook_Example
{
class Program
{
//Bu iki DLL Import işlemi API adresi saptanması için.
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi)]
static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName);
//============================================================
[DllImport("user32.dll")] //API'yi Console uygulamamızda kullanıyoruz.
static extern int MessageBoxA(IntPtr hWnd,
string lpText,
string lpCaption,
uint uType);
static HookManager hook; //Hook sınıfımızı tanıttık.
delegate int hookedMessageBox(IntPtr hWnd,
string lpText,
string lpCaption,
uint uType); //Fonksiyon adresini tutabilmemiz için.
static int fakeMessageBox(IntPtr hWnd,
string lpText,
string lpCaption,
uint uType)
{
Console.WriteLine("\"lpText\" Yakalandi : {0}", lpText) ;
Console.WriteLine("\"lpCaption\" Yakalandi : {0}", lpCaption);
hook.Uninstall(); //dead cycle girmemek için.
MessageBoxA(hWnd, lpText, lpCaption, uType);
hook.Install();
return 0;
}
static void Main(string[] args)
{
var funcAddress = GetProcAddress(LoadLibrary("user32"), "MessageBoxA"); //MessageBoxA API'sinin başladığı adresi aldık.
//HookManager olarak tanımladığımız "hook" değişkenine atama yapıyoruz.
//Marshal sınıfında bulunan GetFunctionPointerForDelegate fonksiyonu ile delegate attığımız fake fonksiyonun hafızadaki adresini alıyoruz.
hook = new HookManager(funcAddress, Marshal.GetFunctionPointerForDelegate((hookedMessageBox)fakeMessageBox));
//hook işlemini gerçekleştiriyoruz.
hook.Install();
MessageBoxA((IntPtr)null, "Test", "TestCaption", 0);
Console.ReadKey();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment