BattlEye related
issues and more

During the past couple of weeks we encountered a decent amount of problems connected with BattlEye system and games using similar kind of anti-cheat protection. Considering some of the today's most played games (PUBG, Fortnite, R6S and many more) use this type of protection we had to find a solution as soon as possible.

Intro

Firstly, I would like to describe what kind of issues we actually experienced and later on how we managed to solve them.

Our software runs on hundreds of machines and as PUBG is by far the most played game it became our main focus for testing. At start, these problems didn't seem to happen so often but soon after it became almost impossible to finish a game without getting some kind of error.

Examples of error messages (we pretty much experienced all of them at one point).

BattlEye: Query timeout
BattlEye: Client not responding
BattlEye: Bad Service Version
BE service is not running properly


The ones stated above didn't have any relatable patterns, all happened at random times, and mostly always prevented player from returning to the game.

To make things much worse, shortly after we started experiencing these initial problems, the one that bugged us the most has arisen. All of the games using BattlEye started freezing permanently, without option to continue the game and almost always required machine reboot in order to resolve system functionality.

In the beginning it seemed like it is as random as all of the other errors but soon we noticed a pattern. This kind of full game freeze always happened at mid - end phase of the game in the time when player interaction is at it's peak. This led to almost two weeks of heavy testing from our side in order to find a valid solution for this problem.

Taking all of these observations into account, the testing started with assumption of BattlEye doing some kind of eliminatory anti-cheat check at mid - end game time frame.

In order to fully understand our testing phase I should tell you a bit about how our software cohabitates inside the Windows OS. Unlike all of the other solutions, our main goal was to integrate into OS without restricting any of it's crucial functionalities. For example, the simplest way to restrict user actions, which all of the other solutions use, is to completely replace Windows shell (Explorer) and run your own implementation instead. Do not get me wrong, replacing user shell is a completely native solution but it brings some major issues. Main problem with shell replacement is improper driver installation. Some of the most crucial drivers for gaming, like graphics drivers, are unable to properly finish setup without fully featured Explorer running. Since Explorer is Windows's original shell it will never run if the shell is replaced.

While Microsoft assures us all the system services remain functional after shell replacement, this is not the case. I'm not going to lie to you, back in the beta phase of our software our solution was based on shell replacement but, thanks to the intensive debugging phase, this is not the case anymore.

Testing Phase

Anyway, now it's time to dig into our testing phase.

Considering we're all experienced Linux developers when things start to go wrong your first thought is it must be permissions. Since we now run on top of fully featured Explorer, we had to apply whole bunch of GPO and other restrictions in order to provide same experience as shell replacement would do. The part when things get a bit tricky is that after every change you actually need to get into final phase of the game to see it's effect. While this might sound fun, playing the same game, 8-10h a day, just to see a freeze, it's actually quite frustrating.

A few days into the testing, after some of the permission changes, it seemed like we're close to the solution. Sadly, we weren't. What started to happen is that every time we applied some minor permission changes we got a few hours of error-less experience. Luckly, soon after noticing this we made a restriction-free build which had the same issues like the one with restrictions. This made us realize problem is caused by something much more complicated and had nothing to do with permission changes we make.

Now we're slowly getting to the interesting part. In order to manage running games and applications we had to create running process management module. This was our second guess for problem source, since it does direct memory access in order to provide proper process and window management.

There are multiple ways for accessing process info inside Windows, out of which two ways are advised by Microsoft. First one is directly querying process info from process handle inside memory buffer and the other one is triggering a snapshot of all running processes while data is being processed afterwards. Both methods are thread-safe, and utilize Windows API methods. We extensively tested both solution and decided to go with direct process query due to much faster info processing times ( ~5ms vs ~50ms ). Only problem with this method was that it required memory access token privileges adjustment in order to read privileged process info. For some reason, out of hundreds of games and applications we tested, PUBG is the only game which makes it's own process privileged and restricts regular processes from querying info so we had to adjust privileges in order to access data. Keep in mind we only raised info query privilege inside our process and no other which allowed us to get all process data we needed.

Solutions

After going over the source again, part with the privilege changes seemed suspicious. Almost instantly after disabling token privileges we realized this was the thing causing all of these issues. What it seems is that BattlEye has some kind of access token check, causing termination if any of running processes not explicitly whitelisted by BattlEye is using this kind of token. The strange part is we didn't request any process tampering privileges, our token was only allowed to read info parameters like process id, name, path. Sadly, looks like BattlEye just doesn't care about this, they disallow access token usage without checking it's allowed privileges. Another strange thing here is, they don't terminate process in question or display any error message.

All that happens is they terminate it's own BE_Service process which leaves the game in frozen state. We're not sure if this is the behavior they wanted to accomplish but my wild guess would be we just managed to hit that uncovered situation inside their source code which causes their process to crash. If that is the case then they have some serious exploit vulnerability. We tried to contact them regarding this matter but they weren't interested in what we have to say.

Now when we discovered what was causing all these issues we were able to solve them. Direct process query method was replaced with process snapshotting. Of course the ~10x times slower processing time was not forgotten. After extensive snapshotting logic optimization we managed to reduce processing times to ~8ms which was acceptable compared to previous ~50ms . Even 50ms would be acceptable since it utilizes separate thread but once you work with embedded devices you learn to value processing times even on powerful machines.

Another thing we're proud about is that we implemented native BattlEye restart solution inside our software.

This solution completely solves the above stated BattlEye: Bad Service Version error which happens sometimes during loading periods.

In a way we're happy these issues occurred because our process management implementation is now working on a much higher lever and is much more optimized than it used to be.

To conclude this matter, BattlEye definitely is an advanced anti-cheat solution and probably as every other software has it's downsides. The point of this post was to inform you what we're going through, how we solve some of the complicated issues and how we generally operate. As well the intention of this was to help other individuals struggling with this type of issues. Make sure you check your system for running software, any kind of third-party process could use access token privileges which will irritate BattlEye eventually.

Hope you found this interesting, will keep you posted in the future. Of course we're more than welcome to answer any kind of inquiries regarding this.

Yours sincerely,

Patrik

GameBay Developer