之前写外挂都用的是网上的帖子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函数地址,我们要在这个函数之前处理一些数据,最后调用这个函数。
-
站点信息
- 文章2305
- 用户1336
- 访客11456237
每日一句
Talent without working hard is nothing.
没有努力,天份不代表什么。
没有努力,天份不代表什么。
MySQL 数据库优化
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de
免ROOT实现模拟点击任意位置
Mobaxterm终端神器
CreateProcessW要注意的细节问题
Autonomous NAT Traversal
【教程】win10 彻底卸载edge浏览器
eclipse工程基于Xposed的一个简单Hook
排名前5的开源在线机器学习
Mac OS最简单及(Karabiner)快捷键设置
发一款C++编写的麻将
VMware NAT端口映射外网访问虚拟机linux
独家发布最新可用My-AutoPost——wordpress 采集器
新会员