################################################################ Gamespy Presence System Login Algorithm October 22, 2003 Reversed by xoclipse@cox.net http://xoclipse.fraghosts.net The following is how you compute the 2 challenge responses in the login packet. ################################################################ Upon connecting to gpsp.gamespy.com:29900, you receive a challenge packet. Example: \lc\1\challenge\JQIQSWIHIN\id\1\final\ After this packet, you can send your login packet. Here is an example of how a login packet looks: \login\\challenge\CuwuIcWVSxZuhZc4mTjxRXGXhNkRf5VJ\user\user@email\response\a452d8f8e1f54bfb5af21558fe411921\port\1283\productid\60\id\1\final\ Where nickname is the user's nickname, and email is the users email(i.e xoclipse@cox.net) and nickname(xoclipse) - xoclipse@xoclipse@cox.net would be the full string for \user\ The 2 Important things to note: The string after "\\challenge\" The string after "\response\" - String used to authenticate password and a few other things ############################################## Creating the \\challenge\ string ############################################## The challenge string is a 32-byte hashed string, which is computed from a base random number. Here is the algorithm in C: /* START CODE */ int ecx,eax,edx,esi; char hash[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; ecx = rand(); esi = 0; int test = ecx; char *result = new char[33]; for(int x = 0; x < 32; x++) { /* CALL */ ecx = test; ecx *= 0x343fd; ecx += 0x269ec3; eax = ecx; eax >>= 0x10; eax = eax & 0x7FFF; test = ecx; /* END CALL */ ecx = 0x3e; edx = eax % ecx; esi++; result[x] = hash[edx]; } result[32] = 0; /* END CODE */ The previous ends with the variable result containing the "challenge" string, it is also used for the "response" string, later in the packet ############################################## Creating the \response\ string ############################################## The response string is computed with MD5 First, you have to compute the MD5 of the user's password. Then we will MD5 the Following string: MD5Password(48 0x20's)USER@EMAIL(ABOVE CHALLENGE STRING WE COMPUTED IN ALGORITHM)(CHALLENGE STRING SENT BY SERVER)MD5Password 0x20 = Blank space To form the above string, use a sprintf: /* START CODE */ sprintf(temp,"%s%s%s@%s%s%s%s", pass,blanks,user, email,hash, challenge, pass); */ END CODE */ The parentheses are NOT included in the MD5, Below is an example string to MD5 for the "response" | Md5 of password | 48 Blank Spaces | 098f6bcd4621d373cade4e832627b4f6 xoclipse@xoclipse@cox.net5a105e8b9d40e1329780d62ea2265d8aJQIQSWIHIN098f6bcd4621d373cade4e832627b4f6 | user@email ||CHALLENGE STRING WE CALCULATED||SRV CHALLENGE|| md5 password again| We send as the "\response"\ string the MD5 of the large string above ############################################## Forming the login packet ############################################## To form the login packet, we just use sprintf... sprintf(login, "\\login\\\\challenge\\%s\\user\\%s@%s\\response\\%s\\port\\%d\\productid\\60\\id\\1\\final\\", hash, user, email, response, port); ################################################# Conclusion ################################################# Once you have succesfully logged in, you will receive a sesskey, and some more session information. If your password is wrong, or you incorrectly computed the md5 or hash strings, you will get an invalid password error. Here is an example successfull login response: \lc\2\sesskey\4862342\proof\72ac551f3647c6ac79f34ee4a6ba5dac\userid\1646201\profileid\13201358\uniquenick\\id\1\final\ I hope you have learned about the Gamespy Login process, and have benefited from this paper. Any questions or comments can be directed to my email - xoclipse@cox.net You can reach my on AIM, my screenname is xoclipse MSN Name - xoclipse@hotmail.com