mirror of
https://github.com/wiiu-env/FunctionPatcherModule.git
synced 2025-01-07 23:50:44 +01:00
Implement v2 of the FunctionPatcherModule API
This commit is contained in:
parent
1e2457b266
commit
5adf6c3688
@ -1,7 +1,7 @@
|
|||||||
FROM wiiuenv/devkitppc:20220806
|
FROM wiiuenv/devkitppc:20221228
|
||||||
|
|
||||||
COPY --from=wiiuenv/libkernel:20220904 /artifacts $DEVKITPRO
|
COPY --from=wiiuenv/libkernel:20220904 /artifacts $DEVKITPRO
|
||||||
COPY --from=wiiuenv/libfunctionpatcher:20220904 /artifacts $DEVKITPRO
|
COPY --from=wiiuenv/libfunctionpatcher:20230106 /artifacts $DEVKITPRO
|
||||||
COPY --from=wiiuenv/wiiumodulesystem:20220904 /artifacts $DEVKITPRO
|
COPY --from=wiiuenv/wiiumodulesystem:20221005 /artifacts $DEVKITPRO
|
||||||
|
|
||||||
WORKDIR project
|
WORKDIR project
|
||||||
|
@ -4,40 +4,53 @@
|
|||||||
#include "utils/globals.h"
|
#include "utils/globals.h"
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <wums/exports.h>
|
||||||
|
|
||||||
bool FunctionPatcherPatchFunction(function_replacement_data_t *function_data, PatchedFunctionHandle *outHandle) {
|
FunctionPatcherStatus FPAddFunctionPatch(function_replacement_data_t *function_data, PatchedFunctionHandle *outHandle, bool *outHasBeenPatched) {
|
||||||
|
if (function_data == nullptr) {
|
||||||
|
DEBUG_FUNCTION_LINE_ERR("function_data was NULL");
|
||||||
|
return FUNCTION_PATCHER_RESULT_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
if (function_data->VERSION != FUNCTION_REPLACEMENT_DATA_STRUCT_VERSION) {
|
if (function_data->VERSION != FUNCTION_REPLACEMENT_DATA_STRUCT_VERSION) {
|
||||||
DEBUG_FUNCTION_LINE_ERR("Failed to patch function. struct version mismatch");
|
DEBUG_FUNCTION_LINE_ERR("Failed to patch function. struct version mismatch");
|
||||||
return false;
|
return FUNCTION_PATCHER_RESULT_UNSUPPORTED_STRUCT_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto functionDataOpt = PatchedFunctionData::make_shared(gFunctionAddressProvider, function_data, gJumpHeapHandle);
|
auto functionDataOpt = PatchedFunctionData::make_shared(gFunctionAddressProvider, function_data, gJumpHeapHandle);
|
||||||
|
|
||||||
if (!functionDataOpt) {
|
if (!functionDataOpt) {
|
||||||
return false;
|
return FUNCTION_PATCHER_RESULT_UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto functionData = functionDataOpt.value();
|
auto &functionData = functionDataOpt.value();
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(gPatchedFunctionsMutex);
|
// PatchFunction calls OSFatal on fatal errors.
|
||||||
|
// If this function returns false the target function was not patched
|
||||||
if (!PatchFunction(functionData)) {
|
// Usually this means the target RPL is not (yet) loaded.
|
||||||
DEBUG_FUNCTION_LINE_ERR("Failed to patch function");
|
auto patchResult = PatchFunction(functionData);
|
||||||
return false;
|
if (outHasBeenPatched) {
|
||||||
|
*outHasBeenPatched = patchResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outHandle) {
|
if (outHandle) {
|
||||||
*outHandle = functionData->getHandle();
|
*outHandle = functionData->getHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
gPatchedFunctions.push_back(std::move(functionData));
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(gPatchedFunctionsMutex);
|
||||||
|
gPatchedFunctions.push_back(std::move(functionData));
|
||||||
|
|
||||||
OSMemoryBarrier();
|
OSMemoryBarrier();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return FUNCTION_PATCHER_RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FunctionPatcherRestoreFunction(PatchedFunctionHandle handle) {
|
bool FunctionPatcherPatchFunction(function_replacement_data_t *function_data, PatchedFunctionHandle *outHandle) {
|
||||||
|
return FPAddFunctionPatch(function_data, outHandle, nullptr) == FUNCTION_PATCHER_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionPatcherStatus FPRemoveFunctionPatch(PatchedFunctionHandle handle) {
|
||||||
std::lock_guard<std::mutex> lock(gPatchedFunctionsMutex);
|
std::lock_guard<std::mutex> lock(gPatchedFunctionsMutex);
|
||||||
std::vector<std::shared_ptr<PatchedFunctionData>> toBeTempRestored;
|
std::vector<std::shared_ptr<PatchedFunctionData>> toBeTempRestored;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@ -60,7 +73,7 @@ bool FunctionPatcherRestoreFunction(PatchedFunctionHandle handle) {
|
|||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
DEBUG_FUNCTION_LINE_ERR("Failed to find PatchedFunctionData by handle %08X", handle);
|
DEBUG_FUNCTION_LINE_ERR("Failed to find PatchedFunctionData by handle %08X", handle);
|
||||||
return false;
|
return FUNCTION_PATCHER_RESULT_PATCH_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore function patches that were done after the patch we actually want to restore.
|
// Restore function patches that were done after the patch we actually want to restore.
|
||||||
@ -79,5 +92,36 @@ bool FunctionPatcherRestoreFunction(PatchedFunctionHandle handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
OSMemoryBarrier();
|
OSMemoryBarrier();
|
||||||
return true;
|
return FUNCTION_PATCHER_RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FunctionPatcherRestoreFunction(PatchedFunctionHandle handle) {
|
||||||
|
return FPRemoveFunctionPatch(handle) == FUNCTION_PATCHER_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionPatcherStatus FPGetVersion(FunctionPatcherAPIVersion *outVersion) {
|
||||||
|
if (outVersion == nullptr) {
|
||||||
|
return FUNCTION_PATCHER_RESULT_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
*outVersion = 2;
|
||||||
|
return FUNCTION_PATCHER_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionPatcherStatus FPIsFunctionPatched(PatchedFunctionHandle handle, bool *outIsFunctionPatched) {
|
||||||
|
if (outIsFunctionPatched == nullptr) {
|
||||||
|
return FUNCTION_PATCHER_RESULT_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
std::lock_guard<std::mutex> lock(gPatchedFunctionsMutex);
|
||||||
|
for (auto &cur : gPatchedFunctions) {
|
||||||
|
if (cur->getHandle() == handle) {
|
||||||
|
*outIsFunctionPatched = cur->isPatched;
|
||||||
|
return FUNCTION_PATCHER_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FUNCTION_PATCHER_RESULT_PATCH_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
WUMS_EXPORT_FUNCTION(FPGetVersion);
|
||||||
|
WUMS_EXPORT_FUNCTION(FPAddFunctionPatch);
|
||||||
|
WUMS_EXPORT_FUNCTION(FPRemoveFunctionPatch);
|
||||||
|
WUMS_EXPORT_FUNCTION(FPIsFunctionPatched);
|
@ -38,7 +38,7 @@ bool PatchFunction(std::shared_ptr<PatchedFunctionData> &patchedFunction) {
|
|||||||
|
|
||||||
// The addresses of a function might change every time with run another application.
|
// The addresses of a function might change every time with run another application.
|
||||||
if (!patchedFunction->updateFunctionAddresses()) {
|
if (!patchedFunction->updateFunctionAddresses()) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (patchedFunction->functionName) {
|
if (patchedFunction->functionName) {
|
||||||
|
Loading…
Reference in New Issue
Block a user