Winsock Hook



  • Hallo,
    ich habe mithilfe von MS Detours send() und recv() gehookt. Funktioniert eigentlich auch. Allerdings scheine ich nicht alle Pakete zu empfangen.

    Wenn ich mit WPE Pro (ein Packet Sniffer) Pakete aufzeichne und dann das selbe noch mal mit meinem Hook aufzeichne, kommen verschiedene Ergebnisse bzw. ein Paket (das worum es eigentlich geht) fehlt.

    #include <Winsock2.h>
    #include <Windows.h>
    #include <fstream>
    #include <detours.h>
    
    #pragma comment(lib, "detours.lib")
    #pragma comment(lib, "ws2_32.lib")
    
    using namespace std;
    
    ofstream out("C:\\logW32sock.txt", ios::out | ios::binary);
    
    DETOUR_TRAMPOLINE(int WINAPI Real_send(SOCKET a0, char* a1, int a2, int a3), send);
    DETOUR_TRAMPOLINE(int WINAPI Real_recv(SOCKET a0, char* a1, int a2, int a3), recv);
    DETOUR_TRAMPOLINE(int WINAPI Real_connect(SOCKET s,const struct sockaddr *name, int namelen), connect);
    
    void WriteLog(char FAR* buf, bool type);
    
    int WINAPI custom_send(SOCKET sock, char* buf, int len, int flags);
    int WINAPI custom_recv(SOCKET sock, char FAR* buf, int len, int flags);
    int WINAPI custom_connect(SOCKET s,const struct sockaddr *name, int namelen);
    
    char* TextToHex( char *text) 
    {
    	if (!text) return 0;
    
    	int len = strlen(text);
    
    	char *buffer = new char[2*len]+1;
    	if (!buffer) return 0;
    
    	for (int i=0; i<len; i++)
    		sprintf( buffer+2*i, "%x", (unsigned int) text[i]);
    
    	return buffer;
    }
    
    BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
    {
    	if ( reason == DLL_PROCESS_ATTACH )
    	{
    		DetourFunctionWithTrampoline((PBYTE)Real_send,(PBYTE)custom_send);    
    		DetourFunctionWithTrampoline((PBYTE)Real_recv,(PBYTE)custom_recv);
    		DetourFunctionWithTrampoline((PBYTE)Real_connect, (PBYTE)custom_connect);
    
    	}
    	else if ( reason == DLL_PROCESS_DETACH )
    	{
    		DetourRemove((PBYTE)Real_send,(PBYTE)custom_send);
    		DetourRemove((PBYTE)Real_recv,(PBYTE)custom_recv);
    		DetourRemove((PBYTE)Real_connect, (PBYTE)custom_connect);
    		out.close();
    	}    
    	return true;
    }
    
    int WINAPI custom_send(SOCKET sock, char* buf, int len, int flags)
    {
    	WriteLog (buf, true);
    	return Real_send(sock, buf, len, flags);
    }
    int WINAPI custom_recv(SOCKET sock, char FAR* buf, int len, int flags)
    {
    	WriteLog (buf, false);
    	return Real_recv(sock, buf, len, flags);
    }
    
    int WINAPI custom_connect(SOCKET s, const struct sockaddr *name, int namelen)
    {
    	return Real_connect(s, name, namelen);
    }
    
    void WriteLog(char FAR* buf, bool type) 
    {
    	if (type == true)
    	{
    		out << "SEND:" << TextToHex(buf) << "\n\n\n\n";   
    	} else 
    	{
    		out << "RECIEVED: " << TextToHex(buf) << "\n\n\n\n";  
    	}
    }
    

    Hat jemand eine Idee warum?



  • du solltest der TextToHex Funktion die Pufferlänge übergeben anstatt strlen zu benutzen



  • Ändert leider nichts daran, dass ein riesen Paket einfach fehlt...



  • Hallo,

    *buffer als return? Mault da nicht dein Compiler? Und zwar zurecht?

    Wenn, dann wenigstens:

    static char *buffer = null;
    static char *buffer = new char[Realbuffer];

    dann was zuweisen oder

    besser

    static char buffer[realbufferstore];



  • 1. Kopier den Code nicht von ceplusplus@loggedoff 🙂
    2. Lass mal die Frickeleien weg (new ohne delete, char FAR* buf and shit...)
    3. Nimm mal das neue Detours 2.1 (Wennst nen Minimalbeispiel brauchst, sag bescheid)
    4. Vielleicht wird schneller empfangen als in die Datei geschrieben werden kann

    Nur so aus dem Bauch raus...



  • Ja der Code ist kopiert, weshalb er doch trotzdem funktionieren sollte. Das neue Detours sagt mir nicht so zu (scheint umständlich und es gibt merkwürdige Errors). Ich bezweifle, dass zu schnell gesendet/empfangen wird. Der buffer besteht ja trotzdem und die Funktion ist gedetourt, das wird ja nicht einfach so übersprungen.



  • du musst auch WSASend, sendto und so hooken.



  • Ich weiß aber, dass das Programm weder WSASend noch sendto nutzt (per Debugger überprüft).



  • doch



  • WSARecv/Send und sendto recvfrom gehookt... nie gecallt... wie gesagt.



  • Hat vielleicht jemand das neue Detours von Microsoft compiliert? Also .lib und .h, ich kann es zwar kompilieren kriege aber dann merwürdige Errors (Makefile funzt erst gar nicht).

    Oder eine andere gute Library die ähnliches schafft?



  • Du solltest zuerst mal das richtige environment setzen...
    vcvars32.bat suchen, ins cmd ziehen, enter, dann ins Verzeichnis von Detours gehen, nmake eingeben, enter, fertig, am Ende Error is normal, dauert aber schon ~15 Sekunden der build bei mir



  • @Bronson, danke, das hat funktioniert

    Ich habe im Packet Sniffer gesehen, dass die Paketgröße des gesuchten Pakets 25 ist. Ich habe dann die Paketgröße mal mit protokolliert. Die Pakete sehen allerdings ganz anders aus.

    Hier alle Pakete mit Größe 25 im Log.

    8566C8D
    8566CB6
    8566CDF
    8566D13
    8566D3C
    8566D65
    8566D8E
    

    Hier im Sniffer:
    http://de.tinypic.com/view.php?pic=2i7olqo&s=4



  • Du hast doch recv gehookt, nich? Am screen ist das 25' Paket aber von send()...

    Außerdem:
    25 != 25.
    Ein Paket hat mehrere Parts. Vielleicht kann das WPE Pro ja nur den "Presentation Part" eines Pakets anzeigen? Versuch das mal... Den TPC-Header brauchst du ja wohl nicht...



  • Nein die receiveten sind mir egal, es geht ja gerad um das, dass ich sende mit der Größe 25...



  • Also hookst du send()...
    Im WPE Pro ist wohl die gesamte Paketgröße gemeint, in der send() Funktion aber nur der "Presentation Part".
    Bin schwach in dem Gebiet, aber ich denke du musst zu dataSize in send() eine bestimmte Größe hinzuaddieren (Den TCP-Header, und noch was?), um auf die angegebene Paketgröße im WPE Pro zu kommen. Ich hab da was mit 14 bytes in Erinnerung, google halt mal...



  • Lad dir mal das Programm "PIAFCTM 2.2".
    Damit kannst du die verschiedenen Parts eines Paketes anzeigen.
    Datalink, Network, Transport und Presentation.

    Dich interessiert dann nur der Presentation Part, genau diesen hast du in der send() Funktion in data.

    Also suchst du dir das Paket mit dem Programm, schaltest dann auf Presentation View und zählst die Bytes. So groß ist dann dataSize in send().

    Die 14 Bytes scheinen zu stimmen, also vielleicht erst mal nach dataSize == 11 prüfen (25 - 14 = data only).



  • Ich glaub das Problem ist nicht ganz klar... Die Größe ist mir vollkommen egal, ich will nur das Paket genauso darstellen wie in WPE aber meins sieht einfach nicht so aus...



  • Ja, weils wahrscheinlich das falsche ist?
    Wonach filterst du denn das Paket im send()? Nach der dataSize nehm ich an...
    Und die ist im send() wahrscheinlich NICHT die gleiche wie im WPE Pro..



  • Size stimm überein, genauso wie Reihenfolge der Pakete und Größen. Ich kann sogar die "aufgezeichnete" Aktion ausführen wenn ich den Buffer usw. speicher und selbst sende...


Anmelden zum Antworten