Protecting Your Game Trainer - Tutorial

There are many tricks for other people to find out what bytes your trainer changes. The most common way is to use a trainer spy program, see my article on trainer spy programs, or a debugger such as OllyDbg.

Some people will take the information from your trainer, where and what bytes are being changed, and write a trainer claiming they found the cheats themselves. Another option now is to sell trainers, as it is becoming popular, so they can even profit from your work.

If you have a problem with others stealing your work then read on.

There are many various ways to try and protect your trainer, and the cheat data. Several are simple methods and some are more advanced. For more advanced coding methods I have include links to other tutorials, and you can find more online with a web search.

Although protection will help stop the majority of such lamers there is no real way to protect your trainer from anyone with some skills that want to find the data. The only way to truly protect your trainer is to keep it for yourself and not give it to anyone else.

Any software protection is at best a method to make it harder for someone to steal the data, in our case the trainer cheat data. It can often stop lamers, otherwise it will just slow others down a bit.

The easiest method to stop debuggers and trainer spy programs is to search for their windows. For example to check for the trainer spy program, Trainer Spy 2008, this is the code in FreeBASIC.
If FindWindow(NULL, "TSpy2008") > 0 Then
  'what to do
FindWindow Explained
The Windows API FindWindow works by searching for the ClassName and WindowName of all processes running.

My above example searched for a NULL ClassName, which means it ignores the ClassName, and finds any process with the WindowName of TSpy2008.

The following example searches for the ClassName of OLLYDBG found in any process - as the WindowName is NULL and ignored.
If FindWindow("OLLYDBG", NULL) > 0 Then
  'what to do
The last example searches for a process that has the ClassName of #32770 and the WindowName TRAINER SPY.
If FindWindow("#32770", "TRAINER SPY") > 0 Then
  'what to do
The FindWindow API will return the handle, a integer for example 3988 (decimal format), of a window that matches the search of the ClassName and WindowName.

If a process is matched with FindWindow the example codes above will execute any code you place on the line 'what to do.

Case-Sensitive & Titles
The API FindWindow is not case-sensitive of what to search for; however, the ClassName and WindowName must be complete.

For example using OllyDbg for the ClassName is the same as OLLYDBG. The same is true of the WindowName, Trainer spy is the same as TRAINER SPY.

The WindowName of TRAINER is not the same as TRAINER SPY. It must be exactly as the program uses/displayed. You must include any spaces, symbols, and text that is used.

False Positive Matches
If you use FindWindow to search only for a ClassName or WindowName, or sometimes both, it can find a process that is not the program you are looking for.

For example if the user has a document open that is called TSpy2008 the first code example will say it is a match and execute the anti-ts (anti-trainer spy) code.

In this instance the possibility is so low I wouldn't worry about it, especially as anyone with a document named TSpy2008 open while playing a game is likely the type of person you need the code for in the first place.

However if the ClassName or WindowName is so generic it matches several programs you should use both the ClassName and WindowName to avoid problems.

An example is the ClassName #32770 and WindowName of NULL. That would match several programs and should be avoided. If you run into anything that generic simply use the ClassName and WindowName.

Getting Window Text
The best way to get the information needed for the FindWindow API is the AutoIt tool called Au3Info.exe and Au3Info_x64.exe (depending on your OS).

You get the tool from downloading the free AutoIt scripting language. Here is a link to the AutoIt download page. You can get either the Full Installation, or the Self Extracting Archive - and if you are just wanting the Au3Info tool get the Self Extracting Archive to avoid installing and uninstalling everything else.

Of course you will need to run the various trainer spy and debugger programs yourself to find the text data with the Au3Info tool.

List Of ClassNames and WindowNames
For a list of the trainer spy/debugger/etc. window titles and classes to use in the FindWindow API the best option is to download the programs yourself.

A quicker way is to use the Game Trainer Studio (GTS) create a dummy trainer and view the MASM Assembly programming language file in the GTS MASM folder. The file is named trainer.asm and can be opened with any text editor.

You may also find a list of ClassNames and WindowNames online, do a Google search.

Another easy to use trick to keep people from tracking through your trainer - is the API IsDebuggerPresent.

The API checks if a debugger is currently running, and returns 0 if there is no debugger, otherwise returns a non-zero number. For example here is the code to use it in FreeBASIC.
If IsDebuggerPresent() > 0 Then
  'what to do
This will prevent a user from loading your trainer in OllyDbg or any other debugger, and from simply attaching a debugger to the trainer already running.

Putting It Together
Including several FindWindow functions together is easy enough, but it would be a better idea to include some addition code that will help stop them as well.
Prog_Check = 0
If IsDebuggerPresent() > 0 Then
  Prog_Check = 1
  'Actual code to preform if debug/spy found
ElseIf FindWindow(NULL, "TSpy2008") > 0 Then
  Prog_Check = 1
ElseIf FindWindow("#32770", "TRAINER SPY") > 0 Then
  Prog_Check = 1

If Prog_Check = 1 Then
  'Actual code to preform if debug/spy found
An easy way to use the FindWindow function is to update a variable. The above code sets the variable Prog_Check to 0 before checking for the programs.

If a program is found it changes the variable Prog_Check to 1. At the end of the program checks, it then compares the variable to 1, and if it is 1 then it calls the function to do whatever you want when a debugger or trainer spy is found.

Additional Code
For example if a debugger is found in the code above, the variable Prog_Check is set to 1 then the code from the debugger/spy function itself is inserted directly into the check. The code replaces the text 'Actual code to preform if debug/spy found.

This makes sure that the code for a debugger/spy is preformed, as it is a backup in-case the user patches your trainer to skip the function in the If Prog_Check = 1 Then code.

Other FindWindow checks also use the debugger/spy function code itself, and/or simply calls the function. The order of which they appear also are mixed up so the trainer code is not the same for a easy patch.

These calls and direct code of the debugger/spy function ensure the code is used.

One of the best points is to make sure the code is repetitive in various order and places in the checks. This will help to make it harder for someone to remove all the checks/code.

Avoid Descriptive Names
Do not user variables names, or function/sub names, that are easily identifiable for users to modify your trainer code.

For example do not use a variable called Debugger_FoundTrainer_Spy, Lamer, etc. Or functions called Kill-Cheats, Stop_Trainer, etc.

It is better to use variable and function names that can blend in with your trainer and not look out of place. As a blatantly obvious name will have the user modifying the trainer even easier.

Program Loop
Be sure to include the code to check for debuggers/trainer spy programs/etc. in the main program loop of your trainer.

The user can start the program at anytime and if you only check for them when the trainer is first loaded, your trainer will not discover them in many cases.

It is also a good idea to have your trainer recheck after a time delay - that way your trainer can function as fast as possible. A delay of 500 milliseconds to 2000 milliseconds will be fine (Half second to two seconds).

Actions To Preform
With the code above you will find debuggers, trainer spy programs, and everything else you want to search for. The next step is to figure out what you want to do when they are found.

The common action is to simply close the trainer to prevent the users from getting the cheat information; however, there are other actions you can preform.

Random Memory Bytes
Perhaps one of the best actions is to write random bytes at random places in the game memory. Here is a example in FreeBASIC using the t2EservoMemory functions or library.
Dim GNumber As Integer
GNumber = Int(Rnd * 6) + 1
Select Case As Const GNumber
  Case 1
    _MemoryWrite(Int(Rnd * 999999), hWnd, Int(Rnd * 127), "Byte")
  Case 2
    _MemoryWrite(Int(Rnd * 999999), hWnd, Int(Rnd * 32767), "2Bytes")
  Case 4
    _MemoryWrite(Int(Rnd * 999999), hWnd, Int(Rnd * 999999), "8Bytes")
  Case 5
    _MemoryWrite(Int(Rnd * 999999), hWnd, Rnd * 999999, "Float")
  Case 6
    _MemoryWrite(Int(Rnd * 999999), hWnd, Rnd * 999999, "Double")
  Case Else
    _MemoryWrite(Int(Rnd * 999999), hWnd, Int(Rnd * 999999), "4Bytes")
End Select
The above code example will randomly select a number one thru six, which is used to select the byte type (Byte, 2Bytes, 8Bytes, Float, etc.).

A random position in the game memory is selected, and then a random integer is written to the game address.

Writing random bytes is a popular method to fool users looking to steal your cheats. Just place the above code in your trainer so that it is used when a cheat is actually on and a debugger/trainer spy/etc. are found.

As the code is just an example, I highly recommend you change the code to randomly write to the game memory in safe (empty) areas.

In it's current form it will likely crash the game as the memory locations that are written to are random; however, you may prefer it crashes the game as a protection action.

Other Actions
Besides writing random bytes to the game memory, other actions include -
  • Close the trainer
  • Display messages
  • Cause game errors
  • Delete your trainer
  • Close the debugger or trainer spy itself
Of course you could do several actions, or better yet do actions that you think of. The most recommended actions by trainer authors (by articles found online) is simply to close your trainer or to write random byes to the game.

Several of the other actions listed are themselves considered bad ideas, perhaps worse than the lamer trying to steal your game cheats. Do what you feel are adequate actions.

Memory Addresses
Besides using debuggers and trainer spy programs a often simple approach to find your cheat data is to simply look through your trainer with a hex editor for memory addresses.

Even if you use a EXE packer on your trainer users can usually unpack your trainer EXE, or simply view it once it has unpacked itself in memory. So the tips below will still apply to your trainer.

Split Addresses
A easy way to hide your cheat addresses from prying eyes is to split the address into multiple variables. For example if your cheat address is 0B262610 then do this -
address1 = 0B2
address2 = 62
address3 = 610

'trainer code

cheat = address1 & address2 & address3
Then when you are ready to use it simply recombine the variables address1 & address2 & address3. Preferably recombine only when your trainer needs the address.

Of course switching the order of the address, creating dummy variables, and combing several different addresses, will help hide them better (even if the user knows what is going on).

Math Addresses
Another easy way to hide your addresses is to perform some math on your address variable so it uses the correct address.

For example a variable has the number 187048438, when your trainer needs the address add 1050 to the variable, which gives the correct address of 187049488 (0B262610 HEX).
address = 187048438

'trainer code

cheat = address + 1050
This has the added bonus that the lamer will think they discovered your cheat addresses to only find out after much testing they found nothing.

To further hide your addresses preform different math to different addresses. This will help keep the user guessing longer. Mix it up by using any typical math such as addition, subtraction, multiplying, and division.

Of course if you know how to use advanced math or programming such as shifting bits left or right, xor, other bitwise operators, or anything else - use it too.

Using multiple math expressions on the same cheat address may also to help as well. For example -
address = 93524694

'trainer code

cheat = address * 2
cheat = cheat + 100

'Or simplified as
cheat = (address * 2) + 100

Writing Cheats
One other easy trick is when you are writing the cheats to the game memory. For example if your cheat is 4 bytes long - instead of writing to the memory using 4 bytes split the cheat up using two 2 byte memory writes.

This example is in FreeBASIC using the t2EservoMemory functions or library.
_MemoryWrite(0B262610), hWnd, &H6300, "2Bytes")
_MemoryWrite(0B262612), hWnd, &H0000, "2Bytes")
It is writing the cheat in HEX format, in FreeBASIC HEX is wrote as &H followed by the HEX numbers. The number written is 99 decimal (63 HEX).

The example could have also used a 2 byte memory write along with two single byte memory writes, or four single byte memory writes.

Writing your cheats to memory this way will simply make it harder for the lamer to understand what your cheats are. If you use some programming strategy tricks from above this will further help hide your cheat data and further frustrate a would be cheat ripper.

EXE Packers - Protectors
Another approach is to use another program to protect your trainer software. There are many different programs that claim to be able to protect software from many different threats and users.

Generally speaking most software EXE protectors will compress your trainer, encrypt the data, and write protection to the trainer file itself - creating a new EXE.

The generated EXE file is the one you give to others and includes the protection. When the trainer EXE is ran it is unpacked to memory and ran normally, with various protection functions waiting to be used.

Overall any EXE protector program fails as it is targeted by many people, and there are often scripts for debuggers (such as OllyDbg) or tools made to remove the protection often at a click of a button.

Nearly all such program protectors are shareware and require a large registration fee (hundreds or thousands of dollars) - as they are used by other shareware authors to make money.

Protection programs can however provide basic protection from the lamers who would steal your cheat data, and sometimes can be even more effective than any of the tricks I listed. The best attribute of using such a program is that you do not have to waste time programming the protection code yourself - and if they work why not use them.

If you plan to use a EXE protector ensure that it is protecting your cheat data from trainer spy programs, as most will simply protect your trainer from debuggers.

While no protection is truly safe, using the above examples and tricks will stop many lamers, or perhaps make them so mad trying to rip your cheat data they give-up.

As I've mentioned the protection methods I have listed are easy to use, and easy to bypass if a lamer knows what they are doing.

I have included some more advanced resource links below that you can include in your trainers; however, even those can be bypassed as well. The ultimate question is how much time do you want to devote trying to protect your trainer versus making other trainers or playing games?

The quest to protect your trainers is a losing battle and many trainer authors do not even waste time trying to protect their trainers.

I myself include some basic tricks in my trainers but I waste very little time doing it as I know it is ultimately pointless.

Additional Resources
This is a list of additonal tutorials and articles I found about protecting trainers or programs in general. You can find even more online searching for anti-debugging or anti-trainer spy.


Post a Comment