Using SoftICE for Game Training Author: Orr Preface ------- Most of the game trainers out there relax when they figure out that the game they have been training is not using DMA (Dynamic Memory Allocation), in order to store the values it needs for the gameplay. Once they are sure it is Static (that is, the address never changes), they go on and code their trainer. In this tutorial I will show how to use SoftICE in order to create a trainer, even if the address is static. I usually can't care less if the game is 'static' or 'dynamic'. I use SoftICE, and I have more control over the game. Pre-Requisits: - Basic Knowledge of Game Hacking (using a memory seeker). - Basic Knowledge of Assembly commands (I will review some). - Basic Knowledge of SoftICE. The target game for this tutorial is "The House of the Dead 2". I chose it because it is using Static Memory Allocation, and because it is quite easy game for beginners. There are 2 main items in this game; The Bullets, and the Life. The second is a bit more tough than the first one, so I will teach how to hack the both of them here. Bullets ------- Start playing alittle, and you will notice then you have 6 bullets. Shoot them all up and you get this nasty message "RELOAD". Basically you reload with the right mouse button. In the first "House of the Dead" game there was an auto-reload option, but they 'forgot' to add it in this version... playing without auto-reload is harder... uhm, I say we should ReCREATE this option, and show the coders of the game how to do it properly! hahaha! ok. I will calm down now. Open up your favorite memory seeker, and search for the value "6" (make sure that indeed you have 6 bullets). After the search is done, shoot away one bullet, and search for 5 now. Perform this usual drill until you have ONE memory address. It should be 009A3EFC. If you will poke any value you want to this address, it WILL affect the bullet number, but we want to freeze it don't we? Get back into the game, and load SoftICE (Control+D). Now we will set a Breakpoint on Memory Address (BPM). When you set a BPM, SoftICE will break whenever the memory address that we specified was ACCESSED. For example: BPM[SIZE] ADDRESS [R|W|RW|X] Size: There are 3 types of sizes: B - Byte W - Word (2 bytes) D - Double Word (4 bytes) Why do we need to specify sizes? Well, I usally don't specify size, BUT it may get useful. Say we have the address 111, and it holds our money, which is in many cases a big value. If this value is a DWORD (4 bytes), then the address will be 'spread' on 4 bytes, that is: 111, 112, 113, 114. So if we BPMD (BPM Dword) on 111, it will detect any access to one of the four addresses specified. We also have BPM Permissions: R - Break if the address was READ W - Break if something was WRITTEN into the address RW - Break if both Read and Write access happend on the address. X - Break if the address was executed (Eqivalent to BPX) So let's figure out what we need. We don't know whether this address is B/W/D so we will use plain BPM, BUT, we know that we need WRITE permission (whenever this address gets updated with the correct value), so enter this command in SoftICE: BPM 9A3EFC W Get out of SoftICE (Control+D) again, and shoot another time. SoftICE should now pop-up, and you should see this code: 00414AC3 48 dec eax ; EAX stores num of bullets, ; and it is now decreased. 00414AC4 6689461C mov word ptr [esi+1C], ax ; Move updated bullet num ; to the mem address ESI+1C 00414AC8 66837E1C00 cmp word ptr [esi+1C], 0000 ; You will land here If you don't see this, then scroll up a bit (Control+UP). For those of you who don't remember or don't know the basic Assembly commands, I will review some of the relevant ones. MOV DEST, SRC - Moves a value to a register or memory address ADD DEST, SRC - Adds a value to a reg or mem address SUB DEST, SRC - Subtracts a value from a reg or mem address INC DEST - Increases a value DEC DEST - Decreases a value NOP - No OPeration. Doesnt do anything, moves to the next instruction. (DEST = Destination; SRC = Source.) So, from observing the code, we see that the number of bullets is DECresed by one, and then it is being written again to the address. So, what can we do in order to freeze the bullets? Remember that neat little command called NOP? We can replace that DEC with NOP! This way, whenever the processor will reach this line, he will simply move to the next command, without decreasing anything. We see that the memory LOCATION of the DEC EAX is in 00414AC3. So, in order to patch it, simply type in SoftICE the following command: A 414AC3 NOP You will see that the DEC changes into a NOP, and that 48 is changed into 90. Those are the HEXADECIMAL Representations of the instructions and those are called OPCODES. I think that it is a short name for OPeration-Codes. Clear all your Breakpoints (BC *), and get back into the game (Control+D). Shoot some bullets, and you will that it doesn't decrease anymore! Nice eh? By the way, I always like to seek other solutions to the same problem, so lets see if we can find any other ways to patch the game, so it will freeze the bullets. After the number of bullets was decreased, we see this command: 00414AC4 66 89 46 1C mov word ptr [esi+1C], ax This is the actual instruction that writes the value back into the address. as you can see, it is 4 opcodes long (which means it is 4 bytes long), so we can replace those four opcodes with 4 NOPs. Also, a nice idea would be to write a fixed value into that address. What do you mean fixed value? What if we will replace that line of code with this line of code: mov BYTE ptr [esi+1C], 6 ^^^^ ^ It will always write the value 6 into the bullet address, no matter what operations were performed on it! There are many nice solutions available! Be creative... just study the flow of the code, and you will see how many possibilities you have in store. Life ---- OK, I won't explain this thing again, so just find the value of life the way we found the value of bullets. If you did everything alright, you should have found the address 9A3EE8. Now, Poke some value into it (say, 8), and get back to the game. Nothing happens. The poking did not affect the value of lives... why? In order to find out, we must set a breakpoint again, and study the code... so the breakpoint should be: BPM 9A3EE8 W Go back to the game and SoftICE should pop again, and you should be in this location: 0041404B 668B4606 mov ax, word ptr [esi+06] ; AX = What's in [ESI+6] 0041404F 83C404 add esp, 00000004 ; *not important* 00414052 66894608 mov word ptr [esi+08], ax ; Write back AX to [ESI+8] 00414056 57 push edi ; You will land here So, from examining the code, we can see that the address that the actual memory address that holds the value of the life is [ESI+6]. In SoftICE, do this: ? ESI+8 And you will get this: 009A3EE8 0010108648 "š>è" ESI+8 is the address that we found! So, let's see what's inside ESI+6: D ESI+6 you will see this, in the data window: 019F:009A3EE6 03 00 03 00 00 00 C0 03-00 00 00 00 00 00 00 00 ................ 019F:009A3EF6 00 00 00 00 00 00 04 00-00 00 12 00 00 00 26 00 ..............&. OK, I figured it out... The game takes the value in 9A3EE6, and then puts it again inside 9A3EE8. So in order to find the decrementing routine, we should set a BPM on 9A3EE6. Clear all breakpoints (BC *), and set a new one: BPM 9A3EE6 W Get out of SoftICE, and get hit once. You will be in this location: 00415429 66FF8AE63E9A00 dec word ptr [edx+009A3EE6] 00415430 8D82E63E9A00 lea eax, dword ptr [edx+009A3EE6] ; You land here Wow! Did you see this! We found the DEC instruction that controls the value of lives! OK, we see it takes 7 bytes, so we just put 7 nops instead of this instruction. In SoftICE do this: A 415429 NOP NOP NOP NOP NOP NOP NOP Clear all Breakpoints (BC*), and get back to the game... get hit again by one of those dead people, and BOOM! The lives did NOT DECREASE! Success! End --- Whew... I enjoyed writing this text... I hope everything was clear for you. In case it wasn't, don't hesitate mailing me, or coming to the EFNet IRC channel #gamehacking, join us and IDLE :) Greetz: [SHEEP], calligula, Keyboard Junky, jmp_fce4, MacDeath, and all the other people from #gamehacking, and all the people I forgot, sorry... :( Orr in May 2002. OrrAghion@hotmail.com LONG LIVE ISRAEL! /\ ____/__\____ \ / \ / \/ \/ /\ /\ /__\____/__\ \ / \/