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 =