mhook HOOK库,是一个非常不错的开源的HOOK库。支持WIN32/64平台。
测试过程:
1.利用mhook库写了个dll,dll的作用是hook了WSASocketW(随便选的一个函数)。
2.用winsock编程,写了个TCP通信程序(服务端和客户端)。为了方便测试,客户端多次调用“socket( AF_INET ,SOCK_STREAM , 0 )”,注意此函数会再内部调用WSASocketW,即我们上面hook掉的那个函数。
3.用od附加客户端进程,CTL+G到WSASocketW,截个图(此时还没有被hook)。
4.随便用过dll注入工具把第1步的dll注入到客户端进程,CTL+G到WSASocketW后再截个图(此时已经被hook),然后F7或F8单步调试,即可明白原理。
结论:
mhook会修改被hook函数的头5个字节,修改后的内容为"jmp HookFunc",并将被修改或者被破坏掉的指令保存下来,当调用TrueFunc(可以理解为真实函数)的时候,先归还原函数的代码,并jmp到原函数继续执行。(具体流程,参见图1)
测试代码:
#include <windows.h>
#include <Winbase.h>
#include "mhook-lib/mhook.h"
#include <stdio.h>
BOOL bHookSuccess = FALSE;
#define MAX_PROTOCOL_CHAIN 7
#define WSAPROTOCOL_LEN 255
typedef unsigned int GROUP;
typedef struct _WSAPROTOCOLCHAIN {
int ChainLen;
DWORD ChainEntries[MAX_PROTOCOL_CHAIN];
} WSAPROTOCOLCHAIN, *LPWSAPROTOCOLCHAIN;
typedef struct _WSAPROTOCOL_INFO
{
DWORD dwServiceFlags1;
DWORD dwServiceFlags2;
DWORD dwServiceFlags3;
DWORD dwServiceFlags4;
DWORD dwProviderFlags;
GUID ProviderId;
DWORD dwCatalogEntryId;
WSAPROTOCOLCHAIN ProtocolChain;
int iVersion;
int iAddressFamily;
int iMaxSockAddr;
int iMinSockAddr;
int iSocketType;
int iProtocol;
int iProtocolMaxOffset;
int iNetworkByteOrder;
int iSecurityScheme;
DWORD dwMessageSize;
DWORD dwProviderReserved;
TCHAR szProtocol[WSAPROTOCOL_LEN+1];
} WSAPROTOCOL_INFO, *LPWSAPROTOCOL_INFO;
typedef SOCKET (*_WSASocketW)(
int af,
int type,
int protocol,
LPWSAPROTOCOL_INFO lpProtocolInfo,
GROUP g,
DWORD dwFlags
);
_WSASocketW TrueWSASocketW = (_WSASocketW)GetProcAddress(LoadLibraryW(L"WS2_32.dll"),"WSASocketW");
SOCKET HookWSASocketW(
int af,
int type,
int protocol,
LPWSAPROTOCOL_INFO lpProtocolInfo,
GROUP g,
DWORD dwFlags
)
{
_asm
{
NOP
NOP
NOP
} //如果直接return TrueWSASocketW(..)的话,mhook貌似陷入死循环(貌似是个bug)。所以随便写点
return TrueWSASocketW(
af,
type,
protocol,
lpProtocolInfo,
g,
dwFlags
);
}
//////////////////////////////////////////////////////////////////////////
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
if(NULL!=TrueWSASocketW)
{
OutputDebugString("Mhook_SetHook");
bHookSuccess = Mhook_SetHook((PVOID*)&TrueWSASocketW , HookWSASocketW);
}
break;
case DLL_PROCESS_DETACH:
if(bHookSuccess)
Mhook_Unhook((PVOID*)&TrueWSASocketW);
break;
}
return TRUE;
}
图1 mhook的原理揭示
(如果图片不能直接显示出来,请右键复制图片网址在浏览器里打开)
若有纰漏,还望指点批评。
(由于有附件上传限制,这里就不把完整测试代码传上来了。mhook库很容易在网上找到,socket通信demo也很容易找到,dll远程注入也很容易找到。)
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!