Codecaving tutorial
Codecaving is, basically, to put a jump before a target offset that needs to be patched to an empty or unimportant zone in memory, put your modified code there, and then jump back under the target address.
What's the point of doing this?
Codecaving allows you to get the effects of modifying an offset that could be blacklisted by poor anti-cheat software (ex: Warden in Warcraft 3), since you never modify it directly.
You could therefore take the offsets of some hack and make them almost "undetectable" (considering you keep that hack private or simply for yourself).
Pseudo example:
Before the code cave and patching:
- 1 Address 1 and its content
2 Target
3 Address 3 and its content
4 Unimportant stuff
5 Unimportant stuff
6 Unimportant stuff
(Unimportant stuff is mostly 00's and INT3's)
After the Code cave and patching:
- 1 JUMP to address 4
2 Target
3 Address 3 and its content
4 Address 1's content
5 Patched target
6 JUMP back to address 3
As you can see, the target code is still being patched, but not at Address 5 instead of Address 2.
Let's do a codecave now!
Things you will need:
- An offset to patch
- A real-time debugger (OllyDBG)
For this example, we are going to use some stupid offset I found while offset-hunting in Warcraft 3:
6F39B991 BA 08000000 MOV EDX,8
to
6F39B991 BA 00000000 MOV EDX,0
Effect: Removes ground textures (ground becomes all black).
Let's analyze the bunch of code over that address. Open up Warcraft 3 and get in a custom game. Then start OllyDBG and attach war3.exe, then right click -> go to -> 6F39B991 or CTRL+G -> 6F39B991 (you may need to do this twice to get to the address).
We must first find some empty memory zone in which we will input our code.
By scrolling down to the end of Game.dll, I found out this neat little place:
6F85BE24 0000 ADD BYTE PTR DS:[EAX],AL
6F85BE26 0000 ADD BYTE PTR DS:[EAX],AL
6F85BE28 0000 ADD BYTE PTR DS:[EAX],AL
6F85BE2A 0000 ADD BYTE PTR DS:[EAX],AL
6F85BE2C 0000 ADD BYTE PTR DS:[EAX],AL
6F85BE2E 0000 ADD BYTE PTR DS:[EAX],AL
6F85BE30 0000 ADD BYTE PTR DS:[EAX],AL
6F85BE32 0000 ADD BYTE PTR DS:[EAX],AL
6F85BE34 0000 ADD BYTE PTR DS:[EAX],AL
6F85BE36 0000 ADD BYTE PTR DS:[EAX],AL
6F85BE38 0000 ADD BYTE PTR DS:[EAX],AL
6F85BE3A 0000 ADD BYTE PTR DS:[EAX],AL
6F85BE3C 0000 ADD BYTE PTR DS:[EAX],AL
6F85BE3E 0000 ADD BYTE PTR DS:[EAX],AL
6F85BE40 0000 ADD BYTE PTR DS:[EAX],AL
6F85BE42 0000 ADD BYTE PTR DS:[EAX],AL
etc.
Then let'a go back to our target address, 6F39B991, and analyse what's around it.
6F39B974 8D4C24 24 LEA ECX,DWORD PTR SS:[ESP+24]
6F39B978 E8 E3A8C7FF CALL Game.6F016260
=> 6F39B97D E8 1E50C7FF CALL Game.6F0109A0
6F39B982 39AE 30030000 CMP DWORD PTR DS],EBP
6F39B988 74 07 JE SHORT Game.6F39B991
6F39B98A 8BCE MOV ECX,ESI
6F39B98C E8 4FEDFFFF CALL Game.6F39A6E0
6F39B991 BA 08000000 MOV EDX,8 // Target offset
6F39B996 8D4C24 5C LEA ECX,DWORD PTR SS:[ESP+5C] // Return address
We will use a normal jump to get there.
6F39B97D seems like a good place to start our jump since it is 5 bytes long. Take that address's info down in notepad or w/e.
6F39B97D E8 1E50C7FF CALL Game.6F0109A0
PAUSE OllyDBG and change this line:
6F39B97D E8 1E50C7FF CALL Game.6F0109A0
to
6F39B97D E9 A2044C00 JMP Game.6F85BE24
To do this, Select then right click the address -> Assemble or simply press spacebar then type: jmp 6F85BE24 and press enter (don't fill with NOP's)
Now press enter on that address to go the empty zone.
On 6F85BE24, we will place the info of the address we took down in note. It was
CALL Game.6F0109A0
Like we did just a minute ago, we will right click -> assemble.
Type call 6F0109A0 and press enter.
Now that we have added this line, we need to also add everything else that was between it and our target address:
6F39B982 39AE 30030000 CMP DWORD PTR DS:[ESI+330],EBP
6F39B988 74 07 JE SHORT Game.6F39B991
6F39B98A 8BCE MOV ECX,ESI
6F39B98C E8 4FEDFFFF CALL Game.6F39A6E0
6F39B991 BA 08000000 MOV EDX,8 // target address
So, just like we did before, click on the line below the one we modified and assemble this:
Then, on the next line, assemble this twice:
The reason we are putting 2 NOP's here instead of JE SHORT 6F39B991 is because 6F39B991 is way out of range for the short jump.
Then, on the next line:
Then, on the next line:
Now let's modify MOV EDX,8 to MOV EDX,0 to get the black floor effect in-game.
Assemble at 6F85BE38:
Alright, we are almost done! What we need to do now is jump back to 6F39B996, the address that was just below our target.
Assemble this on the next line:
Your memory should now look like this:
Your jump:
Your code cave:
Alright, now we need to jump to the memory zone we just made.
Assemble this at:
You are now ready to press on PLAY in OllyDBG. Your floor should be black.
© Tyrano