Skip to content

Commit

Permalink
SDK: Add initial UObjectBase::get_destructor
Browse files Browse the repository at this point in the history
  • Loading branch information
praydog committed Oct 21, 2023
1 parent 1f27482 commit a3b3a5e
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
67 changes: 67 additions & 0 deletions shared/sdk/UObjectBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "UClass.hpp"
#include "UObjectArray.hpp"
#include "UObjectBase.hpp"
#include "UObject.hpp"

namespace sdk {
void UObjectBase::update_offsets() {
Expand Down Expand Up @@ -175,6 +176,72 @@ void UObjectBase::update_process_event_index() try {
SPDLOG_ERROR("[UObjectBase] Failed to update ProcessEvent index");
}

std::optional<uintptr_t> UObjectBase::get_destructor() {
static auto result = []() -> std::optional<uintptr_t> {
SPDLOG_INFO("[UObjectBase] Searching for destructor...");

const auto uobject_class = sdk::UObject::static_class();

if (uobject_class == nullptr) {
SPDLOG_ERROR("[UObjectBase] Failed to find UObject class, cannot find destructor");
return {};
}

const auto default_object = uobject_class->get_class_default_object();

if (default_object == nullptr) {
SPDLOG_ERROR("[UObjectBase] Failed to find default UObject, cannot find destructor");
return {};
}

const auto uobject_vtable = *(void***)default_object;

if (uobject_vtable == nullptr || IsBadReadPtr(uobject_vtable, sizeof(void*))) {
SPDLOG_ERROR("[UObjectBase] Failed to find UObject vtable, cannot find destructor");
return {};
}

const auto uobject_destructor = uobject_vtable[0];

if (uobject_destructor == nullptr || IsBadReadPtr(uobject_destructor, sizeof(void*))) {
SPDLOG_ERROR("[UObjectBase] Failed to find UObject destructor, cannot find destructor");
return {};
}

// Now we need to exhaustively decode the destructor, looking for a call to the destructor of parent class
std::optional<uintptr_t> out{};

utility::exhaustive_decode((uint8_t*)uobject_destructor, 100, [&](utility::ExhaustionContext& ctx) -> utility::ExhaustionResult {
if (out) {
return utility::ExhaustionResult::BREAK;
}

if (ctx.instrux.BranchInfo.IsBranch) {
return utility::ExhaustionResult::CONTINUE;
}

const auto disp = utility::resolve_displacement(ctx.addr);

if (disp && *disp != (uintptr_t)uobject_vtable) {
out = ctx.branch_start;
return utility::ExhaustionResult::BREAK;
}

return utility::ExhaustionResult::CONTINUE;
});

if (out) {
SPDLOG_INFO("[UObjectBase] Found destructor at 0x{:X}", *out);
} else {
SPDLOG_ERROR("[UObjectBase] Failed to find destructor");
}

return out;
}();

return result;
}

std::wstring UObjectBase::get_full_name() const {
auto c = get_class();

Expand Down
2 changes: 2 additions & 0 deletions shared/sdk/UObjectBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class UObjectBase {
return s_outer_private_offset + sizeof(void*);
}

static std::optional<uintptr_t> get_destructor();

private:
using ProcessEventFn = void(*)(UObjectBase*, UFunction*, void*);
static void update_process_event_index();
Expand Down

0 comments on commit a3b3a5e

Please sign in to comment.