Executing SQF Without Allocating Memory

Firstly, we will need the original onEachFrame value. We’ll reset this pointer when we’re done to ensure we restore the game’s state.

Lets discuss a bit about Arma reference counts. Every GameData object has a count for the number of references to it. When the game is done with the object it’ll call the Release() virtual function. This will decrement the objects reference count, and if the count drops below 1, it will free the memory. When we change the value of OnEachFrame, the previous value is Released as well. So in order to keep our game from crashing if OnEachFrame is changed in the future, our custom value needs to have it’s reference count incremented by 1.

So our next job is to bump the refernce count of our GameDataString variable. This reference count is stored 8 bytes in.

Okay, now our GameDataString variable is ready to go into OnEachFrame!

If you were paying close enough attention you’ll have noticed I added something else into the injected payload. After our custom SQF executes, the code onEachFrame {}; is run. This will wipe out our custom onEachFrame code, but most importantly it makes it so we can detect once our custom SQF has completed execution (or if it has an error!). By reading the OnEachFrame value’s internal ArmaString pointer, we can see if onEachFrame was cleared.

Awesome! At this point we know our sqf was injected and executed. From here, we can go about restoring the game state such that no one will have ever known we executed something. I am kinda tired of creating all these gists, so here is that restoration code:

So now we’ve executed our custom sqf without allocating any memory! Very cool. Finally I want to give my closing thoughts on detection vectors for this approach.

Pages: 1 2 3 4