diff --git a/Dalamud.Injector/Dalamud.Injector.csproj b/Dalamud.Injector/Dalamud.Injector.csproj index 43fbb33c1..3a4da8053 100644 --- a/Dalamud.Injector/Dalamud.Injector.csproj +++ b/Dalamud.Injector/Dalamud.Injector.csproj @@ -60,7 +60,7 @@ - + diff --git a/Dalamud.Injector/EntryPoint.cs b/Dalamud.Injector/EntryPoint.cs index 39aaebfc2..7bd4cdbe9 100644 --- a/Dalamud.Injector/EntryPoint.cs +++ b/Dalamud.Injector/EntryPoint.cs @@ -731,7 +731,7 @@ namespace Dalamud.Injector using var startInfoBuffer = new MemoryBufferHelper(process).CreatePrivateMemoryBuffer(startInfoBytes.Length + 0x8); var startInfoAddress = startInfoBuffer.Add(startInfoBytes); - if (startInfoAddress == IntPtr.Zero) + if (startInfoAddress == 0) throw new Exception("Unable to allocate start info JSON"); injector.GetFunctionAddress(bootModule, "Initialize", out var initAddress); diff --git a/Dalamud.Injector/Injector.cs b/Dalamud.Injector/Injector.cs index e5664388e..17ca5ccb5 100644 --- a/Dalamud.Injector/Injector.cs +++ b/Dalamud.Injector/Injector.cs @@ -32,11 +32,11 @@ namespace Dalamud.Injector private readonly CircularBuffer circularBuffer; private readonly PrivateMemoryBuffer memoryBuffer; - private IntPtr loadLibraryShellPtr; - private IntPtr loadLibraryRetPtr; + private nuint loadLibraryShellPtr; + private nuint loadLibraryRetPtr; - private IntPtr getProcAddressShellPtr; - private IntPtr getProcAddressRetPtr; + private nuint getProcAddressShellPtr; + private nuint getProcAddressRetPtr; /// /// Initializes a new instance of the class. @@ -85,11 +85,11 @@ namespace Dalamud.Injector { var lpParameter = this.WriteNullTerminatedUnicodeString(modulePath); - if (lpParameter == IntPtr.Zero) + if (lpParameter == 0) throw new Exception("Unable to allocate LoadLibraryW parameter"); this.CallRemoteFunction(this.loadLibraryShellPtr, lpParameter, out var err); - address = this.extMemory.Read(this.loadLibraryRetPtr); + this.extMemory.Read(this.loadLibraryRetPtr, out address); if (address == IntPtr.Zero) throw new Exception($"LoadLibraryW(\"{modulePath}\") failure: {new Win32Exception((int)err).Message} ({err})"); } @@ -100,17 +100,17 @@ namespace Dalamud.Injector /// Module address. /// Name of the exported method. /// Address to the function. - public void GetFunctionAddress(IntPtr module, string functionName, out IntPtr address) + public void GetFunctionAddress(IntPtr module, string functionName, out nuint address) { var functionNamePtr = this.WriteNullTerminatedASCIIString(functionName); var getProcAddressParams = new GetProcAddressParams(module, functionNamePtr); var lpParameter = this.circularBuffer.Add(ref getProcAddressParams); - if (lpParameter == IntPtr.Zero) + if (lpParameter == 0) throw new Exception("Unable to allocate GetProcAddress parameter ptr"); this.CallRemoteFunction(this.getProcAddressShellPtr, lpParameter, out var err); - address = this.extMemory.Read(this.getProcAddressRetPtr); - if (address == IntPtr.Zero) + this.extMemory.Read(this.getProcAddressRetPtr, out address); + if (address == 0) throw new Exception($"GetProcAddress(0x{module:X}, \"{functionName}\") failure: {new Win32Exception((int)err).Message} ({err})"); } @@ -120,7 +120,7 @@ namespace Dalamud.Injector /// Method address. /// Parameter address. /// Thread exit code. - public void CallRemoteFunction(IntPtr methodAddress, IntPtr parameterAddress, out uint exitCode) + public void CallRemoteFunction(nuint methodAddress, nuint parameterAddress, out uint exitCode) { // Create and initialize a thread at our address and parameter address. var threadHandle = CreateRemoteThread( @@ -151,26 +151,23 @@ namespace Dalamud.Injector Log.Verbose($"LoadLibraryW: 0x{functionAddr.ToInt64():X}"); var functionPtr = this.memoryBuffer.Add(ref functionAddr); - Log.Verbose($"LoadLibraryPtr: 0x{functionPtr.ToInt64():X}"); + Log.Verbose($"LoadLibraryPtr: 0x{functionPtr:X}"); - if (functionPtr == IntPtr.Zero) + if (functionPtr == 0) throw new Exception("Unable to allocate LoadLibraryW function ptr"); var dummy = IntPtr.Zero; this.loadLibraryRetPtr = this.memoryBuffer.Add(ref dummy); - Log.Verbose($"LoadLibraryRetPtr: 0x{this.loadLibraryRetPtr.ToInt64():X}"); + Log.Verbose($"LoadLibraryRetPtr: 0x{this.loadLibraryRetPtr:X}"); - if (this.loadLibraryRetPtr == IntPtr.Zero) + if (this.loadLibraryRetPtr == 0) throw new Exception("Unable to allocate LoadLibraryW return value"); - var func = functionPtr.ToInt64(); - var retVal = this.loadLibraryRetPtr.ToInt64(); - var asm = new Assembler(64); asm.sub(rsp, 40); // sub rsp, 40 // Re-align stack to 16 byte boundary + shadow space. - 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.call(__qword_ptr[__qword_ptr[functionPtr]]); // call qword [qword func] // CreateRemoteThread lpParameter with string already in ECX. + asm.mov(__qword_ptr[__qword_ptr[this.loadLibraryRetPtr]], rax); // mov qword [qword retVal], rax // asm.add(rsp, 40); // add rsp, 40 // Re-align stack to 16 byte boundary + shadow space. asm.mov(rax, (ulong)getLastErrorAddr); // mov rax, pfnGetLastError // Change return address to GetLastError. asm.push(rax); // push rax // @@ -178,18 +175,18 @@ namespace Dalamud.Injector var bytes = this.Assemble(asm); this.loadLibraryShellPtr = this.memoryBuffer.Add(bytes); - Log.Verbose($"LoadLibraryShellPtr: 0x{this.loadLibraryShellPtr.ToInt64():X}"); + Log.Verbose($"LoadLibraryShellPtr: 0x{this.loadLibraryShellPtr:X}"); - if (this.loadLibraryShellPtr == IntPtr.Zero) + if (this.loadLibraryShellPtr == 0) throw new Exception("Unable to allocate LoadLibraryW shellcode"); this.extMemory.ChangePermission(this.loadLibraryShellPtr, bytes.Length, Reloaded.Memory.Kernel32.Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE); #if DEBUG - var outFunctionPtr = this.extMemory.Read(functionPtr); + this.extMemory.Read(functionPtr, out var outFunctionPtr); Log.Verbose($"LoadLibraryPtr: {this.GetResultMarker(outFunctionPtr == functionAddr)}"); - var outRetPtr = this.extMemory.Read(this.loadLibraryRetPtr); + this.extMemory.Read(this.loadLibraryRetPtr, out var outRetPtr); Log.Verbose($"LoadLibraryRet: {this.GetResultMarker(dummy == outRetPtr)}"); this.extMemory.ReadRaw(this.loadLibraryShellPtr, out var outBytes, bytes.Length); @@ -207,28 +204,25 @@ namespace Dalamud.Injector Log.Verbose($"GetProcAddress: 0x{functionAddr.ToInt64():X}"); var functionPtr = this.memoryBuffer.Add(ref functionAddr); - Log.Verbose($"GetProcAddressPtr: 0x{functionPtr.ToInt64():X}"); + Log.Verbose($"GetProcAddressPtr: 0x{functionPtr:X}"); - if (functionPtr == IntPtr.Zero) + if (functionPtr == 0) throw new Exception("Unable to allocate GetProcAddress function ptr"); var dummy = IntPtr.Zero; this.getProcAddressRetPtr = this.memoryBuffer.Add(ref dummy); - Log.Verbose($"GetProcAddressRetPtr: 0x{this.loadLibraryRetPtr.ToInt64():X}"); + Log.Verbose($"GetProcAddressRetPtr: 0x{this.loadLibraryRetPtr:X}"); - if (this.getProcAddressRetPtr == IntPtr.Zero) + if (this.getProcAddressRetPtr == 0) throw new Exception("Unable to allocate GetProcAddress return value"); - var func = functionPtr.ToInt64(); - var retVal = this.getProcAddressRetPtr.ToInt64(); - var asm = new Assembler(64); asm.sub(rsp, 40); // sub rsp, 40 // Re-align stack to 16 byte boundary +32 shadow space asm.mov(rdx, __qword_ptr[__qword_ptr[rcx + 8]]); // mov rdx, qword [qword rcx + 8] // lpProcName asm.mov(rcx, __qword_ptr[__qword_ptr[rcx + 0]]); // mov rcx, qword [qword rcx + 0] // hModule - asm.call(__qword_ptr[__qword_ptr[func]]); // call qword [qword func] // - asm.mov(__qword_ptr[__qword_ptr[retVal]], rax); // mov qword [qword retVal] // + asm.call(__qword_ptr[__qword_ptr[functionPtr]]); // call qword [qword func] // + asm.mov(__qword_ptr[__qword_ptr[this.getProcAddressRetPtr]], rax); // mov qword [qword retVal] // asm.add(rsp, 40); // add rsp, 40 // Re-align stack to 16 byte boundary + shadow space. asm.mov(rax, (ulong)getLastErrorAddr); // mov rax, pfnGetLastError // Change return address to GetLastError. asm.push(rax); // push rax // @@ -236,18 +230,18 @@ namespace Dalamud.Injector var bytes = this.Assemble(asm); this.getProcAddressShellPtr = this.memoryBuffer.Add(bytes); - Log.Verbose($"GetProcAddressShellPtr: 0x{this.getProcAddressShellPtr.ToInt64():X}"); + Log.Verbose($"GetProcAddressShellPtr: 0x{this.getProcAddressShellPtr:X}"); - if (this.getProcAddressShellPtr == IntPtr.Zero) + if (this.getProcAddressShellPtr == 0) throw new Exception("Unable to allocate GetProcAddress shellcode"); this.extMemory.ChangePermission(this.getProcAddressShellPtr, bytes.Length, Reloaded.Memory.Kernel32.Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE); #if DEBUG - var outFunctionPtr = this.extMemory.Read(functionPtr); + this.extMemory.Read(functionPtr, out var outFunctionPtr); Log.Verbose($"GetProcAddressPtr: {this.GetResultMarker(outFunctionPtr == functionAddr)}"); - var outRetPtr = this.extMemory.Read(this.loadLibraryRetPtr); + this.extMemory.Read(this.loadLibraryRetPtr, out var outRetPtr); Log.Verbose($"GetProcAddressRet: {this.GetResultMarker(dummy == outRetPtr)}"); this.extMemory.ReadRaw(this.getProcAddressShellPtr, out var outBytes, bytes.Length); @@ -298,33 +292,33 @@ namespace Dalamud.Injector return exportFunction.Address; } - private IntPtr WriteNullTerminatedASCIIString(string value) + private nuint WriteNullTerminatedASCIIString(string value) { var bytes = Encoding.ASCII.GetBytes(value + '\0'); var address = this.circularBuffer.Add(bytes); - if (address == IntPtr.Zero) + if (address == 0) throw new Exception("Unable to write ASCII string to buffer"); #if DEBUG this.extMemory.ReadRaw(address, out var outBytes, bytes.Length); - Log.Verbose($"WriteASCII: {this.GetResultMarker(Enumerable.SequenceEqual(bytes, outBytes))} 0x{address.ToInt64():X} {value}"); + Log.Verbose($"WriteASCII: {this.GetResultMarker(Enumerable.SequenceEqual(bytes, outBytes))} 0x{address:X} {value}"); #endif return address; } - private IntPtr WriteNullTerminatedUnicodeString(string value) + private nuint WriteNullTerminatedUnicodeString(string value) { var bytes = Encoding.Unicode.GetBytes(value + '\0'); var address = this.circularBuffer.Add(bytes); - if (address == IntPtr.Zero) + if (address == 0) throw new Exception("Unable to write Unicode string to buffer"); #if DEBUG this.extMemory.ReadRaw(address, out var outBytes, bytes.Length); - Log.Verbose($"WriteUnicode: {this.GetResultMarker(Enumerable.SequenceEqual(bytes, outBytes))} 0x{address.ToInt64():X} {value}"); + Log.Verbose($"WriteUnicode: {this.GetResultMarker(Enumerable.SequenceEqual(bytes, outBytes))} 0x{address:X} {value}"); #endif return address; @@ -337,15 +331,15 @@ namespace Dalamud.Injector [StructLayout(LayoutKind.Sequential)] private struct GetProcAddressParams { - public GetProcAddressParams(IntPtr hModule, IntPtr lPProcName) + public GetProcAddressParams(IntPtr hModule, nuint lPProcName) { this.HModule = hModule.ToInt64(); - this.LPProcName = lPProcName.ToInt64(); + this.LPProcName = lPProcName; } public long HModule { get; set; } - public long LPProcName { get; set; } + public nuint LPProcName { get; set; } } } } diff --git a/Dalamud.Injector/NativeFunctions.cs b/Dalamud.Injector/NativeFunctions.cs index f1749ae0a..2a4654aaf 100644 --- a/Dalamud.Injector/NativeFunctions.cs +++ b/Dalamud.Injector/NativeFunctions.cs @@ -661,8 +661,8 @@ namespace Dalamud.Injector IntPtr hProcess, IntPtr lpThreadAttributes, UIntPtr dwStackSize, - IntPtr lpStartAddress, - IntPtr lpParameter, + nuint lpStartAddress, + nuint lpParameter, CreateThreadFlags dwCreationFlags, out uint lpThreadId); diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs index 24011b489..cc858eee8 100644 --- a/Dalamud/Dalamud.cs +++ b/Dalamud/Dalamud.cs @@ -28,7 +28,6 @@ namespace Dalamud #region Internals private readonly ManualResetEvent unloadSignal; - private bool hasDisposedPlugins = false; #endregion @@ -117,8 +116,6 @@ namespace Dalamud /// public void DisposePlugins() { - this.hasDisposedPlugins = true; - // this must be done before unloading interface manager, in order to do rebuild // the correct cascaded WndProc (IME -> RawDX11Scene -> Game). Otherwise the game // will not receive any windows messages diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs index 5fef315d5..029e8dd55 100644 --- a/Dalamud/EntryPoint.cs +++ b/Dalamud/EntryPoint.cs @@ -10,7 +10,6 @@ using Dalamud.Configuration.Internal; using Dalamud.Logging.Internal; using Dalamud.Support; using Dalamud.Utility; -using ImGuiNET; using Newtonsoft.Json; using PInvoke; using Serilog;