Highscores being sent as hash

There is a game that has been created with Unity which I'm trying to beat. It sends your high-score to a site and gets posted there.

I've sniffed the outgoing traffic and the game sends your username, your score plus a MD5 hash.

Looking to some on-line tutorials (and I'm guessing this too) the hash consists of something along the lines of:

 MD5(user:USERNAME, score:SCORE, SALT)


As you can guess, I know the username and the score, but I don't know the secret. I'm trying to find these strings in Ollydbg but I'm having some trouble finding it.

I'm having trouble in being able to set a breakpoint, as the score is sent when you click submit and time of the game is still running.

Any suggestions on how to find where the hashing occurs using Ollydbg? How would you set the breakpoint if the game is still running?

• It can't be hashed as how would the server know what the score value is? I think you mean it's encrypted. How about setting a breakpoint on Winsock send APIs to begin with? – Paul Feb 25 '15 at 12:33
• It is being hashed: It sends both the unhashed and the hashed values. The server knows the secret too. When the server receives the unhashed values, it will hash it and check if the resulting hash is the same as the one being sent... – Komiblanka Feb 25 '15 at 12:39
• You can use the findcrypt for IDA to find the hashing functions and break there. From there, stack trace your way up until you find the caller that has the secret. – rev Feb 25 '15 at 13:36
• @AcidShout: I've downloaded IDA freeware version and included the plugin findcrypt (from IDA's official site) in the plugins folder. I get an error: the procedure entry point_callui could not be located in the dynamic link library IDA.WLL I'm using win7 64 bit – Komiblanka Feb 25 '15 at 15:28
• @Komiblanka that's because the plugin is not compatible with IDA Free. Maybe you should try the recent demo (I'm not sure whether it supports plugins), or grab a copy of IDA Pro, which is expensive, but is an indispensary tool for reversing. – rev Feb 25 '15 at 15:33

Here are several different approaches to finding the hashing algorithm (and from there, its caller), all of which can be done statically (since you said you were having trouble setting a breakpoint at runtime):

1. Search the disassembly for MD5 constants, such as 67452301, d76aa478, etc.
2. Search the disassembly for the string "MD5" and references to that string.
3. Search the disassembly for any strings/constants that appear in the network packet data that contain the hash. For example, if the network packet data is <user>Komiblanka</user><highscore>1000</highscore><hash>8b1a9953c4611296a827abf8c47804d7</hash>, then search for "highscore".

If these don't provide fruitful results, you can set a breakpoint in OllyDbg on ws2_32!send() and once you see it sending the buffer that contains the score hash, look at the call stack to find the previous functions involved.

• One shortcut I used for this is use the kanal plugin in peid. I've usually been able to track down these constant tables and from there set memory access breakpoints. – gandolf Feb 26 '15 at 13:51

As you mentioned OllyDbg I'm assuming you use windows.

A quick search of the Unity Script Reference brings up Windows.Crypto.ComputeMD5Hash().
This function needs to be implemented by the Unity Engine.

Either using the Windows Api - so set a breakpoint on CryptCreateHash() and CryptHashData()

Or implementing it manually. To find that you can use Jason Geffner's answer OR (which might be faster) write your own small unity script that uses this function and debug that to find the address.

// http://docs.unity3d.com/Manual/CreatingAndUsingScripts.html
using UnityEngine;
using System.Collections;

public class MainPlayer : MonoBehaviour {

// Use this for initialization
void Start () {
byte[] buf = {1, 2, 3};
ComputeMD5Hash(buf);
}

// Update is called once per frame
void Update () {

}
}


When you now look at the CIL code the call to ComputeMD5Hash() should stand out clearly.