Topic: Dynamic Memory Allocation (DMA)
Level: Beginner Gamehacking
Focus: AoE2: The Conquerors (v1.0c)
Dated: 28th June 2009
(¯`·._.·[ Intro ]·._.·´¯)
-------------------------
Welcome to another one of my tutorials! Yes, some of you will be thinking, damn, another one covering DMA. There have been a lot on this subject over the years, some good, some bad. Sheep wrote a very good tutorial, and it is one that people get referred to pretty often. So, why am I writing this? Well, it seems that no matter how hard you try, someone still comes back saying they don't understand something. So, I am writing another tutorial, covering a different target, and written in a slightly different way, in an attempt to clear up any confusion.
This will be the first text tutorial I have written that targets the beginner gamehacker. So, we'll see how it goes. I'll do my best to make it as clear as possible. I hope that someone gains something from this. And if you do, give me feedback. It's only by having this that i'll know who used the tutorial, what you gained from it, and perhaps what to improve on next time. Ok, on we go. Oh, just before we do, make sure to set your notepad/text editor font to 'Lucida Console, Size 10'. I wrote it with this in mind.
(¯`·._.·[ Prerequisites ]·._.·´¯)
---------------------------------
This tutorial assumes a basic knowledge of memory scanning and a certain knowledge of assembly code (ASM). Unfortunately, I can't be convering every little bit of information associated with DMA. If I did that, this tutorial would be huge, and it would be far too generalized. Memory scanning is very simple. All it involves is a memory searcher such as Cheat Engine, MHS, T-Search, to name but a few. Both Cheat Engine and MHS are modern memory searchers and are updated fairly regularly. They also have documentation, and a big community behind them. So, visit their webpages to find guides and tips on using their software.
As for ASM, you only need to do know the very basics, such as the opcodes (CPU instructions) that you will encounter frequently while gamehacking. Some of these instruction are MOV, ADD, SUB, DIV, MUL, INC, DEC, FLD, FSTP and NOP. You only have to run a quick web search to bring up detailed information about assembly code. Finally, you should be able to recognize and count in the Hexadecimal number system (Base16). This is important because a lot of the values and addresses you will be looking at will be in this form. I'll place some links below relating to what I have said above. I can't guarantee they'll last forever though:
*Cheat Engine (by DarkByte): Cheat Engine
*MHS - Memory Hacking Software (by L. Spiro): L. Spiro's Memory Hacking Software
*x86 instruction listins Wiki: x86 instruction listings - Wikipedia, the free encyclopedia
*Basics of ASM 1 (by DABhand): Basics of ASM Day 1 - FileForums
*Basics of ASM 2 (by DABhand): Basics of ASM Day 2 - Floats - FileForums
*Basics of ASM 3 (by DABhand): Basics of ASM Day 3 - Jumps - FileForums
*Hex number system (Wiki): Hexadecimal - Wikipedia, the free encyclopedia
Once you know the very fundamentals, or you already do, then we can move straight on to the good stuff. This tutorial may get fairly long, and go into some detail about areas you aren't familiar with. Don't let this put you off. This isn't particularly hard. Just take breaks every now and then. Don't get stressed out. Drink fluids, relax your shoulders to relieve tension and focus on something else every 15 minutes (with your eyes, not your brain!).
(¯`·._.·[ Tools Needed ]·._.·´¯)
--------------------------------
- A memory scanner (see above)
- A debugger such as OllyDBG (unless you have a memory scanner that will do this - CE & MHS will)
- A pen & paper for notes perhaps, or a new text file
- Some patience & determination which unfortunately you can't download or buy (not yet!)
(¯`·._.·[ Background ]·._.·´¯)
------------------------------
From a gamehacker's perspective, DMA is the phenomenon of a game dynamically assigning it's variables to different spots in memory. I say dynamic because these chosen locations can change. Depending on the game, they could be reassigned extremely quickly or more slowly. Generally, loading a save game, a new map/level or restarting the game causes the game to choose new locations for it's data.
You can expect 99% of all modern games to utilize DMA for most (if not all) of it's main variables. So any variable you would think of hacking, be it Health, Magic, Gold, Attack Power, Spells, Bullets, you name it. So it is important to be able to beat this problem, and take your gamehacking one-step further. If you can beat this problem it means you can start creating hacks that will work all the time. And to do is not rocket-science, as you'll see shortly.
So, before we move on then, let's answer a question that has been raised many times. Why does a game use DMA, this crazy method of grabbing memory locations, as opposed to just having everything static? Is it done this way to stop gamehackers? Firstly, it is much more efficient for a game (or most programs for that matter) to only assign variables when it needs to. This is important in larger, modern games, because the memory used is quite big. In older games, from years past, it was common to find many games storing their variables statically. And as a result, this made gamehacking a lot easier. You could find the variables once and then be able to find it again in the same spot, no messing about.
Also, do not confuse DMA with 'Direct Memory Access'. Although DMA can stand for this, the DMA we are concerned with is completely different. The latter DMA, is the way in which certain pieces of hardware can access system memory without routing through the CPU. This is commonly seen in optical drives for example. Anyway, that's all you need to know. So let's move on now to do some actual practical work. Don't worry if you don't have the game target I am using, as the theory will still apply. So long as you can read, you're all set!
(¯`·._.·[ Finding some variables ]·._.·´¯)
------------------------------------------
So I will be using Cheat Engine to target some variables in Age of Empires 2: The Conquerors (v1.0c), but you can use your preferred combination. As I said before the theory still applies. I will be going after the resources in this game. I need to find food, wood, gold and stone. In this game, these values are stored in the FLOAT value type. Searching on default settings (4-byte/DWORD) won't bring up any results. But you would know that as a competent memory searcher! Just kidding, this game still catches people out with that. So basic stuff, if you don't find it one one data-type try another.
Time to grab food then. Search, lose or gain some of the resource, search again, until you narrow it down. I am left with 3 values that all change together. Only one of these is the 'real' one. Input a new value into each one at a time, or freeze them one at a time, until you find the right one. Delete the others to remove an element of confusion. Now this value is dynamic. So if we reload or restart the game, this will change. We need to find a way of creating a hack so we don't need to rescan every time. Before we proceed to the next step, I want you to know something else. Go ahead and find the other variables. If you don't have the game, it doesn't matter, just keep reading. I'll find wood, stone and gold. Here are my findings (your addresses will be different, because of DMA!):
0x0D1D1CE0 - Food
0x0D1D1CE4 - Wood
0x0D1D1CE8 - Stone
0x0D1D1CEC - Gold
What do you notice about these values? They are all sat next to each other. This is important to know, because no matter where the game decides to allocate the resources, these values will all be next to each other every single time. They aren't all seperate. So if you want to try this out, go ahead and restart the game, or load a new game. Find the values again from scratch, and see where they all reside. With this knowledge, all we would ever have to do is find one of them, and then calculate the rest. If we found food, then we could easily find wood, stone and gold, by adding 4, 8, C (hex). They are all in the same 'structure'.
Let me take another example of this concept. Suppose we had a space-sim game. We have a shield on the ship. The structure may look something like this:
Structure+0x00 - Current Shield Strength
Structure+0x04 - Max Shield Capacity
Structure+0x08 - Shield Regeneration Speed
Structure+0x0C - Shield Rebuild Time
Structure+0x10 - Shield Damage Resistance
Of course, this structure is simplified (and fictitious). In many games the variables may be spaced out further then just 4-bytes, but this principle is the same. The fact is, other related variables are nearby, and that is all we are concerned with. There tends to be many structures in a game too. Not everything is stored in one big structure. Each weapon may have it's own structure (this is usually the case in today's games). So one final example is for a first person shooter game. I'll use the gun example for this:
Structure+0x00 - Current Clip Ammo
Structure+0x04 - Max Clip Ammo
Structure+0x08 - Current Ammo Stock
Structure+0x0C - Max Ammo Stock
Structure+0x10 - Weapon Damage
Structure+0x14 - Fire-rate
Structure+0x18 - Reload Time
So you will already be able to see that, in theory, all you need to do to find some more 'unique' variables is to nail an easy one first, then look around that memory area. This is a very important and powerful technique, and it will serve you well in gamehacking. So now you know what DMA is, what it means to you as a reverser of games, and a brief introduction to structures. Now we will move on, and cover how to make a permanent hack out of the variable(s) we found.
(¯`·._.·[ Intercepting Gamecode & Basic NOP Hacks ]·._.·´¯)
-----------------------------------------------------------
Now we have our resource values, we need to perform a process called 'debugging'. This process will allow us to find gamecode which handles our resources. This gamecode which we will find, will always reside in the same place in memory. Put simply, gamecode is static, whereas our individual variables are allocated to memory through the process of DMA, thus dynamic. Finding this gamecode will allow us to permanently 'hack'the resources.
This next part will be generalized a bit. This is because you could be using one of several debuggers/memory searchers. The process is the same though, so just refer to your tool's documentation/website for more information. We have to place what is known as a 'breakpoint' on one of our addresses. I'll choose food. There are many types of breakpoint we can utilize when debugging, but explaining them all is beyond the scope of this tutorial. Suffice to say, the type we will be using is a memory breakpoint. There are two (or possibly three) ways we can implement it. On 'Write', on 'read' (or on access') are the types:
A 'write' breakpoint will find any gamecode which directly modifies/updates our variable.
A 'read' breakpoint will find any gamecode which retrieves the value of our variable.
An 'access' or 'Open' breakpoint (if applicable) will find anything which reads or writes to our variable.
So set a write breakpoint, and go back in game. Lose of gain some of the resource and the debugger will break. You will be able to see the line of gamecode which was responsible for the change. Depending on your debugger you may need to press a key combination to resume the game after breaking. In this case the game will appear to 'freeze' until resumed.
This is what I got after debugging food:
00457E95 - db 44 24 14 - fild dword ptr [esp+14]
00457E99 - d8 4c 24 10 - fmul dword ptr [esp+10]
00457E9D - d8 29 - fsubr dword ptr [ecx]
00457E9F - d9 19 - fstp dword ptr [ecx] <-- Game breaks here!
00457EA1 - 83 c0 06 - add eax,06
00457EA4 - 4a - dec edx
00457EA5 - 75 d0 - jne 00457e77
Without going overboard then, this code is storing our new value in [ecx]. The value ecx holds is our current resource address. So for me: 0D1D1CE0. FSTP is a floating point instruction (remember our resources are of the FLOAT data-type). The code above it is handling the deduction of the value and then finally storing back in memory. See the FSUBR instruction one line above were we break? 'SUB'. So it is subtracting. And from the 'F' before it, we can see that it is a FLOAT operation. If the resources were stored as an integer (so standard, 'real' numbers) then we would probably see a SUB instruction followed by a MOV instruction, which is essentially the same thing in basic terms.
Once you have intercepted the gamecode like the above, we can do all manner of things. This is the meat and potatoes of gamehacking. Once you have got to the actual code handling a variable you can manipulate it in many ways and do many cool things. You will progress in time to be able to do things like this, as your knowledge of ASM and gamehacking grows. Don't worry too much about it for now, if it all looks very alien and confusing.
All we need to know for this tutorial, is that this opcode 'fstp dword ptr [ecx]' at address '00457E9F' handles our food variable. And we know now that gamecode is always static, so we can now move on to doing something with this instruction to make a permanent hack. As always though, I want you to go ahead and repeat this process for another one of the game variables. Wood, stone or good. Find what opcode is responsible for that. What's that you say? It's the same?! Yes. So, the same bit of gamecode is handling all of our resources. This is a common occurence in games, especially modern ones. The game will make a distinction between which variable it is before it updates.
So, now I can hear you thinking. If we stop this opcode from updating, then in theory, this will freeze our current resources (all of them remember, because the code is handling them all). That sounds great, so let's give it a go. Again, this next bit will vary depending on what software you are using. But basically, you need to go to that memory location: 00457E9F and replace 'fstp dword ptr [ecx]' with a series of NOP's. A NOP means 'no-operation' and when the game encounters that instruction, it will just skip over it without doing anything. Now a NOP is one-byte long. A single 0x90 opcode. So we will need two in order to replace this instruction. Notice above, next to 'fstp dword ptr [ecx]' we have two bytes 'D9 19'. This is the code for the instruction. So we replace those with 90 90. Your software may actually give you the option to replace the code for you. Either way works.
Once this is done, go back in game and build something, buy something or anything else that would normally decrease/increase one of your resources. It's frozen isn't it! We have just created a resource hack for this game. There are of course a few downsides to the NOP method of beating DMA. I will detail these here. It is important to be aware of these. In more advanced hacks, involving 'code-injection' you will be able to better get around these issues. But all in due time. You will get there! So, the pro's and con's of this then, are:
Pro's
-----
- A very quick and simple hack (find the code, NOP it, done!)
- Extremely easy to make a trainer out of (as you are only changing two, or very few, bytes)
- The hack is permament (DMA is beaten, no messing about with changing variables now)
- The hack works for many resources (the opcode is shared, and so we froze all resources in one!)
Con's
-----
- NOP hacks only every stop/freeze a variable (they can't achieve anything more powerful)
- The game use that opcode for something you aren't aware of, and if it's missing it may crash)
- The instruction (from a write breakpoint) is most likely used for AI/CPU players too
Just bear those notes in mind. In another tutorial I may cover code-injection and ways around these problems. But for now, just make sure you understand the points in this tutorial. Play about with things, try other game variables, try other games entirely. Make sure you have a solid understanding of DMA and how to beat it by manipulating game opcodes. Once you know that, other concepts will come to you very easily.
(¯`·._.·[ Outtro ]·._.·´¯)
--------------------------
That brings us to the end of my tutorial on Dynamic Memory Allocation (DMA). I hope you all learnt something from this, as that was my aim of course! If anyone has any suggestions/improvements/corrections, please feel free to contact me, and i'll do my best to act on that information. If anyone wishes to share this tutorial or any part of it on another website/forum then please contact me first so I know were it is been used.
Good luck!
~Psych