Win2K下的Api函数的拦截 <br>原创:tomh(tomh) <br> <br> 这么多高手在这里,哎,小弟愿意向各位高手学习 <br> Api拦截并不是一个新的技术,很多商业软件都采用这种技术。对windows的Api函数的拦截,不外乎两种方法,第一种是Mr. Jeffrey Richter 的修改exe文件的模块输入节,种方法,很安全,但很复杂,而且有些exe文件,没有Dll的输入符号的列表,有可能出现拦截不到的情况。第二种方法就是常用的JMP XXX的方法,虽然很古老,却很简单实用。 <br> 本文一介绍第二种方法在Win2k下的使用。第二种方法,Win98/me 下因为进入Ring0级的方法很多,有LDT,IDT,Vxd等方法,很容易在内存中动态修改代码,但在Win2k下,这些方法都不能用,写WDM太过复杂,表面上看来很难实现, <br>其实不然。Win2k为我们提供了一个强大的内存Api操作函数---VirtualProtectEx,WriteProcessMemeory,ReadProcessMemeory,有了它们我们就能在内存中动态修改代码了,其原型为: <br> BOOL VirtualProtectEx( <br> HANDLE hProcess, // 要修改内存的进程句柄 <br> LPVOID lpAddress, // 要修改内存的起始地址 <br> DWORD dwSize, // 修改内存的字节 <br> DWORD flNewProtect, // 修改后的内存属性 <br> PDWORD lpflOldProtect // 修改前的内存属性的地址 <br> ); <br> BOOL WriteProcessMemory( <br> HANDLE hProcess, // 要写进程的句柄 <br> LPVOID lpBaseAddress, // 写内存的起始地址 <br> LPVOID lpBuffer, // 写入数据的地址 <br> DWORD nSize, // 要写的字节数 <br> LPDWORD lpNumberOfBytesWritten // 实际写入的子节数 <br>  
; <br> BOOL ReadProcessMemory( <br> HANDLE hProcess, // 要读进程的句柄 <br> LPCVOID lpBaseAddress, // 读内存的起始地址 <br> LPVOID lpBuffer, // 读入数据的地址 <br> DWORD nSize, // 要读入的字节数 <br> LPDWORD lpNumberOfBytesRead // 实际读入的子节数 <br> ); <br>具体的参数请参看MSDN帮助。在Win2k下因为Dll和所属进程在同一地址空间,这点又和Win9x/me存在所有进程存在共享的地址空间不同, <br>因此,必须通过钩子函数和远程注入进程的方法,现以一个简单采用钩子函数对MessageBoxA进行拦截例子来说明: <br>其中Dll文件为: <br> HHOOK g_hHook; <br> HINSTANCE g_hinstDll; <br> FARPROC pfMessageBoxA; <br> int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption,UINT uType); <br> BYTE OldMessageBoxACode[5],NewMessageBoxACode[5]; <br> HMODULE hModule ; <br> DWORD dwIdOld,dwIdNew; <br> BOOL bHook=false; <br> void HookOn(); <br> void HookOff(); <br> BOOL init(); <br>LRESULT WINAPI MousHook(int nCode,WPARAM wParam,LPARAM lParam); <br>BOOL APIENTRY DllMain( HANDLE hModule, <br> DWORD ul_reason_for_call, <br> LPVOID lpReserved <br>  
<br>{ <br> switch (ul_reason_for_call) <br> { <br> case DLL_PROCESS_ATTACH: <br> if(!init()) <br> { <br> MessageBoxA(NULL,"Init","ERROR",MB_OK); <br> return(false); <br> } <br> case DLL_THREAD_ATTACH: <br> case DLL_THREAD_DETACH: <br> case DLL_PROCESS_DETACH: <br> if(bHook) UnintallHook(); <br> break; <br> } <br> return TRUE; <br>} <br>LRESULT WINAPI Hook(int nCode,WPARAM wParam,LPARAM lParam)//空的钩子函数 <br>{ <br> <br> return(CallNextHookEx(g_hHook,nCode,wParam,lParam)); <br>} <br>HOOKAPI2_API BOOL InstallHook()//输出安装空的钩子函数 <br>{ <br> g_hinstDll=LoadLibrary("HookApi2.dll"); <br> g_hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)Hook,g_hinstDll,0); <br> if (!g_hHook) <br> { <br> MessageBoxA(NULL,"SET ERROR","ERROR",MB_OK); <br> return(false); <br> } <br> <br> <br> return(true); <br>} <br>HOOKAPI2_API BOOL UninstallHook()//输出御在钩子函数 <br>{ <br> <br> return(UnhookWindowsHookEx(g_hHook)); <br>