From c15e948659c6bd0034b2b074cfedd41fad0d7052 Mon Sep 17 00:00:00 2001 From: Lightczx <1686188646@qq.com> Date: Thu, 11 May 2023 18:17:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=B1=B3=E5=A5=87=E5=A6=99?= =?UTF-8?q?=E5=A6=99=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Snap.Hutao/Snap.Hutao/NativeMethods.txt | 7 ++ .../{MultiChannel.cs => ChannelOptions.cs} | 0 .../Snap.Hutao/Service/Game/ProcessInterop.cs | 69 +++++++++++++++++++ .../Dialog/CultivatePromotionDeltaDialog.xaml | 21 +++--- 4 files changed, 88 insertions(+), 9 deletions(-) rename src/Snap.Hutao/Snap.Hutao/Service/Game/{MultiChannel.cs => ChannelOptions.cs} (100%) diff --git a/src/Snap.Hutao/Snap.Hutao/NativeMethods.txt b/src/Snap.Hutao/Snap.Hutao/NativeMethods.txt index 29666b74..2e9fc3cb 100644 --- a/src/Snap.Hutao/Snap.Hutao/NativeMethods.txt +++ b/src/Snap.Hutao/Snap.Hutao/NativeMethods.txt @@ -8,6 +8,7 @@ WM_NULL // Type & Enum definition CWMO_FLAGS MINMAXINFO +LPTHREAD_START_ROUTINE // COMCTL32 DefSubclassProc @@ -23,11 +24,17 @@ GetDeviceCaps // KERNEL32 CreateEvent +CreateRemoteThread CreateToolhelp32Snapshot +GetModuleHandle +GetProcAddress Module32First Module32Next ReadProcessMemory SetEvent +VirtualAllocEx +VirtualFreeEx +WaitForSingleObject WriteProcessMemory // OLE32 diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/MultiChannel.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/ChannelOptions.cs similarity index 100% rename from src/Snap.Hutao/Snap.Hutao/Service/Game/MultiChannel.cs rename to src/Snap.Hutao/Snap.Hutao/Service/Game/ChannelOptions.cs diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/ProcessInterop.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/ProcessInterop.cs index e59a3df9..e5c3838d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Game/ProcessInterop.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/ProcessInterop.cs @@ -5,6 +5,11 @@ using Snap.Hutao.Core; using Snap.Hutao.Service.Game.Unlocker; using System.Diagnostics; using System.IO; +using System.Runtime.InteropServices; +using Windows.Win32.Foundation; +using Windows.Win32.System.Memory; +using Windows.Win32.System.Threading; +using static Windows.Win32.PInvoke; namespace Snap.Hutao.Service.Game; @@ -83,4 +88,68 @@ internal static class ProcessInterop return false; } + + /// + /// 加载并注入指定路径的库 + /// + /// 进程句柄 + /// 库的路径,不包含'\0' + [SuppressMessage("", "SH002")] + public static unsafe void LoadLibraryAndInject(HANDLE hProcess, ReadOnlySpan libraryPathu8) + { + HINSTANCE hKernelDll = GetModuleHandle("kernel32.dll"); + Marshal.ThrowExceptionForHR(Marshal.GetLastPInvokeError()); + + FARPROC pLoadLibraryA = GetProcAddress(hKernelDll, libraryPathu8); + Marshal.ThrowExceptionForHR(Marshal.GetLastPInvokeError()); + + void* pNativeLibraryPath = default; + try + { + VIRTUAL_ALLOCATION_TYPE allocType = VIRTUAL_ALLOCATION_TYPE.MEM_RESERVE | VIRTUAL_ALLOCATION_TYPE.MEM_COMMIT; + pNativeLibraryPath = VirtualAllocEx(hProcess, default, unchecked((uint)libraryPathu8.Length + 1), allocType, PAGE_PROTECTION_FLAGS.PAGE_READWRITE); + Marshal.ThrowExceptionForHR(Marshal.GetLastPInvokeError()); + + WriteProcessMemory(hProcess, pNativeLibraryPath, libraryPathu8); + Marshal.ThrowExceptionForHR(Marshal.GetLastPInvokeError()); + + LPTHREAD_START_ROUTINE lpThreadLoadLibraryA = pLoadLibraryA.CreateDelegate(); + HANDLE hLoadLibraryAThread = default; + try + { + hLoadLibraryAThread = CreateRemoteThread(hProcess, default, 0, lpThreadLoadLibraryA, pNativeLibraryPath, 0); + Marshal.ThrowExceptionForHR(Marshal.GetLastPInvokeError()); + + // What are we waiting for? + WaitForSingleObject(hLoadLibraryAThread, 2000); + Marshal.ThrowExceptionForHR(Marshal.GetLastPInvokeError()); + } + finally + { + CloseHandle(hLoadLibraryAThread); + } + } + finally + { + VirtualFreeEx(hProcess, pNativeLibraryPath, 0, VIRTUAL_FREE_TYPE.MEM_RELEASE); + } + } + + [SuppressMessage("", "SH002")] + private static unsafe FARPROC GetProcAddress(HINSTANCE hModule, ReadOnlySpan lpProcName) + { + fixed (byte* lpProcNameLocal = lpProcName) + { + return Windows.Win32.PInvoke.GetProcAddress(hModule, new PCSTR(lpProcNameLocal)); + } + } + + [SuppressMessage("", "SH002")] + private static unsafe BOOL WriteProcessMemory(HANDLE hProcess, void* lpBaseAddress, ReadOnlySpan buffer) + { + fixed (void* lpBuffer = buffer) + { + return Windows.Win32.PInvoke.WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, unchecked((uint)buffer.Length)); + } + } } diff --git a/src/Snap.Hutao/Snap.Hutao/View/Dialog/CultivatePromotionDeltaDialog.xaml b/src/Snap.Hutao/Snap.Hutao/View/Dialog/CultivatePromotionDeltaDialog.xaml index 9d940364..72524122 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Dialog/CultivatePromotionDeltaDialog.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Dialog/CultivatePromotionDeltaDialog.xaml @@ -15,7 +15,10 @@ PrimaryButtonText="{shcm:ResourceString Name=ContentDialogConfirmPrimaryButtonText}" Style="{StaticResource DefaultContentDialogStyle}" mc:Ignorable="d"> - + + 180 + 1200 + @@ -48,11 +51,11 @@ TextTrimming="CharacterEllipsis"/> @@ -95,11 +98,11 @@ TextTrimming="CharacterEllipsis"/>