HanDs
管理员

[Visual Studio文章] 开发InlineHook网络数据发送接收函数 



大家都懂,很多时候开发项目需要修改网络数据,代码如下,请柬代码分析

#include "stdafx.h"  
#include <stdio.h>  
#include <Windows.h>  
#include <Winsock2.h>  
  
  
#ifdef _MANAGED  
#pragma managed(push, off)  
#endif  
  
#define HOOK_API extern "C" _declspec(dllexport)  
//本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;  
DWORD g_pRecv = 0;  
//事务,解决同步问题  
HANDLE g_hSendEvent = NULL;  
HANDLE g_hRecvEvent = NULL;  
//自己的send函数地址,参数必须与API的send函数地址相同  
int _stdcall hook_send( SOCKET s, const char *buf, int len, int flags );  
int _stdcall hook_recv(IN SOCKET s,OUT char FAR * buf,IN int len,IN int flags );  
//要Hook的进程和主线程ID号  
DWORD g_dwProcessID = 0;  
DWORD g_dwThreadID = 0;  
  
// 如果是win9x,不能使用fopen函数  
void WriteLog(char *fmt,...)  
{  
    va_list args;  
    char modname[200];  
  
    char temp[5000];  
    HANDLE hFile;  
    SYSTEMTIME loaclTime;  
    GetLocalTime(&loaclTime);  
    GetModuleFileName(NULL, modname, sizeof(modname));  
  
    if((hFile =CreateFile("c:\\hookapi.log", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) <0)  
    {  
        return;  
    }  
  
    SetFilePointer(hFile, 0, NULL, FILE_END);  
  
    wsprintf(temp, "%d:%d:%d mydll.dll:%s:", loaclTime.wHour,loaclTime.wMinute,loaclTime.wMilliseconds, modname);  
    DWORD dw;  
    WriteFile(hFile, temp, strlen(temp), &dw, NULL);  
  
    va_start(args,fmt);  
    vsprintf(temp, fmt, args);  
    va_end(args);  
  
    WriteFile(hFile, temp, strlen(temp), &dw, NULL);  
  
    wsprintf(temp, "\r\n");  
    WriteFile(hFile, temp, strlen(temp), &dw, NULL);  
  
    CloseHandle(hFile);  
}  
  
int _stdcall hook_recv(IN SOCKET s,OUT char FAR * buf,IN int len,IN int flags )  
{  
    int nRet;  
    WaitForSingleObject( g_hRecvEvent, INFINITE );  
  
    //恢复API头8个字节  
    WriteProcessMemory( INVALID_HANDLE_VALUE, ( void* )g_pRecv,( void* )g_dwOldBytes[0], sizeof( DWORD )*2, NULL );  
    /* 
    这里可以添加想要进行的处理过程 
    */  
    //真正执行API函数  
    nRet = recv( s, buf, len, flags );  
    //写入跳转语句,继续Hook  
    WriteProcessMemory( INVALID_HANDLE_VALUE, ( void* )g_pRecv,( void* )g_btNewBytes, sizeof( DWORD )*2, NULL);  
    WriteLog("%s",buf);  
    SetEvent( g_hRecvEvent );  
    return nRet;  
}  
  
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 );  
    /* 
    这里可以添加想要进行的处理过程 
    */  
    WriteLog("Send:%s",buf);  
    //真正执行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;  
}  
  
static LRESULT WINAPI HookProc( int nCode, WPARAM wParam, LPARAM lParam )  
{  
    return CallNextHookEx( g_hOldHook, nCode, wParam, lParam );  
}  
HOOK_API BOOL StartHook(HWND hWnd)  
{  
    //通过传入的窗口句柄获取线程句柄  
    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;  
}  
  
HOOK_API 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 );  
    }  
}  
  
DWORD WINAPI ThreadFunc( LPVOID lpParam )   
{   
    char szMsg[80];  
  
    wsprintf( szMsg, "Parameter = %d.", *(DWORD*)lpParam );   
    MessageBox( NULL, szMsg, "ThreadFunc", MB_OK );  
    while(1) Sleep(1000);  
  
    return 0;   
}   
  
BOOL APIENTRY DllMain( HMODULE hModule,  
                       DWORD  ul_reason_for_call,  
                       LPVOID lpReserved  
                     )  
{  
    if(ul_reason_for_call == DLL_PROCESS_ATTACH)  
    {  
        WriteLog("Start HOOK");  
        //获取本dll句柄  
        g_hInstance = hModule;  
  
        //创建事务  
        g_hSendEvent = CreateEvent( NULL, FALSE, TRUE, NULL );  
  
        //重写API开头的8字节  
        HMODULE hWsock = LoadLibrary( "wsock32.dll" );  
        g_pSend = ( DWORD )GetProcAddress( hWsock, "send" );  
        g_pRecv = (DWORD)GetProcAddress( hWsock, "recv" );  
        //保存原始字节  
        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 );  
  
//      //保存原始字节  
//      ReadProcessMemory( INVALID_HANDLE_VALUE, ( void * )g_pRecv,( void * )g_dwOldBytes[0], sizeof( DWORD )*2, NULL );  
//      //将00400000改写为我们函数的地址  
//      *( DWORD* )( g_btNewBytes + 1 ) = ( DWORD )hook_recv;  
//      WriteProcessMemory( INVALID_HANDLE_VALUE, ( void * )g_pRecv,( void * )g_btNewBytes, sizeof( DWORD )*2, NULL );  
        DWORD dwThreadId, dwThrdParam = 1;   
        HANDLE hThread;   
        char szMsg[80];  
  
        hThread = CreateThread(   
            NULL,                        // default security attributes   
            0,                           // use default stack size    
            ThreadFunc,                  // thread function   
            &dwThrdParam,                // argument to thread function   
            0,                           // use default creation flags   
            &dwThreadId);                // returns the thread identifier   
  
        // Check the return value for success.   
        if (hThread == NULL)   
        {  
            wsprintf( szMsg, "CreateThread failed." );   
            MessageBox( NULL, szMsg, "main", MB_OK );  
        }  
        else   
        {  
            CloseHandle( hThread );  
        }  
    }  
    return TRUE;  
}  
  
#ifdef _MANAGED  
#pragma managed(pop)  
#endif 


学习中请遵守法律法规,本网站内容均来自于互联网,本网站不负担法律责任
开发 I nl in eH oo k 网络 数据 发送 接收 函数
#1楼
发帖时间:2016-7-9   |   查看数:0   |   回复数:0
游客组
快速回复