Add minBytes and maxBytes to Unhooker

This commit is contained in:
nebel 2023-06-04 01:48:18 +09:00
parent 64fddf10bb
commit 429316747d
No known key found for this signature in database
3 changed files with 22 additions and 9 deletions

View file

@ -41,7 +41,7 @@ internal class FunctionPointerVariableHook<T> : Hook<T>
{ {
lock (HookManager.HookEnableSyncRoot) lock (HookManager.HookEnableSyncRoot)
{ {
var unhooker = HookManager.RegisterUnhooker(this.Address); var unhooker = HookManager.RegisterUnhooker(this.Address, 8, 8);
if (!HookManager.MultiHookTracker.TryGetValue(this.Address, out var indexList)) if (!HookManager.MultiHookTracker.TryGetValue(this.Address, out var indexList))
{ {

View file

@ -46,11 +46,13 @@ internal class HookManager : IDisposable, IServiceType
/// an existing instance if the address registered previously. /// an existing instance if the address registered previously.
/// </summary> /// </summary>
/// <param name="address">The address of the instruction.</param> /// <param name="address">The address of the instruction.</param>
/// <param name="minBytes">The minimum amount of bytes to restore when unhooking. Defaults to 0.</param>
/// <param name="maxBytes">The maximum amount of bytes to restore when unhooking. Defaults to 0x32.</param>
/// <returns>A new Unhooker instance.</returns> /// <returns>A new Unhooker instance.</returns>
public static Unhooker RegisterUnhooker(IntPtr address) public static Unhooker RegisterUnhooker(IntPtr address, int minBytes = 0, int maxBytes = 0x32)
{ {
Log.Verbose($"Registering hook at 0x{address.ToInt64():X}"); Log.Verbose($"Registering hook at 0x{address.ToInt64():X} (minBytes=0x{minBytes:X}, maxBytes=0x{maxBytes:X})");
return Unhookers.GetOrAdd(address, adr => new Unhooker(adr)); return Unhookers.GetOrAdd(address, _ => new Unhooker(address, minBytes, maxBytes));
} }
/// <summary> /// <summary>

View file

@ -11,6 +11,7 @@ namespace Dalamud.Hooking.Internal;
public class Unhooker public class Unhooker
{ {
private readonly IntPtr address; private readonly IntPtr address;
private readonly int minBytes;
private byte[] originalBytes; private byte[] originalBytes;
private bool trimmed; private bool trimmed;
@ -20,10 +21,18 @@ public class Unhooker
/// removed. As such this class should be instantiated before the function is actually hooked. /// removed. As such this class should be instantiated before the function is actually hooked.
/// </summary> /// </summary>
/// <param name="address">The address which will be hooked.</param> /// <param name="address">The address which will be hooked.</param>
public Unhooker(IntPtr address) /// <param name="minBytes">The minimum amount of bytes to restore when unhooking.</param>
/// <param name="maxBytes">The maximum amount of bytes to restore when unhooking.</param>
internal Unhooker(IntPtr address, int minBytes, int maxBytes)
{ {
if (minBytes < 0 || minBytes > maxBytes)
{
throw new ArgumentException($"minBytes ({minBytes}) must be <= maxBytes ({maxBytes}) and nonnegative.");
}
this.address = address; this.address = address;
MemoryHelper.ReadRaw(address, 0x32, out this.originalBytes); this.minBytes = minBytes;
MemoryHelper.ReadRaw(address, maxBytes, out this.originalBytes);
} }
/// <summary> /// <summary>
@ -39,7 +48,9 @@ public class Unhooker
return; return;
} }
this.originalBytes = this.originalBytes[..this.GetFullHookLength()]; var len = int.Max(this.GetFullHookLength(), this.minBytes);
this.originalBytes = this.originalBytes[..len];
this.trimmed = true; this.trimmed = true;
} }
@ -51,7 +62,7 @@ public class Unhooker
/// </summary> /// </summary>
public void Unhook() public void Unhook()
{ {
var len = this.trimmed ? this.originalBytes.Length : this.GetNaiveHookLength(); var len = this.trimmed ? this.originalBytes.Length : int.Max(this.GetNaiveHookLength(), this.minBytes);
if (len > 0) if (len > 0)
{ {
HookManager.Log.Verbose($"Reverting hook at 0x{this.address.ToInt64():X} ({len} bytes, trimmed={this.trimmed})"); HookManager.Log.Verbose($"Reverting hook at 0x{this.address.ToInt64():X} ({len} bytes, trimmed={this.trimmed})");
@ -82,7 +93,7 @@ public class Unhooker
{ {
if (current[i] != this.originalBytes[i]) if (current[i] != this.originalBytes[i])
{ {
return i + 1; return int.Max(i + 1, this.minBytes);
} }
} }