Executing SQF Without Allocating Memory
So recently I purchased a Screamer PCIe from LambdaConcept. Personally, I would not recommend buying one of these as two of the three cards I purchased were dead on arrival. However, thanks to the one device that did work, I have been given an opportunity to once again approach attacking the Arma 3 engine from a C++ perspective.
The first thing I wanted to do with it was arbitary SQF execution in Arma. This is a bit of a challenge, as I can’t allocate any memory via DMA. So I had to come up with a unique way to execute an arbitrarily large script without allocating memory for the script code to go into.
In order to execute SQF via memory, there are only a few approaches that are decent. GameState::Execute and OnEachFrame are my two favorite methods. The first method requires we call the Execute virtual function in the GameState object. Doing this over DMA is tricky, as we can’t create our own threads or allocate our own code. OnEachFrame is a lot simpler. By writing a GameDataString (Or GameDataCode!) pointer to a global variable, the engine will execute our code every frame.
So we’ll be using OnEachFrame for our exploit. However, this still begs the question, how can we construct an object for our code to go into?
Well, there are actually a few ways to achieve this. Here is one example:
Have the cheater open 3DEN and define their script like this:
Now we can use our DMA device to find the GameDataCode pointer for that variable. By bumping its reference count by 1, we ensure it’s not released when we leave 3DEN. Now we can join a server and simply push that pointer onto the onEachFrame value and walla!
This works, but it requires user input. I created a technique for executing arbitrary code without requiring any user input and a very limited scope for SQF based anti-cheats to detect.