Releases: Lectem/D2.Detours
Releases · Lectem/D2.Detours
New APIs for patching + refactored patching code
Example code using the new API:
extern "C" {
static ExtraPatchAction D2GameExtraPatchActions[] = {
{ 0x6FC386D0 - D2GameImageBase, &GAME_UpdateProgress_WithDebugger, PatchAction::FunctionReplaceOriginalByPatch, &GAME_UpdateProgress_Original},
{ 0, 0, PatchAction::Ignore}, // Here because we need at least one element in the array
};
static ExtraPatchAction D2ClientExtraPatchActions[] = {
{ 0, 0, PatchAction::Ignore}, // Here because we need at least one element in the array
};
ExtraPatchAction* __cdecl D2ClientGetExtraPatchAction(int index)
{
return &D2ClientExtraPatchActions[index];
}
__declspec(dllexport)
uint32_t __cdecl DllPreLoadHook(HookContext* ctx, const wchar_t* dllName)
{
if (wcsicmp(dllName, L"D2Game.dll") == 0)
{
for (auto& p : D2GameExtraPatchActions)
{
ctx->ApplyPatchAction(ctx, p.originalDllOffset, p.patchData, p.action, (void**)p.detouredPatchedFunctionPointerStorageAddress);
}
}
else if (wcsicmp(dllName, L"D2Client.dll") == 0)
{
for (auto& p : D2ClientExtraPatchActions)
{
ctx->ApplyPatchAction(ctx, p.originalDllOffset, p.patchData, p.action, (void**)p.detouredPatchedFunctionPointerStorageAddress);
}
}
else
{
__debugbreak(); // Insert other dlls here if you added them in the .rc.
return {};
}
return 0;
}
} // extern "C"
Support patching recursively
Bug fix when we try to patch the same .dll recursively
Command line params and patch dll with other name
- Command line parameters can now be sent to the game by using
--
before the game params - It is now possible for a patch.dll to specify the .dll it wants to patch
- The user can now provide his own variable to store the original function pointer that has been patched
- Allow to use any .dll from the patch folder. This means one may now use 3rd party .dlls more easily.
Detours updates variable holding address to let you call the patched function
This fixes a potential use after free and also exposes the detour pointer to ExtraPatchActions. This is useful if you want to just wrap (detour) a function and be able to call its original version.
However, this means that the user provided ExtraPatchAction must be alive until the end of the patching.
This involves a breaking change in the API hence version 3.0.0
Automatic detection of patches
v2.0.0 Add automatic detection of patch .DLLs. Keep only D2CMP manual patch …
Add support for non-ordinal patching
Example usage:
// In your DLL
static const int D2CommonImageBase = 0x6FD40000;
static ExtraPatchAction extraPatchActions[] = {
//{ 0x6FDB6300 - D2CommonImageBase, &STATLIST_FindStatIndex_6FDB6300 , PatchAction::FunctionReplaceOriginalByPatch },
//{ 0x6FDB6C10 - D2CommonImageBase, &sub_6FDB6C10, PatchAction::FunctionReplacePatchByOriginal },
//{ 0x6FDB64A0 - D2CommonImageBase, &sub_6FDB64A0, PatchAction::FunctionReplacePatchByOriginal },
//{ 0x6FDB6920 - D2CommonImageBase, &STATLIST_FindStat_6FDB6920, PatchAction::FunctionReplacePatchByOriginal },
//{ 0x6FDB6970 - D2CommonImageBase, &STATLIST_InsertStatOrFail_6FDB6970, PatchAction::FunctionReplaceOriginalByPatch },
//{ 0x6FDB6AB0 - D2CommonImageBase, &STATLIST_UpdateUnitStat_6FDB6AB0, PatchAction::FunctionReplaceOriginalByPatch },
//{ 0x6FDB63E0 - D2CommonImageBase, &STATLIST_GetTotalStat_6FDB63E0, PatchAction::FunctionReplaceOriginalByPatch },
{ 0, 0, PatchAction::Ignore}, // Here because we need at least one element in the array
};
__declspec(dllexport)
constexpr int __cdecl GetExtraPatchActionsCount() { return sizeof(extraPatchActions) / sizeof(ExtraPatchAction); }
__declspec(dllexport)
ExtraPatchAction __cdecl GetExtraPatchAction(int index)
{
return extraPatchActions[index];
}
D2.DetoursLauncher
This release adds a new launcher to replace withdll.exe
First release
v1.0.0 Fix releases asset publish condition