zoukankan      html  css  js  c++  java
  • 模拟WSockExpert,使用APIHOOK

    转自:http://blog.donews.com/zwell/archive/2004/08/31/84513.aspx

    不知道大家用过WSockExpert没有, 它可以用来截获指定进程网络数据的传输.
    前面我还以为它是通过实时远程注入DLL来更改IAT. 不过后来发现在程序一运行时,
    它就已经将DLL插入所有进程了,这个跟冰哥写的那个模拟SOCKCAP的程序很相似.
    似乎是将DLL注入所有进程, 不过再想一下, 如果是这样的话,那么后来启动的程序
    应该不会被注入DLL(除非用定时^_^,这样就太麻烦了), 考虑到这些, 我估计它是
    用的HOOK,用HOOK的话就有一点方便:不必考虑有没有读写权限的问题. 也就免
    了一些麻烦.
        我在BCB环境中用APIHOOK模拟了一个类似的程序,通过HOOK将DLL插入所有
    进程,然后截获WINSOCK API.中间遇到了一些问题,参考了冰哥的SOCKCAP和
    EYAS大哥的XHOOK. 在XHOOK中将原始DLL做了一个备份, 在执行API时并没有先
    将API地址还原,而是直接调用了备份的函数, 这样提高了执行效率.厉害, :-)
    以后再改,先放上一个简单的演示,大家可以对它进行修改扩展功能:


    DLL代码:

    //---------------------------------------------------------------------------
    // Mady By ZwelL
    // 2004.8
    // zwell@sohu.com
    //---------------------------------------------------------------------------
    #include <Winsock2.h>
    #include <stdio.h>

    #pragma argsused

    //自定义APIHOOK结构
    typedef struct
    {
        FARPROC funcaddr;
        BYTE    olddata[5];
        BYTE    newdata[5];
    }HOOKSTRUCT;

    HHOOK       g_hHook;
    HINSTANCE   g_hinstDll;
    HMODULE     hModule ;
    HANDLE      g_hForm;    //接收信息窗口句柄
    DWORD       dwIdOld, dwIdNew;

    //------------------------------------------------------------------------
    // 由于要截获两个库里面的函数,所以每个函数定义了两个HOOK结构
    // 在编程过程中因为没有考虑到这个问题,导致很多包没有截获到,
    // 后来想到了冰哥在模仿SOCKCAP的程序中每个函数截了两次才明白
    // 一个是wsock32.dll, 一个是ws2_32.dll
    //------------------------------------------------------------------------
    HOOKSTRUCT  recvapi;
    HOOKSTRUCT  recvapi1;
    HOOKSTRUCT  sendapi;
    HOOKSTRUCT  sendapi1;
    HOOKSTRUCT  sendtoapi;
    HOOKSTRUCT  sendtoapi1;
    HOOKSTRUCT  WSASendapi;

    void HookOn();
    void HookOff();
    BOOL Init();
    extern "C" __declspec(dllexport) __stdcall
    BOOL InstallHook();
    extern "C" __declspec(dllexport) __stdcall
    BOOL UninstallHook();

    BOOL hookapi(char *dllname, char *procname, DWORD myfuncaddr, HOOKSTRUCT *hookfunc);
    int WINAPI Myrecv(SOCKET s, char FAR *buf, int len, int flags);
    int WINAPI Myrecv1(SOCKET s, char FAR *buf, int len, int flags);
    int WINAPI Mysend(SOCKET s, char FAR *buf, int len, int flags);
    int WINAPI Mysend1(SOCKET s, char FAR *buf, int len, int flags);
    int WINAPI Mysendto(SOCKET s, const char FAR * buf, int len,
        int flags, const struct sockaddr FAR * to, int tolen);
    int WINAPI Mysendto1(SOCKET s, const char FAR * buf, int len,
        int flags, const struct sockaddr FAR * to, int tolen);
    int WINAPI MyWSASend(
      SOCKET s,
      LPWSABUF lpBuffers,
      DWORD dwBufferCount,
      LPDWORD lpNumberOfBytesSent,
      DWORD dwFlags,
      LPWSAOVERLAPPED lpOverlapped,
      LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
    );
    void sndmsg(char *buf);

    //---------------------------------------------------------------------------
    // 入口函数
    // 在一载入库时就进行API截获
    // 释放时还原
    //---------------------------------------------------------------------------
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
        switch (reason)
        {
            case DLL_PROCESS_ATTACH:
                g_hinstDll = hinst;
                g_hForm = FindWindow(NULL, "ZwelL");
                if(!Init())
                {
                    MessageBoxA(NULL,"Init","ERROR",MB_OK);
                    return(false);
                }
                break;
            case DLL_THREAD_ATTACH:
                break;
            case DLL_THREAD_DETACH:
                break;
            case DLL_PROCESS_DETACH:
                UninstallHook();
                break;
          }
        return TRUE;
    }

    //-----------------------------------------------------------------------
    BOOL Init()
    {
        hookapi("wsock32.dll", "recv", (DWORD)Myrecv, &recvapi);
        hookapi("ws2_32.dll", "recv", (DWORD)Myrecv1, &recvapi1);
        hookapi("wsock32.dll", "send", (DWORD)Mysend, &sendapi);
        hookapi("ws2_32.dll", "send", (DWORD)Mysend1, &sendapi1);
        hookapi("wsock32.dll", "sendto", (DWORD)Mysendto, &sendtoapi);
        hookapi("ws2_32.dll", "sendto", (DWORD)Mysendto1, &sendtoapi1);
        hookapi("wsock32.dll", "WSASend", (DWORD)MyWSASend, &WSASendapi);
        dwIdNew = GetCurrentProcessId(); // 得到所属进程的ID
        dwIdOld = dwIdNew;
        HookOn(); // 开始拦截
        return(true);
    }
    //---------------------------------------------------------------------------
    LRESULT WINAPI Hook(int nCode, WPARAM wParam, LPARAM lParam)
    {
        return(CallNextHookEx(g_hHook, nCode, wParam, lParam));
    }
    //---------------------------------------------------------------------------
    extern "C" __declspec(dllexport) __stdcall
    BOOL InstallHook()
    {
        g_hHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)Hook, g_hinstDll, 0);
        if (!g_hHook)
        {
            MessageBoxA(NULL, "SET ERROR", "ERROR", MB_OK);
            return(false);
        }
        return(true);
    }
    //---------------------------------------------------------------------------
    extern "C" __declspec(dllexport) __stdcall
    BOOL UninstallHook()
    {
        HookOff();
        if(g_hHook == NULL)
            return true;
        return(UnhookWindowsHookEx(g_hHook));
    }

    //---------------------------------------------------------------------------
    // 根据输入结构截获API
    //---------------------------------------------------------------------------
    BOOL hookapi(char *dllname, char *procname, DWORD myfuncaddr, HOOKSTRUCT *hookfunc)
    {
        hModule = LoadLibrary(dllname);
        hookfunc->funcaddr = GetProcAddress(hModule, procname);
        if(hookfunc->funcaddr == NULL)
            return false;

        memcpy(hookfunc->olddata, hookfunc->funcaddr, 6);
        hookfunc->newdata[0] = 0xe9;
        DWORD jmpaddr = myfuncaddr - (DWORD)hookfunc->funcaddr - 5;
        memcpy(&hookfunc->newdata[1], &jmpaddr, 5);
        return true;
    }
    //---------------------------------------------------------------------------
    void HookOnOne(HOOKSTRUCT *hookfunc)
    {
        HANDLE hProc;
        dwIdOld = dwIdNew;
        hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, dwIdOld);
        VirtualProtectEx(hProc, hookfunc->funcaddr, 5, PAGE_READWRITE,&dwIdOld);
        WriteProcessMemory(hProc, hookfunc->funcaddr, hookfunc->newdata, 5, 0);
        VirtualProtectEx(hProc, hookfunc->funcaddr, 5, dwIdOld, &dwIdOld);
    }
    //---------------------------------------------------------------------------
    void HookOn()
    {
        HookOnOne(&recvapi);
        HookOnOne(&sendapi);
        HookOnOne(&sendtoapi);
        HookOnOne(&recvapi1);
        HookOnOne(&sendapi1);
        HookOnOne(&sendtoapi1);
        HookOnOne(&WSASendapi);
    }
    //---------------------------------------------------------------------------
    void HookOffOne(HOOKSTRUCT *hookfunc)
    {
        HANDLE hProc;
        dwIdOld = dwIdNew;
        hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, dwIdOld);
        VirtualProtectEx(hProc, hookfunc->funcaddr,5, PAGE_READWRITE, &dwIdOld);
        WriteProcessMemory(hProc, hookfunc->funcaddr, hookfunc->olddata, 5, 0);
        VirtualProtectEx(hProc, hookfunc->funcaddr, 5, dwIdOld, &dwIdOld);
    }

    //---------------------------------------------------------------------------
    void HookOff()
    {
        HookOffOne(&recvapi);
        HookOffOne(&sendapi);
        HookOffOne(&sendtoapi);
        HookOffOne(&recvapi1);
        HookOffOne(&sendapi1);
        HookOffOne(&sendtoapi1);
        HookOffOne(&WSASendapi);
    }
    //---------------------------------------------------------------------------
    int WINAPI Myrecv(SOCKET s, char FAR *buf, int len, int flags)
    {
        int nReturn;
        HookOffOne(&recvapi);
        nReturn = recv(s, buf, len, flags);
        HookOnOne(&recvapi);

        char *tmpbuf=new char[len+100];
        memset(tmpbuf, 0, sizeof(tmpbuf));
        sprintf(tmpbuf, "recv|%d|%d|%s",
                GetCurrentProcessId(),
                len,
                buf);
        sndmsg(tmpbuf);
        delete tmpbuf;
        return(nReturn);
    }
    //---------------------------------------------------------------------------
    int WINAPI Myrecv1(SOCKET s, char FAR *buf, int len, int flags)
    {
        int nReturn;
        HookOffOne(&recvapi1);
        nReturn = recv(s, buf, len, flags);
        HookOnOne(&recvapi1);

        char *tmpbuf=new char[len+100];
        memset(tmpbuf, 0, sizeof(tmpbuf));
        sprintf(tmpbuf, "recv1|%d|%d|%s",
                GetCurrentProcessId(),
                len,
                buf);
        sndmsg(tmpbuf);
        delete tmpbuf;
        return(nReturn);
    }
    //---------------------------------------------------------------------------
    int WINAPI Mysend(SOCKET s, char FAR *buf, int len, int flags)
    {
        int nReturn;
        HookOffOne(&sendapi);
        nReturn = send(s, buf, len, flags);
        HookOnOne(&sendapi);

        char *tmpbuf=new char[len+100];
        memset(tmpbuf, 0, sizeof(tmpbuf));
        sprintf(tmpbuf, "send|%d|%d|%s",
                GetCurrentProcessId(),
                len,
                buf);
        sndmsg(tmpbuf);
        delete tmpbuf;
        return(nReturn);
    }
    //---------------------------------------------------------------------------
    int WINAPI Mysend1(SOCKET s, char FAR *buf, int len, int flags)
    {
        int nReturn;
        HookOffOne(&sendapi1);
        nReturn = send(s, buf, len, flags);
        HookOnOne(&sendapi1);

        char *tmpbuf=new char[len+100];
        memset(tmpbuf, 0, sizeof(tmpbuf));
        sprintf(tmpbuf, "send1|%d|%d|%s",
                GetCurrentProcessId(),
                len,
                buf);
        sndmsg(tmpbuf);
        delete tmpbuf;
        return(nReturn);
    }
    //--------------------------------------------------------------------------
    int WINAPI Mysendto(SOCKET s, const char FAR * buf, int len,
        int flags, const struct sockaddr FAR * to, int tolen)
    {
        int nReturn;
        HookOffOne(&sendtoapi);
        nReturn = sendto(s, buf, len, flags, to, tolen);
        HookOnOne(&sendtoapi);

        char *tmpbuf=new char[len+100];
        memset(tmpbuf, 0, sizeof(tmpbuf));
        sprintf(tmpbuf, "sendto|%d|%d|%s",
                GetCurrentProcessId(),
                len,
                buf);
        sndmsg(tmpbuf);
        delete tmpbuf;
        return(nReturn);    
    }
    //--------------------------------------------------------------------------
    int WINAPI Mysendto1(SOCKET s, const char FAR * buf, int len,
        int flags, const struct sockaddr FAR * to, int tolen)
    {
        int nReturn;
        HookOffOne(&sendtoapi1);
        nReturn = sendto(s, buf, len, flags, to, tolen);
        HookOnOne(&sendtoapi1);

        char *tmpbuf=new char[len+100];
        memset(tmpbuf, 0, sizeof(tmpbuf));
        sprintf(tmpbuf, "sendto1|%d|%d|%s",
                GetCurrentProcessId(),
                len,
                buf);
        sndmsg(tmpbuf);
        delete tmpbuf;
        return(nReturn);    
    }
    //----------------------------------------------------------------------------
    int WINAPI MyWSASend(
      SOCKET s,
      LPWSABUF lpBuffers,
      DWORD dwBufferCount,
      LPDWORD lpNumberOfBytesSent,
      DWORD dwFlags,
      LPWSAOVERLAPPED lpOverlapped,
      LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
    )
    {
        int nReturn;
        HookOffOne(&WSASendapi);
        nReturn = WSASend(s, lpBuffers, dwBufferCount,
                    lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine);
        HookOnOne(&WSASendapi);

        char *tmpbuf=new char[*lpNumberOfBytesSent+100];
        memset(tmpbuf, 0, sizeof(tmpbuf));
        sprintf(tmpbuf, "WSASend|%d|%d|%s",
                GetCurrentProcessId(),
                lpNumberOfBytesSent,
                lpBuffers->buf);
        sndmsg(tmpbuf);
        delete tmpbuf;
        return(nReturn);  
    }

    //-----------------------------------------------------------------
    // 向窗口发送消息
    // 考虑到简单性,用了COPYDATASTRUCT结构
    // 用内存映射应该会快一点
    //-----------------------------------------------------------------
    void sndmsg(char *buf)
    {
        COPYDATASTRUCT cds;
        cds.dwData=sizeof(COPYDATASTRUCT);
        cds.cbData=strlen(buf);
        cds.lpData=buf;
        SendMessage(g_hForm,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds);
    }






    主窗体代码:
    //---------------------------------------------------------------------------

    #include <vcl.h>
    #pragma hdrstop

    #include "main_Form.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma link "HexEdit"
    #pragma resource "*.dfm"
    TForm1 *Form1;

    HINSTANCE hdll;
    BOOL __stdcall (*InstallHook)();
    BOOL __stdcall (*UninstallHook)();
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
        Application->OnHint=DisplayHint;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        g_dindex=0;
        
        hdll = LoadLibrary("dll.dll");
        if(hdll == NULL)
            MessageBox(NULL, "LoadLibrary", "Error", MB_OK|MB_ICONERROR);
        InstallHook = GetProcAddress(hdll, "InstallHook");
        if(!InstallHook)
        {
            MessageBox(NULL, "InstallHook", "Error", MB_OK|MB_ICONERROR);
        }
        UninstallHook = GetProcAddress(hdll, "UninstallHook");
        if(!UninstallHook)
        {
            MessageBox(NULL, "UninstallHook", "Error", MB_OK|MB_ICONERROR);
        }
        InstallHook();

        startBtn->Enabled=false;
        stopBtn->Enabled=true;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
        g_dindex=0;
        UninstallHook();
        FreeLibrary(hdll);
        startBtn->Enabled=true;
        stopBtn->Enabled=false;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::OnCopyData(TMessage &Msg)
    {
        COPYDATASTRUCT *cds=(COPYDATASTRUCT*)Msg.LParam;
        AnsiString tmpbuf = (char *)cds->lpData;
        TListItem *li=lv->Items->Add();
        li->Caption=g_dindex;
        if(tmpbuf.SubString(1, tmpbuf.Pos("|")-1).Pos("send")>0)
        {
            li->ImageIndex=1;
        }
        else
        {
            li->ImageIndex=0;
        }
        
        li->SubItems->Add(tmpbuf.SubString(1, tmpbuf.Pos("|")-1));
        tmpbuf=tmpbuf.SubString(tmpbuf.Pos("|")+1, tmpbuf.Length());
        li->SubItems->Add(tmpbuf.SubString(1, tmpbuf.Pos("|")-1));
        tmpbuf=tmpbuf.SubString(tmpbuf.Pos("|")+1, tmpbuf.Length());
        li->SubItems->Add(tmpbuf.SubString(1, tmpbuf.Pos("|")-1));
        li->SubItems->Add(tmpbuf.SubString(tmpbuf.Pos("|")+1, tmpbuf.Length()));
    }

    void __fastcall TForm1::lvInsert(TObject *Sender, TListItem *Item)
    {
        g_dindex++;
        lv->Perform(LVM_SCROLL,0,10);
    }
    //---------------------------------------------------------------------------

    void __fastcall TForm1::lvClick(TObject *Sender)
    {
        if(lv->ItemIndex < 0)
            return;
        HexEdit1->LoadFromBuffer(lv->Items->Item[lv->ItemIndex]->SubItems->Strings[3].c_str(),
            lv->Items->Item[lv->ItemIndex]->SubItems->Strings[3].Length());
    }
    //---------------------------------------------------------------------------

    void __fastcall TForm1::SpeedButton3Click(TObject *Sender)
    {
        lv->Clear();    
    }
    //---------------------------------------------------------------------------

    void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
    {
        if(stopBtn->Enabled)
            Button2Click(Sender);
    }
    //---------------------------------------------------------------------------

    void __fastcall TForm1::lvAdvancedCustomDrawItem(TCustomListView *Sender,
          TListItem *Item, TCustomDrawState State, TCustomDrawStage Stage,
          bool &DefaultDraw)
    {
        if(Item->ImageIndex==0)
        {
            lv->Canvas->Brush->Color = 0x00FFF5EC;
        }
    }
    //---------------------------------------------------------------------------

    void __fastcall TForm1::lvKeyUp(TObject *Sender, WORD &Key,
          TShiftState Shift)
    {
        if(lv->ItemIndex < 0)
            return;
        HexEdit1->LoadFromBuffer(lv->Items->Item[lv->ItemIndex]->SubItems->Strings[3].c_str(),
            lv->Items->Item[lv->ItemIndex]->SubItems->Strings[3].Length());    
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::DisplayHint(TObject *Sender)
    {
        StatusBar1->SimpleText=GetLongHint(Application->Hint);
    }




    程序截图:


    程序有什么不足,还请大家一起讨论.

  • 相关阅读:
    hdu 1427 速算24点 dfs暴力搜索
    hihocoder 九十八周 搜索一 24点
    codeforces 352 div 2 C.Recycling Bottles 贪心
    华中农业大学预赛 B Handing Out Candies 余数的和
    neu 1694 Primorial vs LCM 数论
    Codeforces Round #281 (Div. 2) A. Vasya and Football 暴力
    HDU 5538/ 2015长春区域 L.House Building 水题
    HDU 5536/ 2015长春区域 J.Chip Factory Trie
    HDU 5534/ 2015长春区域H.Partial Tree DP
    HDU 5533/ 2015长春区域 G.Dancing Stars on Me 暴力
  • 原文地址:https://www.cnblogs.com/Safe3/p/1335237.html
Copyright © 2011-2022 走看看