之前写外挂都用的是网上的帖子HOOK目标程序的send和recv,然后采用WriteProcessMemory替换我们的函数和Windows API函数,不断的来回切换,这个其实数据密集的时候容易出错也不稳定,不提倡!并且代码输写很容易出错。这里我贴出我自己写过的HOOK库,用过攻城略地和大皇帝等等游戏,均通过测试,非常之稳定。 把MHOOK封装成动态链接库,直接调用DLL文件进行HOOK目标函数,也可以实现远程注入。并且不会被游戏反外挂发觉。动态链接库代码如下:
我这里只针对HOOK socket的send和recv
DLL入口文件
最后加上DEF文件
MHOOK代码网上有下载,这里我就不贴出来了。
看我写的工具抓的包,如图
//Copyright (c) 2007-2008, Marton Anka // //Permission is hereby granted, free of charge, to any person obtaining a //copy of this software and associated documentation files (the "Software"), //to deal in the Software without restriction, including without limitation //the rights to use, copy, modify, merge, publish, distribute, sublicense, //and/or sell copies of the Software, and to permit persons to whom the //Software is furnished to do so, subject to the following conditions: // //The above copyright notice and this permission notice shall be included //in all copies or substantial portions of the Software. // //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS //OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL //THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING //FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS //IN THE SOFTWARE. #ifdef _M_IX86 #define _M_IX86_X64 #elif defined _M_X64 #define _M_IX86_X64 #endif BOOL Mhook_SetHook(PVOID *ppSystemFunction, PVOID pHookFunction); BOOL Mhook_Unhook(PVOID *ppHookedFunction); #define MHOOKS_MAX_SUPPORTED_HOOKS 64
我这里只针对HOOK socket的send和recv
// mk.cpp : 定义 DLL 应用程序的导出函数。 // #include "stdafx.h" #include "mhook-lib/mhook.h" extern mhook_func _msend; extern mhook_func _mrecv; extern mhook_func _mwsend; extern mhook_func _mwrecv; //ppSystemFunction为系统API,pHookFunction为自己定义的API BOOL t001(PVOID *ppSystemFunction, PVOID pHookFunction) { return Mhook_SetHook(ppSystemFunction,pHookFunction); } //pHookFunction为自己定义的API BOOL t002(PVOID *ppHookedFunction) { return Mhook_Unhook(ppHookedFunction); } //设置1.0函数地址 BOOL t003(mhook_func pHookSendFunc,mhook_func pHookRecvFuc) { _msend = pHookSendFunc; _mrecv = pHookRecvFuc; return TRUE; } //设置2.0函数地址 BOOL t004(mhook_func pHookSendFunc,mhook_func pHookRecvFuc) { _mwsend = pHookSendFunc; _mwrecv = pHookRecvFuc; return TRUE; }
DLL入口文件
// dllmain.cpp : 定义 DLL 应用程序的入口点。 #include "stdafx.h" #include "mhook-lib/mhook.h" #include //////////////封包函数////////////// static void GT_WriteReleaseLog(char* str,char* path="C:\mk.log") { HANDLE hFile = CreateFileA(path, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile == NULL) return; //设置文件中进行读写的当前位置 _llseek((HFILE)hFile,0, SEEK_END); DWORD dw; WriteFile(hFile,str,strlen(str),&dw,NULL); _lclose((HFILE)hFile); } HMODULE hMod = LoadLibraryA("Ws2_32"); //1.0 typedef int (WINAPI *_send)(SOCKET s, const char *buf, int len, int flags); typedef int (WINAPI *_recv)(SOCKET s, char *buf, int len, int flags); _send g_trueSend = (_send)GetProcAddress(hMod,"send"); _recv g_trueRecv = (_recv)GetProcAddress(hMod,"recv"); //2.0 typedef int (WINAPI *_wsend)(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent,DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); typedef int (WINAPI *_wrecv)(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); _wsend g_trueWSend = (_wsend)GetProcAddress(hMod,"WSASend"); _wrecv g_trueWRecv = (_wrecv)GetProcAddress(hMod,"WSARecv"); mhook_func _msend = NULL; mhook_func _mrecv = NULL; mhook_func _mwsend = NULL; mhook_func _mwrecv = NULL; /** 参数描述: SOCKET s 发送端套接字描述符 const char *buf 应用程序要发送的数据的缓冲区(想要发送的数据) int len 实际要发送的字节数 int flags 一般置为0即可 如果没有错误发生,send将返回的总字节数发送 */ int WINAPI hook_send(SOCKET s, const char *buf, int len, int flags) { int ret = g_trueSend(s,buf,len,flags); if (ret > 0) { char *temp = new char[ret]; memcpy_s(temp,ret,buf,ret); if(_msend != NULL) _msend(s,temp,ret); delete temp; } return ret; } /** 参数描述: SOCKET s 发送端套接字描述符 const char *buf 应用程序存放接收的数据的缓冲区 int len buf的长度 int flags 一般置为0即可 如果没有错误发生,recv返回的字节数的接收 */ int WINAPI hook_recv(SOCKET s, char *buf, int len, int flags) { int ret = g_trueRecv(s,buf,len,flags); if (ret > 0) { char *temp = new char[ret]; memcpy_s(temp,ret,buf,ret); if(_msend != NULL) _mrecv(s,temp,ret); delete temp; } return ret; } /* s:标识一个已连接套接口的描述字。 lpBuffers:一个指向WSABUF结构数组的指针。每个WSABUF结构包含缓冲区的指针和缓冲区的大小。 dwBufferCount:lpBuffers数组中WSABUF结构的数目。 lpNumberOfBytesSent:如果发送操作立即完成,则为一个指向所发送数据字节数的指针。 dwFlags:标志位。 lpOverlapped:指向WSAOVERLAPPED结构的指针(对于非重叠套接口则忽略)。 lpCompletionRoutine:一个指向发送操作完成后调用的完成例程的指针。(对于非重叠套接口则忽略)。 若无错误发生且发送操作立即完成,则WSASend()函数返回0 */ int WINAPI hook_wsend(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent,DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) { int ret = g_trueWSend(s,lpBuffers,dwBufferCount,lpNumberOfBytesSent ,dwFlags,lpOverlapped,lpCompletionRoutine); DWORD len = *lpNumberOfBytesSent; if (len > 0) { char *temp = new char[len]; memcpy_s(temp,len,lpBuffers->buf,len); if(_mwsend != NULL) _mwsend(s,temp,len); delete temp; } return ret; } int WINAPI hook_wrecv(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) { int ret = g_trueWRecv(s,lpBuffers,dwBufferCount,lpNumberOfBytesRecvd,lpFlags ,lpOverlapped,lpCompletionRoutine); DWORD len = *lpNumberOfBytesRecvd; if (len > 0) { char *temp = new char[len]; memcpy_s(temp,len,lpBuffers->buf,len); if(_mwrecv != NULL) _mwrecv(s,temp,len); delete temp; } return ret; } BOOL APIENTRY DllMain(HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: //直接在这里HOOK SEND和RECV函数 Mhook_SetHook((LPVOID*)&g_trueSend,hook_send); Mhook_SetHook((LPVOID*)&g_trueRecv,hook_recv); Mhook_SetHook((LPVOID*)&g_trueWSend,hook_wsend); Mhook_SetHook((LPVOID*)&g_trueWRecv,hook_wrecv); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: //直接在这里UNHOOK SEND和RECV函数) Mhook_Unhook((LPVOID*)&g_trueSend); Mhook_Unhook((LPVOID*)&g_trueRecv); Mhook_Unhook((LPVOID*)&g_trueWSend); Mhook_Unhook((LPVOID*)&g_trueWRecv); if(hModule != NULL) FreeLibrary(hModule); break; } return TRUE; }
最后加上DEF文件
LIBRARY EXPORTS ; 此处可以是显式导出 t001 @1 t002 @2 t003 @3 t004 @4
MHOOK代码网上有下载,这里我就不贴出来了。
看我写的工具抓的包,如图
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (10)
- LouellaShackelfo 2016-1-14引用 2楼extern mhook_func _msend; extern mhook_func _mrecv; extern mhook_func _mwsend; extern mhook_func _mwrecv; 这个 mhook_func是怎么定义的,大神 代码里没有呢
- kkae8643158 2016-5-3引用 3楼typedef void (WINAPI *mhook_func)(char *buf, int len);
- Darlene54I 2016-5-3引用 4楼函数t003,t004是做什么使用的呢?并没有看见调用,还是说blog里边只是一部分代码呢
- amirassari2002 2016-5-4引用 8楼这篇文章对我很有用,谢谢。或者可以 _send g_trueSend = (_send)GetProcAddress(GetModuleHandle(L"Ws2_32"),"send"); 额,我不太会使用Windows的函数,,,如果错了,额,那就回复告诉我一声,最近在找拦截API出现异常崩溃的原因,如果有这方面经验,求分享,先谢谢你了。
- Will40877336781 2016-5-4引用 10楼多查阅下资料就知道了。这是获取系统的真实api函数地址,我们要在这个函数之前处理一些数据,最后调用这个函数。
站点信息
- 文章2295
- 用户1336
- 访客10160089
每日一句
Success is how high you bounce when you hit bottom.
成功是你跌到谷底时反弹的高度。
成功是你跌到谷底时反弹的高度。
新会员