📜 ⬆️ ⬇️

Steam CEG from Valve and what it eats. Everything is complicated - just

image

Good hour, % USERNAME% ! In my previous article, " Steam CEG from Valve and what it eats. Introduction, " only an abstract understanding and working principles of the CEG technology were given. This article will be on the absolute minimum theory and the overwhelming majority of the practice. Today and now we will consider whether it is possible to “wean” the coveted executable file from this protection.

Step I. The choice of the "victim" and its analysis

The presence of a CEG, and any version, can be easily detected by the presence in the header of the .version section file and the first four bytes in it ( 78 56 34 12 ):
')
image

Knowing this information knowingly and having slightly searched in the Steam library, my choice fell on HD reissue of the legendary Age of Mythology with the “ Extended Edition ” prefix. After successful completion of the download, after waiting a couple of seconds until CEG signs the executable file, open it in our debugger, in my case in x64dbg . Oh yeah, it’s worth noting that Comrade CEG uses some anti-debugging tools, so we’ll use the ScyllaHide plugin with the following settings:

image

So, opening the executable file, we see that it is not covered by third-party packers, so we can safely move on to the second step.

Step II. Debriefing

Absolutely in any version of CEG there is one function that produces a general calculation of the desired values. It looks like this:

image

Knowing this, set bryak either on instructions.
mov eax, dword ptr ds:[ecx]
,
either on the following:
mov dword ptr ds:[ecx],eax
:

image

Press " Run " ( F9 ) and see that the breakpoint worked! “And what did it give us?” - you ask, I answer: the exact value of EAX in the buffer. This can be seen by looking in the right column opposite the " CPU " tab:

image

As can be seen from the image, we obtained the value EDB88320 . Copy it to the clipboard and move on. Press " Step Over " ( F8 ) twice and find ourselves inside one of the functions used by CEG. And at this stage it is worth saying a few words about the existing types of such functions. Actually, all of them can be three types:

1 . Functions with a constant value ( Constant ) - return a constant value, which will always be the same. Patch like:
mov eax, <> ret
;
2 Functions with a random value ( Random ) - return any integer value. Patch like:
mov eax, <> ret
( used only on the latest CEG versions );
3 Protecting functions ( Protect ) are a pointer that lead to a true function. They are patched as:
jmp <>
.

Now let's go back to our game. We are inside the desired function and we have the correct value in the buffer. Now we have to define the look of our function. Scrolling a couple of instructions down, we will see that the instruction is used.
lea eax, dword ptr ds[esi+ebx]
:

image

And this can mean only one thing - we are dealing with a function that returns a constant value. In general, it should be remembered that if values ​​like: EDB88320 , 60 , 11 , 5 , 3f , etc. appear in the EAX buffer, then it will be immediately clear that the function that uses this value will be constant. Why? Because these are “well-known” constant CEG values, they will be the same on any version of CEG. Therefore, we move to the very beginning of the function and adjust it, changing it to
mov eax, EDB88320
ret
:

image

So what next? And then we repeat everything again (of course, having the same breakpoint on the function that calculates the values) until the game starts (Profit!), Which means that we passed all the CEG checks. Everything ?! Well, let's see. Save the file with the done patches and try to run it on another PC (to which the game was already knowingly downloaded). And then ... bummer. The game does not want to run! Oh yeah, we forgot about one more important detail! The fact is that CEG, as mentioned in the first article, uses so-called file checks. Opening the debugger again, we can easily detect these checks by the presence of the characteristic features of the wonderful WinAPI : GetFileInformationByHandle , CreateFileW , OpenFileById , StringFromGUID2 , RegOpenKeyExW , SystemFunction036 and lstrcmpiW . In our game there is only one such check, you can find it immediately by driving GetFileInformationByHandle into the search for " References ":

image

Go to the beginning and look for the function that calls this check ( right click -> Find references -> To Selected Address (es) , or use the keyboard shortcut CTRL + R ). It will look like this:

image

Well, let's do it! Although this can be done in a more sophisticated way, we will proceed more simply by using
mov eax, 1 ret


image

Saving the result of the work done and testing the second time and oh Gods, the game started on another Steam account and on another PC!

Step III. Full decoupling of the game from Steam (Yarr! Edition)

Of course, after the pleasure, I wanted more extreme sports. And what if I just want to play with a friend on LAN without any Steam there as in bearded times? Well, no question. To do this, I downloaded a great Steam emulator with partial support for the overlay (!) Called SmartSteamEmu . Having set it up, I launched the game without Steam enabled. And what I see is that a * .STEAMSTART file was created and the game hung in the processes. Thinking about thirty seconds, the game still started and worked properly. But why? We kind of did everything, right? Yes, it is, but we forgot about one little touch. The fact is that this event file is created when the Steam process is not running and is essentially the last micro-check. Well, open the debugger for the third time and look for all the functions with CreateFileA . Feel free to set breakpoints on all functions (in this case there are only two). When starting the game, the breakpoint worked:

image

STEAMSTART , we see you! So, in order to end this misunderstanding, simply change the top JE to JNZ or JMP:

image

Save the patch, try again to run the game without Steam, fingers crossed . And voila - the game started in seconds! We did this to you, CEG , forgive us.

Actually, the conclusion

Any CEG in Age of Mythology: Extended Edition was easy. In this game, there was no Protect or Random functions, only one Constant , which greatly simplified the task. Also in this game there were no minor checks, in the form of good old CRC or the latest checks ID of the processor or the serial number of the hard disk .
In the future, I hope, I will be able to master these two new checks and write a new article, but for now - see you soon!

Source: https://habr.com/ru/post/274773/


All Articles