Halo: Master Chief Collection - Enable Achievements with EAC Disabled :)

Post here (make sure thread doesn't exist first) any type of tutorials: text, images, videos or oriented discussions on specific games. No online-related discussions/posts OR warez!
User avatar
SunBeam
Administration
Administration
Posts: 4703
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4287

Halo: Master Chief Collection - Enable Achievements with EAC Disabled :)

Post by SunBeam »

Hello folks, been a while since I've wrote a tutorial.

Recently bought this game and started playing, noticing it's protected by EAC. However, there's the possibility to run the game without it. But.. achievements won't trigger on various events if EAC is off. Been reading here and there for some solutions, before I'd go down into it (makes no sense to do anything if someone's already achieved this) and found a post where someone claimed they've got some loader that allows achievements to pipe through while EAC is disabled. That kinda started me thinking a bit: of course developers would want to see if achievements work without EAC on. If achievements were available only when EAC is enabled, then they wouldn't be able to debug-test them. So there should've been some quick, "dirty" way. You'll learn in a bit what that trick is.

Now.. I've been looking for a while now into emulating both the x86 and x64 EAC DLLs for single-player purposes. That would basically eliminate the need for the launchers you've seen with most trainer sites. You'd need just the DLLs alone replaced in the game_folder\EasyAntiCheat_folder.

Back to MCC.. I was interested in 3 components: the UE4-built GUI .exe (MCC-Win64-Shipping.exe), the engine .dll for each of the games in the series and EAC itself. Similarly, my interest in EAC targeted 3 out of 4 major components that are exposed: mcclauncher.exe (launches the anti-cheat, then the game), EasyAntiCheat_x86.dll and EasyAntiCheat_x64.dll. The 4th component isn't quite visible from starters; and that is the .sys driver the x86 .dll downloads on initialization, unpacks, loads up, hooks ObCallbacks to disallow system-wide driver installing, etc. The core of their protection. Lots of reading will help understand what's going under the hood.

The first thing I did in my quest was to see if replacing the x64 .dll with the one I wrote for Wildlands still works. In the sense that I was curious if the current .dll has more exports exposed than the one I used at the time. Surprise, the DLL works, but that isn't sufficient. First-up, the x86 .dll which loads the driver will also hash out all its dependencies. That's where the first fail occurs. Reporting that the x64 .dll is "corrupted". If I manually and directly load MCC-Win64-Shipping.exe, it will skip mcclauncher.exe. Then it will load the EAC x64 library, as there's an initialization function right here:

Image

(you can use AOBs to find it.. or just look for 'EasyAntiCheat' in the string references)

So with that in mind I played 1-2 Reach missions and saw no pop-ups from Steam upon completion. There are achievements for finishing each of the missions in the campaign. Considering I've basically 'bypassed' EAC and all's green, I wondered why nothing happened. So I went back to the code above.

After loading the x64 .dll there's this piece of code:

Code: Select all

00007FF7B1D2CAE8 | 48:8D15 D1682001   | LEA RDX,QWORD PTR DS:[7FF7B2F333C0]    | 00007FF7B2F333C0:"CreateGameClient"
00007FF7B1D2CAEF | 48:8BC8            | MOV RCX,RAX                            |
00007FF7B1D2CAF2 | FF15 E08EAF00      | CALL QWORD PTR DS:[<&GetProcAddress>]  |
00007FF7B1D2CAF8 | 48:8D0D B9672001   | LEA RCX,QWORD PTR DS:[7FF7B2F332B8]    | 00007FF7B2F332B8:"GameClientInterfaceV012"
00007FF7B1D2CAFF | FFD0               | CALL RAX                               |
After acquiring the CreateGameClient export's address, the function is run. Now the DLL for Wildlands has this patched and will just return a pointer to a blank memory space. The function just returns an address, the address of the GameClientInterface. In games like Wildlands, this is checked only to see if it's a valid pointer, nothing else. However.. in MCC.. using the original x64 dll and tracing into the execution of the actual function.. I found this:

Code: Select all

00007FF9FFCE5B51 | 48:8BD7            | MOV RDX,RDI                            | rdi:"GameClientInterfaceV012"
00007FF9FFCE5B54 | B9 AC0E0000        | MOV ECX,EAC                            |
00007FF9FFCE5B59 | FF15 B1390600      | CALL QWORD PTR DS:[<&GetProcAddress>]  |
00007FF9FFCE5B5F | 48:8BD8            | MOV RBX,RAX                            |
00007FF9FFCE5B62 | 48:85C0            | TEST RAX,RAX                           |
00007FF9FFCE5B65 | 75 1E              | JNE easyanticheat_x64.7FF9FFCE5B85     |
00007FF9FFCE5B67 | FF15 6B360600      | CALL QWORD PTR DS:[<&GetCommandLineW>] |
00007FF9FFCE5B6D | 48:8BC8            | MOV RCX,RAX                            |
00007FF9FFCE5B70 | E8 6BC6FEFF        | CALL easyanticheat_x64.7FF9FFCD21E0    |<-- enter here
00007FF9FFCE5B75 | 48:85C0            | TEST RAX,RAX                           |
What the piece of code above does is to fake obtaining the a fictitious API address (MOV ECX,EAC :) - these guys think they're Blizzard; there's a spoof with Blizzard's Warden doing a similar GetProcAddress call, years before EAC even existed, an easter-egg exposed in a video I've seen at some conference), which will of course fail. It will return 0 in RAX. Then the command-line the game was launched with is read and a function run. The one I marked with "<-- enter here". Inside this function we'll see this:

Image

So it checks if the game has been launched with -eac-nop-loaded command-line. Cool. So I then started the game with this command-line and and replayed the first Reach mission. What do you know, upon completion, I got the achievement. Aha, so that's the developers' trick to quickly test out the achievement system while EAC is disabled ;) Naughty naughty.

So that's one way of doing it.

Then I was curious even further: what's the actual trigger in-game that tells the game EAC has been initialized or not? How does the game know, when attempting to unlock an achievement, that EAC is disabled? The answer came a few minutes later.

What I did was to continue tracing the code past the -eac-nop-loaded processing part. Won't detail the whole interface creation process, but just the content of the structure and what I noticed. Exiting the "CreateGameClient" function there's this write here:

Code: Select all

00007FF7B1D2CAE8 | 48:8D15 D1682001   | LEA RDX,QWORD PTR DS:[7FF7B2F333C0]    | 00007FF7B2F333C0:"CreateGameClient"                                      
00007FF7B1D2CAEF | 48:8BC8            | MOV RCX,RAX                            |                                      
00007FF7B1D2CAF2 | FF15 E08EAF00      | CALL QWORD PTR DS:[<&GetProcAddress>]  |                                      
00007FF7B1D2CAF8 | 48:8D0D B9672001   | LEA RCX,QWORD PTR DS:[7FF7B2F332B8]    | 00007FF7B2F332B8:"GameClientInterfaceV012"                                      
00007FF7B1D2CAFF | FFD0               | CALL RAX                               |                                      
00007FF7B1D2CB01 | 48:8947 10         | MOV QWORD PTR DS:[RDI+10],RAX          |<--    
What the above does is to write the result of the CreateGameClient, the game client pointer, into [RDI+10]. The game client structure looks like this, where I've marked some elements I then debugged to see if these are triggered/accessed when and end-mission achievement should be granted:

Image

The first 3 DWORDs I've marked in yellow are some constants I saw EAC writing in the game client structure. I thought maybe these are checked before an achievement is unlocked. The last highlight is your "timestamp" computed using RDTSC. Let's say your HWID. I thought this is also checked.

However, none of these led anywhere.

Then I looked at what's in [RDI+10], where the game client pointer is written to. And saw this:

Image

So what I naturally did was to debug that 0x1 value and flip it between 1 and 0, while ending a mission. When the value is 0x0, you get no achievements. When it's 0x1, you do :) So the check is implemented in a very simple way to tell the game "hey, EAC was initialized successfully" -> write a 0x1.

Restarting the process and setting a breakpoint at [RDI+18] showed me where this 0x1 comes from:

Image

Image

Image

So all I need to do with regards to future endeavors in the EAC emulation is to simply return 1 in the "IsEACInitialized" possibly-SDK function :)

BR,
Sun

User avatar
IFireflyl
Fearless Donors
Fearless Donors
Posts: 247
Joined: Tue Nov 28, 2017 7:27 pm
Reputation: 94

Re: Halo: Master Chief Collection - Enable Achievements with EAC Disabled :)

Post by IFireflyl »

Wow, that's a big write-up for this! I can't wait to see where you take the Master Chief Collection. I know there are plenty of people around here who would love to see the achievement pop even if CE is running. Heck, even if they aren't using CE but are using mods. This is a pretty amazing discovery.

User avatar
Dread_Pony_Roberts
Table Makers
Table Makers
Posts: 521
Joined: Sun Dec 09, 2018 8:46 am
Reputation: 385

Re: Halo: Master Chief Collection - Enable Achievements with EAC Disabled :)

Post by Dread_Pony_Roberts »

Very impressive. I do enjoy reading how you found everything, it's very interesting to see what real deep code diving looks like.

User avatar
SunBeam
Administration
Administration
Posts: 4703
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4287

Re: Halo: Master Chief Collection - Enable Achievements with EAC Disabled :)

Post by SunBeam »

Meanwhile, see bottom left ;)

Image

BR,
Sun

User avatar
Dread_Pony_Roberts
Table Makers
Table Makers
Posts: 521
Joined: Sun Dec 09, 2018 8:46 am
Reputation: 385

Re: Halo: Master Chief Collection - Enable Achievements with EAC Disabled :)

Post by Dread_Pony_Roberts »

SunBeam wrote:
Wed Mar 11, 2020 5:38 pm
Meanwhile, see bottom left ;)

Image

BR,
Sun
Wow, very impressive. You are certainly one to overcome a challenge. This opens up some very interesting possibilities that I am very excited to see. Thank you for making it possible.

With the console comes the question, which version is the game running on exactly. If it's running on Custom Edition then it should come with a good many interesting cheats. Would you mind running cheat_deathless_player 1 through it to see if it works? Here's a list of commands it should have (there may be more) if it's Custom [Link]
Last edited by Dread_Pony_Roberts on Thu Mar 12, 2020 1:57 am, edited 2 times in total.

User avatar
sebastianyyz
Expert Cheater
Expert Cheater
Posts: 315
Joined: Sun Jul 09, 2017 3:33 am
Reputation: 53

Re: Halo: Master Chief Collection - Enable Achievements with EAC Disabled :)

Post by sebastianyyz »

This is so nice. Thank you SunBeam

User avatar
SunBeam
Administration
Administration
Posts: 4703
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4287

Re: Halo: Master Chief Collection - Enable Achievements with EAC Disabled :)

Post by SunBeam »

Dread_Pony_Roberts wrote:
Thu Mar 12, 2020 1:33 am
...
Will see what I can do about it. What happens is I've gotten my hands on the old CE version to compare console behavior back and forth. The problem in the 2019-2020 CE is that the fuckers removed the NtdllDefWindowProc_A handler that listens to key presses. I was able to dump that function, IDA it and recompile it as x64 (the old Halo:CE is x86). The problem I have so far is I am able to bring up the console, though you can't type in it :) Emulating that listener function should do the job, though I've yet to find a spot to inject it. Gotta find Reach's keys handler and re-route from there. Same goes for executing a command (since no keyboard event occurs in the console, Enter doesn't work as well). However.. I can use mouse right-click to paste anything from the clipboard.. but like I said, can't Enter it :) Am sure that once I resolve this, things might fall in place.

I've not seen those commands you linked in the string references, just something like "dbg_god_mode".

User avatar
SunBeam
Administration
Administration
Posts: 4703
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4287

Re: Halo: Master Chief Collection - Enable Achievements with EAC Disabled :)

Post by SunBeam »

Alright.. figured I'd write this down, so it stays here for posterity :)

I've asked fearlessrevolution's permission to share with you the analysis of the Rapid Fire option he's got in his CE trainer. There is a timer that starts from 0x0 and stops at a constant value, 0x7F. That takes about 5 seconds to count. Once you fire, the counter drops to 0x0. It then starts spinning till it hits 0x7F, after which you're allowed to fire again. What fearlessrevolution did was to freeze this to that max value so game doesn't recalculate the time it needs to spawn another projectile. How to find this value in memory, simple: start by looking for your clip ammo value. Once you find that address, browse it in memory and scroll a bit up from it. Make sure to run the game in windowed mode (Alt+Enter) so you can monitor the memory region. You'll find 1 single address that spins till 0x7F (127 decimal) as soon as you've started firing.

Taking a break from the console code analysis I've decided to bring that Rapid Fire option in Reach. It puzzled me why he's got no such option in his trainer. Also, all existing trainers for CE and Reach feature only Super Accuracy. I saw no options like No Recoil and Rapid Fire in the Reach ones :) I mean why?

What I did in Reach was to apply same logic. Find clip ammo, debug the piece of code, check around it. In Reach the functions are not inlined, meaning the function dealing with clip ammo subtraction needs to be exited to get to the core processing code:

Image

Image

Browsing the clip ammo area returned no address whose value ticked from 0x0 to 0x7F or some other value. I guess that's where fearlessrevolution stopped, as he'd have to approach it differently.

Upon debugging the clip ammo processing core code I found that if I do not execute the function above the subtraction one (marked with "<" in my screenshot above), the weapon doesn't fire. Then I wanted to learn what other locations is this function accessed while firing the weapon. And CE helped with that, as debugging the function's RET - this RET -> haloreach.dll+5CB420 - showed this:

Image

Then I tested each function whose code popped there and stopped at the 4th one: haloreach.dll+61AA09. Breaking here and exiting the function led me to this:

Image

Entering the function above and tracing led to this:

Image

And inside I saw this code:

Image

What I then tried was to change that 60 value to something else. I changed 0x3C in hexa to 0x3A. And I then saw I was able to fire way faster in-game, but at the same time realized this is a player-related timer. Why, because am familiar with the piece of code running before the timer read, which I've explained in the article on UC. The TLS read and getting our player's structure.

So what I did next, just so I don't fuck up the whole game timer, was to debug that 0x3C value (60 decimal) on access and see what pops-up in the window WHEN I FIRE THE WEAPON. There's a shitload of hits, so don't be surprised when you see something like this:

Image

You may need to alt-tab in-game, then alt-tab out just to let some more hits pop that you DON'T NEED (while not firing the weapon). We want to narrow down the hits to just those few that happen while firing. The address I've highlighted above is the point where all the next hits happened only when I fired. All of the others above that highlighted one are occurrences that constantly run in the engine, which we don't need.

So I started investigating that first one: haloreach.dll+181443. What I did to begin with was to scroll up to prologue, RET it and fire. See what happens. What I noticed is the screen doesn't shake that much anymore as I fire the Rifle :) Meaning I'm onto No Recoil. So I restored the code, exited this function and RET'd the prologue of the outer function: haloreach.dll+1800B0. If you head there, put a 0xC3 so the function exits quick, you will find that you've gotten no recoil :P As a bonus, try jumping, then on land notice there's no screen shake as well. So this function, accessed from several locations, processes screen shake for various actions. In a similar fashion you could disable the screen shake for the Sprint active skill.

Then the function that contains haloreach.dll+676D71 address, if RET'd at prologue, you'll see there's no bullets being fired from your weapon :) So there's your shot processing code. Am sure inside this function you'll find references to shot distance, power, etc. Just do some digging in.

Will return with a Rapid Fire option, as I've got several locations to test out :P

EDIT: That was quick. The address I needed was right above the line I highlighted in the CE screenshot :) So.. head to haloreach.dll+611C23, scroll up to prologue, RET it and try firing :) There you go, Rapid Fire: RET @ haloreach.dll+611B30.

BR,
Sun

User avatar
Dread_Pony_Roberts
Table Makers
Table Makers
Posts: 521
Joined: Sun Dec 09, 2018 8:46 am
Reputation: 385

Re: Halo: Master Chief Collection - Enable Achievements with EAC Disabled :)

Post by Dread_Pony_Roberts »

SunBeam wrote:
Thu Mar 12, 2020 2:53 am

Will see what I can do about it. What happens is I've gotten my hands on the old CE version to compare console behavior back and forth. The problem in the 2019-2020 CE is that the fuckers removed the NtdllDefWindowProc_A handler that listens to key presses. I was able to dump that function, IDA it and recompile it as x64 (the old Halo:CE is x86). The problem I have so far is I am able to bring up the console, though you can't type in it :) Emulating that listener function should do the job, though I've yet to find a spot to inject it. Gotta find Reach's keys handler and re-route from there. Same goes for executing a command (since no keyboard event occurs in the console, Enter doesn't work as well). However.. I can use mouse right-click to paste anything from the clipboard.. but like I said, can't Enter it :) Am sure that once I resolve this, things might fall in place.

I've not seen those commands you linked in the string references, just something like "dbg_god_mode".
Them darn developers spoilin all the fun :) . It would be interesting if you are able to do it, sadly though, if that is the only string referencing it then we may be dealing with plain Combat Evolved. I haven't seen much talking about the commands in the original CE, but according to this "[Link]" god mode is the only cheat available in the original. The guide's from IGN and their command (and dbg_god_mode) doesn't even work on my copy of the game, but it's the closest I've found to mention of cheats in the original. But I could be wrong and there could be other developer commands available. Cls and quit work in the original and you didn't see them in your string reference so there's still a chance, and we may as well see how their god mode works, so if you still enjoy it then I say press on.

User avatar
SunBeam
Administration
Administration
Posts: 4703
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4287

Re: Halo: Master Chief Collection - Enable Achievements with EAC Disabled :)

Post by SunBeam »

Currently got a nice "easyanticheat_x64.dll" proxy ;) Am getting the hang of this. Time for a re-routed "easyanticheat_x86.dll". Will post the result + source code when I'm done. Oh, coded in ASM, like a true super-star.

User avatar
Dread_Pony_Roberts
Table Makers
Table Makers
Posts: 521
Joined: Sun Dec 09, 2018 8:46 am
Reputation: 385

Re: Halo: Master Chief Collection - Enable Achievements with EAC Disabled :)

Post by Dread_Pony_Roberts »

SunBeam wrote:
Fri Mar 13, 2020 5:11 am
Currently got a nice "easyanticheat_x64.dll" proxy ;) Am getting the hang of this. Time for a re-routed "easyanticheat_x86.dll". Will post the result + source code when I'm done. Oh, coded in ASM, like a true super-star.
Hey now, you're an all-star, get your game on, go play
Hey now, you're a rock star, get the show on, get paid
And all that glitters is gold
Only shooting stars break the mold

User avatar
SunBeam
Administration
Administration
Posts: 4703
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4287

Re: Halo: Master Chief Collection - Enable Achievements with EAC Disabled :)

Post by SunBeam »

I've managed to test out MCC with and without EAC running (basically bypassing the driver initialization and letting it run the game from x64dbg) and noticed there's no difference between using a launcher that runs MCC-Win64-Shipping.exe with -eac-nop-loaded command-line and Steam running the game through mcclauncher.exe. Why is that.. well.. because EasyAntiCheat.exe (that gets downloaded via the launcher) works with signals it receives from the driver. For example, 0x4 from DeviceIoControl at top of the decoded buffer means "debugger detected". Additional checks are performed and the computed signal value is then used to determine which branch should the CreateProcessW perform the launch: 0x0 starts the process with no command-line; 0x1 starts the process with -eac-nop-loaded command-line appended to what EAC reads from settings.json; 0xY - perhaps some other combinations, whereas some of these values are used to keep the launcher window alive, to draw the progression.

Bottom line is EAC will run the game itself with -eac-nop-loaded command-line. Why am I talking about it? Because it's the only factor that lets the GameClient pointer be written into the structure (at [rdi+10]) after CreateGameClient function runs. So NULL or valid pointer. Based on this, the IsEACInitialized function sets the 0x1 flag (if pointer in [rdi+10] is not NULL). Simple. And no other conditions.

Since the handle to the process is stripped by the driver, you will not see this command-line in any tool at your disposal:

Image

Just know that it is there and it is what was used when EAC launched the game.

So there you go.. the big mystery behind the differentiation between "achievements" and "no achievements" :D Oh.. and that "EasyAntiCheat successfully initialized" function is available in all EasyAntiCheat_x64.dll libraries. I checked the one in Gears 5, as well as Wildlands. Present in both games' EAC. Furthermore, developers often opt to add additional checks; in Gears 5 they are computing MD5 hashes of all binaries in the game folder, just so you can't tamper the files. If the hashes don't check out, then main .exe will never run. Of course, it's also checked by EAC on initialization. So double the trouble :P And in Gears 5 you'd want to start the game with " NoEAC" parameter. Slight variations in how developers implement this EAC shit.

BR,
Sun

User avatar
SunBeam
Administration
Administration
Posts: 4703
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4287

Re: Halo: Master Chief Collection - Enable Achievements with EAC Disabled :)

Post by SunBeam »

And here are the two DLLs:
  • EasyAntiCheat_x86.dll
    This DLL will just simply fetch the filename from the spot where the exported CreateGameLauncher function is called. Function has been replaced with a simple CreateProcessW call that launches MCC-Win64-Shipping.exe directly. And I didn't need to hard-code the process name or folder path :) Why? Because there's no need to run it with "-eac-nop-loaded" parameter, as explained above.
  • EasyAntiCheat_x64.dll
    This DLL contains a single exported function the x64 DLL runs first-up: CreateGameClient. The function returns a pointer I called "g_GameClient" and initializes the structure content. At 0x0 offset in this structure there is a pointer to a vtable of functions, called member-functions. This is where the trick lies with the x64 DLL: resolving these member-functions so when your fake DLL is loaded, any dynamic call to either of those won't crash the game (they need to exist!). There are like 10 meaningful functions in the vtable, while the rest are: RET; XOR AL,AL|RET; MOV AL,1|RET; XOR EAX,EAX|RET; etc. The DLL contains a table of 0x1E0/8 functions. That's 61. Features also the "EasyAntiCheat successfully initialized" ripped function, just in case your game would make use of it for.. achievements enablement. And something tells me this will work with other games, like Wildlands.
What to do with them:

1) Head into SteamLibrary\steamapps\common\Halo The Master Chief Collection\easyanticheat folder.

2) Rename easyanticheat_x86.dll to easyanticheat_x86.dll.BAK, then easyanticheat_x64.dll to easyanticheat_x64.dll.BAK, so you have a backup of these files (I know you could always verify integrity of game files if you accidentally overwrite them, but why waste time waiting for validation of 32GB?..)

3) Extract the 2 DLLs from the archive below into this folder.

4) Run the game from either the Desktop shortcut or Steam, choosing the first option "Play Halo: The Master Chief Collection". No need to select the 2nd one with EAC disabled ;)

Profit.

If you're using some launcher from C H -or- W e M o d -or- M A F, restore the original mcclauncher.exe file, please.

SayNOtoEAC.zip
(7.04 KiB) Downloaded 1907 times

BR,
Sun

P.S.: ASM sources included. In case you don't know what to do with them or want to compile them, PM me. Make no sense to instruct on it if there's no interest :P

User avatar
Dread_Pony_Roberts
Table Makers
Table Makers
Posts: 521
Joined: Sun Dec 09, 2018 8:46 am
Reputation: 385

Re: Halo: Master Chief Collection - Enable Achievements with EAC Disabled :)

Post by Dread_Pony_Roberts »

Incredible, works exactly as intended. Even tested it with one of my cheats enabled and sure enough it works.

You are a true master at your craft.

PureReality
Expert Cheater
Expert Cheater
Posts: 126
Joined: Wed Dec 04, 2019 4:33 am
Reputation: 10

Re: Halo: Master Chief Collection - Enable Achievements with EAC Disabled :)

Post by PureReality »

can confirm this works wonders! I just hope that this doesn't get patched some how.

Just glad though that I don't have to sit here and switch between Non-EAC and EAC version anymore.

Locked

Who is online

Users browsing this forum: DotBot