2013-03-03 150 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