diff --git a/Dalamud/Game/Internal/Gui/GameGui.cs b/Dalamud/Game/Internal/Gui/GameGui.cs
index 431c9ad6e..2f1d213df 100644
--- a/Dalamud/Game/Internal/Gui/GameGui.cs
+++ b/Dalamud/Game/Internal/Gui/GameGui.cs
@@ -75,6 +75,9 @@ namespace Dalamud.Game.Internal.Gui {
private delegate IntPtr GetUiModuleDelegate(IntPtr basePtr);
private readonly GetUiModuleDelegate getUiModule;
+ private delegate IntPtr GetAgentModuleDelegate(IntPtr uiModule);
+ private GetAgentModuleDelegate getAgentModule;
+
public bool GameUiHidden { get; private set; }
///
@@ -117,6 +120,7 @@ namespace Dalamud.Game.Internal.Gui {
Log.Verbose("HandleItemHover address {Address}", Address.HandleItemHover);
Log.Verbose("HandleItemOut address {Address}", Address.HandleItemOut);
Log.Verbose("GetUIObject address {Address}", Address.GetUIObject);
+ Log.Verbose("GetAgentModule address {Address}", Address.GetAgentModule);
Chat = new ChatGui(Address.ChatManager, scanner, dalamud);
PartyFinder = new PartyFinderGui(scanner, dalamud);
@@ -159,6 +163,7 @@ namespace Dalamud.Game.Internal.Gui {
this.getUIObjectByName = Marshal.GetDelegateForFunctionPointer(Address.GetUIObjectByName);
this.getUiModule = Marshal.GetDelegateForFunctionPointer(Address.GetUIModule);
+ this.getAgentModule = Marshal.GetDelegateForFunctionPointer(Address.GetAgentModule);
}
private IntPtr HandleSetGlobalBgmDetour(UInt16 bgmKey, byte a2, UInt32 a3, UInt32 a4, UInt32 a5, byte a6) {
@@ -454,6 +459,48 @@ namespace Dalamud.Game.Internal.Gui {
return new Addon.Addon(addonMem, addonStruct);
}
+ public IntPtr FindAgentInterface(string addonName)
+ {
+ var addon = this.dalamud.Framework.Gui.GetUiObjectByName(addonName, 1);
+ return this.FindAgentInterface(addon);
+ }
+
+ public IntPtr FindAgentInterface(IntPtr addon)
+ {
+ if (addon == IntPtr.Zero)
+ return IntPtr.Zero;
+
+ var uiModule = this.dalamud.Framework.Gui.GetUIModule();
+ if (uiModule == IntPtr.Zero)
+ {
+ return IntPtr.Zero;
+ }
+
+ var agentModule = this.getAgentModule(uiModule);
+ if (agentModule == IntPtr.Zero)
+ {
+ return IntPtr.Zero;
+ }
+
+ var id = Marshal.ReadInt16(addon, 0x1CE);
+ if (id == 0)
+ id = Marshal.ReadInt16(addon, 0x1CC);
+
+ if (id == 0)
+ return IntPtr.Zero;
+
+ for (var i = 0; i < 379; i++)
+ {
+ var agent = Marshal.ReadIntPtr(agentModule, 0x20 + (i * 8));
+ if (agent == IntPtr.Zero)
+ continue;
+ if (Marshal.ReadInt32(agent, 0x20) == id)
+ return agent;
+ }
+
+ return IntPtr.Zero;
+ }
+
public void SetBgm(ushort bgmKey) => this.setGlobalBgmHook.Original(bgmKey, 0, 0, 0, 0, 0);
public void Enable() {
diff --git a/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs b/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs
index 0592ca3f6..b38acc7fd 100644
--- a/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs
+++ b/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs
@@ -20,6 +20,7 @@ namespace Dalamud.Game.Internal.Gui {
public IntPtr GetBaseUIObject { get; private set; }
public IntPtr GetUIObjectByName { get; private set; }
public IntPtr GetUIModule { get; private set; }
+ public IntPtr GetAgentModule { get; private set; }
public GameGuiAddressResolver(IntPtr baseAddress) {
BaseAddress = baseAddress;
@@ -47,6 +48,9 @@ namespace Dalamud.Game.Internal.Gui {
GetBaseUIObject = sig.ScanText("E8 ?? ?? ?? ?? 41 B8 01 00 00 00 48 8D 15 ?? ?? ?? ?? 48 8B 48 20 E8 ?? ?? ?? ?? 48 8B CF");
GetUIObjectByName = sig.ScanText("E8 ?? ?? ?? ?? 48 8B CF 48 89 87 ?? ?? 00 00 E8 ?? ?? ?? ?? 41 B8 01 00 00 00");
GetUIModule = sig.ScanText("E8 ?? ?? ?? ?? 48 8B C8 48 85 C0 75 2D");
+
+ var uiModuleVtableSig = sig.GetStaticAddressFromSig("48 8D 05 ?? ?? ?? ?? 4C 89 61 28");
+ this.GetAgentModule = Marshal.ReadIntPtr(uiModuleVtableSig, 34 * IntPtr.Size);
}
}
}
diff --git a/Dalamud/Game/SigScanner.cs b/Dalamud/Game/SigScanner.cs
index 1242935ef..8449098a3 100644
--- a/Dalamud/Game/SigScanner.cs
+++ b/Dalamud/Game/SigScanner.cs
@@ -83,6 +83,21 @@ namespace Dalamud.Game
///
public int DataSectionSize { get; private set; }
+ ///
+ /// Gets the base address of the .rdata section search area.
+ ///
+ public IntPtr RDataSectionBase => new IntPtr(this.SearchBase.ToInt64() + this.RDataSectionOffset);
+
+ ///
+ /// Gets the offset of the .rdata section from the base of the module.
+ ///
+ public long RDataSectionOffset { get; private set; }
+
+ ///
+ /// Gets the size of the .rdata section.
+ ///
+ public int RDataSectionSize { get; private set; }
+
///
/// Gets the ProcessModule on which the search is performed.
///
@@ -126,7 +141,8 @@ namespace Dalamud.Game
instrAddr = IntPtr.Add(instrAddr, 1);
num = Marshal.ReadInt32(instrAddr) + (long)instrAddr + 4 - bAddr;
}
- while (!(num >= this.DataSectionOffset && num <= this.DataSectionOffset + this.DataSectionSize));
+ while (!(num >= this.DataSectionOffset && num <= this.DataSectionOffset + this.DataSectionSize)
+ && !(num >= this.RDataSectionOffset && num <= this.RDataSectionOffset + this.RDataSectionSize));
return IntPtr.Add(instrAddr, Marshal.ReadInt32(instrAddr) + 4);
}
@@ -322,6 +338,10 @@ namespace Dalamud.Game
this.DataSectionOffset = Marshal.ReadInt32(sectionCursor, 12);
this.DataSectionSize = Marshal.ReadInt32(sectionCursor, 8);
break;
+ case 0x61746164722E: // .rdata
+ this.RDataSectionOffset = Marshal.ReadInt32(sectionCursor, 12);
+ this.RDataSectionSize = Marshal.ReadInt32(sectionCursor, 8);
+ break;
}
sectionCursor += 40;
diff --git a/Dalamud/Interface/DalamudDataWindow.cs b/Dalamud/Interface/DalamudDataWindow.cs
index 142018601..e6d38f65f 100644
--- a/Dalamud/Interface/DalamudDataWindow.cs
+++ b/Dalamud/Interface/DalamudDataWindow.cs
@@ -510,7 +510,7 @@ namespace Dalamud.Interface
}
if (ImGui.Button("Find Agent"))
- this.findAgentInterfacePtr = this.FindAgentInterface(this.inputAddonName);
+ this.findAgentInterfacePtr = this.dalamud.Framework.Gui.FindAgentInterface(this.inputAddonName);
if (this.resultAddon != null)
{
@@ -583,30 +583,6 @@ namespace Dalamud.Interface
}
}
- private unsafe IntPtr FindAgentInterface(string addonName)
- {
- var addon = this.dalamud.Framework.Gui.GetUiObjectByName(addonName, 1);
- if (addon == IntPtr.Zero) return IntPtr.Zero;
- SafeMemory.Read(addon + 0x1CE, out var id);
-
- if (id == 0)
- _ = SafeMemory.Read(addon + 0x1CC, out id);
-
- var framework = this.dalamud.Framework.Address.BaseAddress;
- var uiModule = *(IntPtr*)(framework + 0x29F8);
- var agentModule = uiModule + 0xC3E78;
- for (var i = 0; i < 379; i++)
- {
- var agent = *(IntPtr*)(agentModule + 0x20 + (i * 8));
- if (agent == IntPtr.Zero)
- continue;
- if (*(short*)(agent + 0x20) == id)
- return agent;
- }
-
- return IntPtr.Zero;
- }
-
private void PrintActor(Actor actor, string tag)
{
var actorString =