Code:
#include <windows.h>#include <stdio.h>
#include <vector>
#include "Stream.h"
#include "resource.h"
#pragma comment(lib, "ws2_32.lib")
hostent * GetHost(const char * host);
INT_PTR CALLBACK Main_DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
std::vector<std::string> TokenizeString(const std::string& str, const std::string& delim);
hostent* host = 0;
sockaddr_in svr, local;
SOCKET s = 0;
int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
HWND hWnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, Main_DlgProc);
MSG Msg = {0};
while(GetMessage(&Msg, 0, 0, 0) > 0)
{
// Process GUI messages
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return 0;
}
void transformData(LPBYTE stream, int len)
{
const char* secString = "gamespy";
int secLen = strlen(secString);
for (int i = 0, j = 0; i < len; i++)
{
if (!secString[j]) j = 0;
stream[i] ^= secString[j++];
}
}
INT_PTR CALLBACK Main_DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// Handle the message
switch(uMsg)
{
// Dialog initialize
case WM_INITDIALOG:
{
WSADATA wsaData = {0};
// Try to start the winsock library
DWORD dwError = WSAStartup(MAKEWORD(2, 2), &wsaData);
if(dwError != ERROR_SUCCESS)
{
MessageBox(0, "Cannot startup WINSOCK", "ERROR", MB_ICONERROR);
return 0;
}
host = GetHost("halor.master.gamespy.com");
if (!host)
{
MessageBox(0, "Cannot resolve halor.master.gamespy.com.", "ERROR", MB_ICONERROR);
return 0;
}
// Setup the connection properties
svr.sin_addr.s_addr = *((unsigned long*)host->h_addr);
svr.sin_family = AF_INET;
svr.sin_port = htons(29910);
local.sin_family = AF_INET;
local.sin_addr.s_addr = 0;
local.sin_port = 0; // choose any
s = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
// bind to the local address
int r = bind(s, (sockaddr *)&local, sizeof(local));
if (r == SOCKET_ERROR)
{
MessageBox(0, "Cannot bind the local socket.", "ERROR", MB_ICONERROR);
return 0;
}
}break;
// Commands
case WM_COMMAND:
{
int button = LOWORD(wParam);
// This gets called when a button is pressed, the case is the button id.
switch (button)
{
case IDC_CHECK:
{
if (GetWindowTextLength(GetDlgItem(hWnd, IDC_HASH)) == 32)
{
char hash_to_check[33] = {0};
GetWindowText(GetDlgItem(hWnd, IDC_HASH), hash_to_check, sizeof(hash_to_check));
streamBuilder b;
b.AppendString("\\auth\\\\pid\\793"); // game info
b.AppendString("\\ch\\nxdqevx"); // server key (any random 7 letter str)
b.AppendString("\\resp\\");
b.AppendString(hash_to_check); // hash to verify
b.AppendString("12345678"); // client key
b.AppendString(hash_to_check); // should be the auth token but we can't possibly generate a valid one
b.AppendString("\\ip\\0"); // ip address as 32bit number, 0 works fine too
b.AppendString("\\skey\\12345"); // used to id response
LPBYTE stream = b.getStream();
transformData(stream, b.getStreamSize());
// send the pkt
int ret = sendto( s, (char*)stream, b.getStreamSize(), 0, (sockaddr *)&svr, sizeof(svr));
char buff[1024] = {0};
sockaddr_in from;
int len = sizeof(from);
int bytesReceived = recvfrom(s, (char*)&buff, sizeof(buff), 0, (sockaddr *)&from, &len);
transformData((LPBYTE)buff, bytesReceived);
std::vector<std::string> tokens = TokenizeString(buff, "\\");
if (tokens.size())
{
if (tokens[tokens.size()-1] == "Invalid CD Key")
MessageBox(hWnd, "The CD Key is invalid.", "Response Received", MB_ICONEXCLAMATION);
else if (tokens[tokens.size()-1] == "Invalid authentication")
MessageBox(hWnd, "The CD Key is valid!", "Valid CD Key", MB_ICONINFORMATION);
else
MessageBox(hWnd, "An unknown error occurred :(", "Response Received", MB_ICONERROR);
}
else
MessageBox(hWnd, "An unknown error occurred :(", "Response Received", MB_ICONERROR);
SetWindowText(GetDlgItem(hWnd, IDC_HASH), "");
}
else
MessageBox(hWnd, "The hash must be 32 characters long.", "Error", MB_ICONERROR);
} break;
case IDCANCEL:
{
PostQuitMessage(0);
} break;
}
} break;
//-------------------------------------------------------------------------
default:
{
return FALSE;
}
}
// Message handled
return TRUE;
}
// http://www.gamedev.net/community/forums/topic.asp?topic_id=381544#TokenizeString
std::vector<std::string> TokenizeString(const std::string& str, const std::string& delim)
{
using namespace std;
vector<string> tokens;
size_t p0 = 0, p1 = string::npos;
while(p0 != string::npos)
{
p1 = str.find_first_of(delim, p0);
if(p1 != p0)
{
string token = str.substr(p0, p1 - p0);
tokens.push_back(token);
}
p0 = str.find_first_not_of(delim, p1);
}
return tokens;
}
hostent * GetHost(const char * host)
{
if(inet_addr(host) == INADDR_NONE)
{
return gethostbyname(host);
}
else
{
unsigned long addr = 0;
addr = inet_addr(host);
return gethostbyaddr((char*)&addr, sizeof(addr), AF_INET);
}
}
Bookmarks