-
-
Save hardware/3395025 to your computer and use it in GitHub Desktop.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@ | |
@@@@@@@@@@@@@@@ Reversing Steam CEG Protection @@@@@@@@@@@@@@@@ | |
@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@ | |
@@@@@@@@@@@@@@@ by Push_BirthDay_Ret @@@@@@@@@@@@@@@@ | |
@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@ | |
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
Best viewed with notepad++ | |
JUN 2012 | |
Hallo to all readers out there. It has been a long time since I wrote a paper on | |
reverse engineering. But I couldn't hold myself with Valve's baby. | |
I want to make myself Clear. This paper does not intend to make any harm to Valve or any other | |
S/W house that uses this Tech. I will fully disclose the CEG protection and the way I worked | |
to reverse engineer it and bypass it. By using this information you will be able to defeat | |
CEG in a generic way but not bypass User/Game authentication on Steam. Use the information at | |
your own risk. I do not take any responsibility if the knowledge here is used for actions | |
that are considered illegal on any part of the world. | |
So, what is CEG? CEG stands for Custom Executable Generation and is part of Steam DRM. The CEG | |
is applied on binary files (DLLs, EXEs etc.). It "Binds" the game with the computer on which it | |
runs. So, even if somebody defeates the typical User/Game authentication, by moving the | |
game to another pc and run it, it won't make the game run. Let me give you an example with | |
an Authenticated user. Imagine that I am an authenticated user on Steam and I have bought | |
Game-1. I have installed Game-1 on PC-1. I now decide to copy the game to another PC, let | |
us say PC-2. So, I backup the game using Backup option in Steam Client on PC-1 and I Restore | |
it on PC-2. If I run the game on PC-2, dispite the fact that I am an authenticated user | |
for this game the game will not run on PC-2. This is because protection "Understands" that the | |
protected file/files are trying to run on a different PC. The game should connect on | |
Steam servers, servers will ask and get some information from PC-2 and a new version of the | |
binary/binaries that are protected with CEG will be created. Eventually, the binary files | |
will be replaced with new ones and after that, the game will run. | |
A full Steam DRM crack requires User/Game authentication bypass and CEG bypass. As I said | |
earlier, I will not give out information regarding User/Game authentication bypass. But you | |
can still check that CEG has been bypassed if you Restore the legit game to another PC, | |
login to Steam and change to Offline mode. Now Steam Client will not be able to overwrite the | |
CEG protected binary/binaries (because it is in Offline mode) and game will not run due | |
to CEG protection. By using the information in this paper you will be able to make it run. | |
The game I tested was FEAR3 in Windows XP SP3 machine. I used Olly debugger and Process Monitor. | |
I also used Protection ID tool to find out what files of the game are CEG protected (althought I | |
do not care because the way of bypassing CEG as you will later see is a more generic one). | |
The Protection ID tool showed me that file "F.E.A.R. 3.exe" is CEG protected. This is the | |
Main executable of the game. | |
I first created a VM box using VMware Player. So, the VM is on the Physical machine. I then Backed | |
up the game from the physical machine and I Restored it inside the VM. I logged into Steam and | |
changed the mode to Offline. Now I want to make the game run, but not from the Steam Client. I need | |
the game to run by running the main executable (F.E.A.R. 3.exe) in order to be able to debug it. | |
For doing this, I had to create a file inside the folder where the Main executable of the game exists. | |
In my case the Folder is: | |
C:\Program Files\Steam\steamapps\common\f.e.a.r. 3 | |
The file you need to create is called "steam_appid.txt" and contains a number. This number is | |
the Application ID of the game. You can find the Application ID of any game just by searching | |
on Steam site. You do that. In my case and for that particular game the contents of the file is | |
5 bytes long: | |
21100 | |
But how did I find out that I should create this file with this content? After debugging a little | |
I came accross the function SteamAPI_RestartAppIfNecessary(). I searched over the Internet | |
and here is the information I found: | |
---------------------------------------------------------------------------------------------------- | |
// Detects if your executable was launched through the Steam client, and restarts your game through | |
// the client if necessary. The Steam client will be started if it is not running. | |
// | |
// Returns: true if your executable was NOT launched through the Steam client. This function will | |
// then start your application through the client. Your current process should exit. | |
// | |
// false if your executable was started through the Steam client or a steam_appid.txt file | |
// is present in your game's directory (for development). Your current process should continue. | |
// | |
// NOTE: This function should be used only if you are using CEG or not using Steam's DRM. Once applied | |
// to your executable, Steam's DRM will handle restarting through Steam if necessary. | |
S_API bool STEAM_CALL SteamAPI_RestartAppIfNecessary( uint32 unOwnAppID ); | |
------------------------------------------------------------------------------------------------------ | |
After running the game executable (F.E.A.R. 3.exe) , the game Terminates. So, what i did was to fire up | |
Process Monitor and see what happens to the application when it Terminates. The Log file revealed some useful | |
information (I have "shrink" the output a little in order to save some space): | |
12:01:49,0038683 pµ F.E.A.R. 3.exe 2164 CreateFile C:\WINDOWS\system32\1025 IS DIRECTORY... | |
12:01:49,0040101 pµ F.E.A.R. 3.exe 2164 CreateFile C:\WINDOWS\system32\1025 SUCCESS Desired... | |
12:01:49,0041236 pµ F.E.A.R. 3.exe 2164 QueryInformationVolume C:\WINDOWS\system32\1025 SUCCESS... | |
12:01:49,0042262 pµ F.E.A.R. 3.exe 2164 QueryAllInformationFile C:\WINDOWS\system32\1025 ... | |
12:01:49,0043198 pµ F.E.A.R. 3.exe 2164 CloseFile C:\WINDOWS\system32\1025 SUCCESS | |
Thread Exit SUCCESS Thread ID: 3524 | |
Thread Exit SUCCESS Thread ID: 364 | |
Thread Exit SUCCESS Thread ID: 4000 | |
Thread Exit SUCCESS Thread ID: 3304 | |
Thread Exit SUCCESS Thread ID: 136 | |
Thread Exit SUCCESS Thread ID: 372 | |
Thread Exit SUCCESS Thread ID: 252 | |
Thread Exit SUCCESS Thread ID: 216 | |
Thread Exit SUCCESS Thread ID: 392 | |
Thread Exit SUCCESS Thread ID: 380 | |
Thread Exit SUCCESS Thread ID: 1184 | |
Thread Exit SUCCESS Thread ID: 268 | |
Thread Exit SUCCESS Thread ID: 3992 | |
Thread Exit SUCCESS Thread ID: 3904 | |
Thread Exit SUCCESS Thread ID: 388 | |
What I observe here is the following: | |
1) The application checks if a folder exists. This is done using the CreateFile API. | |
2) If Folder exists the application uses QueryInformationVolume/QueryAllInformationFile APIs | |
in order to collect information regarding the folder. | |
3) The information that QueryInformationVolume/QueryAllInformationFile APIs return is not what | |
CEG protection expects to be. Application starts terminating Threads. | |
4) The Process terminates. | |
There may also be the case that a Folder may not even exist. As a result, Threads will start terminate | |
just after the call to CreateFile API. | |
I wanted to see what happens in a lower level. I run the game under Olly debugger, place breakpoint at | |
CreateFile API and break on the ASM code. The thing is that CEG protection uses many Anti-Debug tricks. | |
In order to bypass those Tricks I used a plugin. I didn't have time to study those anti-X Shit. | |
I used Olly Advanced Plugin and turned the following options on: | |
a) UnhandledExceptionFilter | |
b) Process32Next | |
I finally managed to break into the following place inside ASM code, check my comments next to ASM code : | |
00F2D80F |. 8B1D 18013F01 MOV EBX,DWORD PTR DS:[<&KERNEL32.CreateFileW>] | |
00F2D80A E8 51B86EFF CALL F_E_A_R_.00619060 | |
00F2D80F 8B1D 18013F01 MOV EBX,DWORD PTR DS:[<&KERNEL32.CreateFileW>] ---> First call to CreateFile API as shown | |
00F2D815 6A FF PUSH -1 in Process Monitor. | |
00F2D817 57 PUSH EDI | |
00F2D818 6A 03 PUSH 3 | |
00F2D81A 57 PUSH EDI | |
00F2D81B 6A 07 PUSH 7 | |
00F2D81D 68 00000080 PUSH 80000000 | |
00F2D822 56 PUSH ESI | |
00F2D823 FFD3 CALL EBX | |
00F2D825 8BF8 MOV EDI,EAX | |
00F2D827 83FF FF CMP EDI,-1 | |
00F2D82A 75 16 JNZ SHORT F_E_A_R_.00F2D842 | |
00F2D82C 50 PUSH EAX | |
00F2D82D 68 00000002 PUSH 2000000 | |
00F2D832 6A 03 PUSH 3 | |
00F2D834 6A 00 PUSH 0 | |
00F2D836 6A 07 PUSH 7 | |
00F2D838 68 00000080 PUSH 80000000 | |
00F2D83D 56 PUSH ESI | |
00F2D83E FFD3 CALL EBX ---> Second call to CreateFile API as shown | |
00F2D840 8BF8 MOV EDI,EAX in Process Monitor. | |
00F2D842 837D EC 00 CMP DWORD PTR SS:[EBP-14],0 | |
00F2D846 5B POP EBX | |
00F2D847 74 16 JE SHORT F_E_A_R_.00F2D85F | |
00F2D85F 83FF FF CMP EDI,-1 | |
00F2D862 74 64 JE SHORT F_E_A_R_.00F2D8C8 | |
00F2D864 8D55 AC LEA EDX,DWORD PTR SS:[EBP-54] | |
00F2D867 52 PUSH EDX | |
00F2D868 57 PUSH EDI | |
00F2D869 FF15 14013F01 CALL DWORD PTR DS:[<&KERNEL32.GetFileInformationByHandle>] ----> Inside the call to GetFileInformationByHandle API exist | |
00F2D86F 85C0 TEST EAX,EAX ----> the calls to the 2 APIs -QueryInformationVolume, QueryAllInformationFile- | |
00F2D871 74 4E JE SHORT F_E_A_R_.00F2D8C1 ----> as shown in Process Monitor. | |
00F2D873 8D8D E4FEFFFF LEA ECX,DWORD PTR SS:[EBP-11C] | |
00F2D879 E8 D20C9DFF CALL F_E_A_R_.008FE550 | |
00F2D87E 8B4D D8 MOV ECX,DWORD PTR SS:[EBP-28] | |
00F2D881 8B45 DC MOV EAX,DWORD PTR SS:[EBP-24] | |
00F2D884 6A 08 PUSH 8 | |
00F2D886 8D55 E0 LEA EDX,DWORD PTR SS:[EBP-20] | |
00F2D889 894D E4 MOV DWORD PTR SS:[EBP-1C],ECX | |
00F2D88C 52 PUSH EDX | |
00F2D88D 8D8D E4FEFFFF LEA ECX,DWORD PTR SS:[EBP-11C] | |
00F2D893 8945 E0 MOV DWORD PTR SS:[EBP-20],EAX | |
00F2D896 E8 1582CEFF CALL F_E_A_R_.00C15AB0 | |
00F2D89B 8D8D E4FEFFFF LEA ECX,DWORD PTR SS:[EBP-11C] | |
00F2D8A1 E8 2AE37EFF CALL F_E_A_R_.0071BBD0 | |
00F2D8A6 68 FC0C4701 PUSH F_E_A_R_.01470CFC | |
00F2D8AB 8D4D 98 LEA ECX,DWORD PTR SS:[EBP-68] | |
00F2D8AE E8 CDE9D1FF CALL F_E_A_R_.00C4C280 | |
00F2D8B3 8D8D E4FEFFFF LEA ECX,DWORD PTR SS:[EBP-11C] | |
00F2D8B9 8845 FF MOV BYTE PTR SS:[EBP-1],AL | |
00F2D8BC E8 CF0572FF CALL F_E_A_R_.0064DE90 | |
00F2D8C1 57 PUSH EDI | |
00F2D8C2 FF15 68003F01 CALL DWORD PTR DS:[<&KERNEL32.CloseHandle>] ------> Call to CloseFile as shown in Process Monitor. | |
The basic thing here is that there are 2 APIs been called (as shown in Process Monitor -QueryInformationVolume and | |
QueryAllInformationFile-) inside GetFileInformationByHandle. But we do not care. We need to | |
see it from an abstract level, from GetFileInformationByHandle API. So what does this API do? | |
Here is the definition from MSDN: | |
---------------------------------------------------------------------------------------- | |
BOOL WINAPI GetFileInformationByHandle( | |
__in HANDLE hFile, | |
__out LPBY_HANDLE_FILE_INFORMATION lpFileInformation | |
); | |
Retrieves file information for the specified file. | |
Parameters | |
hFile [in] | |
A handle to the file that contains the information to be retrieved. | |
This handle should not be a pipe handle. | |
lpFileInformation [out] | |
A pointer to a BY_HANDLE_FILE_INFORMATION structure that receives the file information. | |
Return value | |
If the function succeeds, the return value is nonzero and file information data is contained in the | |
buffer pointed to by the lpFileInformation parameter. | |
If the function fails, the return value is zero. To get extended error information, call GetLastError | |
---------------------------------------------------------------------------------------- | |
The interesting part is the lpFileInformation parameter. It contains a pointer to the data returned from | |
the file. This data is used from CEG in order to "Bind" the CEG protected binaries with the FileSystem | |
on the PC. So, I understand that there is FileSystem emulation that should be done. The data structure | |
that is being returned contains 52d bytes. Here is an example of the data that the pointer points to: | |
10 00 00 00 F4 BF A8 DC 55 42 CD 01 08 FF 9D 18 | |
E3 44 CD 01 F4 BF A8 DC 55 42 CD 01 27 39 D9 60 | |
00 00 00 00 00 00 00 00 01 00 00 00 00 00 01 00 | |
70 00 00 00 | |
So, I emulated the FileSystem information needed (I will explain later -fully- any emulation, just wait). | |
I run the game on the same physical machine but on a different VM. The game runs just fine. After this, I | |
changed the Hard Disk on the physical machine, re-installed everything and run the game in the VM. The | |
game terminates. But it does not terminate because of the FileSystem. The reason is that it could not | |
find a registry key entry. I took a look in Process Monitor Log for the registry key that didn't exist: | |
HKEY_CLASSES_ROOT\CLSID\{8028480D-A20A-4F93-96A3-3BF9EA7FE1E2} | |
This key should have the following string value: | |
"Steam Service Class" | |
So, I searched for all keys in the PC that the game was running fine. In my case, there were 6 entries | |
in registry with the "Steam Service Class" string value. Here are the keys in my case: | |
Windows Registry Editor Version 5.00 | |
;"Steam Service Class" string in CLSIDs | |
[HKEY_CLASSES_ROOT\CLSID\{8028480D-A20A-4F93-96A3-3BF9EA7FE1E2}] | |
[HKEY_CLASSES_ROOT\CLSID\{E4526A36-75A2-4F2D-A53F-245F584AF2C5}] | |
[HKEY_CLASSES_ROOT\CLSID\{5E9DEE15-F185-4EB0-A30E-09BA14CA43B3}] | |
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{8028480D-A20A-4F93-96A3-3BF9EA7FE1E2}] | |
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{E4526A36-75A2-4F2D-A53F-245F584AF2C5}] | |
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{5E9DEE15-F185-4EB0-A30E-09BA14CA43B3}] | |
After creating the folling keys the game runs just fine. The final test was to run it | |
on a different Physical PC and make sure that CEG does not use H/W "identification" | |
for example CPU number, GPU number etc. I run it and the game run just fine. | |
So, now I was sure about the following things: | |
1) CEG uses FileSystem checks | |
2) CEG uses Registry checks. | |
3) CEG uses no other check than (1),(2). | |
But how can we find all the Folders/Registry entries to Emulate? And what values for structures will we use | |
for FileSystem Emulation? | |
Here is the beautiful part of this. When Steam servers validate all binary files of the game that are | |
protected with CEG and finds that are not valid, it uses the SAME API -GetFileInformationByHandle- in order | |
to get new information from the FileSystem. So, the structures that should be emulated are actually READ from | |
Steam Client and sent to Steam servers in order to produce the new binary file/files. Those structures | |
are stored encryped in 2 sections of the new binary file(s) created: | |
.rdata | |
.rsrc | |
This is why 2 binary files that were created on different PCs differ only on those sections. The CEG algo | |
is inside the code and is the same for the 2 binary files. Only the FileSystem/Registry data changes. | |
I will run Steam Client under Debugger and I will place a Breakpoint at GetFileInformationByHandle API. I noticed | |
that this API is used only by CEG protection on Steam for creating the new binary file(s). Each time the | |
debugger breaks, I will return the same structure data for ANY file. I choose the data. After the | |
update of binary file(s) have finished I have actually forced Steam Client to produce binary file/files that | |
think all Files should return the same data structure, which is my data structure. If I now hook the | |
GetFileInformationByHandle API during game runtime and always return my data structure, CEG will think | |
that everything is ok. It is fine to replace the GetFileInformationByHandle API with my code since this API is | |
only used by CEG. But if you have any problems with later games, you should just change your inline patch a little. | |
Here is the Hook I placed under the debugger for the GetFileInformationByHandle API: | |
7C810CFD GetFileInformationByHandle 60 PUSHAD --> save all registers | |
7C810CFE 9C PUSHFD --> save flag register | |
7C810CFF 8B4424 2C MOV EAX,DWORD PTR SS:[ESP+2C]--> Now EAX contains the lpFileInformation Pointer | |
7C810D03 C700 10000000 MOV DWORD PTR DS:[EAX],10 --> Next code just enters pre-defined 54d bytes of data | |
7C810D09 83C0 04 ADD EAX,4 | |
7C810D0C C700 0098CAB6 MOV DWORD PTR DS:[EAX],B6CA9800 | |
7C810D12 83C0 04 ADD EAX,4 | |
7C810D15 C700 BC41CD01 MOV DWORD PTR DS:[EAX],1CD41BC | |
7C810D1B 83C0 04 ADD EAX,4 | |
7C810D1E C700 1A6711F0 MOV DWORD PTR DS:[EAX],F011671A | |
7C810D24 83C0 04 ADD EAX,4 | |
7C810D27 C700 3447CD01 MOV DWORD PTR DS:[EAX],1CD4734 | |
7C810D2D 83C0 04 ADD EAX,4 | |
7C810D30 C700 0098CAB6 MOV DWORD PTR DS:[EAX],B6CA9800 | |
7C810D36 83C0 04 ADD EAX,4 | |
7C810D39 C700 BC41CD01 MOV DWORD PTR DS:[EAX],1CD41BC | |
7C810D3F 83C0 04 ADD EAX,4 | |
7C810D42 C700 0162B380 MOV DWORD PTR DS:[EAX],80B36201 | |
7C810D48 83C0 04 ADD EAX,4 | |
7C810D4B C700 00000000 MOV DWORD PTR DS:[EAX],0 | |
7C810D51 83C0 04 ADD EAX,4 | |
7C810D54 C700 00000000 MOV DWORD PTR DS:[EAX],0 | |
7C810D5A 83C0 04 ADD EAX,4 | |
7C810D5D C700 01000000 MOV DWORD PTR DS:[EAX],1 | |
7C810D63 83C0 04 ADD EAX,4 | |
7C810D66 C700 00000100 MOV DWORD PTR DS:[EAX],10000 ; UNICODE "=::=::\" | |
7C810D6C 83C0 04 ADD EAX,4 | |
7C810D6F C700 40000000 MOV DWORD PTR DS:[EAX],40 | |
7C810D75 9D POPFD | |
7C810D76 61 POPAD | |
7C810D77 90 NOP | |
7C810D78 C2 0800 RETN 8 | |
The only thing left is to find out what Folders need to exist on the Disk and what Registry entries need to | |
exist in the Registry. This is easy to be found. Before Steam Client updates the Binary/Binaries and applies the | |
new structure signature data, make sure you open Process Monitor. When Client starts reading the new | |
file structures ProcMon will log calls to QueryInformationVolume and QueryAllInformationFile APIs, just like it does | |
when the game starts running. Then it will start searching for the same Folders, as it does when the game runs. | |
After the calls to the FileSystem, it will start checking Registry keys with string value "Steam Service Class". | |
You should write down all Folder names and Registry key names. After that, you can see TCP communication with | |
Steam servers, they are probably creating the new binary files. | |
Here are the Registry Keys and Folders in my case: | |
[HKEY_CLASSES_ROOT\CLSID\{8028480D-A20A-4F93-96A3-3BF9EA7FE1E2}] | |
[HKEY_CLASSES_ROOT\CLSID\{E4526A36-75A2-4F2D-A53F-245F584AF2C5}] | |
[HKEY_CLASSES_ROOT\CLSID\{5E9DEE15-F185-4EB0-A30E-09BA14CA43B3}] | |
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{8028480D-A20A-4F93-96A3-3BF9EA7FE1E2}] | |
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{E4526A36-75A2-4F2D-A53F-245F584AF2C5}] | |
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{5E9DEE15-F185-4EB0-A30E-09BA14CA43B3}] | |
C:\WINDOWS\Connection Wizard | |
C:\Program Files\Steam\Graphics | |
C:\WINDOWS\system32\1033 | |
C:\WINDOWS\Config | |
C:\Program Files\Steam\dumps | |
C:\WINDOWS\system32\1032 | |
C:\WINDOWS\assembly | |
C:\Program Files\Steam\config | |
C:\WINDOWS\system32\1031 | |
C:\WINDOWS\AppPatch | |
C:\Program Files\Steam\bin | |
C:\WINDOWS\system32\1028 | |
C:\WINDOWS\addins | |
C:\Program Files\Steam\Backups | |
C:\WINDOWS\system32\1025 | |
C:\WINDOWS\$NtUninstallXPSEPSCLP$ | |
C:\Program Files\Steam\appcache | |
C:\WINDOWS\system32\mui | |
C:\WINDOWS\Fonts | |
By following the previous steps, you should be able to bypass CEG protection. You do not care | |
how many binary files are been updated, because we Hook in Windows API Level and NOT Application level. | |
To sum up, here are the steps: | |
1) Load Steam Client in debugger and Hook GetFileInformationByHandle API to return your structure. I have | |
included an ASM code sample of this Hook earlier in this paper. | |
2) Open ProcMon. Let Steam Client to apply CEG in the game (online). Note down Folders/Registry entries that | |
CEG needs, from ProcMon Log. | |
2) Make sure all necessary Folders exist. | |
3) Make sure all necessary Registry keys exist. | |
4) Load game in debugger and Hook GetFileInformationByHandle API to return your structure, same structure | |
you returned in (1). Since this API is only used for CEG you should not have any problem to overwrite the | |
API code. But if you do have problems in later games, you should change my inline patch to something else (eg. | |
check what file it is etc.) | |
Keep in mind that CEG protection continues to run during the game execution and does not only run | |
at start of the game. It also checks for Registry/Folders signatures with no specific order/frequency. | |
This is why you should follow my approach and hook the signature creation when CEG protection is | |
applied on the binaries. Only after that you can be sure that you have all Folder names and Registry entries in | |
your "list". | |
> Final Words < | |
Valve did a great Job with CEG. I really had a great time looking on this protection. It reminds me of | |
the good days where sharing was an art. I am sharing this information with you and I hope you will | |
do the same. Should I receive possitive feedback from you I will continue this paper serries. | |
Should I not, I'll stop. | |
Wish you all a great night out. | |
Push_BirthDay_Ret | |
Interesting read. Thanks for sharing. I wonder if the protection - 10 years later - is still the same.
Interesting read. Thanks for sharing. I wonder if the protection - 10 years later - is still the same.
this document is far from exhaustive. you can find killswitches by searching for x-refs to GetTickCount; it always accompanied by return address override (which is why you can't see the callstack when placing a breakpoint at TerminateProcess). x-refs to these killswitches share common code - it is possible to completely bypass CEG by patching a single function. If you REALLY want to get rid of CEG for good, take a look at how PLAZA removed CEG from iw5sp (compare their crack with original exe). Also, use LumaCEG.
Interesting read. Thanks for sharing. I wonder if the protection - 10 years later - is still the same.
this document is far from exhaustive. you can find killswitches by searching for x-refs to GetTickCount; it always accompanied by return address override (which is why you can't see the callstack when placing a breakpoint at TerminateProcess). x-refs to these killswitches share common code - it is possible to completely bypass CEG by patching a single function. If you REALLY want to get rid of CEG for good, take a look at how PLAZA removed CEG from iw5sp (compare their crack with original exe). Also, use LumaCEG.
Maybe you weren't viewing the gist in Notepad++.
@illnyang I tried LumaCEG but it could'nt generate a working executable. It hangs on creating certificate
. Nevermind
I found this but their protection is a lot weaker than on my exe (civ v).
it is possible to completely bypass CEG by patching a single function
Please could you provide a disassembly / screenshot / description of that function ?
Many thanks
Definitely an interesting read - Thanks for sharing.