Skip to content

Commit

Permalink
Added: Explicit check that page is executable before hooking it.
Browse files Browse the repository at this point in the history
Fixes booting with Steam DRM and local install of Special K <= 24.3.1.6.

This is fixed on Special K's end on a93a975aeb05965ff074118d44c9a0dbd806dd65 (Removed private D3DKMT and D3D11 DLL symbol exports from SK), so future versions won't need this patch, however it's still good for backcompat.
  • Loading branch information
Sewer56 committed Mar 2, 2024
1 parent 31115d1 commit ca10702
Show file tree
Hide file tree
Showing 2 changed files with 360 additions and 9 deletions.
40 changes: 32 additions & 8 deletions source/Reloaded.Mod.Loader/Utilities/DelayInjector.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
using Reloaded.Hooks.Definitions.Enums;
using static Reloaded.Mod.Loader.Utilities.Native.Kernel32;
using static Reloaded.Mod.Loader.Utilities.Native.Kernel32.MEM_PROTECTION;
using static Reloaded.Mod.Loader.Utilities.Native.Kernel32.MEM_STATE;

namespace Reloaded.Mod.Loader.Utilities;

/// <summary>
Expand Down Expand Up @@ -37,17 +42,25 @@ public DelayInjector(IReloadedHooks hooks, Action action, Logger logger)
for (var x = 0; x < _dlls.Count; x++)
{
var dll = _dlls[x];
var handle = Native.Kernel32.GetModuleHandle(dll.Name);
var handle = GetModuleHandle(dll.Name);
if (handle == IntPtr.Zero)
continue;

for (var y = 0; y < dll.Functions.Length; y++)
{
var functionAddr = Native.Kernel32.GetProcAddress(handle, dll.Functions[y]);
var functionAddr = GetProcAddress(handle, dll.Functions[y]);
if (functionAddr == IntPtr.Zero)
continue;

_hooks.Add(CreateHook((long) functionAddr, x, y, hooks));
// Before hooking, assert that our functions are executable.
MEMORY_BASIC_INFORMATION mi = default;
VirtualQuery((nuint)functionAddr, &mi, (nuint)sizeof(MEMORY_BASIC_INFORMATION));
var isExecutable =
(mi.Protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE |
PAGE_EXECUTE_WRITECOPY)) != 0;

if (mi.State == COMMIT && isExecutable)
_hooks.Add(CreateHook((ulong)functionAddr, x, y, hooks));
}
}
}
Expand All @@ -59,10 +72,10 @@ public DelayInjector(IReloadedHooks hooks, Action action, Logger logger)
/// <param name="dllOrdinal">Index of the DLL in the DLL list.</param>
/// <param name="functionOrdinal">Index of the function in the DLL's function list.</param>
/// <param name="hooks">The hooking library to use.</param>
private unsafe IAsmHook CreateHook(long address, int dllOrdinal, int functionOrdinal, IReloadedHooks hooks)
private unsafe IAsmHook CreateHook(ulong address, int dllOrdinal, int functionOrdinal, IReloadedHooks hooks)
{
var utilities = hooks.Utilities;

// Assumes function uses Microsoft call convention on x64.
var asmCode = new string[]
{
Expand All @@ -73,8 +86,8 @@ private unsafe IAsmHook CreateHook(long address, int dllOrdinal, int functionOrd
$"{Macros.PushAll}",
Macros.Is64Bit ? Macros.PushSseCallConvRegistersx64 : "", // Push Microsoft Call Convention SSE Float Registers

$"mov dword [dword 0x{(long)_asmEntryDllOrdinal:X}], {dllOrdinal}",
$"mov dword [dword 0x{(long)_asmEntryFunctionOrdinal:X}], {functionOrdinal}",
$"mov dword [dword 0x{(ulong)_asmEntryDllOrdinal:X}], {dllOrdinal}",
$"mov dword [dword 0x{(ulong)_asmEntryFunctionOrdinal:X}], {functionOrdinal}",

utilities.GetAbsoluteCallMnemonics<Macros.AsmAction>(HookImpl, out var wrapper),

Expand All @@ -85,7 +98,18 @@ private unsafe IAsmHook CreateHook(long address, int dllOrdinal, int functionOrd
};

_wrappers.Add(wrapper);
return hooks.CreateAsmHook(asmCode, address).Activate();

// The current Reloaded.Hooks library has some shortcomings with handling invalid bytes leftover from
// previous hooks. While we wait for the much more advanced Rust rewrite, `reloaded-hooks-rs`, requesting a
// relative jump should be sufficient.
return hooks.CreateAsmHook(asmCode, (long)address, new AsmHookOptions()
{
Behaviour = AsmHookBehaviour.ExecuteFirst,
PreferRelativeJump = true,
MaxOpcodeSize = 5,
hookLength = -1,
}).Activate();
// dw 'address' is still unsigned, it's signed in API for backcompat
}

/// <summary>
Expand Down
Loading

0 comments on commit ca10702

Please sign in to comment.