mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Merge pull request #646 from goatcorp/corehook
This commit is contained in:
commit
a7ac7b48cf
10 changed files with 141 additions and 21 deletions
33
Dalamud/Configuration/Internal/EnvironmentConfiguration.cs
Normal file
33
Dalamud/Configuration/Internal/EnvironmentConfiguration.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
|
||||
namespace Dalamud.Configuration.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Environmental configuration settings.
|
||||
/// </summary>
|
||||
internal class EnvironmentConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the DALAMUD_NOT_HAVE_INTERFACE setting has been enabled.
|
||||
/// </summary>
|
||||
public static bool DalamudNoInterface { get; } = GetEnvironmentVariable("DALAMUD_NOT_HAVE_INTERFACE");
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the XL_WINEONLINUX setting has been enabled.
|
||||
/// </summary>
|
||||
public static bool XlWineOnLinux { get; } = GetEnvironmentVariable("XL_WINEONLINUX");
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the DALAMUD_NOT_HAVE_PLUGINS setting has been enabled.
|
||||
/// </summary>
|
||||
public static bool DalamudNoPlugins { get; } = GetEnvironmentVariable("DALAMUD_NOT_HAVE_PLUGINS");
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the DalamudForceCoreHook setting has been enabled.
|
||||
/// </summary>
|
||||
public static bool DalamudForceCoreHook { get; } = GetEnvironmentVariable("DALAMUD_FORCE_COREHOOK");
|
||||
|
||||
private static bool GetEnvironmentVariable(string name)
|
||||
=> bool.Parse(Environment.GetEnvironmentVariable(name) ?? "false");
|
||||
}
|
||||
}
|
||||
|
|
@ -186,7 +186,7 @@ namespace Dalamud
|
|||
|
||||
Log.Information("[T2] LOC OK!");
|
||||
|
||||
if (!bool.Parse(Environment.GetEnvironmentVariable("DALAMUD_NOT_HAVE_INTERFACE") ?? "false"))
|
||||
if (!EnvironmentConfiguration.DalamudNoInterface)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CheapLoc" Version="1.1.6" />
|
||||
<PackageReference Include="CoreHook" Version="1.0.4" />
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2021.2.0" />
|
||||
<PackageReference Include="Lumina" Version="3.3.0" />
|
||||
<PackageReference Include="Lumina.Excel" Version="5.50.0" />
|
||||
|
|
@ -93,6 +94,12 @@
|
|||
<AdditionalFiles Include="..\stylecop.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="corehook64.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="AddRuntimeDependenciesToContent" BeforeTargets="GetCopyToOutputDirectoryItems" DependsOnTargets="GenerateBuildDependencyFile;GenerateBuildRuntimeConfigurationFiles">
|
||||
<ItemGroup>
|
||||
<ContentWithTargetPath Include="$(ProjectDepsFilePath)" CopyToOutputDirectory="PreserveNewest" TargetPath="$(ProjectDepsFileName)" />
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace Dalamud.Game.Network.Internal
|
|||
public WinSockHandlers()
|
||||
{
|
||||
this.ws2SocketHook = HookManager.DirtyLinuxUser ? null
|
||||
: Hook<SocketDelegate>.FromSymbol("ws2_32.dll", "socket", this.OnSocket);
|
||||
: Hook<SocketDelegate>.FromSymbol("ws2_32.dll", "socket", this.OnSocket, true);
|
||||
this.ws2SocketHook?.Enable();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Hooking.Internal;
|
||||
using Dalamud.Memory;
|
||||
using Reloaded.Hooks;
|
||||
|
|
@ -16,6 +17,8 @@ namespace Dalamud.Hooking
|
|||
{
|
||||
private readonly IntPtr address;
|
||||
private readonly Reloaded.Hooks.Definitions.IHook<T> hookImpl;
|
||||
private readonly CoreHook.IHook<T> coreHookImpl;
|
||||
private readonly bool isCoreHook;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Hook{T}"/> class.
|
||||
|
|
@ -24,8 +27,22 @@ namespace Dalamud.Hooking
|
|||
/// <param name="address">A memory address to install a hook.</param>
|
||||
/// <param name="detour">Callback function. Delegate must have a same original function prototype.</param>
|
||||
public Hook(IntPtr address, T detour)
|
||||
: this(address, detour, false)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Hook{T}"/> class.
|
||||
/// Hook is not activated until Enable() method is called.
|
||||
/// Please do not use CoreHook unless you have thoroughly troubleshot why Reloaded does not work.
|
||||
/// </summary>
|
||||
/// <param name="address">A memory address to install a hook.</param>
|
||||
/// <param name="detour">Callback function. Delegate must have a same original function prototype.</param>
|
||||
/// <param name="useCoreHook">Use the corehook hooking library instead of Reloaded.</param>
|
||||
public Hook(IntPtr address, T detour, bool useCoreHook)
|
||||
{
|
||||
address = HookManager.FollowJmp(address);
|
||||
this.isCoreHook = useCoreHook || EnvironmentConfiguration.DalamudForceCoreHook;
|
||||
|
||||
var hasOtherHooks = HookManager.Originals.ContainsKey(address);
|
||||
if (!hasOtherHooks)
|
||||
|
|
@ -35,7 +52,14 @@ namespace Dalamud.Hooking
|
|||
}
|
||||
|
||||
this.address = address;
|
||||
this.hookImpl = ReloadedHooks.Instance.CreateHook<T>(detour, address.ToInt64());
|
||||
if (this.isCoreHook)
|
||||
{
|
||||
this.coreHookImpl = CoreHook.HookFactory.CreateHook<T>(address, detour);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.hookImpl = ReloadedHooks.Instance.CreateHook<T>(detour, address.ToInt64());
|
||||
}
|
||||
|
||||
HookManager.TrackedHooks.Add(new HookInfo(this, detour, Assembly.GetCallingAssembly()));
|
||||
}
|
||||
|
|
@ -62,7 +86,14 @@ namespace Dalamud.Hooking
|
|||
get
|
||||
{
|
||||
this.CheckDisposed();
|
||||
return this.hookImpl.OriginalFunction;
|
||||
if (this.isCoreHook)
|
||||
{
|
||||
return this.coreHookImpl.Original;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.hookImpl.OriginalFunction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +105,14 @@ namespace Dalamud.Hooking
|
|||
get
|
||||
{
|
||||
this.CheckDisposed();
|
||||
return this.hookImpl.IsHookEnabled;
|
||||
if (this.isCoreHook)
|
||||
{
|
||||
return this.coreHookImpl.Enabled;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.hookImpl.IsHookEnabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -92,6 +130,19 @@ namespace Dalamud.Hooking
|
|||
/// <param name="detour">Callback function. Delegate must have a same original function prototype.</param>
|
||||
/// <returns>The hook with the supplied parameters.</returns>
|
||||
public static Hook<T> FromSymbol(string moduleName, string exportName, T detour)
|
||||
=> FromSymbol(moduleName, exportName, detour, false);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a hook. Hooking address is inferred by calling to GetProcAddress() function.
|
||||
/// The hook is not activated until Enable() method is called.
|
||||
/// Please do not use CoreHook unless you have thoroughly troubleshot why Reloaded does not work.
|
||||
/// </summary>
|
||||
/// <param name="moduleName">A name of the module currently loaded in the memory. (e.g. ws2_32.dll).</param>
|
||||
/// <param name="exportName">A name of the exported function name (e.g. send).</param>
|
||||
/// <param name="detour">Callback function. Delegate must have a same original function prototype.</param>
|
||||
/// <param name="useCoreHook">Use the corehook hooking library instead of Reloaded.</param>
|
||||
/// <returns>The hook with the supplied parameters.</returns>
|
||||
public static Hook<T> FromSymbol(string moduleName, string exportName, T detour, bool useCoreHook)
|
||||
{
|
||||
var moduleHandle = NativeFunctions.GetModuleHandleW(moduleName);
|
||||
if (moduleHandle == IntPtr.Zero)
|
||||
|
|
@ -101,7 +152,7 @@ namespace Dalamud.Hooking
|
|||
if (procAddress == IntPtr.Zero)
|
||||
throw new Exception($"Could not get the address of {moduleName}::{exportName}");
|
||||
|
||||
return new Hook<T>(procAddress, detour);
|
||||
return new Hook<T>(procAddress, detour, useCoreHook);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -112,10 +163,19 @@ namespace Dalamud.Hooking
|
|||
if (this.IsDisposed)
|
||||
return;
|
||||
|
||||
this.IsDisposed = true;
|
||||
if (this.isCoreHook)
|
||||
{
|
||||
this.Disable();
|
||||
// Disposing CoreHook causes an APPCRASH on game exit.
|
||||
// We already overwrite the original hook code, so there shouldn't be any real risk with not disposing here.
|
||||
// this.coreHookImpl.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Disable();
|
||||
}
|
||||
|
||||
if (this.hookImpl.IsHookEnabled)
|
||||
this.hookImpl.Disable();
|
||||
this.IsDisposed = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -125,11 +185,19 @@ namespace Dalamud.Hooking
|
|||
{
|
||||
this.CheckDisposed();
|
||||
|
||||
if (!this.hookImpl.IsHookActivated)
|
||||
this.hookImpl.Activate();
|
||||
if (this.isCoreHook)
|
||||
{
|
||||
if (!this.coreHookImpl.Enabled)
|
||||
this.coreHookImpl.Enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this.hookImpl.IsHookActivated)
|
||||
this.hookImpl.Activate();
|
||||
|
||||
if (!this.hookImpl.IsHookEnabled)
|
||||
this.hookImpl.Enable();
|
||||
if (!this.hookImpl.IsHookEnabled)
|
||||
this.hookImpl.Enable();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -139,11 +207,19 @@ namespace Dalamud.Hooking
|
|||
{
|
||||
this.CheckDisposed();
|
||||
|
||||
if (!this.hookImpl.IsHookActivated)
|
||||
return;
|
||||
if (this.isCoreHook)
|
||||
{
|
||||
if (this.coreHookImpl.Enabled)
|
||||
this.coreHookImpl.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this.hookImpl.IsHookActivated)
|
||||
return;
|
||||
|
||||
if (this.hookImpl.IsHookEnabled)
|
||||
this.hookImpl.Disable();
|
||||
if (this.hookImpl.IsHookEnabled)
|
||||
this.hookImpl.Disable();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Logging.Internal;
|
||||
using Dalamud.Memory;
|
||||
using Iced.Intel;
|
||||
|
|
@ -40,7 +41,7 @@ namespace Dalamud.Hooking.Internal
|
|||
|
||||
bool Check1()
|
||||
{
|
||||
return Environment.GetEnvironmentVariable("XL_WINEONLINUX") != null;
|
||||
return EnvironmentConfiguration.XlWineOnLinux;
|
||||
}
|
||||
|
||||
bool Check2()
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ namespace Dalamud.Interface.Internal
|
|||
}
|
||||
|
||||
this.setCursorHook = HookManager.DirtyLinuxUser ? null
|
||||
: Hook<SetCursorDelegate>.FromSymbol("user32.dll", "SetCursor", this.SetCursorDetour);
|
||||
: Hook<SetCursorDelegate>.FromSymbol("user32.dll", "SetCursor", this.SetCursorDetour, true);
|
||||
this.presentHook = new Hook<PresentDelegate>(this.address.Present, this.PresentDetour);
|
||||
this.resizeBuffersHook = new Hook<ResizeBuffersDelegate>(this.address.ResizeBuffers, this.ResizeBuffersDetour);
|
||||
|
||||
|
|
|
|||
|
|
@ -56,8 +56,8 @@ namespace Dalamud.Plugin.Internal
|
|||
if (!this.devPluginDirectory.Exists)
|
||||
this.devPluginDirectory.Create();
|
||||
|
||||
var noPlugins = bool.Parse(Environment.GetEnvironmentVariable("DALAMUD_NOT_HAVE_PLUGINS") ?? "false");
|
||||
if (this.SafeMode = noPlugins || configuration.PluginSafeMode)
|
||||
this.SafeMode = EnvironmentConfiguration.DalamudNoPlugins || configuration.PluginSafeMode;
|
||||
if (this.SafeMode)
|
||||
{
|
||||
configuration.PluginSafeMode = false;
|
||||
configuration.Save();
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ namespace Dalamud.Support
|
|||
DoPluginTest = configuration.DoPluginTest,
|
||||
InterfaceLoaded = interfaceManager?.IsReady ?? false,
|
||||
ThirdRepo = configuration.ThirdRepoList,
|
||||
ForcedCoreHook = EnvironmentConfiguration.DalamudForceCoreHook,
|
||||
};
|
||||
|
||||
var encodedPayload = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload)));
|
||||
|
|
@ -112,6 +113,8 @@ namespace Dalamud.Support
|
|||
|
||||
public bool InterfaceLoaded { get; set; }
|
||||
|
||||
public bool ForcedCoreHook { get; set; }
|
||||
|
||||
public List<ThirdPartyRepoSettings> ThirdRepo { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
BIN
Dalamud/corehook64.dll
Normal file
BIN
Dalamud/corehook64.dll
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue