An alternative method to Code-Caves
A much safer and better way to do injections
Code-caves are the central part of an injection even if it’s a simple one, you need to have some empty space to write your own code. Well the problem with code-caves is you can’t be 100% sure they will be available on every pc, if you're not too careful and don’t know much about the sections of a PE files, you can choose a place as code-cave which isn't guaranteed to be empty on other PC's or even on the same pc. It has happened to me a lot and I think its part of reason we have some non-working/faulty trainers. There is another problem, using cracked games, you can choose an empty place in a section that has been added by the crack team for its use or actually the empty space is a result of sections being moved so it probably won’t be present in an unmodified/original retail version of the game. So your trainer won’t work for a person using original/cracked game by some other team.
And in some games, especially today's code-shifting ones, you can seldom find an empty place or a place which is safe enough for injection, because most of the times, in code-shifting games, the main exe is barely just a few KB's acting just as launcher while all the code resides inside DLL.
There are ways around that though for example, using your dll as the code-cave source, I’ve not seen any documentation on this though. The method I am telling you about in this tutorial though is very efficient and 100% safe.
We will be allocating memory inside the game and using that allocated memory as our code-cave. The advantage is that each time our trainer is run; it will allocate memory so we won’t depend upon the game for the space. Instead we will be making space for ourselves. The way we do this is by using an API called VirtualAllocEx(); Its parameters are as follows:
HANDLE hProcess, // process within which to allocate memory
LPVOID lpAddress, // desired starting address of allocation
DWORD dwSize, // size, in bytes, of region to allocate
DWORD flAllocationType, // type of allocation
DWORD flProtect // type of access protection
Its pretty straight-forward, the first parameter is handle to process which we can grab by using OpenProcess() API. The next param is starting address. Since we don't care where it will be allocated, we will let windows choose an address itself by setting it to zero. Next is allocation size i.e. the size of our allocated memory or code-cave. Next param is type of allocation and finally the type of access we want over the allocated memory is defined in last param. Set it to READ/WRITE/EXECUTE so we can do all the operations necessary.
Upon execution of this API, we get the address of allocated memory as the function return value. We can then use that address however we like it and it will always be of the size we desire plus it will always be empty and safe to use! Best of all, you can do error-checking to see if the memory is allocated or NOT. If it's not, the return value returned by VirtualAllocEx() would be NULL. So you can warn the user that there's no memory for injection and hopefully save yourself from the curse you'd get, had the trainer crashed the user's game and ****ed up his saves.
You can easily write to the allocated memory just as you would normally to a cave inside a game i.e. by writing the Opcodes/Bytes using WriteProcessMemory().
Important Note: Do NOT use VirtualFreeEx() as a clean up measure during the execution of trainer or even upon exiting the trainer since that will wipe out the space we reserved for code-cave and cause the game to crash as game-code will still be jumping to the now unavailable allocated memory. However you can do it that when the trainer exits, you disable the options, return the game code to normal and then use VirtualFreeEx() to clean/wipe out the space we reserved for Code-Cave. However, that will need the user to keep running your trainer in background for the options to remain enabled, but that’s really a big annoyance for user, isn't it?
Don't worry, the allocated space doesn't take up much of game's resources since we barely need more than 200 or even 100 bytes for complex injections. And that is nothing in today's several GB's RAM memory.