Go Back

Rift - Entity Components

My previous blog basically showed you how I got all the entities from Rift, but it did not show you how to get the needed data from the entities. Thing's like 'what type of entity is it', 'where is it located', etc. In this blog I'll try to explain how I found out how Rift stores this data.

As with my previous blog, I wrote using an open-beta executable. For this part it is a must. The release-executable no longer contains the information that I will be talking about, which will make it a whole lot harder to find out which entity component your dealing with.

When analyzing Rift (when looking at how it handles entity data) you will often see code that looks like this:

v5 = *(_BYTE *)(dword_12055DC + entity + 24);
if ( v5 == -1 )
  v6 = 0;
else
  v6 = *(_DWORD *)(*(_DWORD *)(entity + 88) + 4 * v5);

The dword_12055DC usually varies, but the code is almost always the same. Although you might sometimes see it mixed up in other if-statements (usually it's only the first line of the above block).

Basically every entity in Rift is build up out of several components, the code that is shown gets the entity component address (if the component exists). From what I gather, each component has an id/index. When a component gets added to an entity, it's component index is used to look up the index of the address. Why the component index isn't directly used directly to get the address is a bit of a mystery to me.

The above code however does not get you very far, considering there are likely around 64 possible entity components. To find out what entity component the game is accessing you need an open-beta executable. They removed the string-names (for each component) from the release.

If we look at the cross reference of dword_12055DC, you will notice that there is one line of code that stands out "mov eax, offset dword_12055DC". This line is shared between all entity components. If we go to the function, you will notice that the only thing it does is return the offset. If we cross reference that function, we will notice its used in a v-table.

We're interested in the first function in the v-table, usually (always?) the constructor, to give us a clue on which component it is. The release executable has no info for you there (as said they removed all string references). However the above component had this constructor in the beta:

_UNKNOWN *__cdecl sub_615970()
{
  int v0; // eax@2

  if ( !(dword_1264178 & 1) )
  {
    dword_1264178 |= 1u;
    v0 = sub_5CB980(0);
    sub_A2B6C4((int)&unk_126414C, "ClientEntityComponentNPC", v0);
    atexit(sub_105B3B0);
  }
  return &unk_126414C;
}

Now isn't that lovely, we just got the name of the component. While it doesn't magically give you all the information that you need, it does help you understand what it is used for.

For me, 5 components where of interest:

  • The ClientEntityComponentActor component, it stores health of the entity
  • The ClientEntityComponentPlayer component, it stores the player's name
  • The ClientEntityComponentNPC component, it stores the NPC's name (but only if it is different from it's original name)
  • The ClientEntityComponentMod component, it stores the entities faction
  • The ClientEntityComponentTransform component, it stores the location of the entity

I will not go into detail on all of these components (heck I don't know half of the info that is stored in them), but I will go into two. The Transform component and the Player component.

The Transform component is the easiest of them all. We have to look up the /loc command. Using the same technique used in the previous blog. When looking at the code of SlashLoc, we notice that it uses an entity component (ClientEntityComponentTransform) and right after that it loads a couple of variables from the address.

v3 = *(_BYTE *)(ClientEntityComponentTransform + entity + 24);
if ( v3 == -1 )
  v4 = 0;
else
  v4 = *(_DWORD *)(*(_DWORD *)(entity + 88) + 4 * v3);
v6 = *(_DWORD *)(v4 + 0x3C);
v12 = *(_DWORD *)(v4 + 0x38);
v14 = *(_DWORD *)(v4 + 0x40);

You can probably guess what it loads. As I said, this was the easiest (and I wasn't kidding! :).

The Player component probably stores a lot more then "just the name" but I only needed the name. Unlike the Transform component, the player's name is stored 2 levels deep.

To find the player name we go back to the SlashTarget function from the previous blog, and we go into sub_64A500 again. We look through the function and dive into sub_5E5110 and then dive straight into the only function in there as well. If you look into that function, you will see three components being used. There's a big if-statement, checking if there is a player address or not. We are interested in the first function that gets called when there is a player address (sub_616270).

If you look into that function, the first code line reads as follows (in the o-beta exe) "sub_57B7E0((void *)(*(_DWORD *)(this + 0x2C) + 0xA0), (int)&v3);", and guess what. In the open beta, the pointer at "((playerNameAddress + 0x2C) + 0xA0)" pointed to a unicode string with the player name in it. In the release its 0x2C + 0x180 .

The use of entity components makes it a lot harder to find values that your interested in. I, for example, would love to find out the class of a player. But haven't gotten around to looking at where the game stores it. Health took a while to figure out, I found that using a debugger and simply back-tracing each of the pointer addresses.

For the standings/faction I used "SlashFollow", since you can't follow enemies the game must check the standings in "SlashFollow" (and it does).

I have no code example for this part, but if anyone is interested, I could make an example for it. Leave a comment if you are (or if you have questions).

One small warning, there's some extensive error checking inside Rift, crashing the client (or pausing the debugger too long when performing certain actions) can get you banned!  Be careful!

Posted by: Da_Teach on Monday, March 07, 2011  •  Comments (10)  •  Full story  •  Pointers Rift IDA Pro

Rift - The Entities

For the purpose of this blog I will refer to an older version of Rift (an open beta version, dated 20-2-2011), since the latest version is missing some of the IDA info (lazy :) and I expect you to have some IDA and debugging knowledge and I expect you to have the decompiler plugin as well.

Well I said I was going to blog about Rift, so here is the first in a few blogs about Rift. I will not have any code-samples for you to play with and you will have to lookup the latest pointers yourself (if you wish to play with this info). But I'll try to explain how I got the info that I needed.

The first thing I am usually interested in when looking at a new MMO is the way it stores its entities, you know the other players, the npcs, etc. Knowing how the game stores it's entities is vital for creating bots, radars, etc. It is not vital for float hacking, teleport hacking and speed hacking, but I usually stay away from those types of hacks.

We know what we are looking for, but the question quickly arises "how do you look for something like that", well luckily for us hackers most new MMO's have in-game commands and functions to help you out. Rift also has a command which helps you to find this and it's called "/target". With that nice command you can target anything in-game by name. As such this command must (somehow) loop through all the entities (or at least part of them) to find out which entity you want to target.

So the first thing we want to do is find the function responsible for the target-command, we open up IDA's string-list and look for "target" and we look at the references to "aTarget" (the variable name IDA gives it), one line stands out which is "mov eax, offset aTarget". If we visit the reference, we find a function which is pretty empty. If we check the reference of that function, we see its a virtual function of a class. With a bit of trial/error, it was easy to find out that the class in question is indeed the target-command class, and the 3rd virtual function is the actual SlashTarget function (we will call it SlashTarget from now on). The process of finding the correct function differs per game, but in this case it was easy.

If we open up SlashTarget we see a reasonably large function, which does a lot of things. Most of which we do not care about, the one thing we do care about though is the string "No target with the name: [%NAME]", it indicates that the target we are looking for does not exist. If we look a bit up (in the decompiled view) then we see that a function is called prior to the "if" that leads to the "No target" string. In this case it was sub_64A500. If we open up that function we see a "while (1)" loop.

I will spare you the details, while the loop does loop through all the entities. It is not looping through the actual entity list but rather a copy of it. Having no idea how it got this copy, I did something that I usually try to avoid (with a passion), I opened up OllyDBG set a breakpoint at the start of SlashTarget and at the end of SlashTarget, used the command and traced all instructions. This is a horrible way of reverse engineering, but it does work :) (note, I did have to enable "Remember memory" in the debugging -> run trace options of OllyDBG)

Ending up with a 100-150mb tracelog, you can understand why you'd want to avoid this. However it does give meaningful insight. The way I went about it was to do a "/target <someone>" and having the name in lowercase. This way I could see the difference between the entity name and the target-command argument. Now I looked for the first occurrence of <someone> in the correct case. From there I back-traced all the pointers to its origin.

The first occurrence of the pointer was inside the function (sub_6E0100) that copied the entity list. Back tracing where it was called I found out that it was indeed called from sub_64A500, and to be more precise this line "(*(void (__thiscall **)(void *, struct tm **))(*(_DWORD *)v8 + 0x18))(v8, &Tm);" (yeay for IDA screwing up half of rift by adding some TM structure).

It's reasonably easy to find out what function is at 0x18, if you look at the v8 you see its filled by a function a few lines above the call. If you look into that function then near the end you will see that it is actually setup by another function. Then if you dive into that function you'd see what the class v-table is. If you go to the v-table and get the function at 0x18 (the 6th function), the function should look like this. If you then dive into that function you will see sub_6E0100 being called.

If we inspect sub_6E0100 we'll probably agree that it's a bit of a nasty beast. At least it took me a few tries to get the data out correctly (at least I think I have it correct now). I can't remember how I exactly found out, but the EntityManager that I marked when looking for the v-table has the entity array that this function is looping through at offset-4 and the length (parameter a3) at offset-8. I am pretty sure that was from back-tracing the trace-log.

After a lot of trial and error (and trying to figure out how the freaking sub_6E0100 function worked), I came to this C# code:

var entityManager = memory.ReadInteger(_entityManager);
var entityArray = memory.ReadInteger(entityManager + 4);
var entityArrayLength = memory.ReadInteger(entityManager + 8);

var items = new List<int>();
for (var i = 0; i < entityArrayLength; i++)
{
    var entityArrayItem = entityArray + i * 0x18;
    int nextAddress = memory.ReadInteger(entityArrayItem + 0x10);
    if ((nextAddress & 1) == 1)
    {
        nextAddress ^= 1;
        if (nextAddress == 0)
            continue;
    }

    while (true)
    {
        items.Add(entityArrayItem);

        entityArrayItem = memory.ReadInteger(entityArrayItem + 0x10);

        if ((entityArrayItem & 1) == 1)
            entityArrayItem ^= 1;
        if (entityArrayItem == 0)
            break;
    }
}

I did a few compares a bit differently then the original Rift code, mostly because I wasn't getting the expected behavior in C# (mainly the ^= part).

Basically from analyzing the function I came to the conclusion that the EntityArray is not 'really' an array but more a hash table. The initial item's are in the array (0x18 bytes in size) and if more item's are in the same bucket, then the next item is stored at 0x10 . The entity id is stored at offset 0 (its a ulong) and the pointer to the entity itself is stored at offset 8.

Why the first bit is sometimes set when there is also a pointer in at 0x10 is a bit unclear to me. Perhaps someone else can shed some light on that ? :)

The above code sample does get all entities. My next blog (that I'll put up in a few days) will explain a bit about how Rift stores data for its entities (if you have a beta-exe still lying around, look for the "EntityComponent"'s).

This game takes OO very serious, things are stored so many level's deep it's very annoying :)

Posted by: Da_Teach on Saturday, March 05, 2011  •  Comments (4)  •  Full story  •  Rift Decompiler IDA Pro

Defense Grid: The Awakening Part #2

Since Defense Grid: The Awakening used a, for me, unknown PE Packer, the easiest way to disassemble it is to dump the executable once you have started it. There are various tools out there which allow you to do this, I used LordPE it's easy to use and has a ton of options which I didn't use ;)

The output of this dump is not a working executable. It is possible to create a working executable, but it requires more work which is often not worth the effort. The only reason I could think of would be if you wanted to pre-patch the executable, however this often is only required for cracks.

Anyways, back to the game. We now have a dumped executable which IDA Pro can actually disassemble and with the help of the Hex-Ray's wonderfull decompiler add-on, we where able to convert the function which contained the credit-modification code to semi-readable C/C++ code. While I can read assembly code, its a lot harder and more error prone.

The decompiler has some limitations, for example it can't decompile MMX instructions. If it could, the code would probably be a lot easier to understand. But here's the decompiled function (sub_8BB110)(note that I have circled parts of the function which are of interest):

sub_8BB110

As you can see, just before the instruction that modifies the credits, _EBX is filled with variable v27, that variable in turn is filled by sub_47E6E0. This might not be clear until you disassemble sub_47E6E0. As you can see in the disassembled code of function sub_8BB110, a pointer was given to v26 but in sub_47E6E0 the result is actually put into v26 and v26 + 4. The last addition actually causes function sub_47E6E0 to write into v26 and v27.

Here's what sub_47E6E0 looks like:

sub_47E6E0

I've added some names to the parameters, one of the parameters "basePointer" is especially interesting. In sub_8BB110 you will see that "basePointer" is v25 + 16. Now the fun part is that if you look back in sub_8BB110 you will see that its filled by v6 + 4. Now its not hard to guess that the same trick done by sub_47E6E0 was done by sub_47E1B0 as well. If you look at sub_47E1B0 you will see a very similar function:

sub_47E1B0

Note that the basePointer for this function is dword_B458E8 + 44.

This however only explains 2 of the 3 parameters to get the pointer to the value we're interested in. The 3rd parameter of function sub_47E1B0 and sub_47E6E0 are actually lookup values. I've called them type values in my disassembly though. These type values originate from a2 (v23 is filled with a2) and a3.

We know that the value that we are looking at is at pointer + 0x10 and if you look at sub_47E6E0 you will see that type-value that it looks for is at 0xC (12). So if we go back to Cheat Engine and decrease the pointer of "credits spent" by 4, we will know the lookup value for the "credit spent". In our case its 9. It wouldnt be hard to find the starting-credit lookup value either, but you can do that yourself ;)

This still leaves the lookup value for sub_47E1B0 (a2), for this we look at the usage of sub_8BB110. If we look at the cross reference of that function and goto the first usage of sub_8BB110, we will see that a2 is filled with dword_B458C4+212. Now I havent fully tested it, but I assume that value always has the right lookup/type value. In testing that turned out to be true anyway.

Now that we have the pointer-lookup scheme of the game, we can write a trainer which uses this information to increase / decrease the credits spent. In part #3 I'll show you how I converted the pointer-code into an external program (trainer) which will increase or decrease the credits spent.

Posted by: Da_Teach on Saturday, January 02, 2010  •  Comments (0)  •  Full story  •  Decompiler IDA Pro Defense Grid

Defense Grid: The Awakening Part #1

With Steam having those amazing sales, I picked up Defense Grid: The Awakening for something like 2-3 euro. I was bored, so sue me. I found that it was actually a pretty funny game for a few hours and then I figured, what the hell lets start hacking :D

Started up Cheat Engine and started searching for some values. Interestingly enough this game had some unexpected anti-cheat mechanisms in place.

Anyways, I went through the usual tricks, search for the credits as a integer, float, double, etc. Funny enough it seemed it was stored both as a float and a double. But changing those values did not do anything to the ingame credits.

That got me intrigued, apparently this game was either using memory-encryption or some other form of anti-cheat mechanisms. I then remembered that the first level starts off with 0 credits and a bit later in the level you got 200 credits to finish the mission. So I put Cheat Engine to work.

A minute or so later I had the starting-credits and I saw something strange. The value at this pointer never went down and in fact (by killing enemies) only went up, regardless of the amount of credits I spent.

This got me thinking, if this value does not go down, another value must be somewhere in memory that keeps track of what has been spent. So started a new mission,searched for the amount of credits spent on towers and found the value that keeps track of the amount of credits that have been spent.

Now having two values in memory it was time to find out what static addresses point to these values so I can create a trainer for the game. This is where things got funky. Normally I would use the pointer-scanner in Cheat Engine and it'll quickly tell you what base pointer points to the value. However that would be too easy wouldn't it ;)

With that not getting anywhere, I used Cheat Engine's "what changes this address" only to crash the game seconds later. I should have known because its a Steam game, it has anti-debugger protection. So I booted up my VMware image with Syser and repeated the whole process.

I found out that the code-address changing was at 8BB1FCh, the instruction in question as "movss dword ptr [ebx+10h], xmm0", great.

As I was interested in base address of the value, I booted up IDA Pro Disassembler which has to be the best disassembler on the market at this moment. Only to find out that there was yet another protection in place, the executable had been packed by a PE Packer.

For 2-3 euro, I didnt expect this many protections in place, but it sure made hacking this game so much more interesting. Anyways, check out part 2 which will be posted later to find out a way to get around a PE Packer. Its only one of the possible ways, but its probably the easiest way.

Posted by: Da_Teach on Friday, January 01, 2010  •  Comments (0)  •  Full story  •  Syser IDA Pro Cheat Engine Defense Grid