Hooked recv(Winsock) problem

11/25/2013 21:47 XxharCs#1
Hi!

Ich habe die send&recv function von Winsock gehooked (von einem Spiel).
Das Problem aber ist irgendwie die recv Funktion und zwar liefert sie mir falsche Werte bzw. "unmögliche" Werte. Verglichen mit WPE Pro liefert WPE Pro die richtigen Werte.

Siehe Screens: (Achtets aufs Recv)
Mein Sniffer:

WPE Pro:


Komisch, send funktioniert, aber recv nicht :confused:

Code:
Code:
void printPacket(const char *buf, int len) {
	
	cout << "0000   ";

	for ( int i = 0; i < strlen(buf); ++i ) { //weil recv failt, verwende ich strlen(buf) um unnötigen packet inhalt nicht auszugeben
		if ( i != 0 && i % 16 == 0 ) {
			cout << "  ";

			int line = ( i / 16 ) - 1;

			for ( int j = 0; j < 16; ++j ) {
				char c = buf[line * 16 + j];

				if ( c >= 32 && c <= 126 ) {
					cout << c;
				} else {
					cout << '.';
				}
			}

			cout << "\n" << hex << setw( 4 ) << setfill( '0' ) << i << dec << setw( 0 ) << "   ";
		} else if ( i % 16 == 8 ) {
			cout << ' ';
		}

		cout << hex << setw( 2 ) << setfill( '0' ) << ( int( buf[i] ) & 0xFF ) << ' ';
		cout << dec << setw( 0 );

		if ( i == len - 1 ) {
			int remaining = 16 - ( len % 16 );
			int fill = ( remaining * 3 ) + 2;

			if ( remaining >= 8 ) {
				++fill;
			}

			for ( int j = 0; j < fill; ++j ) {
				cout << ' ';
			}

			int line = ( i - ( ( len % 16 ) - 1 ) ) / 16 ;

			for ( int k = 0; k < ( len % 16 ); ++k ) {
				char c = buf[line * 16 + k];

				if ( c >= 32 && c <= 126 ) {
					cout << c;
				} else {
					cout << '.';
				}
			}
		}
	}

	cout << "\n\n";
}


int WINAPI send_hook(SOCKET s, const char *buf, int len, int flags){

	cout << "Send "<< TimeToString() << ": (Length: " << len << " bytes)\n\n";
	printPacket(buf, len);
	cout << endl;
	//Sleep(10);
	return send_detour(s, buf, len, flags);
}

int WINAPI recv_hook(SOCKET s, const char *buf, int len, int flags){
	
	cout << "Recv "<< TimeToString() << ": (Length: " << len << " bytes)\n\n";
	printPacket(buf, len);
	cout << endl;
	//Sleep(10);
	return recv_detour(s, buf, len, flags);
}

Habe erst vor kurzem angefangen mich mit Sockets zu beschäftigen und kann sein das ich etwas übersehe. Man lernt ja immer wieder was neues dazu, also seits nicht ganz böse zu mir :p :)

Wo ist mein fehler? :/
PS: Falls gefragt, ich leite das cout in die Console, deswegen das cout da.
11/25/2013 21:57 snow#2
Code:
printPacket(buf, len);
...
return recv_detour(s, buf, len, flags);
Du liest hier die Daten aus dem Buffer, bevor Daten in den Buffer geschrieben werden.

Code:
int received = recv_detour(s, buf, len, flags);
printPacket(buf, len);
return received;
sollte funktionieren.
11/25/2013 22:04 +Yazzn#3
Kleine Verbesserung: len gibt die Größe des receive buffers an, die Anzahl der empfangenen Bytes werden von der recv Funktion zurückgegeben.

Code:
int received = recv_detour(s, buf, len, flags);
printPacket(buf, received);
return received;
P.S.: Und buf ist bei recv nicht const.
11/25/2013 22:16 XxharCs#4
Quote:
Originally Posted by snow911 View Post
Du liest hier die Daten aus dem Buffer, bevor Daten in den Buffer geschrieben werden.

Code:
int received = recv_detour(s, buf, len, flags);
printPacket(buf, len);
return received;
sollte funktionieren.
&
Quote:
Originally Posted by Peter File View Post
Kleine Verbesserung: len gibt die Größe des receive buffers an, die Anzahl der empfangenen Bytes werden von der recv Funktion zurückgegeben.

Code:
int received = recv_detour(s, buf, len, flags);
printPacket(buf, received);
return received;
Das erklärt mal so einiges..^^ Danke!


Quote:
Originally Posted by Peter File View Post
P.S.: Und buf ist bei recv nicht const.
In printPacket wird buf sowieso in eine char Varable geschrieben oder sollte es sofort beim einlesen in eine char Variable gespeichert werden? Soweit ich weiß sollte man const nicht explizit weggelassen.
11/25/2013 22:20 +Yazzn#5
recv und recv_hook sollten die gleiche Signatur haben, weil wegen Prinzip.
11/25/2013 22:30 XxharCs#6
Quote:
Originally Posted by Peter File View Post
recv und recv_hook sollten die gleiche Signatur haben, weil wegen Prinzip.
Stimmt!

Mein verbesserter Code (nur recv ausschnitt):
Code:
DETOUR_TRAMPOLINE(int WINAPI recv_detour(SOCKET s, char *buf, int len, int flags), recv);
...
...
int WINAPI recv_hook(SOCKET s, char *buf, int len, int flags){
	
	int received = recv_detour(s, buf, len, flags);
	cout << "Recv "<< TimeToString() << ": (Length: " << received << " bytes)\n\n";
	printPacket(buf, received);
	cout << endl;
	//Sleep(10);
	return received;
}

Da ist aber jetzt ein neues kleines Problem aufgetaucht undzwar, bei etwas größeren Packets stehen wieder 4-5 Zeilen mehr, bei WPE nicht :( Woran liegt das?
11/26/2013 00:52 +Yazzn#7
Dann läuft da vermutlich was bei deiner printPacket Funktion falsch. Sonst erklär uns doch mal was deine printPacket Funktion genau machen soll.
11/26/2013 16:48 XxharCs#8
Quote:
Originally Posted by Peter File View Post
Dann läuft da vermutlich was bei deiner printPacket Funktion falsch. Sonst erklär uns doch mal was deine printPacket Funktion genau machen soll.
Mit printPacket gebe ich einfach das Packet formatiert aus.(16 Stellen hex und dannach bzw. daneben den ASCII dazu/zur Zeile, diese formatierte Ausgabe hängt natürlich mit der Packet länge zusammen)

Ich glaub ich habe mich mit einer for-Schleife vertan, ich werd es nochmal durchgehen sobald ich mit der Zeit besser bin.
11/26/2013 17:35 Omdi#9
Eventuell liegt es daran?

Code:
for ( int i = 0; i < strlen(buf); ++i ) { //weil recv failt, verwende ich strlen(buf) um unnötigen packet inhalt nicht auszugeben
11/26/2013 18:05 XxharCs#10
Quote:
Originally Posted by Omdihar View Post
Eventuell liegt es daran?

Code:
for ( int i = 0; i < strlen(buf); ++i ) { //weil recv failt, verwende ich strlen(buf) um unnötigen packet inhalt nicht auszugeben
Durch das behobene Problem mit der Packet Länge, verwende ich len, der Funktion wieder. len ist die Packetgröße die ich übergebe (also das received in dem Fall)

Code:
void printPacket(const char *buf, int len) {
    
...
	for ( int i = 0; i < len; ++i ) {
...
Code:
...
printPacket(buf, received);
...

Edit:
Das Problem war das ich Packet Länge übergegeben hab, man musste aber die Daten Länge des Packets übergeben.
Kann geclosed werden.