C++ hooking winsock

前端 未结 2 931
眼角桃花
眼角桃花 2021-02-03 15:10

I am trying to hook winsock send and recv in order to read all traffic of a process. I am injectin the following code as a dll inside the target process

#include         


        
相关标签:
2条回答
  • 2021-02-03 15:53

    Ok. Its working now, even with DataExecutionPrevention enabled. In case someone has a similar problem in future, here is the working code:

    dllmain.cpp:

    #include "dll.h"
    #include <windows.h>
    #include <winsock2.h>
    #include <iostream>
    #include <fstream>
    
    #pragma comment(lib, "ws2_32.lib")
    
    using namespace std;
    
    DllClass::DllClass()
    {
    
    }
    
    
    DllClass::~DllClass ()
    {
    
    }
    
    BYTE hook[6];
    BYTE hook2[6];
    BYTE jmp[6] = { 0xe9,0x00, 0x00, 0x00, 0x00 ,0xc3 };  
    ofstream myfile;
    ofstream myfile2;
    DWORD pPrevious;
    
    DWORD HookFunction(LPCSTR lpModule, LPCSTR lpFuncName, LPVOID lpFunction, unsigned char *lpBackup)
    {  
          DWORD dwAddr = (DWORD)GetProcAddress(GetModuleHandle(lpModule), lpFuncName);
          ReadProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, lpBackup, 6, 0);
          DWORD dwCalc = ((DWORD)lpFunction - dwAddr - 5);
          VirtualProtect((void*) dwAddr, 6, PAGE_EXECUTE_READWRITE, &pPrevious);
          memcpy(&jmp[1], &dwCalc, 4);
          WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, jmp, 6, 0);
          VirtualProtect((void*) dwAddr, 6, pPrevious, &pPrevious);
          FlushInstructionCache(GetCurrentProcess(),0,0);
          return dwAddr;
    }    
    
    BOOL UnHookFunction(LPCSTR lpModule, LPCSTR lpFuncName, unsigned char *lpBackup)
    {
    DWORD dwAddr = (DWORD)GetProcAddress(GetModuleHandle(lpModule), lpFuncName);
    
    if (WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, lpBackup, 6, 0))
            return TRUE;
            FlushInstructionCache(GetCurrentProcess(),0,0);
    
    return FALSE;  
    }
    
    int __stdcall nSend(SOCKET s, const char *buf, int len,int flags){
    UnHookFunction("ws2_32.dll", "send", hook);
    
    
    int result = send(s,buf,len,flags);
    
    
      myfile.open ("C:\\tmp\\log.txt",ios::app | ios::binary);
      myfile << buf;
      myfile.close();
    
    
    
    
    HookFunction("ws2_32.dll", "send", (LPVOID*) nSend, hook);
    return result;
    } 
    
    int __stdcall nRecv(SOCKET s, char* buf, int len, int flags)
    {
        UnHookFunction("ws2_32.dll", "recv", hook2);
        DWORD tmp;
    
        len = recv(s, buf, len, flags);
    
        if (len > 0)
        {
    
            myfile2.open ("C:\\tmp\\log.txt",ios::app | ios::binary);
            myfile2 << buf;
            myfile2.close();
        }
       HookFunction("ws2_32.dll", "recv", (LPVOID*) nRecv, hook2);
        return len;
    }
    void fun(){
    HookFunction("ws2_32.dll", "send", (LPVOID*) nSend, hook);
    HookFunction("ws2_32.dll", "recv", (LPVOID*) nRecv, hook2);
    }
    
    BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
    {
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    HookFunction("ws2_32.dll", "send", (LPVOID*) nSend, hook);
    HookFunction("ws2_32.dll", "recv", (LPVOID*) nRecv, hook2);
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
    break;
    }
    return TRUE;
    }
    

    dll.h

    #ifndef _DLL_H_
    #define _DLL_H_
    
    #if BUILDING_DLL
    # define DLLIMPORT __declspec (dllexport)
    #else /* Not BUILDING_DLL */
    # define DLLIMPORT __declspec (dllimport)
    #endif /* Not BUILDING_DLL */
    
    
    class DLLIMPORT DllClass
    {
      public:
        DllClass();
        virtual ~DllClass(void);
    
      private:
    
    };
    extern "C" __declspec(dllexport) void fun();
    
    #endif /* _DLL_H_ */
    

    Tested and working with nearly all programs on Win XP 32bit and some programs on Win 7 x64

    0 讨论(0)
  • 2021-02-03 15:57

    Be sure to use the correct calling convention on your hooked functions. The default calling convention is usually __cdecl. However 'send', and 'recv' use __stdcall (#define WINAPI __stdcall)

    The main difference between the two are:

    When a function uses __cdecl the caller is responsible for stack cleanup. However when a function uses __stdcall the called function is responsible for stack cleanup.

    int WINAPI nSend(SOCKET s, const char *buf, int len,int flags);
    int WINAPI nRecv(SOCKET s, char* buf, int len, int flags)
    

    See here for more information.

    0 讨论(0)
提交回复
热议问题