diff --git a/Dalamud.Injector/Windows/NtException.cs b/Dalamud.Injector/Windows/NtException.cs
index 6887dc3ff..c4f2d25c9 100644
--- a/Dalamud.Injector/Windows/NtException.cs
+++ b/Dalamud.Injector/Windows/NtException.cs
@@ -2,11 +2,11 @@ using System;
namespace Dalamud.Injector.Windows
{
- internal sealed class NtException : Exception
+ internal sealed class NtStatusException : Exception
{
public NtStatus Status { get; }
- public NtException(NtStatus status)
+ public NtStatusException(NtStatus status)
{
Status = status;
}
diff --git a/Dalamud.Injector/Windows/Process.cs b/Dalamud.Injector/Windows/Process.cs
index 8645a7bd3..0fdb04899 100644
--- a/Dalamud.Injector/Windows/Process.cs
+++ b/Dalamud.Injector/Windows/Process.cs
@@ -5,18 +5,13 @@ using System.Runtime.InteropServices;
namespace Dalamud.Injector.Windows
{
- ///
- ///
- ///
- ///
- ///
- ///
internal sealed partial class Process : IDisposable
{
private SafeProcessHandle m_handle;
}
- internal sealed partial class Process {
+ internal sealed partial class Process
+ {
///
///
///
@@ -51,6 +46,12 @@ namespace Dalamud.Injector.Windows
return new Process(handle);
}
+ ///
+ /// Reads the process memory.
+ ///
+ ///
+ /// The number of bytes that is actually read and written into the buffer.
+ ///
public int ReadMemory(IntPtr address, Span destination)
{
unsafe
@@ -64,6 +65,7 @@ namespace Dalamud.Injector.Windows
throw new Win32Exception();
}
+ // this is okay as Span can't really be longer than int.Max
return (int)bytesRead;
}
}
@@ -75,11 +77,12 @@ namespace Dalamud.Injector.Windows
while (totalBytesRead < destination.Length)
{
var bytesRead = ReadMemory(address + totalBytesRead, destination[totalBytesRead..]);
-
- if (bytesRead == 0)
- {
- throw new NotImplementedException("TODO: unexpected EOF");
- }
+
+ // err -> partial read -> page fault?
+ //if (bytesRead == 0)
+ //{
+ // throw new NotImplementedException("TODO: unexpected EOF");
+ //}
totalBytesRead += bytesRead;
}
@@ -116,43 +119,39 @@ namespace Dalamud.Injector.Windows
unsafe
{
var info = new PROCESS_BASIC_INFORMATION();
- IntPtr _retLen;
+ var status = Win32.NtQueryInformationProcess(m_handle, PROCESSINFOCLASS.ProcessBasicInformation, &info, sizeof(PROCESS_BASIC_INFORMATION), (IntPtr*)IntPtr.Zero);
- var status = Win32.NtQueryInformationProcess(m_handle, PROCESSINFOCLASS.ProcessBasicInformation, &info, sizeof(PROCESS_BASIC_INFORMATION), &_retLen);
if (!status.Success)
{
- // TODO
- throw new InvalidOperationException("TODO");
+ throw new NtStatusException(status);
}
return info.PebBaseAddress;
}
}
- private ReadOnlySpan ReadMemoryAsUtf16(IntPtr address, int length)
- {
- var buffer = new byte[length];
- ReadMemoryExact(address, buffer);
-
- // TODO..
-
- return MemoryMarshal.Cast(buffer);
- }
-
- public string ReadCommandLine()
+ public string[] ReadCommandLine()
{
unsafe
{
var pPeb = ReadPebAddress();
- var pPebProc = ReadMemoryExact(pPeb + (int)Marshal.OffsetOf("ProcessParameters");
- var
+ // Read peb (partially)
+ Span pebBuf = stackalloc byte[sizeof(PEB)];
+ ReadMemoryExact(pPeb, pebBuf);
+ ref readonly var peb = ref MemoryMarshal.AsRef(pebBuf);
+ // Read process parameters
Span procParamBuf = stackalloc byte[sizeof(RTL_USER_PROCESS_PARAMETERS)];
- ReadMemoryExact(pPebLdr, procParamBuf);
- ref var procParam = ref MemoryMarshal.AsRef(procParamBuf);
+ ReadMemoryExact(peb.ProcessParameters, procParamBuf);
+ ref readonly var procParam = ref MemoryMarshal.AsRef(procParamBuf);
+
+ // Read commandline
+ var commandLineBuf = new byte[procParam.CommandLine.Length]; // arbitrary length; allocate to gc heap
+ ReadMemoryExact(procParam.CommandLine.Buffer, commandLineBuf);
+
+
- var commandLine = ReadMemoryAsUtf16(procParam.CommandLine.Buffer, procParam.CommandLine.Length);
}
throw new NotImplementedException();
diff --git a/Dalamud.Injector/Windows/Win32.cs b/Dalamud.Injector/Windows/Win32.cs
index f4589141c..68cd9e1e7 100644
--- a/Dalamud.Injector/Windows/Win32.cs
+++ b/Dalamud.Injector/Windows/Win32.cs
@@ -23,6 +23,12 @@ namespace Dalamud.Injector.Windows
[DllImport("kernel32", CallingConvention = CallingConvention.Winapi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WriteProcessMemory(SafeProcessHandle hProcess, void* lpBaseAddress, void* lpBuffer, IntPtr nSize, IntPtr* lpNumberOfBytesWritten);
+
+ [DllImport("kernel32", CallingConvention = CallingConvention.Winapi, SetLastError = true)]
+ public static extern void* LocalFree(void* hMem);
+
+ [DllImport("kernel32", CallingConvention = CallingConvention.Winapi, SetLastError = true)]
+ public static extern void* CommandLineToArgvW(, int* pNumArgs);
}
[StructLayout(LayoutKind.Sequential)]