HSEND
// hooksend.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include <WINSOCK2.H>
#pragma comment(lib,"Ws2_32.lib")
//本dll的handle
HANDLE g_hInstance = NULL;
//修改API入口为 mov eax, 00400000;jmp eax是程序能跳转到自己的函数
BYTE g_btNewBytes[8] = { 0xB8, 0x0, 0x0, 0x40, 0x0, 0xFF, 0xE0, 0x0 };
//保存原API入口的8个字节
DWORD g_dwOldBytes[2][2] = { 0x0, 0x0, 0x0, 0x0 };
//钩子句柄
HHOOK g_hOldHook = NULL;
//API中send函数的地址
DWORD g_pSend = 0;
//事务,解决同步问题
HANDLE g_hSendEvent = NULL;
//自己的send函数地址,参数必须与API的send函数地址相同
int _stdcall hook_send( SOCKET s, const char *buf, int len, int flags );
//要Hook的进程和主线程ID号
DWORD g_dwProcessID = 0;
DWORD g_dwThreadID = 0;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if(ul_reason_for_call == DLL_PROCESS_ATTACH)
{
//获取本 dll句柄
g_hInstance = hModule;
//创建事务
g_hSendEvent = CreateEvent( NULL, FALSE, TRUE, NULL );
//重写API开头的8字节
HMODULE hWsock = LoadLibrary( "wsock32.dll" );
g_pSend = ( DWORD )GetProcAddress( hWsock, "send" );
//保存原始字节
ReadProcessMemory( INVALID_HANDLE_VALUE, ( void * )g_pSend,
( void * )g_dwOldBytes[0], sizeof( DWORD )*2, NULL );
//将 00400000改写为我们函数的地址
*( DWORD* )( g_btNewBytes + 1 ) = ( DWORD )hook_send;
WriteProcessMemory( INVALID_HANDLE_VALUE, ( void * )g_pSend,
( void * )g_btNewBytes, sizeof( DWORD )*2, NULL );
}
return TRUE;
}
int _stdcall hook_send( SOCKET s, const char *buf, int len, int flags )
{
int nRet;
WaitForSingleObject( g_hSendEvent, INFINITE );
//恢复API头 8个字节
WriteProcessMemory( INVALID_HANDLE_VALUE, ( void* )g_pSend,
( void* )g_dwOldBytes[0], sizeof( DWORD )*2, NULL );
/*
这里可以添加想要进行的处理过程
*/
//真正执行 API函数
nRet = send( s, buf, len, flags );
//写入跳转语句,继续Hook
WriteProcessMemory( INVALID_HANDLE_VALUE, ( void* )g_pSend,
( void* )g_btNewBytes, sizeof( DWORD )*2, NULL );
SetEvent( g_hSendEvent );
return nRet;
}
BOOL StartHook(HWND hWnd)
{
HOOKPROC HookProc;
//通过传入的窗口句柄获取线程句柄
g_dwThreadID = GetWindowThreadProcessId( hWnd, &g_dwProcessID );
//WH_CALLWNDPROC 类型的Hook
g_hOldHook = SetWindowsHookEx( WH_CALLWNDPROC, HookProc,
( HINSTANCE ) g_hInstance, g_dwThreadID );
if( g_hOldHook == NULL )
return FALSE;
return TRUE;
}
static LRESULT WINAPI HookProc( int nCode, WPARAM wParam, LPARAM lParam )
{
return CallNextHookEx( g_hOldHook, nCode, wParam, lParam );
}
void StopHook(void)
{
if(g_hOldHook != NULL)
{
WaitForSingleObject( g_hSendEvent, INFINITE );
HANDLE hProcess = NULL;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, g_dwProcessID);
DWORD dwOldProc;
DWORD dwNewProc;
//改变页面属性为读写
VirtualProtectEx( hProcess, ( void* )g_pSend, 8, PAGE_READWRITE, &dwOldProc );
//恢复 API的首8个字节
WriteProcessMemory( hProcess, ( void* )g_pSend,
( void* )g_dwOldBytes[0], sizeof( DWORD )*2, NULL );
//恢复页面文件的属性
VirtualProtectEx( hProcess, ( void* )g_pSend, 8, dwOldProc, &dwNewProc );
CloseHandle(g_hSendEvent);
UnhookWindowsHookEx( g_hOldHook );
}
}