"Open" an existing socket instead of creating a new one

01/04/2009 01:55 nc10#1
Hello!

Using WPE PRO I am able to open an existing socket instead of creating a new one. That way I can send packets (for example to make the character run to a specific location) and the game does not crash.

I would like to use this procedure for my own bot. My question: How can i "open" an existing socket?

Programming language: C++
Game: Silkroad Online

Thanks in advance :)
01/04/2009 11:37 schlurmann#2
WPE Pro detours the WinAPI functions send, recv, sendto, recvfrom, WSASend, WSARecv. The first argument passed to those function is a SOCKET. If you got the function hooked you can just use that argument, of course you could also hook connect which gets a SOCKET as well.

If you aren't familiar with detouring functions I can give you a simple example here, just let me know.
01/04/2009 18:22 nc10#3
Thank you!

I'm truly grateful because it's quite hard for me to gather information about this procedure.

Quote:
The first argument passed to those function is a SOCKET.
Until now I always created a new socket and passed it to the send and recv functions.

Code:
WSADATA wsaData;

if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
	return 1;
}

SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
Code:
if (connect(sock, (struct sockaddr *)&silkroad, sizeof silkroad) == SOCKET_ERROR)
{
	closesocket(sock);
	return 1;
}
Code:
/* Example */
iResult = recv(sock, recvbuf, 43, 0);
Actually I just need to send data. But if I create a new socket and send data I get disconnected. Of course I analysed the packets.

Quote:
If you aren't familiar with detouring functions I can give you a simple example here, just let me know.
That would be great.
Excuse me for my bad English.
01/04/2009 21:08 schlurmann#4
Code:
#include <Winsock2.h>
#include <Windows.h>
#include <detours.h>

#pragma comment(lib, "detours.lib")
#pragma comment(lib, "ws2_32.lib")

typedef int (WINAPI* r_send)(SOCKET sock, char* buf, int len, int flags);
r_send osend;

typedef int (WINAPI* r_recv)(SOCKET sock, char* buf, int len, int flags);
r_recv orecv;

int   WINAPI custom_send         (SOCKET sock, char* buf, int len, int flags);
int   WINAPI custom_recv         (SOCKET sock, char* buf, int len, int flags);

SOCKET capSock;

BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
{
	if (reason == DLL_PROCESS_ATTACH)
	{
		osend         = (r_send)         DetourFunction((PBYTE)&send, (PBYTE)&custom_send);
		orecv         = (r_recv)         DetourFunction((PBYTE)&recv, (PBYTE)&custom_recv);
	} 
	return TRUE;
}


int WINAPI custom_send(SOCKET sock, char* buf, int len, int flags)
{
	capSock = sock;
	return osend(sock, buf, len, flags);
}
int WINAPI custom_recv(SOCKET sock, char* buf, int len, int flags)
{
	capSock = sock;
	return orecv(sock, buf, len, flags);
}
I used the Microsoft Detours Library 1.5 which you can get [Only registered and activated users can see links. Click Here To Register...]. So first include all the windows, winsock and detours stuff and link the libs. Next we make ourselves two cute little function pointer types and create two function pointers with them, one for send and one for recv. Those will be holding the copies of the original winsock functions send and recv which the library will create for us (detouring means writing a JMP command that will jump to our custom function at the starting address of the function you want to detour, due to this the original function would be lost, fortunately the library saves the original for us so the program doesn't get fucked up). custom_send and custom_recv will "replace" (not really, we will still call the original function) send and recv, in those we can do what we want with all the parameters (in this case, copy the socket the game uses into our socket). Next we call DetourFunction (if .dll gets attached, you will have to inject this .dll), it gets 2 parameters, 1) address of the original function, 2) address of the "replacing" function. It returns the saved function which we put in our function pointers. Of course, in our custom functions we have to call the original send and recv (saved in the function pointers) so our program won't crash.

Should work, didn't test it though. Not too hard eh?
01/04/2009 23:18 nc10#5
Thanks a million!

Just what I needed.

Quote:
Not too hard eh?
Pretty easy to understand :)
This is much easier than I thought it would be.

Quote:
Should work, didn't test it though.
I'll test it now :)
06/01/2009 22:00 blackmorpheus#6
Is there any other way, not hooking? Ofcourse, hooking send / receive will get u the socket, but I wanna do it with C# and send packets using the existing socket, is this possible?
06/01/2009 23:34 ms​#7
You can open the game in ollydbg and look where it gets the parameters to call a Winsock function, send for example.

[Only registered and activated users can see links. Click Here To Register...]

The first parameter (= the last push) "Socket" is important. ecx contains that parameter. If you look some lines above you can see where ecx gets that value from (0x02220BB8 in this example). So you just need to read the DWORD value stored at 0x02220BB8 in order to obtain the socket.
Not tested, just an idea. ;)

I've got another question though and don't want to create a new topic. How can I send a packet to the client? If I overwrite the recv-buffer one packet sent by the server gets lost.
06/02/2009 12:25 schlurmann#8
Quote:
Originally Posted by Disconnect View Post
I've got another question though and don't want to create a new topic. How can I send a packet to the client? If I overwrite the recv-buffer one packet sent by the server gets lost.
If you detoured it just use the trampoline function.
06/02/2009 13:21 blackmorpheus#9
And probably create a new thread because otherwise you could block the game..