fixup native call

This commit is contained in:
DismissedLight
2023-02-26 14:41:24 +08:00
parent 50007c2c53
commit 5f8ff734f2
3 changed files with 86 additions and 75 deletions

View File

@@ -3,6 +3,7 @@ using System.ComponentModel;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Versioning; using System.Runtime.Versioning;
using Windows.Win32; using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.System.Memory; using Windows.Win32.System.Memory;
using Windows.Win32.System.Threading; using Windows.Win32.System.Threading;
using YaeAchievement.Win32; using YaeAchievement.Win32;
@@ -10,7 +11,7 @@ using YaeAchievement.Win32;
namespace YaeAchievement; namespace YaeAchievement;
public static class Injector { public static class Injector {
public static unsafe bool CreateProcess(string path, out SafeHandle hProc, out SafeHandle hThread, out uint pid) { public static unsafe bool CreateProcess(string path, out HANDLE hProc, out HANDLE hThread, out uint pid) {
Span<char> cmdLines = stackalloc char[1]; // "\0" Span<char> cmdLines = stackalloc char[1]; // "\0"
var si = new STARTUPINFOW() { cb = unchecked((uint)sizeof(STARTUPINFOW)) }; var si = new STARTUPINFOW() { cb = unchecked((uint)sizeof(STARTUPINFOW)) };
var dir = Path.GetDirectoryName(path)!; var dir = Path.GetDirectoryName(path)!;
@@ -19,20 +20,26 @@ public static class Injector {
PROCESS_CREATION_FLAGS.CREATE_SUSPENDED, default, dir, in si, out var pi PROCESS_CREATION_FLAGS.CREATE_SUSPENDED, default, dir, in si, out var pi
); );
pid = pi.dwProcessId; pid = pi.dwProcessId;
hProc = new SafeFileHandle(pi.hProcess, true); hProc = pi.hProcess;
hThread = new SafeFileHandle(pi.hThread, true); hThread = pi.hThread;
return result; return result;
} }
// todo: refactor // todo: refactor
public static unsafe int LoadLibraryAndInject(SafeHandle hProc, string libPath) public static unsafe int LoadLibraryAndInject(HANDLE hProc, ReadOnlySpan<byte> libPath)
{ {
var hKernel = Native.GetModuleHandle("kernel32.dll"); fixed (char* lpModelName = "kernel32.dll")
if (hKernel.IsInvalid) {
HINSTANCE hKernel = Native.GetModuleHandle(lpModelName);
if (hKernel.IsNull)
{ {
return new Win32Exception().PrintMsgAndReturnErrCode("GetModuleHandle fail"); return new Win32Exception().PrintMsgAndReturnErrCode("GetModuleHandle fail");
} }
var pLoadLibrary = Native.GetProcAddress(hKernel, "LoadLibraryA");
fixed(byte* lpProcName = "LoadLibraryA"u8)
{
var pLoadLibrary = Native.GetProcAddress(hKernel, (PCSTR)lpProcName);
if (pLoadLibrary.IsNull) if (pLoadLibrary.IsNull)
{ {
return new Win32Exception().PrintMsgAndReturnErrCode("GetProcAddress fail"); return new Win32Exception().PrintMsgAndReturnErrCode("GetProcAddress fail");
@@ -42,18 +49,18 @@ public static class Injector {
{ {
return new Win32Exception().PrintMsgAndReturnErrCode("VirtualAllocEx fail"); return new Win32Exception().PrintMsgAndReturnErrCode("VirtualAllocEx fail");
} }
fixed (void* lpBuffer = libPath.ToCharArray()) fixed (void* lpBuffer = libPath)
{ {
if (!Native.WriteProcessMemory(hProc, pBase, lpBuffer, unchecked((uint)libPath.Length), default)) if (!Native.WriteProcessMemory(hProc, pBase, lpBuffer, unchecked((uint)libPath.Length), default))
{ {
return new Win32Exception().PrintMsgAndReturnErrCode("WriteProcessMemory fail"); return new Win32Exception().PrintMsgAndReturnErrCode("WriteProcessMemory fail");
} }
} }
var lpStartAddress = pLoadLibrary.CreateDelegate<LPTHREAD_START_ROUTINE>();
using (var hThread = Native.CreateRemoteThread(hProc, default, 0, lpStartAddress, pBase, 0, default)) var lpStartAddress = pLoadLibrary.CreateDelegate<LPTHREAD_START_ROUTINE>();
{ var hThread = Native.CreateRemoteThread(hProc, default, 0, lpStartAddress, pBase, 0, default);
if (hThread.IsInvalid)
if (hThread.IsNull)
{ {
var e = new Win32Exception(); var e = new Win32Exception();
Native.VirtualFreeEx(hProc, pBase, 0, VIRTUAL_FREE_TYPE.MEM_RELEASE); Native.VirtualFreeEx(hProc, pBase, 0, VIRTUAL_FREE_TYPE.MEM_RELEASE);
@@ -63,9 +70,8 @@ public static class Injector {
{ {
Native.VirtualFreeEx(hProc, pBase, 0, VIRTUAL_FREE_TYPE.MEM_RELEASE); Native.VirtualFreeEx(hProc, pBase, 0, VIRTUAL_FREE_TYPE.MEM_RELEASE);
} }
//return !Native.CloseHandle(hThread) ? new Win32Exception().PrintMsgAndReturnErrCode("CloseHandle fail") : 0; return !Native.CloseHandle(hThread) ? new Win32Exception().PrintMsgAndReturnErrCode("CloseHandle fail") : 0;
return 0; }
} }
} }
} }

View File

@@ -2,5 +2,5 @@
"$schema": "https://aka.ms/CsWin32.schema.json", "$schema": "https://aka.ms/CsWin32.schema.json",
"className": "Native", "className": "Native",
"allowMarshaling": true, "allowMarshaling": true,
"public": false "public": true
} }

View File

@@ -5,7 +5,8 @@ using System.IO.Pipes;
using System.Net; using System.Net;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Net.Sockets; using System.Net.Sockets;
using System.Runtime.Versioning; using System.Runtime.InteropServices;
using System.Text;
using Windows.Win32; using Windows.Win32;
using Windows.Win32.Foundation; using Windows.Win32.Foundation;
using Windows.Win32.System.Console; using Windows.Win32.System.Console;
@@ -68,17 +69,20 @@ public static class Utils {
return value != null && bool.TryParse(value, out var result) && result; return value != null && bool.TryParse(value, out var result) && result;
} }
[SupportedOSPlatform("windows5.0")]
public static unsafe void CopyToClipboard(string text) { public static unsafe void CopyToClipboard(string text) {
if (Native.OpenClipboard(HWND.Null)) { if (Native.OpenClipboard(HWND.Null))
Native.EmptyClipboard();
Span<char> textSpan = text.ToCharArray();
fixed (char* lpBuffer = textSpan)
{ {
Native.SetClipboardData(/*CF_UNICODETEXT*/13, (HANDLE)(nint)lpBuffer); Native.EmptyClipboard();
HANDLE hGlobal = (HANDLE)Marshal.AllocHGlobal((text.Length + 1) * 2);
IntPtr hPtr = (IntPtr)Native.GlobalLock(hGlobal);
Marshal.Copy(text.ToCharArray(), 0, hPtr, text.Length);
Native.GlobalUnlock(hPtr);
Native.SetClipboardData(13, hGlobal);
Marshal.FreeHGlobal(hGlobal);
Native.CloseClipboard(); Native.CloseClipboard();
} }
} else { else
{
throw new Win32Exception(); throw new Win32Exception();
} }
} }
@@ -227,9 +231,7 @@ public static class Utils {
if (!Injector.CreateProcess(exePath, out var hProcess, out var hThread, out var pid)) { if (!Injector.CreateProcess(exePath, out var hProcess, out var hThread, out var pid)) {
Environment.Exit(new Win32Exception().PrintMsgAndReturnErrCode("ICreateProcess fail")); Environment.Exit(new Win32Exception().PrintMsgAndReturnErrCode("ICreateProcess fail"));
} }
using (hProcess) if (Injector.LoadLibraryAndInject(hProcess,Encoding.UTF8.GetBytes(GlobalVars.LibFilePath)) != 0)
{
if (Injector.LoadLibraryAndInject(hProcess, GlobalVars.LibFilePath) != 0)
{ {
if (!Native.TerminateProcess(hProcess, 0)) if (!Native.TerminateProcess(hProcess, 0))
{ {
@@ -256,6 +258,9 @@ public static class Utils {
} }
Environment.Exit(e.PrintMsgAndReturnErrCode("ResumeThread fail")); Environment.Exit(e.PrintMsgAndReturnErrCode("ResumeThread fail"));
} }
if (!Native.CloseHandle(hProcess))
{
Environment.Exit(new Win32Exception().PrintMsgAndReturnErrCode("CloseHandle fail"));
} }
var ts = new ThreadStart(() => { var ts = new ThreadStart(() => {