MHOOK的使用

来源:互联网 发布:linux查看当前登录用户 编辑:程序博客网 时间:2024/05/17 07:53

之前写外挂都用的是网上的帖子HOOK目标程序的send和recv,然后采用WriteProcessMemory替换我们的函数和Windows API函数,不断的来回切换,这个其实数据密集的时候容易出错也不稳定,不提倡!并且代码输写很容易出错。这里我贴出我自己写过的HOOK库,用过攻城略地和大皇帝等等游戏,均通过测试,非常之稳定。
把MHOOK封装成动态链接库,直接调用DLL文件进行HOOK目标函数,也可以实现远程注入。并且不会被游戏反外挂发觉。动态链接库代码如下:

01//Copyright (c) 2007-2008, Marton Anka
02//
03//Permission is hereby granted, free of charge, to any person obtaining a
04//copy of this software and associated documentation files (the "Software"),
05//to deal in the Software without restriction, including without limitation
06//the rights to use, copy, modify, merge, publish, distribute, sublicense,
07//and/or sell copies of the Software, and to permit persons to whom the
08//Software is furnished to do so, subject to the following conditions:
09//
10//The above copyright notice and this permission notice shall be included
11//in all copies or substantial portions of the Software.
12//
13//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14//OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16//THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18//FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19//IN THE SOFTWARE.
20 
21#ifdef _M_IX86
22#define _M_IX86_X64
23#elif defined _M_X64
24#define _M_IX86_X64
25#endif
26 
27BOOLMhook_SetHook(PVOID*ppSystemFunction, PVOIDpHookFunction);
28BOOLMhook_Unhook(PVOID*ppHookedFunction);
29 
30#define MHOOKS_MAX_SUPPORTED_HOOKS    64

我这里只针对HOOK socket的send和recv

01// mk.cpp : 定义 DLL 应用程序的导出函数。
02//
03 
04#include "stdafx.h"
05#include "mhook-lib/mhook.h"
06 
07externmhook_func _msend;
08externmhook_func _mrecv;
09externmhook_func _mwsend;
10externmhook_func _mwrecv;
11 
12//ppSystemFunction为系统API,pHookFunction为自己定义的API
13BOOLt001(PVOID*ppSystemFunction, PVOIDpHookFunction)
14{
15    returnMhook_SetHook(ppSystemFunction,pHookFunction);
16}
17 
18//pHookFunction为自己定义的API
19BOOLt002(PVOID*ppHookedFunction)
20{
21    returnMhook_Unhook(ppHookedFunction);
22}
23 
24//设置1.0函数地址
25BOOLt003(mhook_func pHookSendFunc,mhook_func pHookRecvFuc)
26{
27    _msend = pHookSendFunc;
28    _mrecv = pHookRecvFuc;
29    returnTRUE;
30}
31 
32//设置2.0函数地址
33BOOLt004(mhook_func pHookSendFunc,mhook_func pHookRecvFuc)
34{
35    _mwsend = pHookSendFunc;
36    _mwrecv = pHookRecvFuc;
37    returnTRUE;
38}

DLL入口文件

001// dllmain.cpp : 定义 DLL 应用程序的入口点。
002#include "stdafx.h"
003#include "mhook-lib/mhook.h"
004#include <WinSock2.h>
005 
006//////////////封包函数//////////////
007staticvoidGT_WriteReleaseLog(char* str,char* path="C:\\mk.log")
008{
009    HANDLEhFile = CreateFileA(path, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
010    if(hFile == NULL)
011        return;
012    //设置文件中进行读写的当前位置
013    _llseek((HFILE)hFile,0, SEEK_END);
014    DWORDdw;
015    WriteFile(hFile,str,strlen(str),&dw,NULL);
016    _lclose((HFILE)hFile);
017}
018HMODULEhMod = LoadLibraryA("Ws2_32");
019//1.0
020typedefint(WINAPI *_send)(SOCKET s, constchar*buf, intlen, intflags);
021typedefint(WINAPI *_recv)(SOCKET s, char*buf, intlen, intflags);
022_send g_trueSend = (_send)GetProcAddress(hMod,"send");
023_recv g_trueRecv = (_recv)GetProcAddress(hMod,"recv");
024//2.0
025typedefint(WINAPI *_wsend)(SOCKET s, LPWSABUF lpBuffers, DWORDdwBufferCount,                                   
026    LPDWORDlpNumberOfBytesSent,DWORDdwFlags, LPWSAOVERLAPPED lpOverlapped,                          
027    LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
028typedefint(WINAPI *_wrecv)(SOCKET s, LPWSABUF lpBuffers, DWORDdwBufferCount,                                   
029    LPDWORDlpNumberOfBytesRecvd, LPDWORDlpFlags, LPWSAOVERLAPPED lpOverlapped,                          
030    LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
031_wsend g_trueWSend = (_wsend)GetProcAddress(hMod,"WSASend");
032_wrecv g_trueWRecv = (_wrecv)GetProcAddress(hMod,"WSARecv");
033 
034mhook_func _msend = NULL;
035mhook_func _mrecv = NULL;
036mhook_func _mwsend = NULL;
037mhook_func _mwrecv = NULL;
038 
039/**
040参数描述:
041SOCKET s         发送端套接字描述符
042const char *buf  应用程序要发送的数据的缓冲区(想要发送的数据)
043int len          实际要发送的字节数
044int flags        一般置为0即可
045如果没有错误发生,send将返回的总字节数发送
046*/
047intWINAPI hook_send(SOCKET s, constchar*buf, intlen, intflags)
048{
049    intret = g_trueSend(s,buf,len,flags);
050    if(ret > 0)
051    {
052        char*temp = newchar[ret];
053        memcpy_s(temp,ret,buf,ret);
054        if(_msend != NULL)
055            _msend(s,temp,ret);
056        deletetemp;
057    }
058    returnret;
059}
060 
061/**
062参数描述:
063SOCKET s         发送端套接字描述符
064const char *buf  应用程序存放接收的数据的缓冲区
065int len          buf的长度
066int flags        一般置为0即可
067如果没有错误发生,recv返回的字节数的接收
068*/
069intWINAPI hook_recv(SOCKET s, char*buf, intlen, intflags)
070{
071    intret = g_trueRecv(s,buf,len,flags);
072    if(ret > 0)
073    {
074        char*temp = newchar[ret];
075        memcpy_s(temp,ret,buf,ret);
076        if(_msend != NULL)
077            _mrecv(s,temp,ret);
078        deletetemp;
079    }
080    returnret;
081}
082 
083/*
084s:标识一个已连接套接口的描述字。
085    lpBuffers:一个指向WSABUF结构数组的指针。每个WSABUF结构包含缓冲区的指针和缓冲区的大小。
086    dwBufferCount:lpBuffers数组中WSABUF结构的数目。
087    lpNumberOfBytesSent:如果发送操作立即完成,则为一个指向所发送数据字节数的指针。
088    dwFlags:标志位。
089    lpOverlapped:指向WSAOVERLAPPED结构的指针(对于非重叠套接口则忽略)。
090    lpCompletionRoutine:一个指向发送操作完成后调用的完成例程的指针。(对于非重叠套接口则忽略)。
091    若无错误发生且发送操作立即完成,则WSASend()函数返回0
092*/
093intWINAPI hook_wsend(SOCKET s, LPWSABUF lpBuffers, DWORDdwBufferCount,                                   
094    LPDWORDlpNumberOfBytesSent,DWORDdwFlags, LPWSAOVERLAPPED lpOverlapped,                          
095    LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
096{
097    intret = g_trueWSend(s,lpBuffers,dwBufferCount,lpNumberOfBytesSent
098        ,dwFlags,lpOverlapped,lpCompletionRoutine);
099    DWORDlen = *lpNumberOfBytesSent;
100    if(len > 0)
101    {
102        char*temp = newchar[len];
103        memcpy_s(temp,len,lpBuffers->buf,len);
104        if(_mwsend != NULL)
105            _mwsend(s,temp,len);
106        deletetemp;
107    }
108    returnret;
109}
110 
111intWINAPI hook_wrecv(SOCKET s, LPWSABUF lpBuffers, DWORDdwBufferCount,                                   
112    LPDWORDlpNumberOfBytesRecvd, LPDWORDlpFlags, LPWSAOVERLAPPED lpOverlapped,                          
113    LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
114{
115    intret = g_trueWRecv(s,lpBuffers,dwBufferCount,lpNumberOfBytesRecvd,lpFlags
116        ,lpOverlapped,lpCompletionRoutine);
117    DWORDlen = *lpNumberOfBytesRecvd;
118    if(len > 0)
119    {
120        char*temp = newchar[len];
121        memcpy_s(temp,len,lpBuffers->buf,len);
122        if(_mwrecv != NULL)
123            _mwrecv(s,temp,len);
124        deletetemp;
125    }
126    returnret;
127}
128 
129BOOLAPIENTRY DllMain(HMODULEhModule,DWORD ul_reason_for_call,LPVOIDlpReserved)
130{
131    switch(ul_reason_for_call)
132    {
133    caseDLL_PROCESS_ATTACH:
134        //直接在这里HOOK SEND和RECV函数
135        Mhook_SetHook((LPVOID*)&g_trueSend,hook_send);
136        Mhook_SetHook((LPVOID*)&g_trueRecv,hook_recv);
137        Mhook_SetHook((LPVOID*)&g_trueWSend,hook_wsend);
138        Mhook_SetHook((LPVOID*)&g_trueWRecv,hook_wrecv);
139        break;
140    caseDLL_THREAD_ATTACH:
141        break;
142    caseDLL_THREAD_DETACH:
143        break;
144    caseDLL_PROCESS_DETACH:
145        //直接在这里UNHOOK SEND和RECV函数)
146        Mhook_Unhook((LPVOID*)&g_trueSend);
147        Mhook_Unhook((LPVOID*)&g_trueRecv);
148        Mhook_Unhook((LPVOID*)&g_trueWSend);
149        Mhook_Unhook((LPVOID*)&g_trueWRecv);
150        if(hModule != NULL)
151            FreeLibrary(hModule);
152        break;
153    }
154    returnTRUE;
155}

最后加上DEF文件

1LIBRARY
2 
3EXPORTS
4    ; 此处可以是显式导出
5    t001 @1
6    t002 @2
7    t003 @3
8    t004 @4

MHOOK代码网上有下载,这里我就不贴出来了。

看我写的工具抓的包,如图
20141217223605

详情请参考另外博客:IT十万为什么 » MHOOK的使用

1 0
原创粉丝点击