The study of games without source code on the example of Zuma
This game is probably not necessary to submit. Toad, balls and dozens of hours wasted. In the first part (when she came out) he played for hours, until a ripple, all night long. Played wife, friends, all played, in general. Anyone who looked into the eyes of the toad, heard the magic “tink” of balls, made a combination of several colors with a well-aimed punch, stayed with this game for a long time. The cat, and that paw hit the screen when he saw a flying ball. In general, if someone asked about my favorite casual games, I would call Zuma and Bejeweled.
But this is a saying. The tale is that I recently re-read “Futurological Congress” by Lem and came across an order of non-people who are preaching the gospel to computers. This led me to believe that the computer, in general, was useless, but he would not refuse to play Zuma. No sooner said than done. I am writing a program that plays Zuma.
Immediately I warn you that I wanted to write a little and quickly, but it turned out so much that it would have to be divided into several parts. If someone is bored to read - you can watch the video at the bottom of the article. ')
In the comments, please reply: is the topic interesting, and is it worth continuing to write like that? Is the presentation interesting? (I write at the same time as I do, so it may seem strange to someone who reads). An approximate action plan is as follows: 1) Dissect application a) Find how the balls are stored, their coordinates and colors b) Find how the frog is stored c) Determine the method of launching the ball d) Determine where the gameover is, or something like that 2) Make an injection DLL, so that at the touch of a button, the computer plays itself 3) Enjoying the deed
For the preparation of the drug, I will need IDA Pro, I will use OllyDbg as a scalpel.
So, I determine the location of the balls. I think you need to see how the pictures are loaded. I look at the file structure of the game, the resources are stored very simply, in ordinary gif files.
It makes sense to search the source file name. ALT + T, "RedBall", Enter. Nope And if just "Ball"? There is! I turn to the line, I look at cross-references. Used in one place:
Wow, what a great function. Did they manually fill it? All actions are reduced to about one. As far as I understand, the ID for the image is transferred to the image upload function and also some other things that I don’t need right now. The function returns a pointer. A pointer is written to a global variable. Here it is clear. Now turn to the debugger and see what happens next with this pointer.
Put a breakpoint on the pointer and start the game. Stops on this line:
You can clearly see that there is a table of pointers (most likely for pictures). Depending on something, an index is chosen in the picture, corresponding to a ball of a certain color. To be sure of that, I do a small experiment: I make the index a constant. I am changing the string MOV EAX, DWORD PTR DS: [EAX * 4 + 9E9FC8] to MOV EAX, DWORD PTR DS: [9EA760] (9E9FC8 + 1E5 * 4). Here's what happened:
but this, of course, visually. The game perceives the balls still. After analyzing the code, discarding all unnecessary, I get the code to determine the color in this function:
mov eax , [ ebx + 14h ] ; ball register is loaded into register eax
add eax , 1DFh ; add offset balls table
mov eax , off_9E9FC8 [ eax * 4 ] ; take a pointer to a picture from the array
Now look where ebx came from. In this function, nothing is written to it, I look up the stack. Judging by the cross-references, the call comes from the same procedure.
In this function, at the very beginning, the ebx register is initialized with the value of the ecx register. It can be concluded that this is an object. And assume that it is a ball. I'll try to climb the stack and see where this object comes from. And, literally, a couple of functions above come across just what I need:
Again, I discard all unnecessary and write down the code to make it clear:
mov [ ebp + var_C ] , offset dword_E43B9C ; pointer to the structure is placed in a local variable
mov esi , [ ebp + var_C ] ; moved to the register
add esi , 0FFFF1000h ; 0xF000 is subtracted from it (to get the start offset of the balls)
mov ecx , [ esi ] ; take the ball
call edx ; call its member function (I think it's drawing, but god knows that it is there. well, I don't really need it)
add esi , 4 ; move on to the next ball
sub ebx , 1 ; reduce iterator
For the sample I will introduce here a code that will repaint the balls in 4 colors, in turn. I use Microsoft Detours. I will not paint in detail, and so I dashed off so much that hardly anyone read it here. In short, the code will be:
int ball_type = 0 ; // global variable
for ( int i = 0 ; i < balls_count ; ++ i )
{
ball_record * ball = balls [ i ] ;
ball - > type = ball_type % 4 ;
}
This is to make the mode "Nightmare!"
for ( int i = 0 ; i < balls_count ; ++ i )
{
ball_record * ball = balls [ i ] ;
ball - > type = 1 ;
}
and this “I'm too young to die”
So, I fulfilled the first point of the plan, to be continued ...