For the sake of keeping it simple this will only look at UE4 versions before 4.25 (UProperties were changed into FProperties in 4.25, there are some important differences).
I will be keeping things extremely simple, there are a lot of things that I'm leaving out because for people who actually need this it will just become confusing. I might expand on this introduction with more advanced stuff later.
The very first thing you need to do is stop and go learn the Cheat Engine basics and how memory works. You need to know how to use Cheat Engine and you need an understanding of what an offset is and what a base address is and how the two go together.
This introduction is not targeted towards game hackers on their first day of hacking.
This introduction uses the game Satisfactory which uses Unreal Engine 4.22.3 (at the time of writing).
Also, it should go without saying but you will have an easier time understanding any of this if you've got some programming experience but I will try to explain things in such a way that you don't need to be an expert in order to walk away from this introduction with some very useful UE4 game hacking knowledge.
Part 1 - Very Basic Understanding Of Different Types Of UObjects
There are three main types of UObjects that you're dealing with in UE4. This is not true at all but as I said, keeping it simple.
The first type is the active type or base, the object that contains your actual values like current player health and max player health.
The second type is the property type, aka UProperty. This type contains the name of the property (e.g: mCurrentHealth, but more specifically it contains an FName id not a string), offset to the actual value inside the base object (base + offset = health), and some other useful information.
The third type is a Class type. This type is just a class that the base UObjects inherit from. This is not covered in this guide but just know that not all UObjects that aren't UProperty objects are base objects and this is where experimenting and paying attention to patterns will help a lot.
Part 2 - Object Dumping & Understanding The Result
I recommend the which comes with an object dumper and some other nifty features.
In this file you will find stuff like this:
 000001C23C07E9B0 FloatProperty FactoryGame.FGHealthComponent.mCurrentHealth
Lets dissect this line. Lets use the spaces to separate the line into small sections.
The first part
can be ignored for most everything it's beyond the scope of this introduction.
The second part
000001C23C07E9B0is the address of this UObject.
The third part
FloatPropertyis the class that this object belongs to.
In UE4 FloatProperty is a class which inherits from UProperty but the name itself lets us know that this is a float type.
There are other similar classes such as IntProperty and ArrayProperty and many more.
The fact that the type is suffixed with Property means that we can be very sure that this is a UProperty object and not a base object.
The fourth and final part,
FactoryGame.FGHealthComponent.mCurrentHealth, let's split this up again into smaller sections but by the
This is basically the path information for the object aswell as the name of the object.
For most dumpers the part after the last
.will always be the name of the object and everything before will be the path info.
The path info tells you what other UObject this UObject belongs to.
In the above example we can see that our UObject,
mCurrentHealth, belongs to some other UObject named
FGHealthComponentwhich belongs to
The path info can be very long and it can look a bit scary but don't worry about it too much, you'll get the hang of it eventually after experimenting with it a bit.
For searching the dumped txt file:
I recommend using Notepad++ because it has an excellent search feature.
For example, when looking for health you could search for "health" and choose "Find All in Current Document.
You get a ton of results. To narrow it down, you might search for the class. We know from our game hacking experience that health is usually a float. We also know that the class is surrounded by spaces so lets copy & paste our search result into a new tab and search for " FloatProperty " and again choose "Find All in Current Document".
There are not very many results left. Finding useful stuff is much more manageable when we've narrowed it down by class like this.
If you're real crazy then you could also use regex to make finding stuff even easier.
You can also combine UE4 game hacking with regular hacking, obviously.
Find any object by searching like you would any game and then search for the base address in the dumped txt and it should tell you what object this actually is and then you can look up properties for that object.
Okay! Continuing on. Lets look at another line:
 000001C24BE2B080 FGHealthComponent Char_Player.Default__Char_Player_C.HealthComponent
It looks quite different doesn't it ? What's up with the class ?
Well this is where it becomes a little more complicated.
This is due to object oriented programming and inheritance (it's a bit more than that but let's not talk about it for now).
The above example is really just a class named HealthComponent and it's an instance of FGHealthComponent.
The most important thing to remember here is that if the class doesn't end with
Propertythen it's an active or base object.
Otherwise it's a UProperty object.
So we learned that the above example is a base object and we learned in part 1 that base objects are the objects that contain actual values like health numbers and mana numbers etc.
Another quirk that you must learn is defaults. You can safely ignore any object with
Defaultmentioned in the path info because it's useless for 99% of anything you might want to do.
The above UObject does contain
Defaultin its path info so we can ignore this one and move on to the next one.
The base objects that you're looking for usually has
Persistent_Levelsomewhere in it's path info and sometimes it has
Transientin the path info but neither is a guarantee.
They look a little something like this, and sometimes you might find several objects that are very similar:
Code: Select all
 000001C2B664E980 FGHealthComponent Persistent_Level.Persistent_Level.PersistentLevel.Char_Player_C_1.HealthComponent  000001C212FF5500 FGHealthComponent Persistent_Level.Persistent_Level.PersistentLevel.Char_Player_C_2.HealthComponent  000001C2B6648200 FGHealthComponent Persistent_Level.Persistent_Level.PersistentLevel.Char_BabyCrab_C_2.HealthComponent
Char_BabyCrab_C_2is probably not the right object.
If you only have 3-4 similar objects then by far the fastest way to check which is the correct one is to employ some trial & error.
Simply follow the steps in part 3 for each UObject and then change the value and in this example I would see if player health changes, if it does then I've found the right object.
If you have tons of similar objects then there are several other ways to find out, all of which are beyond the scope of this introduction to UE4 game hacking.
Alright! Now we know the address of the base object (our health value is in here at some offset) and also the address of the UProperty that contains the offset into the base object where our health value is.
Part 3 - Exploring Memory
I generally recommend that you set your Cheat Engine memory viewer up to display values as 8-byte hex and lock it to 2 columns for an easier time looking at and navigating UObjects.
We'll start with some universal things that are true (for almost all UE4 versions) for all UObjects no matter if it's a base object or a UProperty object.
I'm keeping this very basic, this introduction does not cover what each and every bit of information in these UObjects mean.
For the purpose of this introduction to UE4 game hacking, the base object is not interesting to us at all so we will start with the UProperty object.
We're looking to find at what offset into the base object our health value is at.
To do this we'll simply open up the address of our
mCurrentHealthUProperty in the memory viewer in Cheat Engine.
Once you've done that you should hit Ctrl + Enter to be able see offsets easier.
We're looking for a 32-bit integer (in other words: 4-byte value) so unless you've spent a lot of time looking at memory I recommend that you change your memory viewer to display as 4-byte hex.
This integer is called Offset_Internal in the engine source code and it's part of the UProperty class.
Different UE4 versions have Offset_Internal at different offsets inside the UProperty class but it's always around the same area.
Typically it's around +0x44 inside the UProperty UObject (e.g: the mCurrentHealth FloatProperty UObject).
The easiest thing to do is to just look for a low number around +0x44, it doesn't have to be a low number but I'd be suspicious of any numbers greater than ~0x3000.
Once you've found the offset that you think is Offset_Internal then make a note of the value at the offset (and also the offset of Offset_Internal for future use since it's the same in all UProperties).
In my case Offset_Internal is at 0x44 and the value at the location in memory is 0x164.
This is the offset into the base object that contains our health value.
So now all you have to do is take the base object and add 0x164 to it and that's your health address.
In this example I was looking to find the player health so in my case if I change the value at base + Offset_Internal to half of it's current value and my health doesn't get cut in half then I have not found Offset_Internal or I have screwed up somewhere, to fix this I would have to go back to this guide and read it again and think real hard.
I've intentionally only used one example here, player health, because I want you to go experimenting with this knowledge and learn how to find anything you want without a step-by-step guide because you will learn so much more if you do the work yourself.
I left a lot of stuff out, this is on purpose as I want you to learn something. This should be a decent base of knowledge for UE4 hacking, now go forth and experiment with UE4 and have fun.