2013-03-03 214 views
3

我正在嘗試hook winsock send和recv以讀取進程的所有流量。 我injectin下面的代碼爲目標的過程C++ hook winsock

#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 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); 
     memcpy(&jmp[1], &dwCalc, 4); 
     WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, jmp, 6, 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; 
return FALSE; 
} 

int 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 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(){ // <-- this is called after the DLL has been injected 
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: 

case DLL_THREAD_ATTACH: 
case DLL_THREAD_DETACH: 
case DLL_PROCESS_DETACH: 
break; 
} 
return TRUE; 
} 

這工作在某些情況下,在一些它不裏面的DLL。 如果我將它注入到filezilla ftp中,它就像一個魅力一樣,並寫入發送或接收到文件的所有內容。

但在幾乎所有其他programms的(IE,火狐usw.),它只是寫一些字節的文件,然後將該進程崩潰...

有沒有人的想法是怎麼回事?

回答

3

請務必在您的掛鉤功能上使用正確的調用約定。默認調用約定通常是__cdecl。然而「發送」,和「recv的」使用__stdcall(#define WINAPI __stdcall

兩者之間的主要區別是:

當一個函數使用__cdecl呼叫者是負責堆清理。但是,當函數使用__stdcall時,被調用的函數負責堆棧清理。

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

更多信息請參見here

+0

好的。我使用: int __stdcall nRecv(SOCKET s,char * buf,int len,int flags);如果我將它注入到Internet Explorer或任何Windows軟件(資源管理器usw.)中,它仍然崩潰... – incognym 2013-03-03 21:32:23

+1

嘗試使用FlushInstructionCache - 「如果應用程序在內存中生成或修改代碼,應該調用FlushInstructionCache。 CPU無法檢測到更改,並可能執行緩存的舊代碼。「 – user1052842 2013-03-03 21:42:02

+0

它變得更好...... 現在我對Win7的X64調用FlushInstructionCache在HookFunction&UnHookFunction結束(前返回) 現在,它的工作原理與InternetExplorer的在Win XP x86的 但它仍然在InternetExplorer的(32位)崩潰 如果我嘗試將其注入explorer.exe(在Xp x86上)DataExecutionPrevention殺死進程-.-' 任何想法? (順便說一下,感謝迄今爲止,你已經幫了很多忙) – incognym 2013-03-03 22:22:17

3

好的。即使啓用了DataExecutionPrevention,它現在也在工作。如果有人在今後類似的問題,這裏是工作代碼:

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_ */ 

測試,與在Win幾乎所有的工作程序XP 32bit和Win 7上的一些程序x64