How to find the base pointers in A2OA

World is what you look in to find your local player, tables of entities, etc.

NetworkManager is what you look into find the scoreboard.

We’re going to take a look at some script functions in order to find those ‘base’ offsets for the two data structures everyone uses most. Continue reading


Battleye script bypass through object manipulation

This is going to be a little messy. There are better ways (multiple vtables you can hook, also you can change a pointer in a script VM context to stop an individual thread from reporting to BE, etc.) but this has the advantage of not requiring any hooks, whether hard hooks or vtable hooks, which makes it considerably less detectable by Battleye, which currently checks a couple locations to check for BE Callback function VTable modifications. The giant disadvantage is you have to predict how the script engine will parse your scripts, which could be difficult.

Every time your client executes a script, it’s broken into expressions that are executed by the script engine. These expressions are pushed through a series of functions that eventually end up at Battleye’s callback function if you are in a multiplayer game with Battleye enabled. After it runs through Battleye’s callback function, it’s added to an AutoArray of recently run script expressions. Then, the next time a script is run, it’s checked against the array of recent expressions and if it matches one of these expressions perfectly (a map exists a few bytes earlier in the function, if the key for that expression exists in the map, it isn’t sent to Battleye for processing)

This image has been resized. Click this bar to view the full image. The original image is sized 1274×772.

I’m sure you all see where this is going.

The script expressions are just regular c strings – they’re pointers to character arrays with ascii strings of the expression.

This image has been resized. Click this bar to view the full image. The original image is sized 1446×816.

It’s in the NetworkClient class, the same place that links to your scoreboard. It’s at 0xDEEAE8 + 0x24] + 0x1DC. It contains a max of 200 expressions, and is a FIFO queue. So if you know you need to run a couple of expressions that will get you kicked, you could add these expressions to the end of the queue and run these expressions and these expressions would not be run through Battleye’s callback function, bypassing the server side script restriction filters in many cases and bypassing Battleye’s client side script detections entirely.

Engine rendering with object manipulation in A2OA

This image has been resized. Click this bar to view the full image. The original image is sized 1900×1002.

D3D is hard.

With Battleye hook scanning D3D Endscene and Present and apparently being very liberal about deciding what is and is not a hack, I had to find some alternative to hardhooking Present. I could have made an overlay or something, but since I’m a masochist I decided instead to investigate how the Arma engine draws on the screen.

Continue reading

Controlling other players in A2OA

Scripters take control of people with three script functions:

  • RemoteControl
  • changeCamera
  • SelectPlayer

Only one of those is necessary. SelectPlayer actually does changeCamera on its own, and remoteControl is for controlling turrets, not players.

This image has been resized. Click this bar to view the full image. The original image is sized 1027×765.

Name: 		selectPlayer
Name (Long): 	selectplayer
Arg1: 		unit
Description: 	Switch player to given unit.
Example Use: 	selectPlayer aP
Category: 	General
Function: 	0x7ADF17

That’s selectPlayer. It does a lot. It messes with the AIBrain in the entities, then does things with the network managers and network clients if you’re in multiplayer, and sends a message to the server in one of those networkManager functions. That message is important, because it tells the server to give your client locality over the target. This is why if you set your local player pointer to the entity of another player, nothing you do to them ‘sticks’. If you move, you get pulled back. If you fire, their ammo goes down but no bullet comes out. All you can do is things on the scroll wheel, and that’s why: you don’t have locality of that entity, so the server doesn’t accept your changes to it.

So by calling selectPlayer, we can get locality of the target. Then, any changes we make ‘stick’, and the previous owner of the entity’s changes don’t ‘stick’. So when you take control of someone, whenever they move, they get pulled back. When they fire, the ammo count goes down but no bullet comes out. Sounds familiar, right?

Calling selectPlayer is easy. The first argument is a buffer in which it can build a gameValue object, just make an 8 byte buffer for that. The second argument is sometimes the GameState object, and sometimes 0. selectPlayer never actually uses this argument, so passing it 0 is safe. The third argument is what I call unitInfo, it’s the link object that points to an entity. Like dfcdd8] + 13a8].

And that’s all there is to it. Give it a second or two and you’ll be controlling your target completely.

PHP Code:
selectPlayer( buffer, 0, target );

Framing other entities for kills in A2OA

Wouldn’t it be cool if we could shoot someone and frame some other player for the kill?

This image has been resized. Click this bar to view the full image. The original image is sized 1905×916.

When your client calculates damage and sends a message to the server about it, your client includes what entity did the damage. In regular Arma a player can have AI team mates, so the server can’t just assume that the actual player did all the damage that gets sent from his client. So Arma keeps track of who fired a bullet and uses that information to determine who did the damage, and sends that information to the server. The server then sends this damage to the receiving client, and that client applies the damage. In the event of a death, the client of the victim applies the damage, sees that there is a death, and writes the kill message using the name of the entity that fired the bullet that caused the death.

You can see where this is going, right?
The ‘Munition’ Class

PHP Code:
    class Munition : public Entity {
char _0x0040[444];
UnitInfo* parent; //0x01FC

Munition shares some base classes with all other in-game entities. What you’re interested in is the parent pointer – which is at 0x1FC. BTW UnitInfo is the class at DFCDD8] + 13A8], the one that contains a pointer to your actual player at +4. That first value is a reference count, BTW.

So anyway, the ‘parent’ of the munition is who is credited with doing the damage. So if you change the parent of a bullet you fire to someone else, they get ‘credit’ for the kill. Which means if you shoot someone 50m away from you and they’re 4km away from you, the kill message will say they killed your target from 4km away. Do this a few times and the person will most assuredly get server banned.

What’s more, you know how some custom anti-hacks redirect damage over a certain amount? So you set your bullet damage to 5000000 and shoot someone and you fall over dead – this is because the custom anti-hack on their client saw that the damage they were being dealt was an impossible amount, so it redirected the damage to you. Well, what if you shoot a 500000 damage bullet and ‘frame’ someone else as the parent? The custom anti hack very politely kills THEM instead. Fun, huh?

I’ve used this to get streamers banned from servers by framing them for impossible kills, or getting lower level admins banned by framing them for a server wipe. The sky is the limit!

BTW the table of munitions in the simulation is here:

PHP Code:
class World
char _0x0000[8];
InGameUI* inGameUI; //0x0008
char _0x000C[16];
DisplayMain* displayMain; //0x001C
char _0x0020[1496];
void* displayMainMap; //0x05F8
AutoArray<EntityEntry>* entityTable;
GameDataNamespace* gameDataNamespace; //0x0600
AutoArray<Munition*> munitions; //0x07DC <----Munitions right here!!
char _0x07E8[148];
EntitiesDistributed* table1; //0x087C

Note: if you change a bullets parent to someone else before it has left your hitbox area, you will shoot yourself. Have you ever teleported bullets into yourself and noticed your own bullets will never hit your player? That’s because they spawn inside of your hit box area. So make sure the bullet is like 1m away from you before setting the parent to someone else.

Protip: increase the reference count on the unit info you set as parent, otherwise when the bullet impacts and disappears it could free the unitinfo of the parent.

Event Handler script executor POC w/Source

In the thread Entity event handlers I talked about the player event handlers and how they’re stored in the entity class. I also theorized about using them for script injection, which I have implemented here. 


This image has been resized. Click this bar to view the full image. The original image is sized 1906×1035.

How to use the code: 

1: Initialize the tbb4Malloc_bi malloc function pointer. If you forget to do this, the system will use regular c malloc, which will still work but will cause crashes when Arma goes to free your strings when you leave a game. You don’t need to do this for each object, you only have to do it once.

2: Create an A2EventHandler object and pass it a pointer to the first event handler in the class of the unit you want to install the event handler in. This is at entity + 0x2AC.

3: Add or remove event handlers as you please. You can remove all event handlers for a given event, remove all event handlers on all events, remove a specific handler (uses strcmp, so you have to know the text of the event) and of course add an event handler to an event. Just pass it the script text you want it to execute.

PHP Code:
HMODULE hMalloc GetModuleHandle("tbb4malloc_bi.dll");
if(hMalloc) { A2OA::A2EventHandler::setMalloc( (A2OA::A2Malloc)((UINT)hMalloc 0x7A90) ); }
Unitunit getRealPlayer(PWorld);
if (unit) { A2OA::A2EventHandler eventHandlersunit->eventHandlers );
eventHandlers.addEventHandlerEHAnimChanged"hint 'You're movin!';"); }

The easiest thing to attach to is AnimChanged, which basically fires at all times. Just remember to remove your event handler, probably within the event itself (removeEventHandlers AnimChanged; ExecVm whatever)

Included executor

Included is a working script executor using this method. It will read a file from your User\Documents directory and put its contents in an event handler on AnimChanged, which means it will be executed almost instantly. It is up to YOU to remove the event handler within your script (should be the first thing), and to make your script work with this system. You can put whatever you want in it, but if you just want to run your menu or whatever, you should put it in a folder and use ExecVM or something probably.

Example Uses:

Remove your HandleDamage event handlers to get God mode in DayZ
Remove your Fired event handlers to shoot people in safe zones
Add an event handler to HandleDamage to fake an infiSTAR detecton on the person that shot you, banning them.