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