Skip to content

Commit

Permalink
SDK: Bruteforce U/FProperty offset
Browse files Browse the repository at this point in the history
  • Loading branch information
praydog committed Jul 7, 2023
1 parent 4c66e78 commit 1103b9a
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ list(APPEND sdk_SOURCES
"shared/sdk/EngineModule.cpp"
"shared/sdk/FField.cpp"
"shared/sdk/FName.cpp"
"shared/sdk/FProperty.cpp"
"shared/sdk/FRenderTargetPool.cpp"
"shared/sdk/FSceneView.cpp"
"shared/sdk/FViewportInfo.cpp"
Expand All @@ -341,6 +342,7 @@ list(APPEND sdk_SOURCES
"shared/sdk/EngineModule.hpp"
"shared/sdk/FField.hpp"
"shared/sdk/FName.hpp"
"shared/sdk/FProperty.hpp"
"shared/sdk/FRenderTargetPool.hpp"
"shared/sdk/FSceneView.hpp"
"shared/sdk/FViewportInfo.hpp"
Expand Down Expand Up @@ -415,6 +417,7 @@ list(APPEND sdk-nolog_SOURCES
"shared/sdk/EngineModule.cpp"
"shared/sdk/FField.cpp"
"shared/sdk/FName.cpp"
"shared/sdk/FProperty.cpp"
"shared/sdk/FRenderTargetPool.cpp"
"shared/sdk/FSceneView.cpp"
"shared/sdk/FViewportInfo.cpp"
Expand All @@ -436,6 +439,7 @@ list(APPEND sdk-nolog_SOURCES
"shared/sdk/EngineModule.hpp"
"shared/sdk/FField.hpp"
"shared/sdk/FName.hpp"
"shared/sdk/FProperty.hpp"
"shared/sdk/FRenderTargetPool.hpp"
"shared/sdk/FSceneView.hpp"
"shared/sdk/FViewportInfo.hpp"
Expand Down
2 changes: 1 addition & 1 deletion shared/sdk/FField.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class FField {
return *(FName*)((uintptr_t)this + s_name_offset);
}

private:
protected:
static inline bool s_attempted_update_offsets{false};
static inline uint32_t s_next_offset{0x20}; // not correct always, we bruteforce it later
static inline uint32_t s_name_offset{0x28}; // not correct always, we bruteforce it later
Expand Down
39 changes: 39 additions & 0 deletions shared/sdk/FProperty.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include <spdlog/spdlog.h>

#include "FProperty.hpp"

namespace sdk {
void FProperty::bruteforce_fproperty_offset(FProperty* x_prop, FProperty* y_prop, FProperty* z_prop) {
SPDLOG_INFO("[FProperty] Bruteforcing offset field via FVector heuristic...");

if (x_prop == nullptr || y_prop == nullptr || z_prop == nullptr) {
SPDLOG_ERROR("[FProperty] Failed to bruteforce offset field");
return;
}

// It has to be at least ahead of the next offset
bool found = false;
for (auto i = FField::s_next_offset + sizeof(void*); i < 0x200; i += 4) try {
const auto x_offset = *(uint32_t*)((uintptr_t)x_prop + i);
const auto y_offset = *(uint32_t*)((uintptr_t)y_prop + i);
const auto z_offset = *(uint32_t*)((uintptr_t)z_prop + i);

// float for UE4, double for UE5
if (x_offset == 0 &&
(y_offset == sizeof(float) || y_offset == sizeof(double)) &&
((z_offset == sizeof(float) * 2) || (z_offset == sizeof(double) * 2)))
{
SPDLOG_INFO("[FProperty] Found offset field at offset 0x{:X}", i);
s_offset_offset = i;
found = true;
break;
}
} catch(...) {
continue;
}

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

#include <cstdint>

#include "UClass.hpp"
#include "FField.hpp"

namespace sdk {
class FProperty : public FField {
public:
int32_t get_offset() const {
return *(int32_t*)((uintptr_t)this + s_offset_offset);
}

// Given xyz props from FVector, find the offset which matches up with all of them
static void bruteforce_fproperty_offset(FProperty* x_prop, FProperty* y_prop, FProperty* z_prop);

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

friend class UStruct;
};
}
32 changes: 32 additions & 0 deletions shared/sdk/UClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "UObjectArray.hpp"
#include "UProperty.hpp"
#include "FProperty.hpp"
#include "FField.hpp"

#include "UClass.hpp"
Expand Down Expand Up @@ -152,6 +153,37 @@ void UStruct::update_offsets() {
const auto next_next_name = next_next_fname.to_string();

SPDLOG_INFO("[UStruct] Next Next Name: {}", utility::narrow(next_next_name));

// now determine which ones are xyz and pass to bruteforce func
FProperty* x_prop{};
FProperty* y_prop{};
FProperty* z_prop{};

if (possible_name_a1 == L"X") {
x_prop = (FProperty*)value;
} else if (possible_name_a1 == L"Y") {
y_prop = (FProperty*)value;
} else if (possible_name_a1 == L"Z") {
z_prop = (FProperty*)value;
}

if (potential_next_field_name == L"X") {
x_prop = (FProperty*)potential_field;
} else if (potential_next_field_name == L"Y") {
y_prop = (FProperty*)potential_field;
} else if (potential_next_field_name == L"Z") {
z_prop = (FProperty*)potential_field;
}

if (next_next_name == L"X") {
x_prop = (FProperty*)next_next;
} else if (next_next_name == L"Y") {
y_prop = (FProperty*)next_next;
} else if (next_next_name == L"Z") {
z_prop = (FProperty*)next_next;
}

FProperty::bruteforce_fproperty_offset(x_prop, y_prop, z_prop);
} catch(...) {
SPDLOG_ERROR("[UStruct] Failed to get Next Next Name!");
}
Expand Down

0 comments on commit 1103b9a

Please sign in to comment.