Log in

View Full Version : Help on how to identify & isolate a checksum routine


Greatwolf
December 12th, 2009, 18:17
Hi all,

I'm trying to identify a checksum algorithm used in an MMORPG, Runes of Magic, that's used for item linking for ingame chat. The format is given as such:

Code:
|Hitem:<id> <bind type> <runes><plus><tiering><max dura> <stats>x7 <current dura> <hash>|h|cff<color>[<name>]|r|h


So a real example:

Code:
|Hitem:35bf3 1 200a62 0 0 0 0 0 0 0 0 e42b|h[Rough Cloth Pants 98]|h
|Hitem:35bf3 1 200a63 0 0 0 0 0 0 0 0 9fd7|h[Rough Cloth Pants 99]|h
|Hitem:35bf3 1 200a64 0 0 0 0 0 0 0 0 e3ed|h[Rough Cloth Pants 100]|h


The 2-byte value in bold italics is the generated checksum calculated from all the previous bytes minus '|Hitem:'

How can I go about figuring out how the checksum is calculated? I tried all the usual hashing algorithms: crc-16, crc16-ccitt, bytesum modulos 256, bytesum + 1's complement (used by tcp/ip packet checksum) etc. So far none of them have reproduce the desired hash output that I am seeing for those ItemLink examples.

I'm pretty sure the hash calculation is done by the game client on the running host computer. How can I go about using a disassembler like ollydbg, to identify and isolate the relevant assembly where this checksum is being calculated?

Also, are there any other approaches to solving this issue that I haven't considered? My current working solution is to simply brute-force the 2-byte value and concatenate it with the rest of the string.

Thanks

FrankRizzo
December 13th, 2009, 16:04
I would use a tool like the ones available here at the CRETL, that would look through the client, and identify any CRC or HASH routines. That'll tell you what you're working with for starters.

Then, once you know what you're working with, you can set a breakpoint on that function (using IDA as a debugger, or the like), and issue your command. It should break at that function, and you can then trace it BACK to where it came from, and right there staring at you should be the function(s), that build the packet, and send it to be hashed.

Once that happens, you should be off to the races.

Greatwolf
December 14th, 2009, 20:33
awesome, thanks for the reply. Will give that a try

SiGiNT
December 18th, 2009, 01:57
Your only chance of fixing your problem is to disable the checksum checking routine, you can't change a checksum, because the minute you do the checksum changes, you can go crazy trying to figure it out ahead - hope this helps - don't know if this helps, because I don't normaly work on games but PEID Kryptoanalyzer can identify the locations of checksum routines, and sometimes it's actually right!

SiGiNT

arc_
December 18th, 2009, 10:41
It might just as well be a complety custom hashing routine, in which case no identification tool in the world will find it for you. E.g. the hashing code of the game Prototype simply performs a multiplication and an xor for every character.

What I would do is try to find the routine that builds these item strings, for example by searching the binary for a string containing the "|Hitem:" part. A function that uses this string will likely either build or parse an item string. Once you find the building routine, the checksum code won't be far. Its result will probably be concatenated to the string, or be used in an sprintf.

Oh, and get IDA if you haven't yet. It's the world's most popular disassembler for a reason.

Greatwolf
December 18th, 2009, 17:17
Thank you everyone for the helpful feedback.

What I did end up doing was using Cheat Engine first to locate the first group of the string in memory. I figured everytime you click on the link, it has to go through some sort of validation. If the checksum fails then the link just displays an empty box instead of the actual item stat encoded in the hex string.

I was able to locate this in memory then I used ollydbg to find out where in the code that memory is referenced. I set a couple of breakpoints, click a few different item links to see how the code path changes.

At the end, I was able to locate precision where the checksum is happening and how it's done. I've already wrote a quick c++ console app to reproduce that checksum and the fabricated link now works ingame.

Thanks all

SiGiNT
December 21st, 2009, 21:14
Another method is to set a memory break on access on the code you want to change - this can sometimes lead you back to the checksum routine.

SiGiNT (Grampy 2)