Files
Yae/src/Injector.cs
HolographicHat 4c2cb28313 add export
2022-08-21 12:06:50 +08:00

52 lines
2.2 KiB
C#

using System.ComponentModel;
using YaeAchievement.Win32;
using static YaeAchievement.Win32.Native;
namespace YaeAchievement;
public static class Injector {
public static unsafe bool CreateProcess(string path, out IntPtr hProc, out IntPtr hThread, out uint pid) {
var si = new StartupInfo();
SecurityAttributes* attr = null;
var dir = Path.GetDirectoryName(path)!;
var result = Native.CreateProcess(
path, null, ref *attr, ref *attr, false,
CreationFlags.CreateSuspended, IntPtr.Zero, dir, ref si, out var pi
);
pid = pi.dwProcessID;
hProc = pi.hProcess;
hThread = pi.hThread;
return result;
}
// todo: refactor
public static int LoadLibraryAndInject(IntPtr hProc, string libPath) {
var hKernel = GetModuleHandle("kernel32.dll");
if (hKernel == IntPtr.Zero) {
return new Win32Exception().PrintMsgAndReturnErrCode("GetModuleHandle fail");
}
var pLoadLibrary = GetProcAddress(hKernel, "LoadLibraryA");
if (pLoadLibrary == IntPtr.Zero) {
return new Win32Exception().PrintMsgAndReturnErrCode("GetProcAddress fail");
}
var pBase = VirtualAllocEx(hProc, IntPtr.Zero, libPath.Length + 1, AllocationType.Reserve | AllocationType.Commit, MemoryProtection.ReadWrite);
if (pBase == IntPtr.Zero) {
return new Win32Exception().PrintMsgAndReturnErrCode("VirtualAllocEx fail");
}
if (!WriteProcessMemory(hProc, pBase, libPath.ToCharArray(), libPath.Length, out _)) {
return new Win32Exception().PrintMsgAndReturnErrCode("WriteProcessMemory fail");
}
var hThread = CreateRemoteThread(hProc, IntPtr.Zero, 0, pLoadLibrary, pBase, 0, out _);
if (hThread == IntPtr.Zero) {
var e = new Win32Exception();
VirtualFreeEx(hProc, pBase, 0, AllocationType.Release);
return e.PrintMsgAndReturnErrCode("CreateRemoteThread fail");
}
if (WaitForSingleObject(hThread, 2000) == 0) {
VirtualFreeEx(hProc, pBase, 0, AllocationType.Release);
}
return !CloseHandle(hThread) ? new Win32Exception().PrintMsgAndReturnErrCode("CloseHandle fail") : 0;
}
}