Skip to content

Commit

Permalink
SDK: Bruteforce Struct offset for U/FStructProperty
Browse files Browse the repository at this point in the history
  • Loading branch information
praydog committed Aug 30, 2023
1 parent 06056b8 commit e5b7289
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 0 deletions.
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ list(APPEND sdk_SOURCES
"shared/sdk/FProperty.cpp"
"shared/sdk/FRenderTargetPool.cpp"
"shared/sdk/FSceneView.cpp"
"shared/sdk/FStructProperty.cpp"
"shared/sdk/FViewportInfo.cpp"
"shared/sdk/Globals.cpp"
"shared/sdk/ScriptMatrix.cpp"
Expand All @@ -335,6 +336,7 @@ list(APPEND sdk_SOURCES
"shared/sdk/StereoStuff.cpp"
"shared/sdk/UClass.cpp"
"shared/sdk/UEngine.cpp"
"shared/sdk/UEnum.cpp"
"shared/sdk/UFunction.cpp"
"shared/sdk/UGameEngine.cpp"
"shared/sdk/UGameViewportClient.cpp"
Expand All @@ -357,6 +359,7 @@ list(APPEND sdk_SOURCES
"shared/sdk/FProperty.hpp"
"shared/sdk/FRenderTargetPool.hpp"
"shared/sdk/FSceneView.hpp"
"shared/sdk/FStructProperty.hpp"
"shared/sdk/FViewportInfo.hpp"
"shared/sdk/Globals.hpp"
"shared/sdk/Math.hpp"
Expand All @@ -369,6 +372,7 @@ list(APPEND sdk_SOURCES
"shared/sdk/TArray.hpp"
"shared/sdk/UClass.hpp"
"shared/sdk/UEngine.hpp"
"shared/sdk/UEnum.hpp"
"shared/sdk/UFunction.hpp"
"shared/sdk/UGameEngine.hpp"
"shared/sdk/UGameViewportClient.hpp"
Expand Down Expand Up @@ -419,6 +423,7 @@ target_link_libraries(sdk PUBLIC

target_link_libraries(sdk PUBLIC
kananlib
Version
)

unset(CMKR_TARGET)
Expand All @@ -441,6 +446,7 @@ list(APPEND sdk-nolog_SOURCES
"shared/sdk/FProperty.cpp"
"shared/sdk/FRenderTargetPool.cpp"
"shared/sdk/FSceneView.cpp"
"shared/sdk/FStructProperty.cpp"
"shared/sdk/FViewportInfo.cpp"
"shared/sdk/Globals.cpp"
"shared/sdk/ScriptMatrix.cpp"
Expand All @@ -450,6 +456,7 @@ list(APPEND sdk-nolog_SOURCES
"shared/sdk/StereoStuff.cpp"
"shared/sdk/UClass.cpp"
"shared/sdk/UEngine.cpp"
"shared/sdk/UEnum.cpp"
"shared/sdk/UFunction.cpp"
"shared/sdk/UGameEngine.cpp"
"shared/sdk/UGameViewportClient.cpp"
Expand All @@ -472,6 +479,7 @@ list(APPEND sdk-nolog_SOURCES
"shared/sdk/FProperty.hpp"
"shared/sdk/FRenderTargetPool.hpp"
"shared/sdk/FSceneView.hpp"
"shared/sdk/FStructProperty.hpp"
"shared/sdk/FViewportInfo.hpp"
"shared/sdk/Globals.hpp"
"shared/sdk/Math.hpp"
Expand All @@ -484,6 +492,7 @@ list(APPEND sdk-nolog_SOURCES
"shared/sdk/TArray.hpp"
"shared/sdk/UClass.hpp"
"shared/sdk/UEngine.hpp"
"shared/sdk/UEnum.hpp"
"shared/sdk/UFunction.hpp"
"shared/sdk/UGameEngine.hpp"
"shared/sdk/UGameViewportClient.hpp"
Expand Down
1 change: 1 addition & 0 deletions cmake.toml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ link-libraries = [
type = "sdk-template"
link-libraries = [
"kananlib",
"Version"
]

[target.sdk-nolog]
Expand Down
2 changes: 2 additions & 0 deletions shared/sdk/FProperty.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace sdk {
class UProperty;
class FStructProperty;

class FProperty : public FField {
public:
Expand All @@ -22,5 +23,6 @@ class FProperty : public FField {

friend class UStruct;
friend class UProperty;
friend class FStructProperty;
};
}
81 changes: 81 additions & 0 deletions shared/sdk/FStructProperty.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include <windows.h>

#include <spdlog/spdlog.h>

#include <utility/String.hpp>

#include "UObjectArray.hpp"
#include "ScriptMatrix.hpp"
#include "FProperty.hpp"

#include "FStructProperty.hpp"

namespace sdk {
void FStructProperty::update_offsets() {
const auto matrix_t = ScriptMatrix::static_struct();

if (matrix_t == nullptr) {
SPDLOG_ERROR("[FStructProperty] Failed to bruteforce Struct field (Matrix not found)");
return;
}

for (auto child = matrix_t->get_child_properties(); child != nullptr; child = child->get_next()) {
SPDLOG_INFO("[UStruct] Checking child property {}", utility::narrow(child->get_field_name().to_string()));
}

const auto xplane_prop = matrix_t->find_property(L"XPlane");
const auto yplane_prop = matrix_t->find_property(L"YPlane");
const auto zplane_prop = matrix_t->find_property(L"ZPlane");
const auto wplane_prop = matrix_t->find_property(L"WPlane");

bruteforce_struct_offset(xplane_prop, yplane_prop, zplane_prop, wplane_prop);
}

void FStructProperty::bruteforce_struct_offset(FProperty* xplane_prop, FProperty* yplane_prop, FProperty* zplane_prop, FProperty* wplane_prop) {
SPDLOG_INFO("[FStructProperty] Bruteforcing Struct field via FMatrix heuristic...");

if (xplane_prop == nullptr || yplane_prop == nullptr || zplane_prop == nullptr || wplane_prop == nullptr) {
SPDLOG_ERROR("[FStructProperty] Failed to bruteforce Struct field (one of the planes is null)");
return;
}

// It has to be at least ahead of the Offset field offset
bool found = false;
const auto alignment = sizeof(void*);
const auto offset_aligned = (FProperty::s_offset_offset + alignment - 1) & ~(alignment - 1);

for (auto i = offset_aligned; i < 0x200; i += sizeof(void*)) try {
const auto x_struct = *(UScriptStruct**)((uintptr_t)xplane_prop + i);
const auto y_struct = *(UScriptStruct**)((uintptr_t)yplane_prop + i);
const auto z_struct = *(UScriptStruct**)((uintptr_t)zplane_prop + i);
const auto w_struct = *(UScriptStruct**)((uintptr_t)wplane_prop + i);

if (x_struct == nullptr || IsBadReadPtr(x_struct, sizeof(void*)) ||
y_struct == nullptr || IsBadReadPtr(y_struct, sizeof(void*)) ||
z_struct == nullptr || IsBadReadPtr(z_struct, sizeof(void*)) ||
w_struct == nullptr || IsBadReadPtr(w_struct, sizeof(void*)))
{
continue;
}

if (x_struct->get_full_name() != L"ScriptStruct /Script/CoreUObject.Plane" ||
y_struct->get_full_name() != L"ScriptStruct /Script/CoreUObject.Plane" ||
z_struct->get_full_name() != L"ScriptStruct /Script/CoreUObject.Plane" ||
w_struct->get_full_name() != L"ScriptStruct /Script/CoreUObject.Plane")
{
continue;
}

SPDLOG_INFO("[FStructProperty] Found Struct field at offset 0x{:X}", i);
s_struct_offset = i;
found = true;
break;
} catch(...) {
continue;
}

if (!found) {
SPDLOG_ERROR("[FStructProperty] Failed to bruteforce Struct field (no matching planes found)");
}
}
}
26 changes: 26 additions & 0 deletions shared/sdk/FStructProperty.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include "FProperty.hpp"

namespace sdk {
class UScriptStruct;

class FStructProperty : public FProperty {
public:
UScriptStruct* get_struct() const {
return *(UScriptStruct**)((uintptr_t)this + s_struct_offset);
}

static void update_offsets();

// From FMatrix
static void bruteforce_struct_offset(FProperty* xplane_prop, FProperty* yplane_prop, FProperty* zplane_prop, FProperty* wplane_prop);

private:
static inline uint32_t s_struct_offset{0x0}; // idk

friend class UStruct;
friend class UProperty;
friend class FProperty;
};
}
10 changes: 10 additions & 0 deletions shared/sdk/UEnum.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "UObjectArray.hpp"

#include "UEnum.hpp"

namespace sdk {
sdk::UClass* UEnum::static_class() {
static auto ptr = (UClass*)sdk::find_uobject(L"Class /Script/CoreUObject.Enum");
return ptr;
}
}
13 changes: 13 additions & 0 deletions shared/sdk/UEnum.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include "UObject.hpp"

namespace sdk {
class UEnum : public UObject {
public:
static UClass* static_class();

private:
// TODO
};
}
2 changes: 2 additions & 0 deletions shared/sdk/UObjectArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "UProperty.hpp"
#include "FName.hpp"
#include "FField.hpp"
#include "FStructProperty.hpp"
#include "UObjectArray.hpp"

namespace sdk {
Expand Down Expand Up @@ -380,6 +381,7 @@ FUObjectArray* FUObjectArray::get() try {
sdk::UStruct::update_offsets();
sdk::UScriptStruct::update_offsets();
sdk::UProperty::update_offsets();
sdk::FStructProperty::update_offsets();

try {
const auto world = sdk::UEngine::get()->get_world();
Expand Down

0 comments on commit e5b7289

Please sign in to comment.