mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
Fetch win32 error codes on remote LoadLibrary/GetProcAddress calls (#816)
* Fetch win32 error codes on remote LoadLibrary/GetProcAddress calls * Fix out of index exc
This commit is contained in:
parent
4d7b3bca9c
commit
eb2197132e
2 changed files with 26 additions and 30 deletions
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
|
@ -83,23 +84,15 @@ namespace Dalamud.Injector
|
|||
if (lpParameter == IntPtr.Zero)
|
||||
throw new Exception("Unable to allocate LoadLibraryW parameter");
|
||||
|
||||
Log.Verbose($"CreateRemoteThread: call 0x{this.loadLibraryShellPtr.ToInt64():X} with 0x{lpParameter.ToInt64():X}");
|
||||
this.CallRemoteFunction(this.loadLibraryShellPtr, lpParameter, out var err);
|
||||
|
||||
var threadHandle = CreateRemoteThread(
|
||||
this.targetProcess.Handle,
|
||||
IntPtr.Zero,
|
||||
UIntPtr.Zero,
|
||||
this.loadLibraryShellPtr,
|
||||
lpParameter,
|
||||
CreateThreadFlags.RunImmediately,
|
||||
out _);
|
||||
|
||||
_ = WaitForSingleObject(threadHandle, uint.MaxValue);
|
||||
if (err != 0)
|
||||
throw new Exception($"LoadLibraryW(\"{modulePath}\") failure: {new Win32Exception((int)err).Message} ({err})");
|
||||
|
||||
address = this.extMemory.Read<IntPtr>(this.loadLibraryRetPtr);
|
||||
|
||||
if (address == IntPtr.Zero)
|
||||
throw new Exception($"Error calling LoadLibraryW with {modulePath}");
|
||||
throw new Exception($"LoadLibraryW(\"{modulePath}\") failure: Error code unavailable");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -113,25 +106,16 @@ namespace Dalamud.Injector
|
|||
var functionNamePtr = this.WriteNullTerminatedASCIIString(functionName);
|
||||
var getProcAddressParams = new GetProcAddressParams(module, functionNamePtr);
|
||||
var lpParameter = this.circularBuffer.Add(ref getProcAddressParams);
|
||||
|
||||
if (lpParameter == IntPtr.Zero)
|
||||
throw new Exception("Unable to allocate GetProcAddress parameter ptr");
|
||||
|
||||
var threadHandle = CreateRemoteThread(
|
||||
this.targetProcess.Handle,
|
||||
IntPtr.Zero,
|
||||
UIntPtr.Zero,
|
||||
this.getProcAddressShellPtr,
|
||||
lpParameter,
|
||||
CreateThreadFlags.RunImmediately,
|
||||
out _);
|
||||
|
||||
_ = WaitForSingleObject(threadHandle, uint.MaxValue);
|
||||
this.CallRemoteFunction(this.getProcAddressShellPtr, lpParameter, out var err);
|
||||
if (err != 0)
|
||||
throw new Exception($"GetProcAddress(0x{module:X}, \"{functionName}\") failure: {new Win32Exception((int)err).Message} ({err})");
|
||||
|
||||
this.extMemory.Read(this.getProcAddressRetPtr, out address);
|
||||
|
||||
if (address == IntPtr.Zero)
|
||||
throw new Exception($"Error calling GetProcAddress with {functionName}");
|
||||
throw new Exception($"GetProcAddress(0x{module:X}, \"{functionName}\") failure: Error code unavailable");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -152,6 +136,9 @@ namespace Dalamud.Injector
|
|||
CreateThreadFlags.RunImmediately,
|
||||
out _);
|
||||
|
||||
if (threadHandle == IntPtr.Zero)
|
||||
throw new Exception($"CreateRemoteThread failure: {Marshal.GetLastWin32Error()}");
|
||||
|
||||
_ = WaitForSingleObject(threadHandle, uint.MaxValue);
|
||||
|
||||
GetExitCodeThread(threadHandle, out exitCode);
|
||||
|
|
@ -161,8 +148,10 @@ namespace Dalamud.Injector
|
|||
|
||||
private void SetupLoadLibrary(ProcessModule kernel32Module, ExportFunction[] kernel32Exports)
|
||||
{
|
||||
var offset = this.GetExportedFunctionOffset(kernel32Exports, "LoadLibraryW");
|
||||
var functionAddr = kernel32Module.BaseAddress + (int)offset;
|
||||
var getLastErrorAddr = kernel32Module.BaseAddress + (int)this.GetExportedFunctionOffset(kernel32Exports, "GetLastError");
|
||||
Log.Verbose($"GetLastError: 0x{getLastErrorAddr.ToInt64():X}");
|
||||
|
||||
var functionAddr = kernel32Module.BaseAddress + (int)this.GetExportedFunctionOffset(kernel32Exports, "LoadLibraryW");
|
||||
Log.Verbose($"LoadLibraryW: 0x{functionAddr.ToInt64():X}");
|
||||
|
||||
var functionPtr = this.memoryBuffer.Add(ref functionAddr);
|
||||
|
|
@ -187,7 +176,9 @@ namespace Dalamud.Injector
|
|||
asm.call(__qword_ptr[__qword_ptr[func]]); // call qword [qword func] // CreateRemoteThread lpParameter with string already in ECX.
|
||||
asm.mov(__qword_ptr[__qword_ptr[retVal]], rax); // mov qword [qword retVal], rax //
|
||||
asm.add(rsp, 40); // add rsp, 40 // Re-align stack to 16 byte boundary + shadow space.
|
||||
asm.ret(); // ret // Restore stack ptr. (Callee cleanup)
|
||||
asm.mov(rax, (ulong)getLastErrorAddr); // mov rax, pfnGetLastError // Change return address to GetLastError.
|
||||
asm.push(rax); // push rax //
|
||||
asm.ret(); // ret // Jump to GetLastError.
|
||||
|
||||
var bytes = this.Assemble(asm);
|
||||
this.loadLibraryShellPtr = this.memoryBuffer.Add(bytes);
|
||||
|
|
@ -212,6 +203,9 @@ namespace Dalamud.Injector
|
|||
|
||||
private void SetupGetProcAddress(ProcessModule kernel32Module, ExportFunction[] kernel32Exports)
|
||||
{
|
||||
var getLastErrorAddr = kernel32Module.BaseAddress + (int)this.GetExportedFunctionOffset(kernel32Exports, "GetLastError");
|
||||
Log.Verbose($"GetLastError: 0x{getLastErrorAddr.ToInt64():X}");
|
||||
|
||||
var offset = this.GetExportedFunctionOffset(kernel32Exports, "GetProcAddress");
|
||||
var functionAddr = kernel32Module.BaseAddress + (int)offset;
|
||||
Log.Verbose($"GetProcAddress: 0x{functionAddr.ToInt64():X}");
|
||||
|
|
@ -240,7 +234,9 @@ namespace Dalamud.Injector
|
|||
asm.call(__qword_ptr[__qword_ptr[func]]); // call qword [qword func] //
|
||||
asm.mov(__qword_ptr[__qword_ptr[retVal]], rax); // mov qword [qword retVal] //
|
||||
asm.add(rsp, 40); // add rsp, 40 // Re-align stack to 16 byte boundary + shadow space.
|
||||
asm.ret(); // ret // Restore stack ptr. (Callee cleanup)
|
||||
asm.mov(rax, (ulong)getLastErrorAddr); // mov rax, pfnGetLastError // Change return address to GetLastError.
|
||||
asm.push(rax); // push rax //
|
||||
asm.ret(); // ret // Jump to GetLastError.
|
||||
|
||||
var bytes = this.Assemble(asm);
|
||||
this.getProcAddressShellPtr = this.memoryBuffer.Add(bytes);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue