View Full Version : high score table manipulation
Naked2
November 20th, 2006, 23:40
I am having difficulties in attempting to manipulate the high score table of a certain game.
The exe is packed and I am running the process through OllyDbg. I have tried opening up the saved game data in hex editors in search of any 'score' related data but the strings have provided as useless; heavy encryptions beyond my know-how/understanding.
My goal is to pause the debugger just before the game is set to transmit the scored data to the server for encryption. The resulting information of the pause immediately after I press enter was non encrypted data, and I was able to locate the name I entered (Naked2) followed by my score and level data of that game through a memory dump.
I have tried everything I know of, including memory access and write breakpoints to 'intercept' the data between pauses and replace it manually but it never actually saves to the high score table. After going through several breakpoint pauses and analysis's of each one, I still cant even find at which point the data has been written to the table. I have noted certain strings where I believe the data is written to but I usually get an error saying that 'the breakpoint cannot be made between 029000 and 029010 binary addresses. (They are not the exact addresses.)
So my ultimate goal is to somehow intercept the data and modify it before it hits the score table. Ideally, as soon as the debugger resumes, it would submit the modified data to the table.
I have attached an image of the process in OllyDbg so you can see exactly what I am doing. Any help or pointers you might have would be greatly appreciated.
http://i64.photobucket.com/albums/h173/naked_07/ollydbg.jpg
dELTA
November 21st, 2006, 00:55
Quote:
...before the game is set to transmit the scored data to the server... |
What kind of game is it? What kind of server? If the game is played through any interaction with the server, chances are that the server keeps track of the score itself, to prevent you from cheating by manipulating the client side of it, like you mention doing.
Naked2
November 21st, 2006, 01:12
The game is similar to Tetris, am I allowed to title it? I didn't want to chance it because of the possible legalities surrounding my intentions.
I think the server is HTTP Apache. The high score table already shows evidence of hacking.
The only interaction with the server is to transmit scores to a high score table.
LLXX
November 21st, 2006, 03:32
Messing with high-score tables... one of the things I used to enjoy doing when I was bored
Two words (actually three...):
Proxomitron
HTTP Log
This looks like a very simple system. The program sends an HTTP GET request to a PHP script on the server with the following parameters, from what I can see
name[1]=Naked2&score[1]=250&level[1]=1&avgtime[1]=0&gameguid[1]={...}
...and further parameters, including what looks like three Unix-type timestamps and some additional nearly self-explanatory parameters (&action=addscore).
Find the name of the PHP and the server to which it's sending the data to, pause the game at that point where you can read the parameter string, and just try hitting that URL with your Browser. If you can even get a score submitted, then try changing some of the parameters and repeat. Etc.
Edit: Send me a PM with the necessary non-public information, as per the FAQ, and I'll see if I can get my name up there

dELTA
November 21st, 2006, 05:03
About the name, no need to mention it, all that is/was needed is a technical description (and you also practically already identified it with that screenshot

).
And just like LLXX says, I'd attack it on a communication-level too, most likely no need at all to reverse the binary client. Sniff and analyze the communication, then manipulate/imitate it.
WaxfordSqueers
November 21st, 2006, 05:09
Quote:
[Originally Posted by LLXX;62554]Two words (actually three...):
Proxomitron
HTTP Log
|
It's amazing how long that little app has been around. I still use it on my XP SP2 system in front of Opera, IE, Firefox...whatever. I turn off their popup killers and just use Prox. Every once in a while I pop some nasty URL in Prox's kill filter.
I heard that the author, Scott Lemmon, passed away in May 2004. He was a pretty smart dude.
Naked2
November 21st, 2006, 09:11
EDIT: Upon following the instructions given, and contrary to this being as simple as first thought, the table data had already been encrypted. The following information is what I intercepted:
POST /XxxLeaderBoard1Servlet/XxxLeaderBoard1Servlet HTTP/1.1
Accept: */*
Content-Type: application/x-www-form-urlencoded
User-Agent: HIP
Host: tryx.srvx.hx.leaderboards.xxxxxxx.com
Content-Length: 255
Pragma: no-cache
action=decrypt&type=hipenc1&key=0&data=yckjprisilwdmhhdsuoiwudqhzdzplwqbsmddcshpsmqknmswvorbnshwsirhiwhohyshsmhzamskdhazvmnpiplihzhilw dmhhsbcdddiodysstxtlnoqszidglxsxsmhszgublgjwdhvwqgtlslqztlaihscktlrlrgueslrzdlcztgvlfztyrwlbswudzpss hmlgadlzvlrkdknhlgvxq
Naked2
November 21st, 2006, 19:55

See above post for update. I am a bit backwards today.
dELTA
November 22nd, 2006, 10:32
Ok, assuming that the encryption is strong enough not to be worth attacking in itself, I'd next suggest you intercept the APIs used to send this data to the server, and work your way backwards from there. This would have quite a good chance of quick success. What kind of binaries does this game depend on? Native stand-alone x86 executable?
Naked2
November 22nd, 2006, 12:48
Yes, it appears to be a stand alone executable. The file is packed and it seems to be self modifying. I have managed to set hardware breakpoints (dword, word or byte)? on the seemingly repetitive addresses where my name and score info show up in the memory dump. Upon entering a unique user name in the text box before pressing submit, I pause Olly and scan the dump. This name shows up only once, which I think is located in the precache memory buffer.
I take note of this address and set a hardware access breakpoint on the first byte of that address. Next, I begin a run trace to search of my username. I do not understand run-trace in its entirety, or the commands associated with it so may some instructions or pointers on how do accomplish my goal using it?
Ultimately this is how I see tackling this:
After setting the hardware break point, but before pressing the 'submit score' button, I would like to begin a trace and somehow set it up to trace over every instruction related to my name and score with the 'fake' replaced information. Wouldn't this guarantee every initial instruction is modified according to my specifications? Thus, leaving no room marginal error and modifying every string before the final data hits the table?
I have traced through so many instructions to just get a glimpse of how the process works and I have actually seen the table data encrypted string by string in front of my eyes in ASCII. I am sure the main problem lies within my limited experience of Olly. At one point yesterday, I felt as if I was on the verge of succeeding but it wound up turning into a 4 hour progressive failure.
EDIT: I may have found the sweet spot; see the image. It appears as though I have located the string that encrypts the name/scoring info before it has actually written the data into the struct? The username is: "Meatball"
http://i64.photobucket.com/albums/h173/naked_07/olly3.jpg
LLXX
November 22nd, 2006, 23:43
I suggest you PNG your images instead of JPG'ing them. JPG is for photos and other images with smooth gradients, not sharp contrasts. You'll get better compression and no compression artifacts (noise). It also yields better results when OCR'd.
I don't think that's the encryptor, as it does not appear to be doing any encrypting, only determining how many bytes to copy based on a strange criteria. Here is the loop reproduced and annotated:
Code:
loop_1: (there is an instruction here that I don't know, two bytes in length)
add edi, 4
dec ecx ; some sort of counter (LOOP would've saved a byte here)
jz ^ (can't see destination in your image)
mov edx, 7efefeffh
mov eax, [esi] ; get 4 bytes
add edx, eax ; add constant 7efefeffh to it
xor eax, 0ffffffffh ; same as NOT EAX - inverts all bits
xor eax, edx ; xor with same constant again
mov edx, [esi] ; get 4 bytes again
add esi, 4 ; advance to next 4 bytes
test eax, 81010100h ; eax = ~*esi^(*esi+0x7efefeff)
jz loop_1 ; jump only if those bits were not 1.
test dl, dl
jz ^ (can't see destination in your image, probably to store 1 byte)
test dh, dh
jz loc_2 ; store two bytes
test edx, 0xx0000 (couldn't read the digits, looks like 0ff0000 to me)
jz loc_3 ; store three bytes
test edx, 0ff000000
jnz loop_1
mov [edi], edx ; store four bytes
...
ret
loc_3: ; store three bytes (and null terminator?)
mov [edi], dx
xor edx, edx
...
mov [edi+2], dl ; 0
...
ret
loc_2: ; store two bytes
mov [edi], dx
...
ret
As you repeatedly mention that the executable is packed, why haven't you unpacked and IDA'd it yet? It is obviously a very simple packer if it doesn't contain any antidebug code, as you seem to be doing fine tracing through with OllyDbg.
Naked2
November 23rd, 2006, 00:42
Photobucket automatically converts my files to jpg's, as though it seems.
There are random debug checks however I have managed to mask Olly and prevent this from occurring.
'EXCEPTION_DATATYPE_MISALIGNMENT' is the packer's way of kicking you out when it discovers debugging.
I have attempted to IDA it but it gave all sorts of problems and error upon execution.
Furthernore, I had someone else with more experience analyze the exe and was told that it was not necessary to unpack it just to modify the struct before it is used. I just can't figure out which struct I need to modify.
I sense this may be going in circles so if you can't help I understand. Otherwise, please specify any other info you may need in order to help me.
dELTA
November 23rd, 2006, 07:38
You say you have defeated the debugger checks. Then continue my strategy above, breakpointing the communication APIs, and working backwards from these.
LLXX
November 23rd, 2006, 20:54
Quote:
[Originally Posted by Naked2;62597]Furthernore, I had someone else with more experience analyze the exe and was told that it was not necessary to unpack it just to modify the struct before it is used. |
I wonder how much experience that 'someone else' exactly has, since anything that's been packed should be unpacked first and subject to further analysis.
You will often miss many interesting points in the code by tracing through it in the debugger, as your mind becomes focused only on the execution flow. Reading calmly through the disassembler listing is much more relaxing too

JMI
November 23rd, 2006, 23:42
In other words, if you want to examine what's in a suitcase, you either need a special x-ray machine, or you actually need to open the suitcase.

Once it is open, it certainly is much easier to determine what's inside.
Regards,
dELTA
November 24th, 2006, 04:02
Unless it was a bomb triggered by opening the suitcase, then you'd just want an X-ray with very long wires.
And what I might or might not mean with that

is that you don't necessarily need to unpack a target the
very first thing you do, it doesn't hurt taking a peak with the debugger first to see if it's a too simple crack to justify unpacking it etc.
JMI
November 24th, 2006, 04:26
Ah, but we both know that he's already taken that"peek" and didn't find his solution.

Therefore, the "open the suitcase" proposal becomes operative.
Regards,
dELTA
November 24th, 2006, 08:19
Yeah, sure, it was just a general comment on the very general statements regarding this issue by LLXX and yourself.
Also, in most cases where the seemingly best starting point is to trace forwards from user input, or backwards from program output, I would at least try to get some starting addresses through live debugging before going through the process of unpacking and statically analyzing. But different people have different favorite ways, most of the time none of them are superior to the other, so my main point is that LLXX's statement is possibly just a little too harsh and categorical.
Naked2
November 27th, 2006, 09:09
Thanks for your responses, but I used another method to compromise the scoring table. No need to further pursue this thread.
dELTA
November 27th, 2006, 09:26
I'm glad you succeeded. But it's considered very bad manners to first receive a lot of help in a thread and then just say "I found another solution, bye" though.
So, why don't you tell us about this alternate method, I'm sure a lot of people are curious.
Naked2
November 27th, 2006, 10:23
Don't misunderstand my intentions, as I have every intention to stick around. I don't have the time to details this method at the moment, but I will post the solution later on tonight.
EDIT: Solution:
I had some help from a talented individual, so if you are reading this you know who you are:
Upon losing the game you are presented with a text submission box to enter your name for the score. At this point you would type in your name and click 'OK' and just as the screen reads 'communicating with server' you immediately pause the debugger. You then dump the memory and search for your username. If done correctly, your name will appear only twice in two different strings. To manipulate the high score you need to examine the structure and change it accordingly. The following table is an example of what you should see. Note that your score is highlighted in red your level is highlited in blue and your time is highlighted in green.
To compromise and modify all of this data you need to select a the numbers you want and convert them to hex dwords, reverse the byte order to get the little-endian representation, and then binary paste over the highlighted dwords.
0569A40 31 24 6D 69 22 61 7C 4D 00 00 00 00 00 00 00 00 Username.........
00569A50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00569A60 27 06 00 00 01 00 00 00 00 00 00 00 7B 46 37 35 '.........{F75
00569A70 38 39 30 33 33 2D 38 45 36 42 2D 34 36 46 33 2D 89033-8E6B-46F3-
00569A80 42 31 2D 41 31 2D 41 32 2D 41 46 2D 36 36 2D 39 B1-A1-A2-AF-66-9
00569A90 33 2D 43 2D 39 44 7D 00 00 00 00 00 00 00 00 00 3-C-9D}.........
As you have probably guessed, these structures need to be modified before they are parsed and used. This is the reason Olly has been paused where it has, prior to execution.
Once all data has been modified, simply hit F9 and allow the program to establish connection to the server and once completed you will have successfully cheated the local and server all time high scores.
LLXX
November 27th, 2006, 19:18
Ok... not really the "proper" Reversing-based method but whatever works for you...
In other words you learned to do something without really learning anything

naides
November 27th, 2006, 20:30
well, to reverse this puppy, I would place read breakpoints on the highlighted memory addresses, track down with Olly which code reads and transforms this plaintext into the cyphertext that gets transmitted to the server
and viola, you cracked this nut
Naked2
November 28th, 2006, 01:24
Quote:
[Originally Posted by naides;62655]well, to reverse this puppy, I would place read breakpoints on the highlighted memory addresses, track down with Olly which code reads and transforms this plaintext into the cyphertext that gets transmitted to the server
and viola, you cracked this nut |
I still want to learn how to reverse the process. Perhaps someone could explain how to breakpoint the communication API's? Or as mentioned above, how do I 'track down' the code that transforms the plain text and what should I be looking for?
dELTA
November 28th, 2006, 08:44
There are thousands of tutorials about setting breakpoints on APIs (I'm sure a quick search in our official OllyDbg support forum would even suffice more than well). Information about which APIs are used to write communication code in Windows is also allover the net. Remember, we require you to do a reasonable amount of homework yourself around here.
Powered by vBulletin® Version 4.2.2 Copyright © 2018 vBulletin Solutions, Inc. All rights reserved.