Skip to content

Commit

Permalink
via.Application: Add bruteforce scan for module entries when all fails
Browse files Browse the repository at this point in the history
This fixes Apollo Justice but will also fix future, unknown REE games.
  • Loading branch information
praydog committed Jan 25, 2024
1 parent 2263953 commit 70910c7
Showing 1 changed file with 85 additions and 1 deletion.
86 changes: 85 additions & 1 deletion shared/sdk/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Application* Application::get() {
}

Application::Function* Application::get_functions() {
static auto functions_offset = []() -> std::optional<int32_t> {
static auto functions_offset = [this]() -> std::optional<int32_t> {
spdlog::info("Searching for Application::functions offset...");

const auto mod = utility::get_executable();
Expand Down Expand Up @@ -72,6 +72,90 @@ Application::Function* Application::get_functions() {
spdlog::info("Skipping invalid Application::functions offset: {:x}", candidate);
}

bool found_wait_rendering = false;
bool found_begin_rendering = false;
bool found_end_rendering = false;

const auto module_entry_enum = sdk::find_type_definition("via.ModuleEntry");

// screw that lets just bruteforce through the Application object looking for huge
// list of valid pointers within the current module
for (auto i = 0x100; i < 0x1000; i += sizeof(void*)) try {
const auto ptr = (Application::Function*)((uintptr_t)this + i);

if (ptr == nullptr || IsBadReadPtr(ptr, sizeof(Application::Function) * 50)) {
continue;
}

for (auto j = 0; j < 1024; ++j) try {
const auto& func = ptr[j];

if (func.description == nullptr || IsBadReadPtr(func.description, 32)) {
break;
}

if (j == 0 && func.entry == nullptr || IsBadReadPtr(func.entry, sizeof(void*))) {
break; // the first one should always be valid.
}

const auto name = std::string_view{func.description};

if (j == 0) {
if (module_entry_enum != nullptr) {
if (auto f = sdk::get_native_field<uint16_t>(nullptr, module_entry_enum, name, true); f != nullptr) {
if (*f != func.priority) {
break; // the first one should always be valid.
}
}
} else if (func.priority != 1) {
break; // the first one should always be valid.
}
}

if (name == "WaitRendering") {
if (module_entry_enum != nullptr) {
if (auto f = sdk::get_native_field<uint16_t>(nullptr, module_entry_enum, "WaitRendering", true); f != nullptr) {
if (*f == func.priority) {
found_wait_rendering = true;
}
}
} else {
found_wait_rendering = true;
}
} else if (name == "BeginRendering") {
if (module_entry_enum != nullptr) {
if (auto f = sdk::get_native_field<uint16_t>(nullptr, module_entry_enum, "BeginRendering", true); f != nullptr) {
if (*f == func.priority) {
found_begin_rendering = true;
}
}
} else {
found_begin_rendering = true;
}
} else if (name == "EndRendering") {
if (module_entry_enum != nullptr) {
if (auto f = sdk::get_native_field<uint16_t>(nullptr, module_entry_enum, "EndRendering", true); f != nullptr) {
if (*f == func.priority) {
found_end_rendering = true;
}
}
} else {
found_end_rendering = true;
}
}

if (found_wait_rendering && found_begin_rendering && found_end_rendering) {
spdlog::info("Application::functions offset: {:x}", i);
return i;
}
} catch (...) {
continue;
}
} catch(...) {
continue;
}


spdlog::error("Cannot find Application::functions offset.");

return std::nullopt;
Expand Down

0 comments on commit 70910c7

Please sign in to comment.