C++ accrochage winsock
Je suis en train de crochet winsock send et recv pour lire tout le trafic d'un processus.
Je suis injectin le code suivant comme un dll qui est dans le processus de
#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;
}
Cela fonctionne dans certains cas et dans certains, il ne marche pas.
Si je l'injecter dans filezilla ftp il fonctionne comme un charme et écrit tout ce qui est envoyé ou reçu dans un fichier.
Mais sur pratiquement tous les autres programmes (internet explorer, firefox, usw.) il écrit seulement quelques octets dans le fichier, puis le processus se bloque...
Quelqu'un a une idée de ce qui va mal?
OriginalL'auteur incognym | 2013-03-03
Vous devez vous connecter pour publier un commentaire.
Ok. Son travail maintenant, même avec DataExecutionPrevention activé. Dans le cas où quelqu'un a un problème similaire dans l'avenir, voici le code de travail:
dllmain.cpp:
dll.h
Testée et fonctionne avec presque tous les programmes sur Win XP 32bit et certains programmes sur Win 7 x64
OriginalL'auteur incognym
Assurez-vous d'utiliser la convention d'appel sur votre accroché fonctions. La convention d'appel par défaut est généralement __cdecl. Cependant, "envoyer", et "recv' utilisation __stdcall (
#define WINAPI __stdcall
)La principale différence entre les deux:
Lorsqu'une fonction utilise __cdecl l'appelant est responsable de la pile de nettoyage. Toutefois, lorsqu'une fonction utilise __stdcall la fonction appelée est responsable de la pile de nettoyage.
Voir ici pour plus d'informations.
Essayez d'utiliser FlushInstructionCache - "les Applications doivent appeler FlushInstructionCache si ils génèrent ou de modifier le code en mémoire. Le PROCESSEUR ne peut pas détecter le changement, et peut exécuter l'ancien code en cache."
Il est de mieux en mieux... Maintenant, je vais appeler FlushInstructionCache à la fin de HookFunction & UnHookFunction (avant le retour) Maintenant, il fonctionne avec internet explorer sur windows XP x86, Mais il se bloque toujours dans internet explorer (32 bits) sur Win7 x64 Et si j'essaie d'injecter dans explorer.exe (sur Xp x86) la DataExecutionPrevention tue le processus de -.-' Des idées? (BTW. merci beaucoup, vous avez déjà beaucoup aidé)
x64 accrochage est différent de celui x86. 0xE9 ne peut JMP 32 bits signés. Donc, si votre JMP est plus grand que cela, ce pourrait être votre problème. Essayez un 0xFF 0x25 JMP. Également sur x64 les 5 premiers octets peuvent être différentes. (Pas votre habitude x86 (mov edi, edi), (push ebp), etc)
À l'aide de VirtualProtect() fixe la gauche les problèmes. Merci pour votre aide 🙂
OriginalL'auteur user1052842