Page 1 of 1

How to unpack Cheat Engine Trainer

Posted: Sat Aug 03, 2019 5:20 am
by _/.CoffeeWine.\_
Original Author:
Posted by: Vladimir Mephisto
Special for
Jul 26, 2012

Let's see what we have in our resources:

We see two interesting resources: ARCHIVE, and DECOMPRESSOR. You can immediately assume from the names that the Archive contains compressed data (perhaps: the Music, which plays; the executor, which starts, etc.), and the decompressor unpacks this archive.

Well, you need to find out how the decompressor works, what parameters to pass to it, and where everything will be unpacked.


We put our trainer in Olly Debugger and set a breakpoint on the call to CreateProcessA (by the way, we have one there there is one). We start debugging.

We see that we were pushed into the stack with parameters for calling CreateProcessA. We look at them carefully:

Code: Select all

CPU Stack
Address   Value      Comments
0012F248  ╓0012F3F8  ; ║ApplicationName = "C:\WINDOWS\Temp\cetrainers\CET153C.tmp\213.EXE"
[B]0012F24C  ║0012FD1C  ; ║CommandLine = ""C:\WINDOWS\Temp\cetrainers\CET153C.tmp\213.EXE" -ORIGIN:"D:\Install\cracking\projects\21\""[/B]
0012F250  ║00000000  ; ║pProcessSecurity = NULL
0012F254  ║00000000  ; ║pThreadSecurity = NULL
0012F258  ║00000000  ; ║InheritHandles = FALSE
0012F25C  ║00000000  ; ║CreationFlags = 0
0012F260  ║00000000  ; ║pEnvironment = NULL
[B]0012F264  ║0012F2F4  ; ║CurrentDirectory = "C:\WINDOWS\Temp\cetrainers\CET153C.tmp"[/B]
0012F268  ║0012F2B0  ; ║pStartupInfo = 0012F2B0 -> STARTUPINFOA {Size=68., Reserved1=NULL, Desktop=NULL, Title=NULL, X=0, Y=0, Width=0, Height=0, XCountChars=0, YCountChars=0, FillAttribute=0, Flags=0, ShowWindow=SW_HIDE, Reserved2=0, Reserved3=NULL, hStdInput=NULL, hStdOutput=
0012F26C  ║0012F2A0  ; └pProcessInformation = 0012F2A0 -> PROCESS_INFORMATION {hProcess=NULL, hThread=NULL, ProcessID=0, ThreadID=0}
In bold, highlighted the lines we need.

Code: Select all

CurrentDirectory = "CurrentDirectory = "C:\WINDOWS\Temp\cetrainers\CET153C.tmp"
This is the directory into which the wrapper trainer unpacks its contents - Temporary folder. We look at what we have there. And there we have two files:

Code: Select all

In size and content it is the same Decompressor and Archive. Now let's see what parameters are passed to the decompressor:

Code: Select all

CommandLine = ""C:\WINDOWS\Temp\cetrainers\CET153C.tmp\213.EXE" -ORIGIN:"D:\Install\cracking\projects\21\""

As you can see, we have only one parameter: the working directory, but, I think, you can do without it.

We try to execute the CreateProcessA call further and see what happens next in the temporary folder. Press the F8 key in the debugger (execute one command without entering it). We see that the extracted folder was created in the temporary directory, into which the contents of the Archive were then extracted:

Code: Select all

extracted\CET_TRAINER.CETRAINER (после успешного запуска трейнера удаляется)
Let's examine the extracted files:
win32 \ dbghelp.dll - from the file name it is clear that this is a standard debug library that is used by the same Olly Debugger.
213.EXE - in the file properties it says that this is Cheat Engine Certainly, it is he who launches a real trainer.
CET_TRAINER.CETRAINER - Google tells us that this is the trainer. True, it also says that when you open this file in notepad, we should see an XML-like document, but we have displayed a complete rubbish. So the file is encrypted.
defines.lua is some kind of LUA script with definitions. Upon examination, nothing interesting was found.
lua5.1-32.dll is a library for executing a LUA script.
xmplayer.exe - the name implies that it plays Mouzon. But we are not interested in this file.

Now let's see how the trainer is executed.


For this task, we load the Decompressor into Olly Debugger (before closing the wrapper trainer). And let's see what it launches and how. And once it starts, then we need to intercept the call of the same CreateProcessA.

We look that in a stack:

Code: Select all

CPU Stack
Address   Value      Comments
0143FE88  ╓00000000  ; ║ApplicationName = NULL
[B]0143FE8C  ║000D5628  ; ║CommandLine = "C:\WINDOWS\Temp\cetrainers\CET153C.tmp\extracted\213.EXE "C:\WINDOWS\Temp\cetrainers\CET153C.tmp\extracted\CET_TRAINER.CETRAINER""[/B]
0143FE90  ║00000000  ; ║pProcessSecurity = NULL
0143FE94  ║00000000  ; ║pThreadSecurity = NULL
0143FE98  ║00000000  ; ║InheritHandles = FALSE
0143FE9C  ║00000000  ; ║CreationFlags = 0
0143FEA0  ║00000000  ; ║pEnvironment = NULL
0143FEA4  ║0005D1F0  ; ║CurrentDirectory = "C:\WINDOWS\Temp\cetrainers\CET153C.tmp\extracted\"
0143FEA8  ║0143FF3C  ; ║pStartupInfo = 0143FF3C -> STARTUPINFOA {Size=68., Reserved1=NULL, Desktop=NULL, Title=NULL, X=0, Y=0, Width=0, Height=0, XCountChars=0, YCountChars=0, FillAttribute=0, Flags=0, ShowWindow=SW_HIDE, Reserved2=0, Reserved3=NULL, hStdInput=NULL, hStdOutput=
0143FEAC  ║0143FF2C  ; └pProcessInformation = 0143FF2C -> PROCESS_INFORMATION {hProcess=NULL, hThread=NULL, ProcessID=0, ThreadID=0}
We see that the extracted EXE-shnik receives the path to the encrypted trainer as a parameter (well, and obviously, it starts it right away, decrypting it before that).


Opens the debugger and click File-> Open. In the window that appears, select the Exe cheat engine, and in the Arguments line, write the path to CET_TRAINER.CETRAINER. Click Open.

Now you need to put a breakpoint on the opening of the trainer file: the CreateFileA function. We start debugging (F9). The debugger interrupted on opening the file. Now our task is to wander a little step by step through the code until we see something interesting (for example, the decrypted text of an XML file). We will “walk” with the F8 key (without going into the procedure) - what if we are lucky)

The first thing we come across:

Code: Select all

CPU Disasm
Address   Hex dump                     Command                                               Comments
004D2D49  ║·  8B45 90                  MOV     EAX, DWORD PTR SS:[LOCAL.28]
[B]004D2D4C  ║·  BA F8668100              MOV     EDX, OFFSET 008166F8                          ; ASCII "<?XML"[/B]
004D2D51  ║·  E8 DA5AF3FF              CALL    00408830                                      ; [213.00408830
But when viewed in the dump of the address, which is located in EAX, we will not see the beginning of "<? XML", so let’s go further. At one of the next steps, we will again have an interrupt on CreateFileA, but we are no longer interested in it, so we just move on. Do not be afraid to miss something - not to notice what we are looking for is impossible) Suddenly:

Code: Select all

CPU Disasm
Address   Hex dump                     Command                                               Comments
[B]004D4A8A  ║·  8B55 DC                  MOV     EDX, DWORD PTR SS:[LOCAL.9]                   ; ASCII "<?xml version="1.0" encoding="utf-8"?>
<CheatTable CheatEngineTableVersion="14">
004D4A8D  ║·  8B4D E8                  MOV     ECX, DWORD PTR SS:[LOCAL.6]
004D4A90  ║·  8B45 F8                  MOV     EAX, DWORD PTR SS:[LOCAL.2]
004D4A93  ║·  8B5D F8                  MOV     EBX, DWORD PTR SS:[LOCAL.2]
004D4A96  ║·  8B1B                     MOV     EBX, DWORD PTR DS:[EBX]
004D4A98  ║·  FF93 84000000            CALL    NEAR DWORD PTR DS:[EBX+84]
Wow! We see that in EDX a pointer to the beginning of the XML file is passed. This is already interesting. Let the first line execute, and then go to this address in the dump (right-click on the value in the register EDX-> Follow in Dump).

Now we do this:
1.Right click and select Binary-> Copy All;
2.Open the hex editor, and paste in it what was copied;
3.We clean the resulting file from garbage (because we know that the beginning of the file should contain "<? Xml", and the end: "</CheatTable>");
4.Save it with the * .CT extension, the standard extension for Cheat Engine projects.


We close everything, download the normal Cheat Engine distribution, install it, and open our project in it. And there already edit as much as you like)