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)
{
var unhooker = HookManager.RegisterUnhooker(this.Address);
var unhooker = HookManager.RegisterUnhooker(this.Address, 8, 8);
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.
/// </summary>
/// <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>
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}");
return Unhookers.GetOrAdd(address, adr => new Unhooker(adr));
Log.Verbose($"Registering hook at 0x{address.ToInt64():X} (minBytes=0x{minBytes:X}, maxBytes=0x{maxBytes:X})");
return Unhookers.GetOrAdd(address, _ => new Unhooker(address, minBytes, maxBytes));
}
/// <summary>

View file

@ -11,6 +11,7 @@ namespace Dalamud.Hooking.Internal;
public class Unhooker
{
private readonly IntPtr address;
private readonly int minBytes;
private byte[] originalBytes;
private bool trimmed;
@ -20,10 +21,18 @@ public class Unhooker
/// removed. As such this class should be instantiated before the function is actually hooked.
/// </summary>
/// <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;
MemoryHelper.ReadRaw(address, 0x32, out this.originalBytes);
this.minBytes = minBytes;
MemoryHelper.ReadRaw(address, maxBytes, out this.originalBytes);
}
/// <summary>
@ -39,7 +48,9 @@ public class Unhooker
return;
}
this.originalBytes = this.originalBytes[..this.GetFullHookLength()];
var len = int.Max(this.GetFullHookLength(), this.minBytes);
this.originalBytes = this.originalBytes[..len];
this.trimmed = true;
}
@ -51,7 +62,7 @@ public class Unhooker
/// </summary>
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)
{
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])
{
return i + 1;
return int.Max(i + 1, this.minBytes);
}
}