-
Notifications
You must be signed in to change notification settings - Fork 22
Replacing temple.dll Functions and Replacing Arbitrary Bytes
TemplePlus provides an infrastructure called TempleFix
to help with replacing entire functions in temple.dll, or manipulate arbitrary bytes to apply DLL fixes.
To write such a fix, add a my_unique_fix.cpp file (use a descriptive name) and add it to the project (no header needed).
#include "stdafx.h"
#include "fixes.h"
static class MyUniqueFix : public TempleFix {
public:
const char* name() override {
return "A human readable description of what my fix does";
}
void apply() override {
...
}
} myUniqueFix;
By instantiating it on the last line, this fix will be automatically applied by TemplePlus before the game starts.
Within the apply function, you can use the helper functions provided by the TempleFix
base class to manipulate temple.dll in memory.
To enable fixes that have to write some raw binary data into the temple.dll address space writeHex
is provided as a convenience function.
The following example replaces a debug message function call with noops at a specific address:
void apply() override {
writeHex(0x10079FEE, "90 90 90 90 90"); // print debug message
}
If you identified a function you want to rewrite in C/C++ without having to redirect all calls to it one-by-one, you can use the replaceFunction
method to automatically write a redirection call into the function in question. This is accomplished using the excellent MinHook library.
The signature of the method is: void *replaceFunction(uint32_t offset, void *replaceWith);
Once you have identified the signature (and calling convention) of a method in temple.dll and know it's address, the method can be used like this, using temple_main as an example
// In this example, the declarations go outside of the class
static int (__cdecl *OrgInitPython)();
static int __cdecl HookedInitPython() {
auto result = OrgInitPython(); // Call original method
// Do some additional stuff
return result;
}
...
void apply() override {
OrgInitPython = (int(__cdecl*)) replaceFunction(0x100ADA30, HookedInitPython);
}
The method will automatically rebase the given memory address to the correct temple.dll offset. It returns a callable function pointer to the original method after it replaces the start of it at the given address with a call to the given hook function.
This is an advanced technique you'll only need if the base class methods are not enough to implement your fix and you need dirty pointer magic to manipulate temple.dll directly.
The MemoryUnprotector
class will temporarily remove the Windows write protection for a memory area while an instance of it is in the local scope.
Usage:
void apply() override {
MemoryUnprotector unprotect(0x10001000, 0x1000);
/* do some funky pointer magic */
}
The class will unprotect the area given by its arguments when it's constructed and restore the previous protection level once it goes out of scope (the end of the function in this case). The given address will automatically be rebased to temple.dll's real load offset.