Theories
and methods of Code-caves
(By
Faldo)
Intro:
Since many
have read my tutorial on basic memory hacking and got stuck on the
creation of code-caves, I’ve decided to make a short follow-up on some code-cave
techniques where I’ll explain the WHYs and the HOWs.
Note: In
order to fully understand this tutorial it is suggested that you read my
previous tutorial on basic memory hacking.
Index:
1. In theory
1.1
RAM, the temporary buffer
1.2
Code-caves in general
2. The
methods
2.1
Tools:
2.2 Changing
values
2.2.1
Changing values theory
2.2.2
Changing values method
3. F.A.Q.
3.1 The hack crashes the game
3.2 The hack has no effect
3.3 PB detects my hack
4. Other tutorials
by Faldo
_______________________________________________________________
1. In theory
1.1 RAM, the
temporary buffer
Before
you’ll be able to understand code-caves you’ll need to understand how your RAM
(Random Access Memory) works.
Everything
running on a computer (even the operative system) uses your RAM as a temporary
buffer to store information. This information is then either forwarded to be
stored on a drive unit (hard drive, CD/DVD-burner, floppy…), or it will remain
in the RAM as long as the process is running.
Whenever a
program runs, it either uses your hardware memory modules or a page-file
created by windows (virtual memory). In any case, the program
"injects" code into the memory to be processed (read from and written
to) since the program itself is already compiled* and cannot change.
The manner
of which the program reads and writes code in the memory is fairly simple.
Think of it as a list where numbers (hexadecimal addresses) defines the
location of the rows. When you start a program, it injects (writes) code into a
certain number of rows and then executes one predefined row called “entry
point”. Once the entry point is executed, the program reads the following
addresses in chronicle order.
*Compiled: A
process where sourcecode is gathered by a compiler
program and produces an executable file (.exe in windows).
1.2
Code-caves in general
A code-cave
is a name designated to a method where you assemble (write to) an unused portion
of your memory in order to change the behavior of the original operations.
A code-cave
normally consists of 2 parts:
- The Cave,
located at a free portion of your memory. The cave itself consists of a copy of
the original code, the changes you wish to make to the original code and a jump
back to the original code.
- The
Jump-gate, located in the original code. You can compare a jump-gate with a
crossroad. Instead of letting traffic (dataflow) use the highway, you put up a
roadblock (the jump-gate), diverting traffic to a road you control (whatever
changes you wish).
2. The
methods
2.1 Tools
To be able
to use and follow the methods of this tutorial you will need no knowledge of any
programming language, however, if you know the basics of ASM you will probably
understand it the first time you read it.
The only
tool you will need is Ollydbg 1.10 (search for it on google).
2.2 Changing values
2.2.1
Changing values theory
There are
many reasons why you might need a code-cave. In the method below I’ve chosen to
explain how to change a value in your memory and why you need a code-cave to
accomplish this.
The effects
you could get by changing values are almost unlimited since most functions in a
program rely on values. Examples: money, health, levels, gun damage etc.
I will use
Need For Speed - Underground 2 as example in this
tutorial and explain how to change the value of money.
Since this
tutorial will only cover code-caves, you should already know how to gather the
right addresses in T-search, but I will give you a little reminder:
First of all
you need to use T-search to get the dynamic address holding the value of money.
This is done in the same way it was explained in my tutorial on basic memory
hacking when looking for the dynamic team address or tag address.
Then you
need to monitor the dynamic money address using Autohack in T-search.
You also need to activate the part of the code handling the money value. You could
do this by running over a “bonus icon” or buying something from a shop.
After some
monitoring, T-Search shows these static addresses:

Now we need
to figure out where the value of money is kept so that we can change it.
The best way
to find the offset (in between brackets) in which the value is stored, is to
look for similarities within the code. In this case the common offset is easy
to find. [0x861E74] is the offset storing the value of money.
If we take
the first address as an example (537BB8), the operation tells the game to read
the value at 0x861E74 and move (MOV) it into ECX.
Let me break that line down
even more for you:
ECX is a GPR (General Purpose Register),
a place where information (a hexadecimal value) can be stored temporary. In the
beginning of a code section, the registers are set to a specific value and then
that value gets changed throughout the rest of the code as other operations use
the registers to change that value.
The offset [0x861E74]
is also a kind of variable; it can be either a register or an address.
In order to
tell the game to change the value in the offset to a value we have chosen, we
need to add a line of code into the memory. This is where the code-cave comes
in handy. If we were to add the line of code directly into the original code,
we would have to overwrite some code lines and the game could easily crash.
Finally, you
need to know WHERE to add this line of code. Since only the creator of the game
knows exactly how the game works, our task is to figure it out, by trying.
You can use
many of the addresses above to attach your line of code to. I found one in
particular that is quite suitable since it gets read pretty often: 537C64.
2.2.2
Changing values method
The
following steps will show how to add a line of code without destroying the
original:
From the
list, select the program you want to make a code-cave in and click Attach.

WARNING:
When you attach a program, Ollydbg will automatically pause
the process once it is scanned (if you haven’t set Ollydbg not to). Therefore
you need to unpause it quickly otherwise the game
might crash:


Let’s use the address 00537C64 as an example and call it the “Money address”. Enter it and click OK.

Ollydbg will
go to the address you entered and select it.

This is the
line of code accessing the offset [861E74] and MOVes
the value into EAX:
MOV EAX,DWORD PTR
DS:[861E74]
To change
the value of [861E74], the next line of code should look like this:
MOV DWORD PTR DS:[861E74],
1388
This MOVes the value of 1388 into [861E74],
lets call this line the “value changer”.
1388
is a hexadecimal number of 5000. So when add this line to your code, your money
will change to 5000.
All this is ASM
codes; you don’t need to understand it completely, as long as you understand
what it’s doing.

As you can
see, when adding this line, we destroyed 4 others and the game
will most likely crash. To solve this, we need to create a code-cave.


NOTE: The money
address should not be the first or the last address in the copied range.



The copied
lines will look like this:

So you will
need to make a jump back to the original code so that the dataflow can
continue.
If you take
a look at step 8. above, you will see an address
that reads:
00537C70
E8 FBFBFFFF
CALL speed2.00537870
The code at
this line is the same as the last line in our code-cave. So I can safely
destroy the copied line and create a jump out of it, like this:

There we
are… we’ve now finished our code-cave, only one little thing left to do: The
Jump-gate.

As you can
see, the jump-gate destroys a few lines of code, but since that code is already
recreated in the cave, the game won’t crash.
3. F.A.Q.
This F.A.Q. of this tutorial is going to be an ongoing project
where new questions and answers are entered as new problems occur.
Last
updated:
3.1 The hack
crashes the game
This is the
chronological order in which the above code-cave is read:
Starting at
address 00537C5A ending at address 00537C78:
00537C5A
E8
A13F2200
CALL speed2.0075BC00
00537C5F
8B4E
38
MOV ECX,DWORD
PTR DS:[ESI+38]
00537C62
E9
FDB22400
JMP speed2.00782F64
00782F64
8907
MOV DWORD PTR DS:[EDI],EAX
00782F66
A1
741E8600
MOV
EAX,DWORD PTR DS:[861E74]
00782F6B
C705 741E8600 88130000 MOV DWORD
PTR DS:[861E74],1388
00782F75
50
PUSH EAX
00782F76
68
44F77800
PUSH
speed2.0078F744
00782F7B
51
PUSH ECX
00782F7C
E9
EF4CDBFF
JMP speed2.00537C70
00537C70
E8 FBFBFFFF
CALL speed2.00537870
00537C75
83C4 18
ADD ESP,18
00537C78
5F
POP EDI
Looking at this will expose errors like repeated an ASM code or skipping of a line. The red text is the most important.
This
error can also be fixed by following the method below, solving reference
errors.
3.2 The hack has no effect
Let’s say
you made a code-cave from address 00537C62 to address 00537C70.

That means
your jump-gate is located at 00537C62. That also means that you led the
dataflow in another direction at address 00537C62.
Now imagine
that another address somewhere in the vicinity jumps to address 00537C64.
If that is the case, that jump will “override” your jump to the code-cave,
causing your code-cave never to be read. In other words, the original code is
executed instead of your code-cave and the hack will never be active.
To check if
there are any jumps targeting the portion of code you wish to copy, select the
lines you want to copy, right-click and chose Find references to à Selected block.

The result:

As you can
see, there are 2 addresses containing jumps to the code we need to copy. Let’s
call them “reference jumps”.
To solve
this, you need to assemble the reference jumps and redirect them to your
code-cave addresses corresponding to the original ones.
In this
case, the two addresses containing jumps are targeting addresses right outside
our code-cave, so no adjustments need to be done.
3.3 PB detects my hack
Answer:
To answer this question I need to explain how OPcodes work.
You need to keep
in mind that every address contains 1 pair of opcodes.
Lets
take an example:
00537C62
E9
FDB22400
JMP speed2.00782F64
E9
is the opcode used by the address 00537C62.
You might
think that all the opcodes (E9 FDB22400) are stored in the address 00537C62,
but that is not the case.
These are
the locations of every pair of opcode:
00537C62 E9
00537C63 FD
00537C64 B2
00537C65 24
00537C66 00
So, now you
might realize that if PB scans a few addresses after your jump-gate, you run a
risk having the end of your jump-gate inside the scan-range, even though the
first address of your jump-gate is outside.
4. Other
tutorials by Faldo
-Theories
and methods of memory hacking
Many thanx
to:
Captain
Cox, Max Powers and MPC.de