Easy Anti Cheat how it works (problem solving). Valve Anti-Cheat (VAC) Which games are VAC protected

Good afternoon, dear readers, I want to provide you with a translated manual on a detailed explanation of the work of Anticheat VAC3

First: what is VAC?:

VAC (Valve anti-cheat) - "Anti-cheat system" is used in all valve games (CS:GO, TF2, CS:S etc.). VAC also works in other games like dota 2 or LoadOut.

How does VAC work?:

VAC uses many ways to detect game hacks, but the most common way to detect game hacks is a database with all the "known" Md5 hashes of Cheat programs for valve games.


VAC starts when you open Steam and scans the entire HDD for the presence of known MD5 hashes of cheat files (hash is, the result


calculating the checksum of the file, which serves to check the integrity of the data. Usually, the MD5 hash is used to check the integrity of distributions.) If VAC detects a file on your computer ((on your hard drive)) that is listed in the VAC cheat database, then you will not receive a VAC ban yet, your account will be cataloged suspicious Steam accounts, and in the future when you play games with VAC protection, anti-cheat will perform a more thorough (aggressive) scan of your system for third-party software.

VAC also scans the DNS cache and hashes of every site you visit (just like the files on your hard drive) and compares those sites (or rather their Md5 cache) against the blacklisted sites in the VAC Base.

The main VAC system scan engine is then launched when connected to the secure game servers of the VAC system. When you are connected to a Steam game server, the VAC module checks the game's memory for matching Md5 hashes of cheats, Signatures blacklisted by the VAC.


And also VAC monitors the call of the left WinApi functions such as (VirtualProtect, WriteProcessMemory, etc.)


It checks running processes, executable file paths, and their Md5 hash against the VAC cheat database.


Scans the game directory for changes to game files (transparent textures, left modifications, etc.)


As soon as the VAC system finds a match of the Md5-Hash of the file against its VAC cheat database, your account is flagged for subsequent blocking in the Steam system.

When will my account be banned from Steam? after using a cheat that has already been detected by VAC:

VAC bans with a delay based on the difficulty of the cheat that was detected.


Usually a ban from using public cheats that have been entered into the VAC database comes from 2 hours to 2 days, while other VIP cheats (Private) can be finally entered into the VAC cheat database from several weeks or months.


Also VAC doesn't display any messages about what - for example: (you have been banned for using third party software. Your account has been suspended, etc.)

How can I try to bypass the VAC system?

The main way the VAC system detects cheats is by searching and comparing the Md5 hash of signatures with the VAC system's cheat database.


But there are also simple ways to delay the detection of a cheat by the VAC system,



Although VAC uses many methods to detect cheat programs, these simple methods will help delay the detection of VAC by the cheat system.


And remember only YOU and only YOU! You take the risk of having your Steam account banned.


(You can use the method Ring0)

If I get a VAC ban for 1 game, will I be banned from all games?:

Not! VAC bans on the game engine, that is, if you get a ban in CSS, then you will be denied access to games on the Source Engine (TF2, Hl2, GarrysMod, CS1.6, etc.) But surprisingly, this is not CS: GO applies, you will be able to continue playing online.

Is VAC really that effective?

And yes and no, if we talk about other Anti-cheats, then yes, VAC is perhaps the best and most effective anti-cheat, but there are many cases on the network that players playing with a public cheat lived quietly from 3 to 6 months, and some of them up to they still play on their accounts without being blocked - the main thing is competent use!

The VAC ban is final, non-negotiable, and cannot be removed by Steam Support.

If you are mistakenly subjected to a VAC ban, it will be lifted automatically. If you would like to discuss the VAC system with the Steam community, you can do so.

Frequently asked Questions:

What is VAC?

VAC (Valve Anti-Cheat - Valve Anti-Cheat) - automated system, created to detect cheats on users' computers. If a user connects to a VAC protected server from a computer with recognizable cheats installed, they will be banned by VAC and will no longer be able to play the game on VAC protected servers.

The VAC system reliably detects cheat programs by their signatures. Any third-party game changes made by the user to gain an advantage over others are classified as a cheat or hack and result in a ban by the VAC system. These changes include the replacement of executable files and dynamic link libraries.

Individual server admins can ban a specific player, but they cannot ban a cheater using the VAC system.

The following actions not lead to blocking by the VAC system:

  • Using chat programs similar to X-Fire or Overwolf
  • Hardware configuration
  • Update system drivers such as video card drivers

How can I avoid a VAC ban?

To exclude the possibility of blocking your account, use only verified computers to play on servers protected by the VAC system. If you can't tell for sure if any cheats are installed on the computer you're using, refrain from playing on secure servers.

Be vigilant when installing any modifications, such as scripts or custom skins. Only download user-generated content from trusted sources. Hackers can maliciously disguise their cheats as mods to get other users banned.

For more information about protecting your account, please see our Account Security Best Practices article.

Additional Information Valve guidelines can be found in the Steam Service Subscriber Agreement.

If I'm banned by VAC, what does that mean for my account?

Per detailed information For information on how a VAC ban affects your account, please refer to the article.

How to inform Valve about a new cheat?

If you have information about new cheat programs, especially private ones (not available on public websites), and can provide links to them or the executables themselves, please send an email with all the information to the email address:

All letters will be reviewed by the staff responsible for developing the VAC.

How to report a cheater?

If it seems to you that there was a cheater in the game with you, let us know about it, follow the instructions in the article.

Note: The VAC system does not block users based solely on complaints. When deciding to block a user, other factors are also taken into account.

What games are VAC protected?

The list of games protected by the VAC system can be found in the Steam store at the following link.

If I'm banned, can I play on insecure servers?

Yes, if the game provides such an opportunity.

Some VAC-protected games allow the existence of non-VAC-protected servers. Banned users can still play on insecure servers for the game they were banned for cheating. Please keep in mind that not all games have unsecured servers.

Will I be harmed if the person I gave my game library to is cheating?

What is the difference between a server ban and a VAC ban?

A VAC ban makes it impossible to play on all secure servers on Steam, while server admins can ban someone from their servers, but it's not as severe as with VAC. Valve cannot prevent bans on custom servers. The server owner has the right to block any player for any reason.

If you find yourself banned from a large group of community servers, it's highly likely that you've been banned by a third party system such as Steambans or Punkbuster. These third party systems are used by multiple servers and share a common database of banned players. These systems are not affiliated with Steam in any way, and we cannot help you with issues related to them.

You will only be banned by the VAC system if you connect to a secure VAC server from a computer with cheat programs installed.

The developers of the game once again talked about how it works new system anti-cheat called Mail.Ru AntiCheat. According to Crytek employees, the game initially developed its own level of protection against cheaters with each update, but practice has shown that it was not as effective as it should be.

Earlier, from publications on the game's website, it became known that Mail.Ru developed its own system that performs all calculations on the server side and thus can quickly track down any hacking attempts. After the introduction of the new anti-cheat system, the number of complaints to technical support about violations decreased and about a million accounts of violators were blocked. MRAC is currently being improved and supplemented with new information about all kinds of cheats and vulnerabilities.


According to experts from the MRAC system, the “lifetime” of cheating accounts today is only about five minutes. It is also known that the cheat library within the system itself is constantly updated and new search algorithms are being improved. As a result, any violator is automatically sent to the ban a few seconds after the appearance in the game. “Immunity” is considered an ideal situation - when a sign of some kind is loaded into the defense malware, at first thousands of accounts are banned on it, and then the number of bans is reduced to almost zero.


Today, a new video appeared on the game's website, which describes in detail the MRAC itself. In the video, both Crytek employees and developers from Mail.ru focus on the features of the system.

The built-in system for tracking the process and its environment, in order to counteract various unauthorized modifications of the code, will not surprise anyone: almost any more or less popular multiplayer game project has something similar. In this article, we will analyze the client protection used by Blizzard developers, as well as implement one of effective ways bypass it.

WARNING

Warden (translated from English as a caretaker, overseer) - this is how the developers of the most popular games in their genres from Blizzard decided to call the protective system. The system, being actually part of Battle.net, is used in such projects as World of Warcraft, StarCraft II and Diablo 3. Only according to official data, tens of thousands of Battle.net accounts have been banned all the time, and a large part of this is the merit of Warden .

To begin with, perhaps it is worth finding out what Warden is. The system consists of two parts: server and client, and, of course, we will deal only with the client part. As mentioned earlier, Warden is not an integral part of the game code. The client-side code is loaded dynamically from Battle.net in the form of images, vaguely reminiscent of Portable Executable in their structure, which are then displayed at random addresses in the address space of the gameplay. It's also worth noting that much of the Warden client-side code is obfuscated and can change from one game session to another.

Warden is a passive security mechanism, and all the Warden client side does is collect information, which is then sent to the server side. In general, an approximate algorithm for the work of the client part of Warden is as follows:

  1. Get a list of relative addresses to scan.
  2. Reading the required number of bytes for each of the addresses.
  3. Hashes calculation.
  4. Assembling a package with hashes and sending it to the server.

The procedure is repeated with some frequency several times a minute. If the server part detects a hash mismatch with the reference values, it is considered that prohibited code modifications are used. No immediate action is taken in this case - the account is simply marked as violating the rules, and it will be possible to find out that you are "caught" only after a while, when Account will already be blocked. The entire Battle.net account (which may contain multiple attached licenses) is not blocked, only the game account.

Against the system

It will not be possible to neutralize Warden by simply disabling it or blocking its operation: the system is designed in such a way that the server part must in any case receive response packets from the client, which, in turn, must contain information about the scan. Therefore, there is only one way out - not to get caught. This can be achieved in at least three ways:

  1. Bypass known dangerous addresses when making modifications to the code.
  2. Use indirect injection by intercepting one of DirectX's Device.EndScene() methods.
  3. Hide all perfect modifications on the fly (when scanning).

The first option will work for the time being and by and large is not a bypass as such. The second option (intercepting EndScene()) really works well, the function is called after the completion of each frame displayed on the screen and is intercepted, for example, by completely legal video capture programs, which does not give Warden the opportunity to unambiguously interpret changes in the function code as prohibited modifications. Nevertheless, the option is more suitable for bots and has been successfully operated by them for several years now. The third option is ideal for static modifications (such as enabling the rendering of the entire map in Star Craft - maphack), in addition, its implementation itself is more interesting and more technologically advanced. It is the latter option that we will consider in more detail below.

INFO

Contrary to popular belief, no personal information is leaked (in the version at the time of this writing): only some parts of the address space of the gameplay are scanned.

Obviously, in order to hide the modifications made, it is necessary to infiltrate Warden's scanning code. As you know, this code is not present in the process from the start, besides, it receives a random address during loading. For the first time, it can be detected using a debugger, simply by setting a breakpoint to read any of the scanned addresses (from some old, long-detected hack). For example, for the latest (at the time of this writing) build of World of Warcraft, setting a breakpoint at the relative base of the main image at 0x0045A6F0 , we get into the following code section:


Warden Scanner Heart masm push esi push edi cld mov edx, dword ptr ss: mov esi, dword ptr ss: mov eax, dword ptr ss: mov ecx, edx mov edi, eax shr ecx, 2 je short ; Here the data goes into a temporary buffer from which the hash will be calculated. ; It is enough to replace the changed bytes with the original rep movs dword ptr es:, dword ptr ds: mov cl, 3 and ecx, edx je short rep movs byte ptr es:, byte ptr ds: pop edi pop esi ret

Empirically, it was found that the discovered code is not subject to polymorphic changes, unlike the rest of the module, moreover, it has changed only once in recent years, which makes it an ideal target for implementation. But since this code is part of a dynamically loaded module, it will also be necessary to intercept the moment it appears in the process in order to make changes before the first execution. In the case of WoW, the loader is part of the game code and is located directly in Wow.exe (for the 32-bit version), you can find it by shoveling through kilometers of listings in the disassembler, or go a more tricky way. Memory for loadable images of Warden modules is allocated by the VirtualAlloc() function, the call log, indicating the place from which the call was made, will contain the address belonging to the loader.

C++ void VA_hook_(DWORD dwCallAddr, DWORD dwMemBlock, DWORD dwSize) ( if (dwMemBlock && dwSize > 0x2000) ( Logger::OutLog("Allocated block:%.8x - %.8x, called from:%.8x\r\n ", dwMemBlock, dwMemBlock+dwSize, dwCallAddr); ) )

In this case, there is no need to go through all the records: after logging in and entering the game realm, the necessary Warden module will already be loaded, you can simply search the entire address space of the process for a binary pattern corresponding to the previously found data scanning procedure:

C++ Scanner::TPattern WardenPattern("\x56\x57\xFC\x8B\x54\x24\x14\x8B\x74\x24\x10\x8B\x44\x24\x0C\x8B\xCA\x8B\xF8\xC1\xE9 \x02\x74\x02\xF3\xA5", "x26"); DWORD WardenProc = (DWORD) Scanner::ScanMem(&WardenPattern); if (WardenProc) ( Logger::OutLog("Warden::Scan proc:0x%.8X\r\n", WardenProc); ) else Logger::OutLog("Warden::Scan proc not found\r\n" );

Thus, we will determine the exact current location of the Warden code we need, and the VirtualAlloc () call log will allow us to determine where exactly the memory for this code was requested from, thereby pointing to the Warden module loader. By analyzing the loader code in the disassembler, you can find a suitable place to intercept. To do this, you need to find the right moment when all sections of the image received from the Network are successfully displayed in the process AP, after which it will be possible to implement an interception that modifies the Warden code. A suitable site would be a call to VirtualProtect() , which sets the final permissions on the sections:

Masm lea ecx, push ecx ; lpflOldProtect push dword ptr ; flNewProtect push eax ; dwSize push ebx ; lpAddress call ds:VirtualProtect test byte ptr , 0F0h jz short loc_A5BE9C push ; dwSize push ebx ; lpBaseAddress call ds:GetCurrentProcess push eax ; hProcess call ds:FlushInstructionCache

The code for the trampoline function, the transition to which is set instead of call ds:VirtualProtect , might look like this:

C++ // Called for each section __declspec(naked) void WardenLoader_hook(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect) ( __asm ​​( push ebp mov ebp, esp pushad ) if (flNewProtect==PAGE_EXECUTE_READ) // For section containing WardenModulePatch executable code (lpAddress, dwSize); // Patch Warden code __asm ​​( popad pop ebp jmp dword ptr ) )

Data search by binary pattern

To make code-modifying patches independent of the version of games and not to interrupt offsets over and over again, you will need the ability to search by a binary pattern (template). In this case, based on the code that needs to be changed, a pattern is created that contains enough information so that, if there is a match, you can confidently say that exactly what was required was found. There are many different ways to implement pattern matching. In the solution I propose, the search is performed using a pattern like: xA?B (where A and B are natural numbers, x is an exact match of bytes, the number of which is indicated by the following characters, ? are bytes to skip).

C++ // Initialize the pattern // The first parameter is the data to compare, the second is the comparison pattern Scanner::TPattern SamplePattern ("\x56\x57\xFC\x00\x00\x90", "x3?2x1"); /* This pattern matches data whose first three bytes match 0x56, 0x57, 0xFC, then two arbitrary bytes follow, and the last one matches 0x90 */ // Search for a given pattern in a limited area, starting with pMemBase and dwSize DWORD size dwProc = (DWORD) Scanner::FindPattern(pMemBase, dwSize, &SamplePattern);

Full source can be found in the attached project.

Patcher

In order to be able to hide your actions from the eyes of Warden, you must remember absolutely all the changes made in the memory of the process and have access to the original data that existed before the changes were made. Any changes (interceptions, substitutions, etc.) must be made by the same means, which must guarantee the fulfillment of the stated requirements:

C++ /* pAddr - pointer to the location of the modification pData - data to replace dwDataSize - data size */ BOOL Patcher::MakePatch(PBYTE pAddr, PBYTE pData, DWORD dwDataSize) ( BOOL fRes = false; DWORD dwOldp; if (VirtualProtect(pAddr , dwDataSize, PAGE_EXECUTE_READWRITE, &dwOldp)) ( // Remember original bytes pPatchStruc = // Last element pPatchStruc->addr = dwAddr; pPatchStruc->len = dwSize; memcpy(pPatchStruc->org , (PVOID) dwAddr, dwSize); / / Write new memcpy(pAddr, pData, dwDataSize); dwPatches++ fRes = true; ) return fRes; )

A list of structures containing information on all changes made in the process may belong to an object with a global scope. Modification of the code can now be done approximately as follows:

C++ bool PatchVirutalProtect() ( bool bRetval = false; PBYTE bCode = (PBYTE) "\xE8\x90\x90\x90\x90\x90"; // call rel32 DWORD pProc = (DWORD) GetProcAddress(GetModuleHandleA("KernelBase.DLL "), "VirtualProtect"); *((PDWORD)(bCode+1)) = (DWORD)&VP_hook - ((DWORD)pProc+5); if (Patcher::Instance()->MakePatch((PBYTE)pProc , bCode, 5)) ( Logger::OutLog("VirtualProtect patched at: %x\r\n", pProc); bRetval = true; ) else Logger::OutLog("VirtualProtect patch failed\r\n"); return bRetval; )

Using a centralized patcher does not cause additional trouble, while in addition to simply accessing the original data, we get the opportunity to roll back any change, returning everything to its original state, which is sometimes very useful.

INFO

If you are interested in the topics presented in the article and you want to dig even deeper, then I can recommend perhaps the best specialized forum.

Warden's Unseeing Eye

Now that we have all the necessary information and tools, it remains to replace the Warden scanning procedure with our own, which will substitute the original data instead of the modified data. In this case, the hashes will be identical to those stored on the server, and code changes will go unnoticed.

To prevent any changed bytes from getting into Warden's field of vision, with each scan call, it is necessary to look for the intersection of the sets of scanned addresses with the addresses of the patched data. Since the patches will most likely not go one after the other (this does not make sense) - there will be a maximum of one intersection for one scan and the data can be taken from the structure associated with any one particular patch. All possible intersections come down to one double condition: either the address of the beginning of the set of scanned bytes is included in the set of patch addresses, or vice versa. Thus, we must iterate over all patches, checking the given condition:

C++ // Do scanned addresses fall under any patch? for (unsigned int i=0; i< dwPatches; i++) // перебираем все патчи if ((PatchList[i].addr - dwAddr < dwSize) || (dwAddr - PatchList[i].addr < PatchList[i].len)) // Находим пересечение { pCurrentPatch = &(PatchList[i]); break; }

Having received the structure associated with the current scan with information about the patch, it will not be difficult to replace the data:

C++ if (!pCurrentPatch) ( // Unpatched area scanned - copy directly memcpy(pOutBuff, (PVOID)dwAddr, dwSize); ) else ( // Byte processing for (unsigned int i=0; i< dwSize; i++) { unsigned int delta = dwAddr+i - pCurrentPatch->addr; byte*pCurrent; // Has the byte at this address been patched? if(delta< pCurrentPatch->len) pCurrent = pCurrentPatch->org + delta; else pCurrent = (PBYTE)(dwAddr+i); pOutBuff[i] = *pCurrent; ) )

By using the code above instead of the original scan procedure, we can monitor Warden's activity, preventing him from detecting any changes made to the code, even if Warden tries to check the integrity of himself.

SOURCE

The article provides a lightweight and incomplete source, the author has created a full-fledged working draft attached to the article. Do not be lazy and look into the source, it is quite possible that you will find something useful for yourself there.

proof of concept

As a demonstration of the workability of the bypass with the extraction of some practical use it was decided to modify the World of Warcraft code at the relative offset 0x008C9A3E , which is checked by the Warden scanner. The procedure corresponding to this offset is responsible for checking the execution rights of the Lua script (many of the WoW API functions are locked to the user and can only be used by the native user interface). The section of code in the area of ​​this offset looks like this:

Masm mov ebp, esp mov edx,dword ptr ss: mov eax,dword ptr ds: xor ecx,ecx push esi cmp dword ptr ds:,ecx je short 01309A84 cmp edx, 22

The offset itself corresponds to a conditional jump after comparing the global variable containing the access level identifier for the current context with zero (zero corresponds to the highest rights). Replacing a conditional transition with an unconditional one, we get the opportunity to use any WoW API functions, creating complex and "smart" scripts that automate many game actions (the most primitive use case: bind the entire rotation of spells to one button, check cooldowns, and so on, which is initially impossible to do ). The simplified patch installation code looks something like this:

C++ PBYTE bCode = (PBYTE) "\xEB"; // JMP SHORT Scanner::TPattern Pattern("\x33\xC9\x56\x39\x0D\xFF\xFF\xFF\xFF\x74\x44\x83\xFA\x22", "x5?4x5"); DWORD dwProc = (DWORD) Scanner::ScanMem(&Pattern); if (dwProc) ( DWORD dwProcChangeOffset = dwProc+9; if (Patcher::Instance()->MakePatch((PBYTE)dwProcChangeOffset, bCode, 1); )

After installing the patch, the "protected" functions of the WoW API become available directly from the macros, and in the Warden activity log, we can see the prevented attempts to scan the patched area. You can verify this by compiling and testing the source codes attached to the article.

What about other Blizzard projects?

The article considered the option of intercepting the loader code for WoW, for other projects this code is in the obfuscated battle.net.dll library, according to which, in principle, it is impossible to create a pattern that does not depend on the version of the library to search for the loader code. In this case, as one option, you can intercept all VirtualProtect() calls made from battle.net.dll, processing them like this:

C++ void VP_hook_internal(DWORD dwCallAddr, DWORD dwMemBlock, DWORD dwSize, DWORD flNewProtect) ( // The call was made from battle.net.dll if (dwCallAddr - WardenLoaderHack::dwBNetBase< WardenLoaderHack::dwBNetImageSize) { // Секция кода if (dwMemBlock && flNewProtect==PAGE_EXECUTE_READ) { MEMORY_BASIC_INFORMATION Mem; // Ищем начало блока памяти if (VirtualQuery((PVOID) dwMemBlock, &Mem, sizeof (MEMORY_BASIC_INFORMATION))) { // Первые четыре байта - сигнатура модуля Warden if (*(PDWORD)Mem.AllocationBase == "2LLB") { Logger::OutLog("Warden image found at:%.8X, code section:%.8X\r\n", Mem.AllocationBase, dwMemBlock); // Патчим код Warden WardenModulePatch(dwMemBlock, dwSize); } } } } }

Complete freedom of action

The ability to make any changes to the game client with impunity opens up the broadest prospects for further research. In fact, in Blizzard games, you can create absolutely anything you can imagine or want. One could write a separate article about the possibilities of unlocked Lua scripts in WoW. After all, even simple scripts can save the player from routine actions or reduce dependence on reaction and attentiveness, allowing them to devote a little more time to other things. At the same time, the possibilities of free modifications of the client are not limited to a simple unlocking of certain features. In general, go for it!

Internet