ObRegisterCallbacks and countermeasures

Because anti-virus softwares were hardhooking the Windows kernel to intercept WinAPI calls when processes were opening files and stuff, Microsoft implemented official and supported methods for receiving notifications for certain events and acting on them.  For instance, when a user launches an executable file, an anti-virus software can be alerted and can scan the file for malicious signatures before launching it.  Or, as is the case in the context of the research that led to this posting, an anti-cheat software can be alerted when a process is attempting to open a handle to the protected game and deny that handle privileges.

This is achieved by registering a callback function for a given event in the kernel using the function ObRegisterCallbacks.  You can see its MSDN article here https://msdn.microsoft.com/en-us/library/windows/hardware/ff558692%28v=vs.85%29.aspx

The short of it is, if you fill out some information regarding what you want to watch and what function you want called when the kernel needs to alert you and pass it to that function, your callback will be called at the appropriate time and you can take appropriate action.  The function returns a handle that you can later use to unregister the callback using ObUnRegisterCallbacks.  This is necessary if your driver unloads because if you left your callback in place and unloaded your driver the callback would probably cause a nice big bugcheck.

This is very annoying when anti-cheats such as Battleye and EasyAntiCheat leverage the callback system to lock down a process and prevent cheaters from reading or manipulating the process memory.  There already exist numerous ways  of countering the callbacks, such as implementing reading/writing functions in your own driver that don’t rely on the standard Windows method of reading from a file.  I wanted to do something a little cleaner, though, and hopefully enable non-modified software access to the protected process.

The Undocumented Structures

The callbacks are obviously stored in kernel objects and there MUST exist some way to either manipulate these objects or resolve a handle to pass to ObUnRegisterCallbacks.  Then we can just disable the callbacks and read and write to our heart’s content, right?  Well, sort of.  To begin with, I dug into ObRegisterCallbacks to figure out exactly what was going on.

The function begins by allocating some memory.

The first argument is a pointer to the OB_CALLBACK_REGISTRATION structure that describes how the callback is to be installed.  If the structure version starts with 0x100 and the registration count is greater than zero, it allocates a buffer the size of 0x20 + OperationCount * 64 + the altitude string length.  It’s very easy, at this point, to start getting some information on the object that is going to be used to store the callback information.  There will be a header of size 0x20 and a series of objects of size 64.  So already we can start figuring out our structures.

For the sake of brevity (and since I already put these structures into IDA) I’m going to go ahead and give you the structure definitions here:


typedef struct _CALLBACK_ENTRY_ITEM {
LIST_ENTRY EntryItemList;
OB_OPERATION Operations;
CALLBACK_ENTRY* CallbackEntry; // Points to the CALLBACK_ENTRY which we use for ObUnRegisterCallback
POBJECT_TYPE ObjectType;
POB_PRE_OPERATION_CALLBACK PreOperation;
POB_POST_OPERATION_CALLBACK PostOperation;
__int64 unk;
}CALLBACK_ENTRY_ITEM, *PCALLBACK_ENTRY_ITEM;

typedef struct _CALLBACK_ENTRY{
 __int16 Version;
 char buffer1[6];
 POB_OPERATION_REGISTRATION RegistrationContext;
 __int16 AltitudeLength1;
 __int16 AltitudeLength2;
 char buffer2[4];
 WCHAR* AltitudeString;
 CALLBACK_ENTRY_ITEM Items; // Is actually an array of CALLBACK_ENTRY_ITEMs that are also in a doubly linked list
}CALLBACK_ENTRY, *PCALLBACK_ENTRY;

Where the 0x20 length header is the beginning of the CALLBACK_ENTRY and the 64 size structure is the CALLBACK_ENTRY_ITEM.  While the CALLBACK_ENTRY_ITEM in the CALLBACK_ENTRY could be accessed as an array of CALLBACK_ENTRY_ITEMs because they’re right next to each other, the kernel doesn’t do this and walks through the linked list instead, and they are only next to each other out of convenience.

ObRegisterCallback then works on filling out these structs using data from the OB_CALLBACK_REGISTRATION object passed in the first argument.  Curiously, when filling out the CALLBACK_ENTRY_ITEMs, it obtains a pointer to the last QWORD of the entry and sets its members according to negative offsets from that point.

Once a CALLBACK_ENTRY_ITEM has been filled out, it’s passed to ObpInserCallbackByAltitude which is exactly what it sounds like.  If you’re not familiar with the Altitude, it’s just a numeric value indicating the order that callbacks should be called.  Lower numbers are called first, higher numbers are called last.  When you insert a callback, the callback is inserted into the linked list according to its altitude value.  If a callback with the same altitude is already in the list, the new callback is not inserted and instead ObpInsertCallbackByAltitude returns a value of STATUS_FLT_INSTANCE_ALTITUDE_COLLISION indicating a collision.  Given that Microsoft’s supported altitudes go up to 430,000 it is unlikely a collision would occur in the wild by chance.  https://msdn.microsoft.com/en-us/library/windows/hardware/ff549689%28v=vs.85%29.aspx

Finding Registered Callbacks

But where does it put the callback objects?  Well, it’s passed in ObpInsertCallbackByAltitude’s first parameter.  Sort of.  The first parameter is to an OBJECT_TYPE structure which is considered opaque by Microsoft but, unlike our other structures in this post, can be dumped with dt in kd.  Its definition is:

typedef struct _OBJECT_TYPE {
 LIST_ENTRY TypeList;
 UNICODE_STRING Name;
 VOID* DefaultObject; 
 UCHAR Index;
 unsigned __int32 TotalNumberOfObjects;
 unsigned __int32 TotalNumberOfHandles;
 unsigned __int32 HighWaterNumberOfObjects;
 unsigned __int32 HighWaterNumberOfHandles;
 OBJECT_TYPE_INITIALIZER TypeInfo;
 EX_PUSH_LOCK TypeLock;
 unsigned __int32 Key;
 LIST_ENTRY CallbackList; // A linked list of CALLBACK_ENTRY_ITEMs, which is what we want!
}OBJECT_TYPE, *POBJECT_TYPE;

These objects are global variables, such as PsProcessType and PsThreadType (the only two object types that allow callbacks on their creation or copying).  Note: Those global variables are OBJECT_TYPE**’s, not just single indirection pointers, so beware.

How did ObRegisterCallbacks know which object to use?  It’s passed in the OB_CALLBACK_REGISTRATION.  Or, at least, one of its substructures.  So it gets that handy LIST_ENTRY of Callback items at the end of the object and inserts into that list.  Super convenient!

After the callbacks are inserted ObRegisterCallbacks does some stuff, fires off an APC, whatever.  It doesn’t matter, we have what we’re interested in: The callback structures and how they’re registered and unregistered.  Speaking of unregistering, you know the handle that ObRegisterCallbacks returns?  It’s just a pointer to the CALLBACK_ENTRY structure, the one that is effectively a 0x20 byte header.  But how do we get to that structure?  After all, the OBJECT_TYPE which we will have to parse to find callbacks only has the CALLBACK_ENTRY_ITEMs in a linked list.  Conveniently, each CALLBACK_ENTRY_ITEM has a pointer to its parent CALLBACK_ENTRY, giving us a ‘handle’ with which to unregister it.

So armed with this information, we can just grab PsProcessType and PsThreadType, parse its Callback List, find each entry item’s parent entry, and unregister them with ObUnRegisterCallbacks by passing the address of the entry as the handle!  Bazinga!

Unregistering the callbacks using ObUnRegisterCallbacks and reading memory from a protected process

The Problem

Sort of.  This works just fine and unregisters the callback.  Unfortunately, when the driver that actually owns the callback goes to unregister it itself when it unloads or whatever, it passes a now invalid handle to ObUnRegisterCallbacks.  Why is this a problem?

ObUnRegisterCallbacks

When we unregister the callback, the memory of the entry is freed.  So, when the parent driver goes to unregister the now invalid handle pointer to freed memory, bugchecks happen.  Unless this is an acceptable price to pay for unregistering those callbacks, something must be done.

My short term solution is to just do some good old fashioned DKOM.  On Windows 7, as far as I can tell, those callbacks are not monitored by Patchguard.  Simply put, all one has to do is overwrite the PreCallback and PostCallback function pointers in the CALLBACK_ENTRY_ITEM to dummy functions either located in one’s own driver or elsewhere.  This solution seemed to work fine and could even be reversed.  Your driver could disable the callbacks, load its cheat into the target process, then replace the callbacks through DKOM.  This is not an option when using ObUnRegisterCallbacks because the parent driver of the original callbacks would not have a handle to your newly added callbacks.

Things to consider

An anti-virus or anti-cheat software may occasionally attempt to re-register its callback and see if the return value is success or STATUS_FLT_INSTANCE_ALTITUDE_COLLISION.  A collision would indicate that the callback was still in place, while success would indicate that it had been removed.  While an anti-virus has little recourse if this occurs, an anti-cheat software could see this as a sign of tampering and ban the user or close the game.  The solution to this could be to register your own callback at the same altitude as the callback you’re replacing, meaning the anti-cheat will get the collision value and assume its callback is still in place.

An anti-virus or anti-cheat software could check the integrity of its callback items by walking the list itself.  While this is obviously a bad idea in general, if their objects are being manipulated directly it seems like the most direct countermeasure.  Of course, this would spell disaster if a service pack update came out and suddenly anti-viruses and anti-cheats started bugchecking people’s computers because an opaque structure definition changed.

I feel like this is one of the ‘cleanest’ ways to deal with modern anti-cheats kernel modules.  This allows Ring 3 cheat delivery systems to work again without modification and should be relatively stable.  I have no doubt that a similar solution could be used for PsSetLoadImageNotifyRoutine, which I intend on researching next.  I’m sure that the anti-cheat developers will come up with new, exciting, and clever countermeasures to our countermeasures, and the cat and mouse game will rage on 🙂

Doug “Douggem” Confere

How to make a DayZ Standalone admin menu

Hey fellow DayZ admins!  Keeping cheaters out of your servers can be hard, and we don’t have a lot of official admin tools yet, so I’m releasing info on creating your own admin tool!

Back in November when the BE Kernel Module for SA was going to be in the “next patch”, I said I was going to release admin menu and injector source when it went live. At the time I expected “next patch” to be in a few weeks, not months. In the time since I made that promise the kernel module has improved, breaking the user mode methods I was using to inject (including a really slick modified PBO that callextensioned your admin menu which hid the modified PBO – I was pretty proud of it even if it was stupid!). It’s all kernel now. Since things have changed, I’m having to alter my release. Instead of admin menu source and injector source, I’m going to release basic admin menu source with detailed explanations of how to flesh it out into your own personal admin menu.

The reason for this is because I’d rather enable people to make their own admin menus than just give them admin menus, and also because there are about a hundred 12 year olds waiting for me to release something so they can start selling it on Skype. This way they’ll actually have to do some work themselves to get a working sellable admin menu which I don’t expect any of them to do.

1 – Introduction

Well shit dawg, the Battleye kernel module just went live (at the time when I started writing this)! It’s blocking access to the DayZ process from our external admin menus. What ever will we do guys? In the words of Eugen Harton, no admin menuers anymore

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


Much like increased police presence in one neighborhood will push criminal activity to another, this hurdle in the way of external admin menus is going to push most people to internal admin menus. It’s possible to make your own driver to read the DayZ process’s memory, but it’s a lot easier to fire up Xenos and inject a DLL. This is ultimately a good thing for heckers, as internal cheats are actually easier than external ones! Reading classes and calling engine functions is much easier when you’re in the process than when you’re in some other process. Instead of writing ReadProcessMemory wrappers and manually dereferencing everything, all you have to do is map out your classes! And for calling engine functions, instead of making a system to write bytecode into the target process to call the function and calling createthread on it, you just have to make a function pointer and call it!

So let’s do that! Let’s create a simple internal admin menu.

1.1 – Internal vs External

An external admin menu is a admin menu made as a second separate program from the game entirely. To get information from the game or to write information to it, we have to get a handle to the process and use ReadProcessMemory and WriteProcessMemory to view and manipulate the memory of the game. The information taken from the game is used to draw radars or ESP overlays, or sometimes a admin menu might just manipulate memory in the game in order to spawn items or teleport the character. Because external cheats can be written in Fisher Price languages like C#, they can be made very quickly. They are also very ‘safe’ in the terms of causing the game to crash – if you’re just reading from the game to draw a radar and you mess something up, you might crash your own program but not the game.

An internal admin menu is code that’s loaded into the game itself instead of being in a separate program. This means you can interface with the memory of the game as if it were in your own program! This makes things very very easy as we don’t have to manually add up offsets and do dereferences through function calls to ReadProcessMemory. We also have added power since we can hook functions in the game and directly call the game’s functions, which can both be done from an external admin menu but it’s much more involved and difficult. But with this ease of use and power comes responsibility – if we done goof too bad we can crash the game. If we try to dereference a bad pointer or write to something we don’t have permission to write to we will cause an exception that, if not handled, will crash our game. This means in early testing when you make some small mistake you can crash over and over again until you figure it out.

Each system has its own advantages and disadvantages, but because of the BE Kernel Module it is much easier to make an internal admin menu than an external, so that is what we will be doing in this tutorial.

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


An external admin menu is usually its own free-standing program that displays information in its own window

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


An internal admin menu is loaded into the game and usually displays information inside the game itself

1.2 – Getting object information in an internal admin menu
0xDFCDD8] + 0x13A8] + 4]
That’s the path to your local player in Arma 2 OA. Or, it was a few patches ago. If you’ve made external admin menus you probably understand that notation – you read the value at 0xDFCDD8, then add 0x13A8 to the result, read that, add 4 to the result, and read that.

Why? Why DFCDD8? Why do you add 13A8 to whatever’s there? Well, I’m super bad at explaining this but I’m going to give it a shot. Imagine we make the following class:

PHP Code:
class TheNumbers {
int numberOfNumbers;
bool numbersFilledIn;
bool numbersDeleted;
bool myDogIsCool;
bool cowwaDooty;
float numberCoefficient;
int* numbers;
};

Let’s say we create an instance of that class and fill the members in. That class is going to be located somewhere in memory, right? And it’s going to take up a certain amount of memory, right? How much memory will it take up? Assuming 32 bit an int is going to take up 4 bytes, a bool is going to take up 1 byte, a float is going to take up 4 bytes, and a pointer is going to take up 4 bytes. So we end up with:

1 int: 4 bytes, 4 bools: 4 bytes, 1 float: 4 bytes, 1 pointer: 4 bytes. 4 + 4 +4 + 4 = 16 bytes total.

So if our class is located at memory address 0xD0000, it takes up bytes 0xD0000 through 0xD0010. So if we want to pull something out of that class in memory, say myDogIsCool’s byte, we know that it’s somewhere in those 16 bytes. But how do we figure out which one? Well, assuming the class isn’t re-arranged by the optimizer, it’s pretty straightforward!

Since numberOfNumbers is the first member of the class, it should be the very first thing in the class in memory, right? So if our class is at 0xD0000, numberOfNumbers should be right there at 0xD0000! Since an int is 4 bytes big, the next thing in the class, numbersFilledIn, should be 4 bytes into the class! That means it should be at 0xD0004! So the class looks like this, with the memory address of each member as well as how far it is in the class:

PHP Code:
/* 0xD0000 */ class TheNumbers {
/* 0xD0000 */ int numberOfNumbers; // 0x00
/* 0xD0004 */ bool numbersFilledIn; // 0x04
/* 0xD0005 */ bool numbersDeleted; //0x05
/* 0xD0006 */ bool myDogIsCool; //0x06
/* 0xD0007 */ bool cowwaDooty; //0x07
/* 0xD0008 */ float numberCoefficient; //0x08
/* 0xD000C */ int* numbers; //0x0C
};// Size: 0x10

What if we want to read the number pointed to by numbers? We need to read the pointer and then read the memory pointed to by the pointer. So we would go to the address of TheNumbers, then add the offset of the pointer we want to read(0xC), read the value at the address (read the memory at 0xD000C, which is the pointer), then read the memory address that the pointer points to.

So we end up with this:
numbers = 0xD0000 + 0xC] which is in a notation you should be familiar with. Now imagine TheNumbers was a game class that someone had partially reversed. We know it resides at 0xD0000 and know the pointer to numbers is at 0xC in the class, but don’t know any of the other members. We would write the class like this:

PHP Code:
/* 0xD0000 */ class TheNumbers {
/* 0xD0000 */ char buffer[0xC]; // 0x00
/* 0xD000C */ int* numbers; //0x0C
};// Size: 0x10

That puts numbers in the correct place even though we don’t know what comes before it. So why? Why do it? Why write out classes like this? It allows us to interact with game classes as if they were our own classes. Take our definition for TheNumbers above, if we want to get the “numbers” value from the pointer in the class, this is all we have to do:

PHP Code:
TheNumbers* globalNumbers = (TheNumbers*)0xD0000;
int numbersValue = *globalNumbers->numbers;

That is, we make a TheNumbers pointer for 0xD0000, then dereference the ‘numbers’ pointer to get the ‘numbers’ value! So with our classes mapped out we can easily dereference members which makes things much, much simpler.

1.3 – Null pointers and crashes, Doug’s system for stability
So let’s take some actual Arma classes and make a real-world example:

PHP Code:
class World {
char buffer[0x13A8];
EntityLink* cameraOn;
};

class EntityLink {
int referenceCount;
Entity* entity;
};

class Entity {
char buffer[0x18];
VisualState* visualState;
};

class VisualState {
char buffer[0x28];
D3DXVECTOR3 position;
};

Awesome! If we know our World pointer is 0xDFCDD8, we can get our local player position super easy!

PHP Code:
World* gameWorld = *(World**)0xDFCDD8; // NOTE: Casting to pointer-pointer and dereferencing because DFCDD8
//isn't world, but a POINTER to world!
D3DXVECTOR3 localPlayerPos = world->cameraOn->entity->visualState->position;

Hot damn hellz yeah! But wait, now I crash all the time! If I inject before I’m all the way in game I crash, and I crash if I die, what’s up?

Muh’ fuggin null pointers my friend

If you try to dereference a pointer that points to a bad place in memory, you will crash. Null pointers (pointers with a value of ‘0’) are always bad and attempting to dereference them will result in a crash. Why is this important? If you try to get your local position as above before your local player is created or at any time where he does not exist, the pointer to him will be null and you will crash when you try to dereference!

So what do we do? Well, we need to check every pointer every time. The naive method is this:

PHP Code:
World* gameWorld = *(World**)0xDFCDD8;
D3DXVECTOR3 position(0, 0, 0);
if(gameWorld != nullptr) {
EntityLink* cameraOn = gameWorld->cameraOn;
if (cameraOn != nullptr) {
Entity* localPlayer = cameraOn->entity;
if (localPlayer != nullptr) {
VisualState* localPlayerVisualState = localPlayer->visualState;
if (visualState != nullptr) {
position = visualState->position;

Alternatively, some people do this:

PHP Code:
World* gameWorld = *(World**)0xDFCDD8;
D3DXVECTOR3 position(0, 0, 0);
if (gameWorld)
if (gameWorld->cameraOn)
if (gameWorld->cameraOn->entity)
if (gameWorld->cameraOn->entity->visualState)
position = gameWorld->cameraOn->entity->visualState->position;

These methods work fine! They’re just very ugly. I, personally, would suggest that if you decide to use this method, instead of nested if statements you would instead combine them into one if statement. It’s ugly too, but you don’t end up on the very right side of your visual studio pane writing code because you’re so deep in if statements.

PHP Code:
World* gameWorld = *(World**)0xDFCDD8;
D3DXVECTOR3 position(0, 0, 0);
if (gameWorld && gameWorld->cameraOn && gameWorld->cameraOn->entity && gameWorld->cameraOn->visualState)
position = gameWorld->cameraOn->entity->visualState->position;

Bonus points if you assign a pointer to shorten that assignment statement:

Quote:
World* gameWorld = *(World**)0xDFCDD8;
D3DXVECTOR3 position(0, 0, 0);
VisualState* localPlayerVisualState = nullptr;
if (gameWorld && gameWorld->cameraOn && gameWorld->cameraOn->entity && localPlayerVisualState = gameWorld->cameraOn->visualState, localPlayerVisualState != nullptr)
position =localPlayerVisualState->position;

Delegating pointer checks

Of course, if you do this everywhere in your code it will get very long and very ugly very quick. I choose to use a different method: I make each class responsible for verifying its own pointer by wrapping dereferences in class functions. Let me show you what I mean:

PHP Code:
class World {
char buffer[0x13A8];
EntityLink* cameraOn;

EntityLink* getCameraOn() {if (!this) return nullptr; else return cameraOn;}
};

class EntityLink {
int referenceCount;
Entity* entity;

Entity* getEntity() { if(!this) return nullptr; else return entity; }
};

class Entity {
char buffer[0x18];
VisualState* visualState;

VisualState* getVisualState() { if(!this) return nullptr; else return visualState; }
};

class VisualState {
char buffer[0x28];
D3DXVECTOR3 position;

D3DXVECTOR3 getPosition() { if(!this) return D3DXVECTOR3(0, 0, 0); else return position; }
};

So to get our local player’s position we do the following:

PHP Code:
World* gameWorld = *(World**)0xDFCDD8; // Ok ya got me, we DO assume this pointer is good!  You can add your own check for that
D3DXVECTOR3 position = gameWorld->getCameraOn()->getEntity()->getVisualState()->getPosition();

If ANY of those pointers are bad, it will pass a nullptr to the next function which ultimately gets to getPosition. When getPosition is passed a null pointer, it returns a null vector! So we don’t have to check any of our pointers manually anymore, they’re all done automatically by our delegated functions!

Using macros to make pointer checking even simpler

But what if my classes are all messed up and I try to dereference a float as a pointer or something? Yeah I do that stuff sometimes too, that’s why I use a few simple macros to assist in my pointer checking. They run IsBadReadPtr on the this pointer and if the pointer IS bad, it bails out.

PHP Code:
#define CHECK_BAD(x) if(IsBadReadPtr(this, sizeof(x))) return
#define CHECK_BAD_NUM(x) if(IsBadReadPtr(this, sizeof(x))) return 0
#define CHECK_BAD_PTR(x) if(IsBadReadPtr(this, sizeof(x))) return nullptr

Used in our original classes, they would look like this:

PHP Code:
class World {
char buffer[0x13A8];
EntityLink* cameraOn;

EntityLink* getCameraOn() {CHECK_BAD_PTR(World); return cameraOn;}
};

class EntityLink {
int referenceCount;
Entity* entity;

Entity* getEntity() { CHECK_BAD_PTR(EntityLink); return entity; }
};

class Entity {
char buffer[0x18];
VisualState* visualState;

VisualState* getVisualState() { CHECK_BAD_PTR(Entity); return visualState; }
};

class VisualState {
char buffer[0x28];
D3DXVECTOR3 position;

D3DXVECTOR3 getPosition() { CHECK_BAD(VisualState) D3DXVECTOR3(0, 0, 0); return position; }
};

You’ll notice since CHECK_BAD leaves an open return statement at the end of the macro, we can use that to return objects or something other than nothing, 0, and nullptr. With this system of delegation and automatic checking of (hopefully!) all dereferences, we can be pretty safe from crashes due to bad pointers!

2 – Let’s Get Started

Prepare your Skypes, it’s copy/paste/resell time
2.1 – Common Classes
There are a few classes we will see recur over and over as we go through the classes we want to pull information from.

ArmaString

PHP Code:
class ArmaString
{
public:
__int32 referenceCount; //0x0000
__int32 Length; //0x0004
char string[1]; //0x0008
char* getString() { CHECK_BAD_PTR(ArmaString); return string; }
}

This is how Arma encapsulates its strings. It’s a very simple object, nothing really exciting here.

AutoArray

PHP Code:
template <class T>
class AutoArray {
public:
T* cArray;
int count;
int max;
};

The AutoArray. These are EVERYWHERE! And is how Bohemia likes to keep arrays of objects. It’s a pointer to an array, a count of how many items are currently in the array, and the max size before the array will have to be resized and reallocated. Using this templated class will make your iteration MUCH easier! You can add your own add, remove, and resize functions to manipulate arrays and do some pretty cool things.

TackLLinks

PHP Code:
template <class C>
class TrackLLinks
{
public:
void* vtable;
__int32 refCount; //0x0004
C* link; //0x0008
char _0x000C[4];

C* getLink() { CHECK_BAD_PTR(TrackLLInks; return link; }
};//Size=0x0010

These encapsulate a pointer to an object and appear quite frequently in Arma classes. They’re typically used to keep a reference to a parent or to the object that contains the link itself.

2.2 – The Entity Class
I would encourage you guys to make separate soldier/vehicle class that share the same base class. However, in the interest of brevity I will not be doing that here and will outline only one “catchall” entity class. We will get enough information from the entity to get its name and position so we can draw it on the screen.

PHP Code:
class Entity
{
public:
char _0x0000[28];
EntityVisualState* visualState; //0x001C
char _0x0020[48];
EntityType* entityType; //0x0050
char _0x0054[560];
BYTE isDead; //0x0284
char _0x0285[175];
EventHandler eventHandlers[38]; //0x0334
char _0x062C[64];
GameVarSpace variables; //0x066C
char _0x0684[184];
AIAgent* agent; //0x073C
char _0x0740[4];
ArmaString* playerName; //0x0744
char _0x0748[168];
__int32 _playerID; //0x07F0
};//Size=0x07F1

You can tell right off by looking at the class that we can get a few things directly from this class. The byte isDead is exactly what it sounds like – if it’s non-zero, the entity is dead. If it’s zero, the entity is a live. We can also grab our player name directly from here so we don’t have to mess with the network manager.

To get our position, we need to look int the EntityVisualState class:

PHP Code:
class EntityVisualState
{
public:
char _0x0000[28];
Vec3 Direction; //0x001C
Vec3 Coordinates; //0x0028
char _0x0034[252];
Vec3 _headCoords; //0x0130 - only in man classes
Vec3 _torsoCoords; //0x013C  - only in man classes

};//Size=0x0148

The coordinate vector is the position at the player’s FEET if it’s a human, so be careful! If you want to draw your ESP markers above a player’s head, take the head coords and add a half a meter or so. Using head and torso coords you can draw a poor man’s skeletal ESP as well, which is what I do.

But how do we know if it’s a man or not? Well, we will look inside the EntityType class

PHP Code:
class EntityType
{
public:
char _0x0000[40];
LODShape* lodShape; //0x0028
char _0x002C[8];
ArmaString* _entityName; //0x0034
char _0x0038[4];
ArmaString* N092957C9; //0x003C
char _0x0040[48];
ArmaString* _entityType; //0x0070

};//Size=0x0074

entityType is “soldier” or “car” etc. while entityName is the class name such as “manParts01” or “zombie02” etc. You can use these strings to if and how to draw an entity. Pro-tip: all entities of the same type share an entityType object, so you could keep track of the objects and store their types in an enum instead of doing string comparisons to speed up your admin menu a little bit.

So we know how to get basic information from entities, but how do we get those entities?

2.2 – The World Class
World stores tons of information on the simulation – entities in the game world, weather information, ALL KINDS of stuff! It’s hella important.

PHP Code:
class World
{
public:
char _0x0000[36];
InGameUI* inGameUI; //0x0024
char _0x0028[1860];
AutoArray<EntityContainer>* fastEntities; //0x076C
GameVarNamespace* missionNamespace; //0x0770
GameVarNamespace* profileNamespace; //0x0774
char _0x0778[740];
EntitiesDistributed mobiles; //0x0A5C
EntitiesDistributed animals; //0x0D20
EntitiesDistributed slowEntities; //0x0FE4
EntityList stationaryEntities; //0x12A8
char _0x1358[52];
EntityList unknown; //0x138C
char _0x143C[708];
EntityLink* cameraOn; //0x1700
char _0x1704[4];
EntityLink* playerOn; //0x1708
EntityLink* realPlayer; //0x170C
char _0x1710[52];
float actualOvercast; //0x1744
float wantedOvercast; //0x1748
char _0x174C[4];
float actualFog; //0x1750
float wantedFog; //0x1754
char _0x1758[4];
float actualFogBase; //0x175C
float wantedFogBase; //0x1760
char _0x1764[8];
float aperture; //0x176C -1 for automatic, otherwise adjust by VERY small increments like 0.001
};

With the important sub classes here:

PHP Code:
class EntitiesDistributed
{
public:
char _0x0000[4];
EntityList nearEntities; //0x0004
EntityList farEntities; //0x00B4
EntityList invisibleNearEntities; //0x0164
EntityList invisibleFarEntities; //0x0214

};//Size=0x02C4

class EntityList
{
public:
char _0x0000[4];
AutoArray<EntityBase*> entities
char _0x0010[160];

};//Size=0x00B0

class InGameUI
{
public:
char _0x0000[32];
EntityLink* targetEntity; //0x0020
char _0x0024[8];
Vec3 cursorCoords; //0x002C
char _0x0038[72];

};//Size=0x0080

class EntityLink
{
public:
char _0x0000[4];
Entity* entity; //0x0004

};//Size=0x0008

class EntityContainer
{
public:
EntityLink* entityLink; //0x0000
char _0x0004[36];
TrackLLinks<EntityType>* entityType; //0x0028

};//Size=0x002C

// EntityList points to a base class of what fastEntities and CameraOn etc. point to
class EntityBase
{
public:
char _0x0000[40];
Entity entity; //0x0028
};

Getting Entities
fastEntities containers other players and vehicles. Zombies, animals, and loot on the ground are contained in the other EntitiesDistributed and EntityLists in the World class. The lists can be iterated through very easily:

PHP Code:
AutoArray<EntityBase*>* nearAnimals = World->animals->nearEntities->entities;
for (int i = 0; i < entities.count; i++)
Entity* entity = entities.cArray[i];
// Then do whatever you want with the entity object!

Add checks for null pointers (Or delegate them!) as appropriate! Since when we made our class we already sorted the entity lists into near, far, visible, invisible, and their types, it should be very easy to just go through the lists you need for your ESP.

Aperture
Aperture is how much light is let through the lens of the “camera’ that you see the game through. -1 makes it automatic, while other values allow you to fine tune it yourself. You can manipulate this value to see during the night time.

Weather
You can change these values if you want, it’s kinda fun.

2.3 – Putting it all together

You’re going to have to do a little work. Flesh out your classes and work out getting information from them safely. Grab tim0n’s source and use his D3D hook and the included W2S by Fatboy. Plug everything together and you should have something made almost entirely by you from the ground up. This will decrease its detectability DRASTICALLY.

3 – Extra Stuff
3.1 – Augmenting weapons and ammo

Hit detection in DayZ is completely client sided. This has the pleasant side effect of trusting whatever your client says with regards to shooting and hitting people. Your client tells the server you swung your first and a frag grenade came out at 2000m/s and exploded next to a dude on the other side of a wall? Sure, why not, client! Let me tell that guy he’s dead!

This means we can change the values of our weapons and ammunition. We can change our ammo’s damage, how it’s effected by gravity, etc. We can make changes to magazine types to make our guns shoot different bullets as well.

PHP Code:
class AmmoType
{
public:
char _0x0000[52];
ArmaString* name; //0x0034
char _0x0038[12];
AmmoType* parent; //0x0044
char _0x0048[40];
ArmaString* type; //0x0070
char _0x0074[188];
float directHit; //0x0130
float indirectHit; //0x0134
float indirectHitRange; //0x0138
char _0x013C[64];
float explosive; //0x017C
float caliber; //0x0180
float deflecting; //0x0184
float deflectionSlowDown; //0x0188
float timeToLive; //0x018C
float airFriction; //0x0190
float coefGravity; //0x0194
float typicalSpeed; //0x0198
char _0x019C[8];
__int32 simulation; //0x01A4
char _0x01A8[664];

};//Size=0x0440

class MagazineType
{
public:
char _0x0000[52];
ArmaString* name; //0x0034
char _0x0038[4];
ArmaString* model; //0x003C
char _0x0040[48];
ArmaString* type; //0x0070
char _0x0074[3276];
__int32 type; //0x0D40
__int32 count; //0x0D44
char _0x0D48[4];
float initSpeed; //0x0D4C i.e. muzzle velocity
char _0x0D50[4];
__int32 quickReload; //0x0D54
char _0x0D58[432];
AmmoType* N09C16026; //0x0F08

};//Size=0x0F0C

So how do we get to our magazine type? Well it’s probably somewhere in the magazine class, but I’ve never actually gotten a gun in this game so I never really looked at it. Here’s another way to find it:

At 0x2817F040 (B9 ? ? ? ? 56 57 FF 74 24 18) is a class VehicleTypeBank, which includes a hash table of all the entity types of everything currently loaded into the game. Included in this table are ammunition types and magazine types!

PHP Code:
class VehicleTypeBank
{
public:
char _0x0000[16];
AutoArray<AutoArray<TrackLLinks<EntityType*>*>> types;

};//Size=0x0044

Magazinetype and Ammotype inherit from a base class shared by EntityType, which means the name and type armastring pointers are in the same place (0x34 and 0x70). So you can iterate through all the types, look for your magazine or ammo by name and make changes appropriately.

Source will be coming soon. This has been sitting in my google drive for a looooooooong time but I never really was motivated to finish it, so I an going ahead and posting it. Will slap together a working source and post in the next week or so

I would encourage you guys to share snippets of your own solutions and classes since I don’t play this game and so don’t really admin menu it.

Simple script injection – OnEachFrame

So I learned about OnEachFrame the other day https://community.bistudio.com/wiki/onEachFrame and thought I’d take a look at it.


As you can see, all it does is take the ArmaString pointer from the argument object and put it in a global GameValue object. That’s it – that’s all OnEachFrame is. It’s a global GameValue object that has its text, if there is any, executed on each frame. So I figured, why not make a really simple executor from it?

</div>
<div>// A2 allocator.  Not used for everything.</div>
<div class="alt2" dir="ltr">typedef void *(WINAPI* A2Malloc)(SIZE_T);
typedef void (WINAPI* A2Free)(void*);
A2Malloc MemAlloc = *(A2Malloc*)0xDBF2A0;
A2Free MemFree = *(A2Free*)0xDBF2A4;
// To get with sig:
/*
DWORD mallocObject = DUtils::findPatternPlusBytes((DWORD)a2oaModule, (DWORD)a2LastModuleByte, "FF 15 ? ? ? ? 8B F8 85 FF 75 54", 2);
MemAlloc = *(A2Malloc*)mallocObject;
MemFree = *(A2Free*)(mallocObject + 4);*/


class ArmaString {
public:
int References;
int StringLength;
char AString[1];

// Call this to create a new ArmaString.  We're basically using it as a constructor without setting up an actual Allocator for A2Malloc
static ArmaString* CreateArmaString(const char* text) {
if (!text) return 0; // you're retarded

int length = strlen(text);
ArmaString *newArmaString = (ArmaString*)MemAlloc(length + 9);
if (!newArmaString) return nullptr;        // Shouldn't happen, if your MemAlloc pointer is wrong you'll crash on the call unless you get REALLY lucky
newArmaString->References = 1;
newArmaString->StringLength = length;
memcpy(&newArmaString->AString, text, length + 1);

return newArmaString;
}
};
// Kept the inheritance model in case you guys want to do things with scalars or some shit.
class GameData {
public:
void* GameDataTypeVTable;
int References;
void* DebugValueVTable;
};

class GameDataString : public GameData {
public:
ArmaString* Data;

// Calling the engine's constructor is going to be easier than manually doing our own.
typedef GameData* (__thiscall* GDConstructor)(GameData* thisptr, ArmaString* initialValue);
static GDConstructor Constructor;
GameDataString(ArmaString* initialValue) {
if (Constructor != nullptr) // If your constructor pointer is null, your object is going to be empty and you're going to crash
Constructor(this, initialValue);
References++;
}
};
// 0x9D51CB.  No unique sig, other ways to find it programatically at runtime
GameDataString::GDConstructor GameDataString::Constructor = (GameDataString::GDConstructor)0x9D51CB;

class GameValue {
public:
void* GameValueVTable;
GameData* Value;
};

GameValue* OnEachFrame = (GameValue*)0xDB0614;

void InjectScript(const char* scriptText) {
ArmaString* script = ArmaString::CreateArmaString(scriptText);
GameDataString* data = new GameDataString(script);
OnEachFrame->Value = data;
}

void ExecuteScriptFile(std::string filePath) {
// execVM "filePath"; onEachFrame{};
// gotta clear the onEachFrame event since I know you tards won't do it yourselves
std::string scriptText = "execVM \"" + filePath + "\"; onEachFrame{};";
InjectScript(scriptText.c_str());
} 


Super simple, able to be done externally without any nasty CreateThread function calls from the outside (pump up the reference count on your strings and GameData objects so they don’t get freed by Arma), and very stable.  Will port to A3 and SA very soon.

DayZ Standalone script function descriptions and addresses

The Real Virtuality engine keeps a sort of catalog of script engine functions, descriptions, and examples in memory while it’s running.  This catalog is walked by the script VM when searching for a script function, and it can be dumped to easily get an enumeration of script engine functions.  This is a dump of the latest catalog for the DayZ Standalone, and can be used to easily find script function addresses to reverse them.  It’s linked as a private paste because it’s so massive and WordPress is weird about formatting: http://privatepaste.com/325702e386/Douggem

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