From 2a82a163012eef66f1e4af4ed3f3cb5f7a77b124 Mon Sep 17 00:00:00 2001 From: Mino <1381835+Minoost@users.noreply.github.com> Date: Tue, 3 Mar 2020 23:40:40 +0900 Subject: [PATCH] shit codes --- Dalamud.Injector/Dalamud.Injector.csproj | 1 + Dalamud.Injector/DalamudLauncher.cs | 2 +- Dalamud.Injector/FFI/Win32.cs | 65 --------- Dalamud.Injector/OS/Process.cs | 33 ----- Dalamud.Injector/Program/Program.cs | 1 + Dalamud.Injector/Windows/NtException.cs | 14 ++ Dalamud.Injector/Windows/Process.cs | 160 +++++++++++++++++++++++ Dalamud.Injector/Windows/Win32.cs | 145 ++++++++++++++++++++ Dalamud/Dalamud.csproj | 9 -- Dalamud/EntryPoint.cs | 5 - 10 files changed, 322 insertions(+), 113 deletions(-) delete mode 100644 Dalamud.Injector/FFI/Win32.cs delete mode 100644 Dalamud.Injector/OS/Process.cs create mode 100644 Dalamud.Injector/Windows/NtException.cs create mode 100644 Dalamud.Injector/Windows/Process.cs create mode 100644 Dalamud.Injector/Windows/Win32.cs diff --git a/Dalamud.Injector/Dalamud.Injector.csproj b/Dalamud.Injector/Dalamud.Injector.csproj index 8e2137758..8712672e8 100644 --- a/Dalamud.Injector/Dalamud.Injector.csproj +++ b/Dalamud.Injector/Dalamud.Injector.csproj @@ -4,6 +4,7 @@ netcoreapp3.1 preview enable + true diff --git a/Dalamud.Injector/DalamudLauncher.cs b/Dalamud.Injector/DalamudLauncher.cs index 531b7b80a..4c2c91f98 100644 --- a/Dalamud.Injector/DalamudLauncher.cs +++ b/Dalamud.Injector/DalamudLauncher.cs @@ -19,7 +19,7 @@ namespace Dalamud.Injector public void Launch(string exePath) { - // + } public void Relaunch(uint pid) diff --git a/Dalamud.Injector/FFI/Win32.cs b/Dalamud.Injector/FFI/Win32.cs deleted file mode 100644 index 394065fbc..000000000 --- a/Dalamud.Injector/FFI/Win32.cs +++ /dev/null @@ -1,65 +0,0 @@ -using Microsoft.Win32.SafeHandles; -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Text; - -namespace Dalamud.Injector.FFI -{ - internal static class Win32 - { - [DllImport("kernel32", CallingConvention = CallingConvention.Winapi, SetLastError = true)] - public static extern SafeProcessHandle OpenProcess(uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId); - - [DllImport("kernel32", CallingConvention = CallingConvention.Winapi, SetLastError = true)] - public static extern NtStatus NtQueryInformationProcess(/* TODO */); - - - } - - [StructLayout(LayoutKind.Sequential)] - internal partial struct NtStatus - { - public uint Value { get; } - } - - internal partial struct NtStatus - { - public NtStatus(uint value) - { - Value = value; - } - - /// - /// Equivalent to NT_SUCCESS - /// - public bool Success => Value <= 0x7FFFFFFF; - - /// - /// Equivalent to NT_INFORMATION - /// - public bool Information => 0x40000000 <= Value && Value <= 0x7FFFFFFF; - - /// - /// Equivalent to NT_WARNING - /// - public bool Warning => 0x80000000 <= Value && Value <= 0xBFFFFFFF; - - /// - /// Equivalent to NT_ERROR - /// - public bool Error => 0xC0000000 <= Value; - } - - [StructLayout(LayoutKind.Sequential)] - internal struct PROCESS_BASIC_INFORMATION - { - // https://github.com/processhacker/processhacker/blob/e43d7c0513ec5368c3309a58c9f2c2a3ca5de367/phnt/include/ntpsapi.h#L272 - public NtStatus ExitStatus; - public IntPtr PebBaseAddress; - public IntPtr AffinityMask; - public IntPtr BasePriority; - public IntPtr UniqueProcessId; - public IntPtr InheritedFromUniqueProcessId; - } -} diff --git a/Dalamud.Injector/OS/Process.cs b/Dalamud.Injector/OS/Process.cs deleted file mode 100644 index fd316bf91..000000000 --- a/Dalamud.Injector/OS/Process.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Microsoft.Win32.SafeHandles; -using System; -using System.Collections.Generic; -using System.Text; - -namespace Dalamud.Injector.OS -{ - internal sealed partial class Process : IDisposable - { - private SafeProcessHandle m_handle; - } - - internal sealed partial class Process { - internal Process(SafeProcessHandle handle) - { - m_handle = handle; - } - - public static Process Open(uint pid/* and perms? maybe? */) - { - // - throw new NotImplementedException("TODO"); - } - - - - public void Dispose() - { - m_handle?.Dispose(); - m_handle = null!; - } - } -} diff --git a/Dalamud.Injector/Program/Program.cs b/Dalamud.Injector/Program/Program.cs index d6552585c..c62e8e037 100644 --- a/Dalamud.Injector/Program/Program.cs +++ b/Dalamud.Injector/Program/Program.cs @@ -1,6 +1,7 @@ using System; using CommandLine; + namespace Dalamud.Injector { internal static class Program diff --git a/Dalamud.Injector/Windows/NtException.cs b/Dalamud.Injector/Windows/NtException.cs new file mode 100644 index 000000000..6887dc3ff --- /dev/null +++ b/Dalamud.Injector/Windows/NtException.cs @@ -0,0 +1,14 @@ +using System; + +namespace Dalamud.Injector.Windows +{ + internal sealed class NtException : Exception + { + public NtStatus Status { get; } + + public NtException(NtStatus status) + { + Status = status; + } + } +} diff --git a/Dalamud.Injector/Windows/Process.cs b/Dalamud.Injector/Windows/Process.cs new file mode 100644 index 000000000..38b585695 --- /dev/null +++ b/Dalamud.Injector/Windows/Process.cs @@ -0,0 +1,160 @@ +using Microsoft.Win32.SafeHandles; +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; + +namespace Dalamud.Injector.Windows +{ + /// + /// + /// + /// + /// + /// + internal sealed partial class Process : IDisposable + { + private SafeProcessHandle m_handle; + } + + internal sealed partial class Process { + /// + /// + /// + /// A process handle. Note that this functinon will take the ownership of the handle. + public Process(SafeProcessHandle handle) + { + m_handle = handle; + } + + public void Dispose() + { + m_handle?.Dispose(); + m_handle = null!; + } + + public static Process Open(uint pid) + { + const PROCESS_ACCESS_RIGHT access = PROCESS_ACCESS_RIGHT.PROCESS_VM_OPERATION | + PROCESS_ACCESS_RIGHT.PROCESS_VM_READ | + PROCESS_ACCESS_RIGHT.PROCESS_VM_WRITE | + PROCESS_ACCESS_RIGHT.PROCESS_QUERY_LIMITED_INFORMATION | + PROCESS_ACCESS_RIGHT.PROCESS_QUERY_INFORMATION | + PROCESS_ACCESS_RIGHT.PROCESS_CREATE_THREAD | + PROCESS_ACCESS_RIGHT.PROCESS_TERMINATE; + + var handle = Win32.OpenProcess((uint) access, false, pid); + if (!handle.IsInvalid) + { + throw new Win32Exception(); + } + + return new Process(handle); + } + + public int ReadMemory(IntPtr address, Span destination) + { + unsafe + { + fixed (byte* pDest = destination) + { + IntPtr bytesRead; + + if (!Win32.ReadProcessMemory(m_handle, (void*)address, pDest, (IntPtr)destination.Length, &bytesRead)) + { + throw new Win32Exception(); + } + + return (uint)bytesRead; + } + } + } + + public void ReadMemoryExact(IntPtr address, Span destination) + { + var totalBytesRead = 0; + while (totalBytesRead < destination.Length) + { + var bytesRead = ReadMemory(address + totalBytesRead, destination[totalBytesRead..]); + + if (bytesRead == 0) + { + throw new NotImplementedException("TODO: unexpected EOF"); + } + + totalBytesRead += bytesRead; + } + } + + public IntPtr WriteMemory(IntPtr address, ReadOnlySpan source) + { + unsafe + { + fixed (byte* pSrc = source) + { + IntPtr bytesWritten; + + if (!Win32.WriteProcessMemory(m_handle, (void*)address, pSrc, (IntPtr)source.Length, &bytesWritten)) + { + throw new Win32Exception(); + } + + return bytesWritten; + } + } + } + + public void Terminate(uint exitCode = 0) + { + if (!Win32.TerminateProcess(m_handle, exitCode)) + { + throw new Win32Exception(); + } + } + + private IntPtr ReadPebAddress() + { + unsafe + { + var info = new PROCESS_BASIC_INFORMATION(); + IntPtr _retLen; + + var status = Win32.NtQueryInformationProcess(m_handle, PROCESSINFOCLASS.ProcessBasicInformation, &info, sizeof(PROCESS_BASIC_INFORMATION), &_retLen); + if (!status.Success) + { + // TODO + throw new InvalidOperationException("TODO"); + } + + 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() + { + unsafe + { + var pPeb = ReadPebAddress(); + var pPebLdr = pPeb + (int)Marshal.OffsetOf("ProcessParameters"); + + Span procParamBuf = stackalloc byte[sizeof(RTL_USER_PROCESS_PARAMETERS)]; + ReadMemoryExact(pPebLdr, procParamBuf); + ref var procParam = ref MemoryMarshal.AsRef(procParamBuf); + + 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 new file mode 100644 index 000000000..f4589141c --- /dev/null +++ b/Dalamud.Injector/Windows/Win32.cs @@ -0,0 +1,145 @@ +using Microsoft.Win32.SafeHandles; +using System; +using System.Runtime.InteropServices; + +namespace Dalamud.Injector.Windows +{ + internal static unsafe class Win32 + { + [DllImport("kernel32", CallingConvention = CallingConvention.Winapi, SetLastError = true)] + public static extern SafeProcessHandle OpenProcess(uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId); + + [DllImport("kernel32", CallingConvention = CallingConvention.Winapi, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool TerminateProcess(SafeProcessHandle hProcess, uint uExitCode); + + [DllImport("ntdll", CallingConvention = CallingConvention.Winapi, SetLastError = true)] + public static extern NtStatus NtQueryInformationProcess(SafeProcessHandle processHandle, PROCESSINFOCLASS processInfoClass, void* processInformation, int processInformationLength, IntPtr* returnLength); + + [DllImport("kernel32", CallingConvention = CallingConvention.Winapi, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool ReadProcessMemory(SafeProcessHandle hProcess, void* lpBaseAddress, void* lpBuffer, IntPtr nSize, IntPtr* lpNumberOfBytesRead); + + [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); + } + + [StructLayout(LayoutKind.Sequential)] + internal partial struct NtStatus + { + public uint Value { get; } + } + + internal partial struct NtStatus + { + public NtStatus(uint value) + { + Value = value; + } + + /// + /// Equivalent to NT_SUCCESS + /// + public bool Success => Value <= 0x7FFFFFFF; + + /// + /// Equivalent to NT_INFORMATION + /// + public bool Information => 0x40000000 <= Value && Value <= 0x7FFFFFFF; + + /// + /// Equivalent to NT_WARNING + /// + public bool Warning => 0x80000000 <= Value && Value <= 0xBFFFFFFF; + + /// + /// Equivalent to NT_ERROR + /// + public bool Error => 0xC0000000 <= Value; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct UNICODE_STRING + { + public ushort Length; + public ushort MaximumLength; + public IntPtr Buffer; + } + + internal enum PROCESSINFOCLASS : uint + { + ProcessBasicInformation = 0, + ProcessDebugPort = 7, + ProcessWow64Information = 26, + ProcessImageFileName = 27, + ProcessBreakOnTermination = 29, + ProcessSubsystemInformation = 75, + } + + [StructLayout(LayoutKind.Sequential)] + internal struct PROCESS_BASIC_INFORMATION + { + // https://github.com/processhacker/processhacker/blob/e43d7c0513ec5368c3309a58c9f2c2a3ca5de367/phnt/include/ntpsapi.h#L272 + public NtStatus ExitStatus; + public IntPtr PebBaseAddress; + public IntPtr AffinityMask; + public IntPtr BasePriority; + public IntPtr UniqueProcessId; + public IntPtr InheritedFromUniqueProcessId; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct PEB + { + // https://github.com/processhacker/processhacker/blob/238287786b80abad647b988e60f69090cab4c8fe/phnt/include/ntpebteb.h#L57-L218 + public byte InheritedAddressSpace; + public byte ReadImageFileExecOptions; + public byte BeingDebugged; + public byte BitField; + public IntPtr Mutant; + public IntPtr ImageBaseAddress; + public IntPtr Ldr; + public IntPtr ProcessParameters; + // ..snip.. + } + + [StructLayout(LayoutKind.Sequential)] + internal struct RTL_USER_PROCESS_PARAMETERS + { + + public uint MaximumLength; + public uint LengthInitialized; + public uint Flags; + public uint DebugFlags; + public IntPtr ConsoleHandle; + public uint ConsoleFlags; + public IntPtr StandardInput; + public IntPtr StandardOutput; + public IntPtr StandardError; + public UNICODE_STRING CurrentDirectory_DosPath; + public IntPtr CurrentDirectory_Handle; + public UNICODE_STRING DllPath; + public UNICODE_STRING ImagePathName; + public UNICODE_STRING CommandLine; + // ..snip.. + } + + [Flags] + internal enum PROCESS_ACCESS_RIGHT : uint + { + PROCESS_TERMINATE = 0x1, + PROCESS_CREATE_THREAD = 0x2, + PROCESS_VM_OPERATION = 0x8, + PROCESS_VM_READ = 0x10, + PROCESS_VM_WRITE = 0x20, + PROCESS_DUP_HANDLE = 0x40, + PROCESS_CREATE_PROCESS = 0x80, + PROCESS_SET_QUOTA = 0x100, + PROCESS_SET_INFORMATION = 0x200, + PROCESS_QUERY_INFORMATION = 0x400, + PROCESS_SUSPEND_RESUME = 0x800, + PROCESS_QUERY_LIMITED_INFORMATION = 0x1000, + SYNCHRONIZE = 0x100000, + } +} diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj index a5d982e6e..257e33532 100644 --- a/Dalamud/Dalamud.csproj +++ b/Dalamud/Dalamud.csproj @@ -6,21 +6,12 @@ true enable - - - - - - - - - diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs index cf4be768e..e7e8404f4 100644 --- a/Dalamud/EntryPoint.cs +++ b/Dalamud/EntryPoint.cs @@ -1,9 +1,4 @@ using System; -using System.IO; -using System.Net; -using Dalamud.Interface; -using Serilog; -using Serilog.Core; using CoreHook; namespace Dalamud