fix: injector race condition

This commit is contained in:
goat 2020-06-08 02:57:04 +02:00
parent a4c3e60105
commit 458d9a5185
2 changed files with 27 additions and 21 deletions

View file

@ -12,7 +12,6 @@ namespace Dalamud.Injector
{ {
static class NativeFunctions static class NativeFunctions
{ {
// OpenProcess signture https://www.pinvoke.net/default.aspx/kernel32.openprocess
[Flags] [Flags]
public enum ProcessAccessFlags : uint public enum ProcessAccessFlags : uint
{ {
@ -41,7 +40,6 @@ namespace Dalamud.Injector
return OpenProcess(flags, false, proc.Id); return OpenProcess(flags, false, proc.Id);
} }
// VirtualAllocEx signture https://www.pinvoke.net/default.aspx/kernel32.virtualallocex
[Flags] [Flags]
public enum AllocationType public enum AllocationType
{ {
@ -56,7 +54,6 @@ namespace Dalamud.Injector
LargePages = 0x20000000 LargePages = 0x20000000
} }
// VirtualFreeEx signture https://www.pinvoke.net/default.aspx/kernel32.virtualfreeex
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress,
int dwSize, AllocationType dwFreeType); int dwSize, AllocationType dwFreeType);
@ -85,24 +82,20 @@ namespace Dalamud.Injector
AllocationType flAllocationType, AllocationType flAllocationType,
MemoryProtection flProtect); MemoryProtection flProtect);
// WriteProcessMemory signture https://www.pinvoke.net/default.aspx/kernel32/WriteProcessMemory.html
[DllImport("kernel32.dll", SetLastError = true)] [DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory( public static extern bool WriteProcessMemory(
IntPtr hProcess, IntPtr hProcess,
IntPtr lpBaseAddress, IntPtr lpBaseAddress,
[MarshalAs(UnmanagedType.AsAny)] object lpBuffer, byte[] lpBuffer,
int dwSize, int dwSize,
out IntPtr lpNumberOfBytesWritten); out IntPtr lpNumberOfBytesWritten);
// GetProcAddress signture https://www.pinvoke.net/default.aspx/kernel32.getprocaddress
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName); public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
// GetModuleHandle signture http://pinvoke.net/default.aspx/kernel32.GetModuleHandle
[DllImport("kernel32.dll", CharSet = CharSet.Auto)] [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetModuleHandle(string lpModuleName); public static extern IntPtr GetModuleHandle(string lpModuleName);
// CreateRemoteThread signture https://www.pinvoke.net/default.aspx/kernel32.createremotethread
[DllImport("kernel32.dll")] [DllImport("kernel32.dll")]
public static extern IntPtr CreateRemoteThread( public static extern IntPtr CreateRemoteThread(
IntPtr hProcess, IntPtr hProcess,
@ -113,7 +106,6 @@ namespace Dalamud.Injector
uint dwCreationFlags, uint dwCreationFlags,
IntPtr lpThreadId); IntPtr lpThreadId);
// CloseHandle signture https://www.pinvoke.net/default.aspx/kernel32.closehandle
[DllImport("kernel32.dll", SetLastError = true)] [DllImport("kernel32.dll", SetLastError = true)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity] [SuppressUnmanagedCodeSecurity]

View file

@ -73,6 +73,8 @@ namespace Dalamud.Injector {
// Inject to process // Inject to process
Inject(process, startInfo); Inject(process, startInfo);
Thread.Sleep(1000);
// Inject exception handler // Inject exception handler
NativeInject(process); NativeInject(process);
} }
@ -92,9 +94,15 @@ namespace Dalamud.Injector {
Console.WriteLine("Injected"); Console.WriteLine("Injected");
} }
private static void NativeInject(Process process) { private static void NativeInject(Process process)
{
var libPath = Path.GetFullPath("DalamudDebugStub.dll"); var libPath = Path.GetFullPath("DalamudDebugStub.dll");
var pathBytes = Encoding.Unicode.GetBytes(libPath);
var len = pathBytes.Length + 1;
Console.WriteLine($"Injecting {libPath}...");
var handle = NativeFunctions.OpenProcess( var handle = NativeFunctions.OpenProcess(
NativeFunctions.ProcessAccessFlags.All, NativeFunctions.ProcessAccessFlags.All,
false, false,
@ -106,25 +114,28 @@ namespace Dalamud.Injector {
var dllMem = NativeFunctions.VirtualAllocEx( var dllMem = NativeFunctions.VirtualAllocEx(
handle, handle,
IntPtr.Zero, IntPtr.Zero,
libPath.Length, len,
NativeFunctions.AllocationType.Reserve | NativeFunctions.AllocationType.Commit, NativeFunctions.AllocationType.Commit,
NativeFunctions.MemoryProtection.ExecuteReadWrite); NativeFunctions.MemoryProtection.ReadWrite);
if (dllMem == IntPtr.Zero) if (dllMem == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not alloc memory"); throw new Win32Exception(Marshal.GetLastWin32Error(), $"Could not alloc memory {Marshal.GetLastWin32Error():X}");
Console.WriteLine($"dll path at {dllMem.ToInt64():X}");
var pathBytes = Encoding.ASCII.GetBytes(libPath);
if (!NativeFunctions.WriteProcessMemory( if (!NativeFunctions.WriteProcessMemory(
handle, handle,
dllMem, dllMem,
pathBytes, pathBytes,
pathBytes.Length, len,
out var bytesread out var bytesWritten
)) ))
throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not write DLL"); throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not write DLL");
Console.WriteLine($"Wrote {bytesWritten}");
var kernel32 = NativeFunctions.GetModuleHandle("Kernel32.dll"); var kernel32 = NativeFunctions.GetModuleHandle("Kernel32.dll");
var loadLibA = NativeFunctions.GetProcAddress(kernel32, "LoadLibraryA"); var loadLibA = NativeFunctions.GetProcAddress(kernel32, "LoadLibraryW");
var remoteThread = NativeFunctions.CreateRemoteThread( var remoteThread = NativeFunctions.CreateRemoteThread(
handle, handle,
@ -137,13 +148,16 @@ namespace Dalamud.Injector {
); );
if (remoteThread == IntPtr.Zero) if (remoteThread == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not alloc memory"); throw new Win32Exception(Marshal.GetLastWin32Error(), $"Could not CreateRemoteThread");
NativeFunctions.VirtualFreeEx( /*
TODO kill myself
VirtualFreeEx(
handle, handle,
dllMem, dllMem,
0, 0,
NativeFunctions.AllocationType.Release); AllocationType.Release);
*/
NativeFunctions.CloseHandle(remoteThread); NativeFunctions.CloseHandle(remoteThread);
NativeFunctions.CloseHandle(handle); NativeFunctions.CloseHandle(handle);