Jump to content

Detecting Arma Image-ESPs

There has been a recent surge of ESPs that utilize PAA files to draw boxes and health bars on screen. Drawing PAA files is possible because drawIcon3D does not check file-patching. This means you can load PAA files that are not packed into PBOs.

Cheaters put all their PAAs into a folder in Arma’s root directory and load them like this: drawIcon3D ["Morpheus\fov.paa", [0,0,0,1], _pos, Pb0X1Lrhsqjd_circlesize, Pb0X1Lrhsqjd_circlesize, 5, "", 2, 0.022, "PuristaSemiBold"]; (Morpheus menu)

Your thought right now might be to just use fileExists to check if there are any known PAA files in players’ Arma directories, but it’s not that simple. The fileExists script command is subject to file-patching, meaning it cannot check for files outside of PBOs.
To get around this, we looked at a few different methods of loading images into the game. One of the ideas we had was to use RscStructuredText.

RscStructuredText (CT_STRUCTURED_TEXT) is an in-game control type that allows you to format text and display images (see the wiki page for more info).
After a bit of testing, we got <img image='%1' />to work with PAAs in our game directory, outside of any PBO.

With the recently added ctrlTextWidth, we could check if an image gets loaded into the RscStructuredText. If the image doesn’t exist, the text width does not change from the standard 0.016 (2x 0.008 for margins).
After gathering this information, it was time to put together some simple detection code:

// Call this code on user then send back serverside to whatever antihack you are using
// This is a stupid easy detection method for 2 different menus, you probably also need to do display text checks, and also simple var checks for scriptkiddies
private _imageExists = {
    private _ctrl = (findDisplay 46) ctrlCreate ["RscStructuredText", -1];
    _ctrl ctrlSetPosition [0,0,0,0.1];
    _ctrl ctrlSetBackgroundColor [0,0,0,0];
    _ctrl ctrlSetStructuredText parseText format["<img image='%1' />", param [0]];
    _ctrl ctrlCommit 0;
    private _w = ctrlTextWidth _ctrl;
    ctrlDelete _ctrl;
    (_w != 0.016);
if (['Pictures\box.paa'] call _imageExists || ['Morpheus\boxesp.paa'] call _imageExists) then {
    // Do detection bonk here, user is using Morpheus or m5 menu.

So this code defines a simple function that takes in an image name as an argument. It then creates an invisible control on display 46. The image passed in the arguments is loaded into the RscStructuredText control and the control width is checked against the known value of 0.016.
If the text’s width is not 0.016, we can assume the image exists and call our logging and banning functions.

If you want to extend the code to detect more menus than M5 and Morpheus, you can wrap the _imageExists call in a forEach loop and run through a bunch of file names.
To dump PAA names from clients, you could add a Battleye script filter for logging PAA file names, like this:  1 ".paa" !"menu.paa" !"server.paa" !"and_so_on.paa"

As a side note: This will cause an error on players’ screens, a simple fix for that would be to first check an image like check completed, invalid textures. This would output an error like “Image check completed, invalid textures not found”. You can customise that to your liking.
Another option would be to close the error message programmatically, but that’s a bit more difficult and I’ll leave that for you to figure out.

xoxoxo to jimbs for helps with the coodz