This commit is contained in:
Mino 2020-03-11 22:28:06 +09:00
parent 350d2961c1
commit a01bc259a8
7 changed files with 55 additions and 17 deletions

View file

@ -4,6 +4,7 @@ using System.IO.Pipes;
using CoreHook.BinaryInjection.RemoteInjection; using CoreHook.BinaryInjection.RemoteInjection;
using CoreHook.BinaryInjection.RemoteInjection.Configuration; using CoreHook.BinaryInjection.RemoteInjection.Configuration;
using CoreHook.IPC.Platform; using CoreHook.IPC.Platform;
using Dalamud.Bootstrap.SqexArg;
namespace Dalamud.Bootstrap namespace Dalamud.Bootstrap
{ {
@ -16,7 +17,7 @@ namespace Dalamud.Bootstrap
m_options = options; m_options = options;
} }
public void Launch(string exePath) public void Launch(string exePath, string? commandLine)
{ {
throw new NotImplementedException("TODO"); throw new NotImplementedException("TODO");
} }
@ -43,8 +44,9 @@ namespace Dalamud.Bootstrap
// Acquire the process handle and read the command line // Acquire the process handle and read the command line
using var process = Process.Open(pid); using var process = Process.Open(pid);
var arguments = process.ReadCommandLine(); var commandLine = process.ReadCommandLine();
var argument = ArgumentDecoder.Decode(commandLine[1]);
// TODO: // TODO:
// .... if arg1 exists // .... if arg1 exists
// DecodeSqexArg(arguments[1]); // DecodeSqexArg(arguments[1]);
@ -54,8 +56,7 @@ namespace Dalamud.Bootstrap
// AddArgs(args, "T", newTick) // AddArgs(args, "T", newTick)
// str = ToString() // str = ToString()
// EncodeSqexArg(str, newKey) // EncodeSqexArg(str, newKey)
process.Terminate(); process.Terminate();
throw new NotImplementedException("TODO"); throw new NotImplementedException("TODO");
@ -94,7 +95,7 @@ namespace Dalamud.Bootstrap
// Could not inject Dalamud for whatever reason; it could be process is not actually running, insufficient os privilege, or whatever the thing SE put in their game; // Could not inject Dalamud for whatever reason; it could be process is not actually running, insufficient os privilege, or whatever the thing SE put in their game;
// Therefore there's not much we can do on this side; You have to trobleshoot by yourself somehow. // Therefore there's not much we can do on this side; You have to trobleshoot by yourself somehow.
throw new BootstrapException(pid, message, ex); throw new ProcessException(message, pid, ex);
} }
} }
} }

View file

@ -1,4 +1,5 @@
using System; using System;
using System.ComponentModel;
namespace Dalamud.Bootstrap namespace Dalamud.Bootstrap
{ {
@ -14,8 +15,26 @@ namespace Dalamud.Bootstrap
internal BootstrapException(string message, Exception innerException) : base(message, innerException) { } internal BootstrapException(string message, Exception innerException) : base(message, innerException) { }
} }
public class NtException : BootstrapException public class ProcessException : BootstrapException
{ {
public uint Pid { get; }
internal ProcessException() : base() { }
internal ProcessException(string message) : base(message) { }
internal ProcessException(string message, Exception innerException) : base(message, innerException) { }
internal ProcessException(string message, uint pid) : base(message) => Pid = pid;
internal ProcessException(string message, uint pid, Exception innerException) : base(message, innerException) => Pid = pid;
internal static ProcessException ThrowLastOsError(uint pid)
{
var inner = new Win32Exception();
const string message = "";
throw new ProcessException(message, pid, inner);
}
} }
} }

View file

@ -42,7 +42,7 @@ namespace Dalamud.Bootstrap.SqexArg
public override string ToString() public override string ToString()
{ {
var buffer = new StringBuilder(256); var buffer = new StringBuilder(300);
foreach (var kv in m_dict) foreach (var kv in m_dict)
{ {

View file

@ -4,7 +4,7 @@ namespace Dalamud.Bootstrap.SqexArg
{ {
internal static class ArgumentDecoder internal static class ArgumentDecoder
{ {
public static void Decode(ReadOnlySpan<char> argument, uint key) public static ArgumentBuilder Decode(ReadOnlySpan<char> argument, uint key)
{ {
// 1. strip //**sqex003 and **// // 1. strip //**sqex003 and **//
// 2. extract checksum // 2. extract checksum
@ -31,7 +31,7 @@ namespace Dalamud.Bootstrap.SqexArg
// stuff // stuff
throw new NotImplementedException("TODO");
} }
private static void DecodeUrlSafeBase64(ReadOnlySpan<char> content) private static void DecodeUrlSafeBase64(ReadOnlySpan<char> content)

View file

@ -42,17 +42,19 @@ namespace Dalamud.Bootstrap
if (handle.IsInvalid) if (handle.IsInvalid)
{ {
throw new Win32Exception(); ProcessException.ThrowLastOsError(pid);
} }
return new Process(handle); return new Process(handle);
} }
private uint GetPid() => Win32.GetProcessId(m_handle);
public void Terminate(uint exitCode = 0) public void Terminate(uint exitCode = 0)
{ {
if (!Win32.TerminateProcess(m_handle, exitCode)) if (!Win32.TerminateProcess(m_handle, exitCode))
{ {
throw new Win32Exception(); ProcessException.ThrowLastOsError(GetPid());
} }
} }
@ -72,7 +74,7 @@ namespace Dalamud.Bootstrap
if (!Win32.ReadProcessMemory(m_handle, (void*)address, pDest, (IntPtr)destination.Length, &bytesRead)) if (!Win32.ReadProcessMemory(m_handle, (void*)address, pDest, (IntPtr)destination.Length, &bytesRead))
{ {
throw new Win32Exception(); ProcessException.ThrowLastOsError(GetPid());
} }
// this is okay as the length of the span can't be longer than int.Max // this is okay as the length of the span can't be longer than int.Max
@ -91,7 +93,7 @@ namespace Dalamud.Bootstrap
if (bytesRead == 0) if (bytesRead == 0)
{ {
// prolly page fault; there's not much we can do here // prolly page fault; there's not much we can do here
throw new Win32Exception(); ProcessException.ThrowLastOsError(GetPid());
} }
totalBytesRead += bytesRead; totalBytesRead += bytesRead;
@ -128,7 +130,10 @@ namespace Dalamud.Bootstrap
if (!status.Success) if (!status.Success)
{ {
throw new NtException(status); var message = $"A call to NtQueryInformationProcess failed. (Status: {status})";
var pid = GetPid();
throw new ProcessException(message, pid);
} }
return info.PebBaseAddress; return info.PebBaseAddress;
@ -150,7 +155,7 @@ namespace Dalamud.Bootstrap
} }
} }
private static string[] ParseCommandLine(ReadOnlySpan<byte> commandLine) private string[] ParseCommandLine(ReadOnlySpan<byte> commandLine)
{ {
unsafe unsafe
{ {
@ -166,7 +171,7 @@ namespace Dalamud.Bootstrap
if (argv == null) if (argv == null)
{ {
throw new Win32Exception(); ProcessException.ThrowLastOsError(GetPid());
} }
try try

View file

@ -29,6 +29,9 @@ namespace Dalamud.Bootstrap.Windows
[DllImport("shell32", CallingConvention = CallingConvention.Winapi, SetLastError = true)] [DllImport("shell32", CallingConvention = CallingConvention.Winapi, SetLastError = true)]
public static extern char** CommandLineToArgvW(void* lpCmdLine, int* pNumArgs); public static extern char** CommandLineToArgvW(void* lpCmdLine, int* pNumArgs);
[DllImport("kernel32", CallingConvention = CallingConvention.Winapi)]
public static extern uint GetProcessId(SafeProcessHandle hProcess);
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
@ -63,6 +66,8 @@ namespace Dalamud.Bootstrap.Windows
/// Equivalent to NT_ERROR /// Equivalent to NT_ERROR
/// </summary> /// </summary>
public bool Error => 0xC0000000 <= Value; public bool Error => 0xC0000000 <= Value;
public override string ToString() => $"0x{Value:X8}";
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]

View file

@ -26,13 +26,21 @@ namespace Dalamud.Injector
RootDirectory = rootDirectory, RootDirectory = rootDirectory,
}); });
// ..
boot.Relaunch(options.Pid); boot.Relaunch(options.Pid);
} }
private static void Launch(LaunchOptions options) private static void Launch(LaunchOptions options)
{ {
var binDirectory = options.BinaryDirectory ?? GetDefaultBinaryDirectory();
var rootDirectory = options.RootDirectory ?? GetDefaultRootDirectory();
var boot = new Bootstrapper(new BootstrapperOptions
{
BinaryDirectory = binDirectory,
RootDirectory = rootDirectory,
});
boot.Launch(options.ExecutablePath, options.CommandLine);
} }
private static string GetDefaultBinaryDirectory() private static string GetDefaultBinaryDirectory()