feat: warn about known problematic injected dlls

This commit is contained in:
dantmnf
2025-06-27 00:31:34 +08:00
committed by dantmnf
parent 1b92e51241
commit 1602f2aa18
6 changed files with 132 additions and 0 deletions

View File

@@ -51,6 +51,10 @@ namespace MaaWpfGui.Configuration
public string WindowTitlePrefix { get; set; } = string.Empty;
public string FoundBadModules { get; set; } = string.Empty;
public string SuppressedBadModules { get; set; } = string.Empty;
// ReSharper disable once UnusedMember.Global
public void OnPropertyChanged(string propertyName, object before, object after)
{

View File

@@ -37,6 +37,7 @@ using MaaWpfGui.Services.Managers;
using MaaWpfGui.Services.RemoteControl;
using MaaWpfGui.Services.Web;
using MaaWpfGui.States;
using MaaWpfGui.Utilities;
using MaaWpfGui.ViewModels.UI;
using MaaWpfGui.ViewModels.UserControl.Settings;
using MaaWpfGui.Views.UI;
@@ -237,6 +238,11 @@ namespace MaaWpfGui.Main
}
}
protected override void OnLaunch()
{
BadModules.CheckAndWarnBadInjectedModules();
}
private static bool HandleMultipleInstances()
{
// 设置互斥量的名称

View File

@@ -24,3 +24,7 @@ TD_ERROR_ICON
TD_WARNING_ICON
TD_INFORMATION_ICON
SHGetStockIconInfo
//BadInjectedDllChecker
GetModuleHandle
GetModuleFileName

View File

@@ -1367,4 +1367,11 @@ If you want to run multiple MAA at the same time, please copy the whole MAA and
<system:String x:Key="Achievement.RoguelikeN15.Description">Immortal MAA truly immortal.</system:String>
<system:String x:Key="Achievement.RoguelikeN15.Conditions">Clear any I.S. at N15 difficulty or above with MAA</system:String>
<!-- !Achievement -->
<!-- BadModules -->
<system:String x:Key="BadModules.Warning.Heading">Compatibility Warning</system:String>
<system:String x:Key="BadModules.Warning.Prolog">The following DLL(s) injected into MAA may crash MAA or corrupt MAA user interface:</system:String>
<system:String x:Key="BadModules.Warning.Epilog">If you encounter such issues with MAA, please try adding MAA to the exclusion list of the relevant software, or uninstall the related software and check if the problem persists.</system:String>
<system:String x:Key="BadModules.Warning.DoNotShowAgain">Do not show this warning again</system:String>
<!-- !BadModules -->
</ResourceDictionary>

View File

@@ -1371,4 +1371,11 @@ C:\\leidian\\LDPlayer9。\n
<system:String x:Key="Achievement.RoguelikeN15.Description">仙术牛牛真仙术。</system:String>
<system:String x:Key="Achievement.RoguelikeN15.Conditions">使用牛牛通关任意肉鸽 N15 以上难度</system:String>
<!-- !Achievement -->
<!-- BadModules -->
<system:String x:Key="BadModules.Warning.Heading">悲报</system:String>
<system:String x:Key="BadModules.Warning.Prolog">以下注入到 MAA 的 DLL 可能会导致 MAA 闪退或界面渲染异常:</system:String>
<system:String x:Key="BadModules.Warning.Epilog">如果您注意到 MAA 存在相关问题,请尝试将 MAA 加入相关软件的排除名单,或卸载相关软件后检查问题是否仍然存在。</system:String>
<system:String x:Key="BadModules.Warning.DoNotShowAgain">不再显示此警告</system:String>
<!-- !BadModules -->
</ResourceDictionary>

View File

@@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MaaWpfGui.Configuration;
using MaaWpfGui.Helper;
using Windows.Win32;
namespace MaaWpfGui.Utilities
{
internal class BadModules
{
private static string[] names = ["NahimicOSD.dll", "AudioDevProps2.dll"];
public static unsafe string[] GetBadInjectedModules()
{
var result = new List<string>();
char[]? buffer = null;
foreach (var name in names)
{
var hmod = PInvoke.GetModuleHandle(name);
if (!hmod.IsInvalid)
{
buffer ??= new char[65536];
fixed (char* ptr = buffer)
{
if (PInvoke.GetModuleFileName(hmod, ptr, 65536) > 0)
{
result.Add(new string(ptr));
}
}
}
}
return result.ToArray();
}
private class WPFWin32Window : System.Windows.Forms.IWin32Window, System.Windows.Interop.IWin32Window
{
public IntPtr Handle => _helper.Handle;
private System.Windows.Interop.WindowInteropHelper _helper;
public WPFWin32Window(System.Windows.Window w)
{
_helper = new System.Windows.Interop.WindowInteropHelper(w);
}
}
public static void CheckAndWarnBadInjectedModules()
{
var allBadModules = GetBadInjectedModules();
var prevFound = ConfigFactory.Root.GUI.FoundBadModules.Split(";", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
var suppressed = ConfigFactory.Root.GUI.SuppressedBadModules.Split(";", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
var newFoundBadModules = allBadModules.Where(x => !prevFound.Contains(x, StringComparer.InvariantCultureIgnoreCase)).ToArray();
var notSuppressedBadModules = allBadModules.Where(x => !suppressed.Contains(x, StringComparer.InvariantCultureIgnoreCase)).ToArray();
ConfigFactory.Root.GUI.FoundBadModules = string.Join(";", [.. prevFound, .. newFoundBadModules]);
if (notSuppressedBadModules.Length > 0)
{
var sb = new StringBuilder();
sb.AppendLine(LocalizationHelper.GetString("BadModules.Warning.Prolog"));
sb.AppendLine();
foreach (var module in allBadModules)
{
sb.AppendLine(module);
}
sb.AppendLine();
sb.Append(LocalizationHelper.GetString("BadModules.Warning.Epilog"));
var page = new TaskDialogPage
{
Caption = "MAA",
Heading = LocalizationHelper.GetString("BadModules.Warning.Heading"),
Text = sb.ToString(),
Icon = TaskDialogIcon.Warning,
Buttons = { TaskDialogButton.OK },
SizeToContent = true,
};
if (newFoundBadModules.Length == 0)
{
// only show the "Do not show again" checkbox on the second time
page.Verification = new()
{
Text = LocalizationHelper.GetString("BadModules.Warning.DoNotShowAgain"),
Checked = false,
};
}
TaskDialog.ShowDialog(new WPFWin32Window(System.Windows.Application.Current.MainWindow), page);
if (page.Verification?.Checked ?? false)
{
ConfigFactory.Root.GUI.SuppressedBadModules = string.Join(";", allBadModules);
}
}
}
}
}