chroe: don't use AsmHook for wndproc fix

This commit is contained in:
goaaats 2022-05-26 15:41:10 +02:00
parent baad575c53
commit 28102b405b
No known key found for this signature in database
GPG key ID: 49E2AA8C6A76498B
3 changed files with 34 additions and 23 deletions

View file

@ -27,11 +27,6 @@ namespace Dalamud.Configuration.Internal
/// </summary> /// </summary>
public static bool DalamudForceMinHook { get; } = GetEnvironmentVariable("DALAMUD_FORCE_MINHOOK"); public static bool DalamudForceMinHook { get; } = GetEnvironmentVariable("DALAMUD_FORCE_MINHOOK");
/// <summary>
/// Gets a value indicating whether or not Dalamud should wait for a debugger to be attached when initializing.
/// </summary>
public static bool DalamudWaitForDebugger { get; } = GetEnvironmentVariable("DALAMUD_WAIT_DEBUGGER");
/// <summary> /// <summary>
/// Gets a value indicating whether or not Dalamud context menus should be disabled. /// Gets a value indicating whether or not Dalamud context menus should be disabled.
/// </summary> /// </summary>

View file

@ -108,14 +108,6 @@ namespace Dalamud
/// <param name="info">The <see cref="DalamudStartInfo"/> containing information needed to initialize Dalamud.</param> /// <param name="info">The <see cref="DalamudStartInfo"/> containing information needed to initialize Dalamud.</param>
private static void RunThread(DalamudStartInfo info) private static void RunThread(DalamudStartInfo info)
{ {
if (EnvironmentConfiguration.DalamudWaitForDebugger)
{
while (!Debugger.IsAttached)
{
Thread.Sleep(100);
}
}
// Setup logger // Setup logger
var levelSwitch = InitLogging(info.WorkingDirectory); var levelSwitch = InitLogging(info.WorkingDirectory);

View file

@ -1,6 +1,8 @@
using System; using System;
using Dalamud.Game; using Dalamud.Game;
using Dalamud.Hooking; using Dalamud.Hooking;
using Dalamud.Memory;
using Serilog; using Serilog;
namespace Dalamud.Fixes; namespace Dalamud.Fixes;
@ -12,28 +14,39 @@ namespace Dalamud.Fixes;
/// </summary> /// </summary>
internal class WndProcNullRefFix : IGameFix, IDisposable internal class WndProcNullRefFix : IGameFix, IDisposable
{ {
private AsmHook? wndProcHook; private Hook<WndProcDelegate>? wndProcHook;
private IntPtr object1Address;
private IntPtr object2Address;
private delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
/// <inheritdoc/> /// <inheritdoc/>
public void Apply() public void Apply()
{ {
var sigScanner = Service<SigScanner>.Get(); var sigScanner = Service<SigScanner>.Get();
if (!sigScanner.TryScanText("E8 ?? ?? ?? ?? 48 83 38 00 74 14", out var patchAddress)) if (!sigScanner.TryScanText("40 55 53 41 54 41 56 48 8D 6C 24 ??", out var patchAddress))
{ {
Log.Error("Failed to find WndProc patch address"); Log.Error("Failed to find WndProc address");
return; return;
} }
Log.Information($"Applying WndProcNullRefFix at {patchAddress:X}"); if (!sigScanner.TryGetStaticAddressFromSig("74 1F E8 ?? ?? ?? ?? 48 83 38 00 ", out this.object1Address))
var patchAsm = new byte[]
{ {
0x48, 0x85, 0xc0, // test rax, rax Log.Error("Failed to find object1 address");
0x74, 0x15, // jz +0x1A return;
}; }
this.wndProcHook = new AsmHook(patchAddress, patchAsm, "WndProcNullRefFix"); if (!sigScanner.TryGetStaticAddressFromSig("E8 ?? ?? ?? ?? 48 83 38 00 74 14", out this.object2Address, 0x7))
{
Log.Error("Failed to find object2 address");
return;
}
Log.Information($"Applying WndProcNullRefFix at {patchAddress:X} with o1 {this.object1Address:X}, o2 {this.object2Address:X}");
this.wndProcHook = new Hook<WndProcDelegate>(patchAddress, this.WndProcDetour);
this.wndProcHook.Enable(); this.wndProcHook.Enable();
} }
@ -42,4 +55,15 @@ internal class WndProcNullRefFix : IGameFix, IDisposable
{ {
this.wndProcHook?.Dispose(); this.wndProcHook?.Dispose();
} }
private IntPtr WndProcDetour(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
if (msg == 0x219 && wParam.ToInt64() == 7 && (MemoryHelper.Read<IntPtr>(this.object1Address) == IntPtr.Zero || MemoryHelper.Read<IntPtr>(this.object2Address) == IntPtr.Zero))
{
Log.Information("Filtered WM_DEVICE_CHANGE message");
return IntPtr.Zero;
}
return this.wndProcHook!.Original(hWnd, msg, wParam, lParam);
}
} }