diff --git a/Dalamud.Injector/Dalamud.Injector.csproj b/Dalamud.Injector/Dalamud.Injector.csproj
index a61c31a09..bf67bb8fd 100644
--- a/Dalamud.Injector/Dalamud.Injector.csproj
+++ b/Dalamud.Injector/Dalamud.Injector.csproj
@@ -14,10 +14,10 @@
true
- 4.7.0.0
- 4.7.0.0
+ 4.7.2.0
+ 4.7.2.0
XIVLauncher addon injection
- 4.7.0.0
+ 4.7.2.0
diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs
index e09c58717..3153de26c 100644
--- a/Dalamud/Dalamud.cs
+++ b/Dalamud/Dalamud.cs
@@ -28,9 +28,9 @@ namespace Dalamud {
private readonly ManualResetEvent unloadSignal;
- public readonly ProcessModule TargetModule;
+ private readonly ProcessModule targetModule;
- private readonly SigScanner sigScanner;
+ public readonly SigScanner SigScanner;
public Framework Framework { get; }
@@ -48,7 +48,7 @@ namespace Dalamud {
public readonly DalamudConfiguration Configuration;
- internal readonly WinSockHandlers WinSock2;
+ private readonly WinSockHandlers WinSock2;
public readonly InterfaceManager InterfaceManager;
@@ -63,11 +63,11 @@ namespace Dalamud {
this.unloadSignal = new ManualResetEvent(false);
// Initialize the process information.
- this.TargetModule = Process.GetCurrentProcess().MainModule;
- this.sigScanner = new SigScanner(this.TargetModule);
+ this.targetModule = Process.GetCurrentProcess().MainModule;
+ SigScanner = new SigScanner(this.targetModule, true);
// Initialize game subsystem
- Framework = new Framework(this.sigScanner, this);
+ Framework = new Framework(this.SigScanner, this);
// Initialize managers. Basically handlers for the logic
CommandManager = new CommandManager(this, info.Language);
@@ -76,7 +76,7 @@ namespace Dalamud {
ChatHandlers = new ChatHandlers(this);
NetworkHandlers = new NetworkHandlers(this, this.Configuration.OptOutMbCollection);
- this.ClientState = new ClientState(this, info, this.sigScanner, this.TargetModule);
+ this.ClientState = new ClientState(this, info, this.SigScanner, this.targetModule);
this.BotManager = new DiscordBotManager(this, this.Configuration.DiscordFeatureConfig);
@@ -84,7 +84,7 @@ namespace Dalamud {
this.WinSock2 = new WinSockHandlers();
- this.InterfaceManager = new InterfaceManager(this, this.sigScanner);
+ this.InterfaceManager = new InterfaceManager(this, this.SigScanner);
this.InterfaceManager.OnDraw += BuildDalamudUi;
this.InterfaceManager.Enable();
}
@@ -135,6 +135,8 @@ namespace Dalamud {
this.unloadSignal.Dispose();
this.WinSock2.Dispose();
+
+ this.SigScanner.Dispose();
}
#region Interface
diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj
index 0855dce85..373898a6c 100644
--- a/Dalamud/Dalamud.csproj
+++ b/Dalamud/Dalamud.csproj
@@ -14,9 +14,9 @@
true
- 4.7.0.0
- 4.7.0.0
- 4.7.0.0
+ 4.7.2.0
+ 4.7.2.0
+ 4.7.2.0
diff --git a/Dalamud/Game/SigScanner.cs b/Dalamud/Game/SigScanner.cs
index 823d016ba..67789a38b 100644
--- a/Dalamud/Game/SigScanner.cs
+++ b/Dalamud/Game/SigScanner.cs
@@ -7,18 +7,24 @@ using System.Runtime.InteropServices;
using Serilog;
namespace Dalamud.Game {
- public sealed class SigScanner {
- public SigScanner(ProcessModule module) {
+ public sealed class SigScanner : IDisposable {
+ public SigScanner(ProcessModule module, bool doCopy = false) {
Module = module;
Is32BitProcess = !Environment.Is64BitProcess;
+ IsCopy = doCopy;
// Limit the search space to .text section.
SetupSearchSpace(module);
+ if (IsCopy)
+ SetupCopiedSegments();
+
Log.Verbose("Module base: {Address}", TextSectionBase);
- Log.Verbose("Moudle size: {Size}", TextSectionSize);
+ Log.Verbose("Module size: {Size}", TextSectionSize);
}
+ public bool IsCopy { get; private set; }
+
public bool Is32BitProcess { get; }
public IntPtr TextSectionBase { get; private set; }
@@ -72,19 +78,58 @@ namespace Dalamud.Game {
}
}
+ private IntPtr textCopyPtr;
+ private IntPtr dataCopyPtr;
+
+ private unsafe void SetupCopiedSegments() {
+ Log.Verbose("text copy START");
+ // .text
+ this.textCopyPtr = Marshal.AllocHGlobal(TextSectionSize);
+ Log.Verbose($"Alloc: {this.textCopyPtr.ToInt64():x}");
+ Buffer.MemoryCopy(TextSectionBase.ToPointer(), this.textCopyPtr.ToPointer(), TextSectionSize,
+ TextSectionSize);
+
+ Log.Verbose("data copy START");
+ // .data
+ this.dataCopyPtr = Marshal.AllocHGlobal(DataSectionSize);
+ Buffer.MemoryCopy(DataSectionBase.ToPointer(), this.dataCopyPtr.ToPointer(), DataSectionSize,
+ DataSectionSize);
+
+ Log.Verbose("copy OK!");
+ }
+
+ public void Dispose() {
+ Marshal.FreeHGlobal(this.textCopyPtr);
+ Marshal.FreeHGlobal(this.dataCopyPtr);
+ }
+
public IntPtr ScanText(string signature) {
- return Scan(TextSectionBase, TextSectionSize, signature);
+ var mBase = IsCopy ? this.textCopyPtr : TextSectionBase;
+
+ var scanRet = Scan(mBase, TextSectionSize, signature);
+
+ return IsCopy
+ ? (new IntPtr(scanRet.ToInt64() - (this.textCopyPtr.ToInt64() - TextSectionBase.ToInt64())))
+ : scanRet;
}
public IntPtr ScanData(string signature) {
- return Scan(DataSectionBase, DataSectionSize, signature);
+ var mBase = IsCopy ? this.dataCopyPtr : DataSectionBase;
+
+ var scanRet = Scan(DataSectionBase, DataSectionSize, signature);
+
+ return IsCopy
+ ? (new IntPtr(scanRet.ToInt64() - (this.textCopyPtr.ToInt64() - TextSectionBase.ToInt64())))
+ : scanRet;
}
public IntPtr ScanModule(string signature) {
+ // TODO: This does not respect the copy flag.
return Scan(Module.BaseAddress, Module.ModuleMemorySize, signature);
}
public IntPtr Scan(IntPtr baseAddress, int size, string signature) {
+ Log.Verbose($"Scan at {baseAddress.ToInt64():x} with {size:x} for {signature}");
var needle = SigToNeedle(signature);
unsafe {
diff --git a/Dalamud/Plugin/DalamudPluginInterface.cs b/Dalamud/Plugin/DalamudPluginInterface.cs
index a0ad75499..5c9cab3d6 100644
--- a/Dalamud/Plugin/DalamudPluginInterface.cs
+++ b/Dalamud/Plugin/DalamudPluginInterface.cs
@@ -55,7 +55,7 @@ namespace Dalamud.Plugin
this.Framework = dalamud.Framework;
this.ClientState = dalamud.ClientState;
this.UiBuilder = new UiBuilder(dalamud.InterfaceManager, pluginName);
- this.TargetModuleScanner = new SigScanner(dalamud.TargetModule);
+ this.TargetModuleScanner = dalamud.SigScanner;
this.dalamud = dalamud;
this.pluginName = pluginName;