Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

Hook.cs 4.8 KiB

8 månader sedan
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. using EasyHook;
  2. using System;
  3. using System.Runtime.InteropServices;
  4. namespace RenderHookAPI.Hook
  5. {
  6. // Thanks to remcoros for the initial version of the following helper classes
  7. /// <summary>
  8. /// Extends <see cref="Hook"/> with support for accessing the Original method from within a hook delegate
  9. /// </summary>
  10. /// <typeparam name="T">A delegate type</typeparam>
  11. public class Hook<T> : Hook
  12. where T: class
  13. {
  14. /// <summary>
  15. /// When called from within the <see cref="Hook.NewFunc"/> delegate this will call the original function at <see cref="Hook.FuncToHook"/>.
  16. /// </summary>
  17. public T Original { get; private set; }
  18. /// <summary>
  19. /// Creates a new hook at <paramref name="funcToHook"/> redirecting to <paramref name="newFunc"/>. The hook starts inactive so a call to <see cref="Activate"/> is required to enable the hook.
  20. /// </summary>
  21. /// <param name="funcToHook">A pointer to the location to insert the hook</param>
  22. /// <param name="newFunc">The delegate to call from the hooked location</param>
  23. /// <param name="owner">The object to assign as the "callback" object within the <see cref="EasyHook.LocalHook"/> instance.</param>
  24. public Hook(IntPtr funcToHook, Delegate newFunc, object owner)
  25. : base(funcToHook, newFunc, owner)
  26. {
  27. // Debug assertion that T is a Delegate type
  28. System.Diagnostics.Debug.Assert(typeof(Delegate).IsAssignableFrom(typeof(T)));
  29. Original = (T)(object)Marshal.GetDelegateForFunctionPointer(funcToHook, typeof(T));
  30. }
  31. }
  32. /// <summary>
  33. /// Wraps the <see cref="EasyHook.LocalHook"/> class with a simplified active/inactive state
  34. /// </summary>
  35. public class Hook: IDisposable
  36. {
  37. /// <summary>
  38. /// The hooked function location
  39. /// </summary>
  40. public IntPtr FuncToHook { get; private set; }
  41. /// <summary>
  42. /// The replacement delegate
  43. /// </summary>
  44. public Delegate NewFunc { get; private set; }
  45. /// <summary>
  46. /// The callback object passed to LocalHook constructor
  47. /// </summary>
  48. public object Owner { get; private set; }
  49. /// <summary>
  50. /// The <see cref="EasyHook.LocalHook"/> instance
  51. /// </summary>
  52. public LocalHook LocalHook { get; private set; }
  53. /// <summary>
  54. /// Indicates whether the hook is currently active
  55. /// </summary>
  56. public bool IsActive { get; private set; }
  57. /// <summary>
  58. /// Creates a new hook at <paramref name="funcToHook"/> redirecting to <paramref name="newFunc"/>. The hook starts inactive so a call to <see cref="Activate"/> is required to enable the hook.
  59. /// </summary>
  60. /// <param name="funcToHook">A pointer to the location to insert the hook</param>
  61. /// <param name="newFunc">The delegate to call from the hooked location</param>
  62. /// <param name="owner">The object to assign as the "callback" object within the <see cref="EasyHook.LocalHook"/> instance.</param>
  63. public Hook(IntPtr funcToHook, Delegate newFunc, object owner)
  64. {
  65. this.FuncToHook = funcToHook;
  66. this.NewFunc = newFunc;
  67. this.Owner = owner;
  68. CreateHook();
  69. }
  70. ~Hook()
  71. {
  72. Dispose(false);
  73. }
  74. protected void CreateHook()
  75. {
  76. if (LocalHook != null) return;
  77. this.LocalHook = LocalHook.Create(FuncToHook, NewFunc, Owner);
  78. }
  79. protected void UnHook()
  80. {
  81. if (this.IsActive)
  82. Deactivate();
  83. if (this.LocalHook != null)
  84. {
  85. this.LocalHook.Dispose();
  86. this.LocalHook = null;
  87. }
  88. }
  89. /// <summary>
  90. /// Activates the hook
  91. /// </summary>
  92. public void Activate()
  93. {
  94. if (this.LocalHook == null)
  95. CreateHook();
  96. if (this.IsActive) return;
  97. this.IsActive = true;
  98. this.LocalHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
  99. }
  100. /// <summary>
  101. /// Deactivates the hook
  102. /// </summary>
  103. public void Deactivate()
  104. {
  105. if (!this.IsActive) return;
  106. this.IsActive = false;
  107. this.LocalHook.ThreadACL.SetInclusiveACL(new Int32[] { 0 });
  108. }
  109. public void Dispose()
  110. {
  111. Dispose(true);
  112. }
  113. protected virtual void Dispose(bool disposeManagedObjects)
  114. {
  115. // Only clean up managed objects if disposing (i.e. not called from destructor)
  116. if (disposeManagedObjects)
  117. {
  118. UnHook();
  119. }
  120. }
  121. }
  122. }