不知道大家用過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);
}




程序截圖:


程序有什么不足,還請大家一起討論.