What is VAC?
VAC stand for (Valve Anti-cheat) and is used in many games to prevent cheats be it Valve games or 3rd party titles (Modern Warfare/DayZ). VAC comes in many different versions at the time of writing this the latest version we are calling VAC3. VAC2 and VAC3 are the only activate modules right now for games like Counter-Strike Global Offensive.
Where is VAC, how is it loaded?
VAC2 is loaded through SteamService, when you start a game steamservice appears to load it. Valve first dumps the vac2 module into your %temp% directory then calls LoadLibrary. You can see this for yourself by hooking the LoadLibrary API call or by using an API Monitor.
Furthermore you can open up the .tmp file which is actually a dll and search for the string “vac2” to confirm thats it.
What about VAC3?
VAC3 works a little differently. It’s manually mapped by steamservice which means there are no calls to LoadLibrary and that means there is no reason for them to write the module to disk.
Dumping VAC2 and VAC3
- Hex editor (010 Editor is what I use and I recommend it)
- patchSteamService (Little tool i made that does the patch work for you )
- A brain and common sense
Dumping VAC2 is the easiest, run procmon and lets set some filters up.
The first is the Process Name set this to “steam”, then add another filter for Path set this to your %temp% directory. If you’re unsure what your temp directory is type %temp% into the windows explorer bar and hit enter.
Now that you have the filter setup launch a game that uses VAC2 for example Counter-Strike Global Offensive.
You will notice that Procmon has some entries now that look like this:
Head over to that directory and copy out the file to a safe place. Double check its vac2 by opening the file with your hex editor and searching for the vac2 string I mentioned eariler.
Since VAC3 is manually mapped into memory the first thought that you might get is “find where its loaded and just dump the region with the size given“. Sure that works and you can do it like that however this way is even easier. Like the subheading says we are going to force steamservice to load it via loadlibrary.
Begin by running patchSteamService.exe
This will now patch the steamservice module and VAC3 should now load like VAC2 via LoadLibrary.
How it works
Found by kokole, there is a subroutine inside steamservice which is basically like this:
You can patch this yourself if you know what you’re doing it’s not hard all you need to do is patch the instruction “jz” to “jmp” so it will always call sub_1000F680. Or just use the tool and it will do it for you.
.text:1000F4C3 test [ebp+arg_4], 2
.text:1000F4C7 jz short loc_1000F4D0
.text:1000F4C9 call sub_1000F680
.text:1000F4CE jmp short loc_1000F4D5
Now to dump!
Hook LoadLibrary inside SteamService and check the parameter image. If the image exports runfunc then that is indeed vac save the module somewhere.