I've been a bad moderator which made the Structs/Offsets thread get way too out of hand. I'm going to maintain a sticky thread with useful information regarding feature development.
Basics:
1. How do I dump the SDK?
2. How do I bypass BattlEye?
3. What do I need to read/write memory?
4. How do I draw onto the screen?
Game Specific:
TArray
The structure of a TArray is shown in the following psuedo-struct.
If you're internal, iteration is trivial. If you're external, you're going to have to jump through some circus hoops to get your data. Here is some pseudo-code.
FString
The structure of an FString is shown in the following pseudo-struct.
Accessing the string internally is trivial. Grabbing it externally requires this pseudo code.
FText
The structure of an FText is shown in the following pseudo-struct. Keep in mind that FText and FString are NOT the same structure.
To read this externally:
Basics:
1. How do I dump the SDK?
- Visit KN4CK3R's Github repository here
- Clone or download the repository
- Compile source using Visual Studio 2015+
- Kill BEService (programmatically or using Services)
- Inject using Xenos or Extreme Injector
- The resulting SDK should be in C:\SDK_GEN
2. How do I bypass BattlEye?
- Nobody will spoonfeed you a bypass, but there are lots of resources in the internet.
- Keep in mind that the section may not necessarily provide currently undetected techniques.
3. What do I need to read/write memory?
- You can read/write memory using a HANDLE (traditionally with OpenProcess), but BattlEye strips handles via ObsRegisterCallbacks as well as manually walking the handle table in kernel + DKOMing the permissions down.
- Be (slightly) creative and read the contents of section 2 for alternative techniques.
- If you are able to read/write externally, you should also be able to inject a module.
4. How do I draw onto the screen?
- Spawn an external overlay using CreateWindow and then calling APIs from the DirectX SDK (or paste imgui).
- Hijack an existing external or internal overlay and render your ESP with it. Some overlays you might think of include Discord or NVIDIA overlays. This is an example using Mumble.
- Inject a module into the game and draw using dx11 hooking directly.
- Inject a module into the game and draw using engine functions.
Game Specific:
TArray
The structure of a TArray is shown in the following psuedo-struct.
Code:
struct TArray
{
DWORD_PTR Data;
int Count;
int Max;
}
If you're internal, iteration is trivial. If you're external, you're going to have to jump through some circus hoops to get your data. Here is some pseudo-code.
Code:
DWORD_PTR actorTArray = ...; // somewhere in game memory
DWORD_PTR actorData = RPM(actorTArray, sizeof(DWORD_PTR)); // read 8 bytes, 0 bytes into the struct
int actorCount = RPM(actorTArray + sizeof(DWORD_PTR), sizeof(int)); // read 4 bytes, 8 bytes into the struct
for (int i = 0; i < actorCount ; i++)
{
AActor* actor = RPM(actorData + i * sizeof(DWORD_PTR), sizeof(AActor)); // read buffers of actors based on the size of your class
...
// continue to operate on this actor
}
FString
The structure of an FString is shown in the following pseudo-struct.
Code:
struct FString
{
DWORD_PTR stringBuffer;
int stringLength;
}
Accessing the string internally is trivial. Grabbing it externally requires this pseudo code.
Code:
DWORD_PTR someFString = ...; // somewhere in game memory
DWORD_PTR ptrToBuffer = RPM(someFString, sizeof(DWORD_PTR);
int stringLength = RPM(someFString + sizeof(DWORD_PTR), sizeof(int));
wchar_t* actualString = RPM(ptrToBuffer, stringLength);
FText
The structure of an FText is shown in the following pseudo-struct. Keep in mind that FText and FString are NOT the same structure.
Code:
struct FText
{
FTextData* Data;
}
struct FTextData
{
char unknown_data0[0x28];
DWORD_PTR stringBuffer;
int stringLength;
}
To read this externally:
Code:
DWORD_PTR someFText = ... // some FText in memory
DWORD_PTR someFTextData = RPM(someFText, sizeof(FTextData)); // read the FTextData struct
int stringLength = RPM(someFTextData + 0x30, sizeof(int)); // read the length
wchar_t* actualString = RPM(someFTextData + 0x28, sizeof(stringLength));