c# r3 inline hook
前言
老婆喜歡在QQ游戲玩拖拉機,且安裝了一個記牌器小軟件,打開的時候彈出幾個IE頁面加載很多廣告,於是叫我去掉廣告。想想可以用OD進行nop填充,也可以寫api hook替換shellexecute函數的調用,以前也有見過有人使用hex editor修改shellexecute函數的,但搞了多年C#,其它很多原來就不熟悉的都忘記了,迫於無奈於是選擇Api Hook這個方式。選擇這Api Hook也面臨很多難題,如何遠程注入,如何讓遠程進程加載.net的程序集,.net程序集如何完成Api的hook工作,網上查到微軟的detours庫,可以滿足APi Hook需求,由於非班科出身,所以從0基礎開始使用VC對detours庫進行封裝和導出給.net進行pinvoke調用(以前搞delphi去了)。
解決方案
1、使用C++編寫Core.dll這個動態連接庫,封裝detours庫的函數並導出,同時開啟C++/CLI,使用托管代碼編寫反射加載和執行外部.Net程序集的Main入口函數;
2、外部.Net程序集使用pinvoke調用Core.dll來完成Api Hook;
3、再編寫一個Main.dll動態連接庫,dllMain創建線程加載Core.dll,使Core.dll加載和運行指定的.Net程序集。
Core.dll功能
遠程注入並Hook Api
更方便的封裝
上面的main.dll是給遠程注入使用的,core.dll是detours的封裝,也是.net程序集的加載器,為了更容易使用core.dll,我使用.net寫了一個叫coreNet.dll的程序集,是對core.dll的導出函數的封裝,提供了APi Hook、Window Hook,還有注入相關方法。
創建進程並注入DotNet_ApiHook.dll例子:
Inject.InjectToProcess("TargetProcess.exe", null, "DotNet_ApiHook.dll");
DotNet_ApiHook.dll 代碼例子,下面是Hook住MessageBoxW函數:
public class Program
{
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
private delegate int MessageBoxW(IntPtr hwnd, string text, string caption, int type);
private static HookResult<MessageBoxW> messageBoxW;
/// <summary>
/// 程序集入口函數
/// </summary>
/// <param name="args"></param>
public static void Main(string[] args)
{
messageBoxW = Hook.HookApi<MessageBoxW>("user32.dll", "MessageBoxW", MessageBoxW_Proxy);
}
private static int MessageBoxW_Proxy(IntPtr hwnd, string text, string caption, int type)
{
return messageBoxW.TargetApi.Invoke(hwnd, "[Hook]" + text, "[Hook]" + caption, type == 0 ? 1 : type);
}
}