mhook的用法_MHOOK的使用

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

//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代码网上有下载,这里我就不贴出来了。

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

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页