From 15d340d0ed490cd13e7b4c48bfbb00b70d354363 Mon Sep 17 00:00:00 2001 From: goat Date: Fri, 21 Feb 2020 00:15:49 +0900 Subject: [PATCH] fix: network sig, some installer bugs --- Dalamud/Game/Internal/AntiDebug.cs | 39 +++++++++++ Dalamud/Game/Internal/Framework.cs | 6 ++ .../Network/GameNetworkAddressResolver.cs | 3 +- Dalamud/Plugin/PluginInstallerWindow.cs | 70 +++++++++++++------ Dalamud/Plugin/PluginManager.cs | 15 ++-- 5 files changed, 105 insertions(+), 28 deletions(-) create mode 100644 Dalamud/Game/Internal/AntiDebug.cs diff --git a/Dalamud/Game/Internal/AntiDebug.cs b/Dalamud/Game/Internal/AntiDebug.cs new file mode 100644 index 000000000..6ce25488b --- /dev/null +++ b/Dalamud/Game/Internal/AntiDebug.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using Dalamud.Hooking; +using EasyHook; +using Serilog; + +namespace Dalamud.Game.Internal +{ + class AntiDebug : IDisposable + { + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + private delegate bool IsDebuggerPresentDelegate(); + + private Hook debuggerPresentHook; + + public AntiDebug() { + this.debuggerPresentHook = new Hook(LocalHook.GetProcAddress("Kernel32", "IsDebuggerPresent"), + new IsDebuggerPresentDelegate(IsDebuggerPresentDetour)); + + Log.Verbose("IsDebuggerPresent address {IsDebuggerPresent}", this.debuggerPresentHook.Address); + } + + public void Enable() { + this.debuggerPresentHook.Enable(); + } + + public void Dispose() { + this.debuggerPresentHook.Disable(); + } + + private bool IsDebuggerPresentDetour() { + return false; + } + } +} diff --git a/Dalamud/Game/Internal/Framework.cs b/Dalamud/Game/Internal/Framework.cs index 1fd8cc62a..31ede43cc 100644 --- a/Dalamud/Game/Internal/Framework.cs +++ b/Dalamud/Game/Internal/Framework.cs @@ -42,6 +42,8 @@ namespace Dalamud.Game.Internal { //public ResourceManager Resource { get; private set; } public LibcFunction Libc { get; private set; } + + private AntiDebug antiDebug; #endregion @@ -65,6 +67,8 @@ namespace Dalamud.Game.Internal { Network = new GameNetwork(dalamud, scanner); //Resource = new ResourceManager(dalamud, scanner); + + this.antiDebug = new AntiDebug(); } private void HookVTable() { @@ -81,6 +85,7 @@ namespace Dalamud.Game.Internal { } public void Enable() { + this.antiDebug.Enable(); Gui.Enable(); Network.Enable(); //Resource.Enable(); @@ -89,6 +94,7 @@ namespace Dalamud.Game.Internal { } public void Dispose() { + this.antiDebug.Dispose(); Gui.Dispose(); Network.Dispose(); //Resource.Dispose(); diff --git a/Dalamud/Game/Internal/Network/GameNetworkAddressResolver.cs b/Dalamud/Game/Internal/Network/GameNetworkAddressResolver.cs index 02f76e865..09ad99ebb 100644 --- a/Dalamud/Game/Internal/Network/GameNetworkAddressResolver.cs +++ b/Dalamud/Game/Internal/Network/GameNetworkAddressResolver.cs @@ -6,7 +6,8 @@ namespace Dalamud.Game.Internal.Network { protected override void Setup64Bit(SigScanner sig) { //ProcessZonePacket = sig.ScanText("48 89 74 24 18 57 48 83 EC 50 8B F2 49 8B F8 41 0F B7 50 02 8B CE E8 ?? ?? 7A FF 0F B7 57 02 8D 42 89 3D 5F 02 00 00 0F 87 60 01 00 00 4C 8D 05"); - ProcessZonePacket = sig.ScanText("48 89 74 24 18 57 48 83 EC 50 8B F2 49 8B F8 41 0F B7 50 02 8B CE E8 ?? ?? 73 FF 0F B7 57 02 8D 42 ?? 3D ?? ?? 00 00 0F 87 60 01 00 00 4C 8D 05"); + //ProcessZonePacket = sig.ScanText("48 89 74 24 18 57 48 83 EC 50 8B F2 49 8B F8 41 0F B7 50 02 8B CE E8 ?? ?? 73 FF 0F B7 57 02 8D 42 ?? 3D ?? ?? 00 00 0F 87 60 01 00 00 4C 8D 05"); + ProcessZonePacket = sig.ScanText("48 89 74 24 ?? 57 48 83 EC 50 8B FA 49 8B F0"); } } } diff --git a/Dalamud/Plugin/PluginInstallerWindow.cs b/Dalamud/Plugin/PluginInstallerWindow.cs index 2f5d9af86..6626239f7 100644 --- a/Dalamud/Plugin/PluginInstallerWindow.cs +++ b/Dalamud/Plugin/PluginInstallerWindow.cs @@ -23,6 +23,7 @@ namespace Dalamud.Plugin private string pluginDirectory; private ReadOnlyCollection pluginMaster; private bool errorModalDrawing = true; + private bool errorModalOnNextFrame = false; private enum PluginInstallStatus { None, @@ -38,7 +39,11 @@ namespace Dalamud.Plugin public PluginInstallerWindow(PluginManager manager, string pluginDirectory) { this.manager = manager; this.pluginDirectory = pluginDirectory; - Task.Run(CachePluginMaster).ContinueWith(t => { this.masterDownloadFailed = t.IsFaulted; }); + Task.Run(CachePluginMaster).ContinueWith(t => { + this.masterDownloadFailed = this.masterDownloadFailed || t.IsFaulted; + this.errorModalDrawing = this.masterDownloadFailed; + this.errorModalOnNextFrame = this.masterDownloadFailed; + }); } private void CachePluginMaster() { @@ -55,28 +60,34 @@ namespace Dalamud.Plugin private void InstallPlugin(PluginDefinition definition) { try { - var path = Path.GetTempFileName(); + var outputDir = new DirectoryInfo(Path.Combine(this.pluginDirectory, definition.InternalName, definition.AssemblyVersion)); + var dllFile = new FileInfo(Path.Combine(outputDir.FullName, $"{definition.InternalName}.dll")); + var disabledFile = new FileInfo(Path.Combine(outputDir.FullName, ".disabled")); - Log.Information("Downloading plugin to {0}", path); - - using var client = new WebClient(); + if (dllFile.Exists) { + if (disabledFile.Exists) + disabledFile.Delete(); - client.DownloadFile(PluginRepoBaseUrl + $"/plugins/{definition.InternalName}/latest.zip", path); - var outputDir = Path.Combine(this.pluginDirectory, definition.InternalName); - - if (File.Exists(Path.Combine(outputDir, ".disabled"))) { - Log.Information("Plugin was disabled, re-enabling."); - File.Delete(Path.Combine(outputDir, ".disabled")); + this.manager.LoadPluginFromAssembly(dllFile); + this.installStatus = PluginInstallStatus.Success; + return; } + if (outputDir.Exists) + outputDir.Delete(true); + outputDir.Create(); + + var path = Path.GetTempFileName(); + Log.Information("Downloading plugin to {0}", path); + using var client = new WebClient(); + client.DownloadFile(PluginRepoBaseUrl + $"/plugins/{definition.InternalName}/latest.zip", path); + Log.Information("Extracting to {0}", outputDir); - Directory.CreateDirectory(outputDir); - - ZipFile.ExtractToDirectory(path, outputDir); + ZipFile.ExtractToDirectory(path, outputDir.FullName); this.installStatus = PluginInstallStatus.Success; - this.manager.LoadPluginFromAssembly(new FileInfo(Path.Combine(outputDir, $"{definition.InternalName}.dll"))); + this.manager.LoadPluginFromAssembly(dllFile); } catch (Exception e) { Log.Error(e, "Plugin download failed hard."); this.installStatus = PluginInstallStatus.Fail; @@ -129,7 +140,11 @@ namespace Dalamud.Plugin { this.installStatus = PluginInstallStatus.InProgress; - Task.Run(() => InstallPlugin(pluginDefinition)).ContinueWith(t => { this.installStatus = t.IsFaulted ? PluginInstallStatus.Fail : this.installStatus; }); + Task.Run(() => InstallPlugin(pluginDefinition)).ContinueWith(t => { + this.installStatus = t.IsFaulted ? PluginInstallStatus.Fail : this.installStatus; + this.errorModalDrawing = this.installStatus == PluginInstallStatus.Fail; + this.errorModalOnNextFrame = this.installStatus == PluginInstallStatus.Fail; + }); } } @@ -184,21 +199,30 @@ namespace Dalamud.Plugin if (ImGui.Button("test modal")) { this.installStatus = PluginInstallStatus.Fail; + this.errorModalDrawing = true; + this.errorModalOnNextFrame = true; } ImGui.Spacing(); - if (this.installStatus == PluginInstallStatus.Fail || this.masterDownloadFailed) { - if (ImGui.BeginPopupModal("Installer failed", ref this.errorModalDrawing, ImGuiWindowFlags.AlwaysAutoResize)) - { - ImGui.TextWrapped("The installer ran into an issue. Please restart the game and report this error on our discord."); + if (ImGui.BeginPopupModal("Installer failed", ref this.errorModalDrawing, ImGuiWindowFlags.AlwaysAutoResize)) + { + ImGui.Text("The plugin installer ran into an issue."); + ImGui.Text("Please restart the game and report this error on our discord."); - if (ImGui.Button("OK", new Vector2(120, 40))) { ImGui.CloseCurrentPopup(); } + ImGui.Spacing(); - ImGui.EndPopup(); - } + if (ImGui.Button("OK", new Vector2(120, 40))) { ImGui.CloseCurrentPopup(); } + + ImGui.EndPopup(); } + if (this.errorModalOnNextFrame) { + ImGui.OpenPopup("Installer failed"); + this.errorModalOnNextFrame = false; + } + + ImGui.End(); return windowOpen; diff --git a/Dalamud/Plugin/PluginManager.cs b/Dalamud/Plugin/PluginManager.cs index 2576475da..70db2506a 100644 --- a/Dalamud/Plugin/PluginManager.cs +++ b/Dalamud/Plugin/PluginManager.cs @@ -42,8 +42,8 @@ namespace Dalamud.Plugin var thisPlugin = this.Plugins.Where(x => x.Definition != null) .First(x => x.Definition.InternalName == definition.InternalName); - var outputDir = Path.Combine(this.pluginDirectory, definition.InternalName); - File.Create(Path.Combine(outputDir, ".disabled")); + var outputDir = new DirectoryInfo(Path.Combine(this.pluginDirectory, definition.InternalName, definition.AssemblyVersion)); + File.Create(Path.Combine(outputDir.FullName, ".disabled")); thisPlugin.Plugin.Dispose(); @@ -68,9 +68,12 @@ namespace Dalamud.Plugin if (type.GetInterface(interfaceType.FullName) != null) { - var plugin = (IDalamudPlugin)Activator.CreateInstance(type); + var disabledFile = new FileInfo(Path.Combine(dllFile.Directory.FullName, ".disabled")); - var dalamudInterface = new DalamudPluginInterface(this.dalamud, type.Assembly.GetName().Name); + if (disabledFile.Exists) { + Log.Information("Plugin {0} is disabled.", dllFile.FullName); + return; + } var defJsonFile = new FileInfo(Path.Combine(dllFile.Directory.FullName, $"{Path.GetFileNameWithoutExtension(dllFile.Name)}.json")); @@ -86,8 +89,12 @@ namespace Dalamud.Plugin else { Log.Information("Plugin DLL {0} has no definition.", dllFile.FullName); + return; } + var plugin = (IDalamudPlugin)Activator.CreateInstance(type); + + var dalamudInterface = new DalamudPluginInterface(this.dalamud, type.Assembly.GetName().Name); plugin.Initialize(dalamudInterface); Log.Information("Loaded plugin: {0}", plugin.Name); this.Plugins.Add((plugin, pluginDef));