前言
老婆喜欢在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); } }
代码下载
当然,所有代码,包括我蹩脚的非托管代码部分,还有网上抄写的,以及.Net的,都拿出给大家看看,工程已经放在了https://github.com/xljiulang/HookSln
如果你想只下载编译好的可以 点击这里下载
其它工程:高性能高可扩展性Socket组件