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 (9)  •  Full story  •  Pointers Rift IDA Pro

Alien Breed: Impact

I recently bought Alien Breed: Impact from Steam, an Arcade Shooter (as they call it themselves) that gave me back 'old' feelings (they don't make that many games like it anymore). Anyways, I played it for a while but the controls of the game are horrid. I ended up getting annoyed by the controls. So the logical next step is to hack it ;)  By the way, if the controls where better, it would be a lot more fun to play.

However, Alien Breed uses the Unreal 3 Engine. Several other games use it too, like Mass Effect 2, which made me 'worry' a bit. The Unreal 3 Engine takes OO-programing to another level. As soon as I found some values (ammo/health) my suspicions where confirmed. Just like Mass Effect 2, Alien Breed uses 1 function to subtract nearly every value in the game.

Initially I wanted to give up, not that hacking it is impossible. It is just a lot of work and is it really worth it? I decided not to give up. And my decision will probably make me look into Mass Effect 2 again.

After putting a (memory-write) break-point on the ammo value, I saw that the instruction at 0x4BE228 is responsible for subtracting health, ammo, enemies health, cash, etc. Replacing the the "sub [ebx], eax" instruction with nothing (nop's) worked.  Ammo was frozen and I couldn't die. But it also made it creatures, windows, etc invincible.

The next step in the chain was to trace (using Syser) the function's return address (which was 0x4C5331), that was a dead-end too. All values used this same function. Instead of digging deeper, I decided to try and find something in the call-arguments of the subtract function (0x4BE180) that allowed me to identify the values it was subtracting from.

To do this I had to figure out a bit on how the subtract function worked. This wasn't easy, mainly because the function accepts a wide array of values it has to subtract from. Through tracing I found out that the first call within the function (call edx at 0x4BE1B5) retrieves the pointer to the value it is going to subtract from.

Looking at the first call that it does, we find out it bases this call on the value that is present at the first argument + 0x18 (it loads the first argument in esi @ 0x4BE183 and then loads a the pointer from [esi+0x18] into eax). It loads a byte from the pointer that it gets, and then uses that to call the function for the address to the value. For ammo, health, cash, that value is 1. The function that it calls when the value is 1 is 0x4BB610.

Inspecting this function gets us to the following conclusion, [[[first argument + 0x18] + 0] + 0x64] contains the offset of value compared to the class that is calling the subtract function. While checking out the memory address that [[first argument + 0x18] + 0] points to, I saw that [[[first argument + 0x18] + 0] + 4] points to a value identifier. For ammo this identifier is 32810 and for health its 5685.

With this info we can determine when to subtract the value, and when to keep the value the same. The problem however was that the function overwrites several things before it finally gets to the actual subtract instruction (at 0x4BE228). So the decision to subtract or not would have to be made at the start of the function. (perhaps its possible to get the  original esi value back, but I gave up looking for it)

This brought me back to the function that calls our subtract function, which was the 0x4C5331 function (or well, thats the return address). In this function we see that it gets the subtract function from a look up array (see 0x4C5322), using Cheat Engine we find that the subtract function-address is stored in 0x11C9438. I decided to make a detour function and write its address into 0x11C9438.

With the detour function in place, my first try was to not-execute the subtract function if it concerned ammo/health/etc. This quickly led to a crash. Apparently the subtract function does more then subtract. My next try was to get the pointer to the value, and increase it with the value being subtracted (as such, subtract would then have no effect). This quickly led to an issue, the value it subtracts from the main value (ok too many value's in one sentence) is also stored in an object.

It was getting late, and I was getting bored real quick with these objects in objects. So I decided to actually change the code depending on the main value. If the value is ammo/etc, I change the subtract instruction at 0x4BE228 to nop, if the value is something else, I change subtract the instruction at 0x4BE228 back to its normal value.

This worked!  So while probably not the most elegant method to success, it definitely works. I had to put in one additional check for Health. Because the Health identifier was the same for everyone (e.g. also enemies), I had to check if the health was player-health or enemy-health, I did this by checking the v-table of the calling-class (for the player its 0xF4FE60).

The end result is this +4 trainer.

Posted by: Da_Teach on Saturday, July 03, 2010  •  Comments (6)  •  Full story  •  C# Code Injection Pointers Syser Codecave Trainer Alien Breed: Impact

Mass Effect Part #1

As I said in the previous post, Mass Effect (like Trine) doesn't have a static pointer to the player object. There are a few ways around this problem and I'm going for the easiest solution.

First get the newest version of Cheat Engine, it has improved kernel debugger support (its not a full kernel debugger though, so you cant step through code) which will allow us to get passed the debugger protection in Mass Effect. Although the newest version should support 64Bit processors, I couldn't get it to work. So I used a clean WinXP install for this hack.

The next thing you do is enable kernel debugging (you can find it under Edit -> Settings -> Extra), I also enabled "Use Global Debug routines". Not entirely sure what it does but it seemed to increase stability a bit for me.

Once you setup Cheat Engine correctly its time to search for Health. Its a float, so make sure you search for a float and not 4 bytes. After you have identified the health address its time to use the kernel debugger routines.

Right click on the health address in your address list and press "Find out what writes to this address". This should return 1 instruction at 10D26F4Bh (fst dword ptr [edi]), its the only instruction (that I found) that lowers the players health. However nop'ing that instruction (e.g. make it do nothing) will result in enemies also becomming invincible. So we're not there yet.

Stop the code-finder and right click on the health address again and now select "Find out what accesses this address". This will return at least 1 function which will access the address using an instruction a bit like this "mov xmms0, [edi+48]". Using that instruction we can conclude that the health address is at 48h offset of the player object.

The reason that is interesting is because we need a way to change the instruction at 10D26F4Bh in such a way that it will decrease health for enemies but not for players.

If we remove 48h from the player address (and change the memory-type to 4 bytes) we will see that it contains 118D6968h. This is the player object's vtable, its a unique number for all objects of that type. In this case 118D6968h is the vtable for the player object and 118D3968h is the vtable for your team members.

With this information we can detour the instruction at 10D26F4Bh to use this information. There is one small problem though, the instruction is only 2 bytes and for a long-jump or call we need at least 5 bytes. To get around that problem I decided to use the code cave right after the call that holds the instruction that we want to change. That way we can use a short jump, which is also 2 bytes in size.

If you open up CheatEngine's memory view and go to address 10D26F4Bh you will see that a code-cave starts at address 10D26F57h.

I decided to write this code into the code-cave:
10D26F57 - cmp [edi-48], 118D6968
10D26F5E - je 10D26F4D
10D26F60 - cmp [edi-48], 118D3968
10D26F67 - je 10D26F4D
10D26F69 - fst dword ptr [edi]
10D26F6B - jmp 10D26F4D

Once you wrote the above code to the code-cave, then change the instruction at 10D26F4Bh to this:
jmp 10D26F57

And voilla your enemies are dieing but you and your team mates are invincible.

Tomorrow I'll write a trainer for Mass Effect which will also include some additional hacks like money, grenades, etc. But its late now and I need to go to bed :D

Posted by: Da_Teach on Wednesday, February 03, 2010  •  Comments (5)  •  Full story  •  Pointers Codecave Cheat Engine Mass Effect Anti-Debugger

A small reply to Derek's Comment(s)

Hi Derek (see his comment here),

Its great to see some people are actually reading my blog :D

I've been short on time the past week, but at least this week I seem to have a few evenings free :)

I completely understand the issue that things get tricky when pointers get involved. Pointers tend to change when the game restarts and/or finishes a loading sequence. I will see if I can help out a bit in that area in the coming days.

Most of the time the only pointer your interested in is the player object pointer. The player object is stored in memory somewhere and usually contains things like the name of the player, its location, its health, etc. These days its hard to find a game that doesnt use a player object in one shape or form.

So when you look for, for example, health you will often find a memory location which is actually an offset in the player object. The trick is to find a static location which holds the pointer for the player object.

This can be very easy (Torchlight has a static address which always contains the pointer to the player object) but it can also be (very) hard. Mass Effect and Trine do not have a static pointer to the player object but use object-lists to store the pointers.

I actually wanted to hack Mass Effect before Mass Effect 2 came out, so I could finish it again on the hardest mode :) But I never got around to it, too busy with other games / real life / etc.

From my initial check of Mass Effect (its hard due to its debugger protection and its unwillingness to run in VMware) seems to be using an object-list to store the object pointers (often not only friendlies but also enemies). These are probably the hardest to hack if you want to change stats.

If you encounter a game which uses an object-list to store object pointers there are a couple of things you can do.

One of them is reverse engineer the way this list is stored, write your own access routines for it, and modify values (Defense Grid was an example for that).

But you can also see if you can find out what decreases health, then see if you can find out what the game uses to identify enemies from friendlies. Thats what I did for Trine.

I am currently working on a proof of concept radar for Modern Warfare 2. It will read the player objects from memory and show them in a radar. Limited use but it'll cover the idea of reverse engineering the way objects are stored in memory. More on this later this week (I think I have the basics figured out, but havent tested anything yet).

That said, I will take a quick look into Mass Effect again tomorrow, see if I can write a quick hack and show you what I did. I did find the instruction a while back that decreased health, but enemies also became invincible. This is the same thing that happened with Trine. I might also write a blog about why this happens, but people with object oriented programming can probably understand why it happens.

As for Warhammer Online (I dont mind Google picking up on it ;), it actually doesnt use Punkbuster. But if it would use Punkbuster then it wouldnt worry me at all.

The hacks that I use for the game are not public (and wont be, until I quit playing) and as such cant be picked up by Punkbuster.

Everything I've read about Punkbuster indicates that you can compare it with a virus scanner. It will detect some common ways to hack a game (like the windows Read/WriteProcessMemory functions) and it'll detect known hacks, but private / unknown hacks wont be picked up by Punkbuster.

So my tip for games that do use Punkbuster, write private hacks and keep them private.

Posted by: Da_Teach on Tuesday, February 02, 2010  •  Comments (0)  •  Full story  •  Pointers