diff --git a/Dalamud.Bootstrap/Bootstrapper.cs b/Dalamud.Bootstrap/Bootstrapper.cs
index 2f1788833..bf84f26b9 100644
--- a/Dalamud.Bootstrap/Bootstrapper.cs
+++ b/Dalamud.Bootstrap/Bootstrapper.cs
@@ -54,65 +54,36 @@ namespace Dalamud.Bootstrap
// delegate Step 3 to 5 to Launch() maybe?
// Acquire the process handle and read the command line
- using var process = Process.Open(pid);
+ using var process = GameProcess.Open(pid);
var exePath = process.GetImageFilePath();
var argument = ReadArgumentFromProcess(process);
+ var encryptedArgument = EncryptArgument(argument.ToString());
- var newTick = (uint)Environment.TickCount;
- var newKey = newTick & 0xFFFF_0000; // only the high nibble is used
- var newArgument = argument
- .Remove("T")
- .Add("T", $"{newTick}")
- .ToString();
- var encryptedArgument = new EncryptedArgument(newArgument, newKey);
-
// TODO: launch new exe with the argument from encryptedArgument.ToString()
// TODO: we also need to figure out where the exe is located
// This is just for poc purpose.
- System.Diagnostics.Process.Start(exePath, encryptedArgument.ToString());
- process.Terminate();
+ //process.Terminate();
}
- private static uint RecoverKey(Process gameProcess)
+ private static string EncryptArgument(string argument)
{
- var createdTime = gameProcess.GetCreationTime();
-
- var currentDt = DateTime.Now;
- var currentTick = Environment.TickCount;
+ // for testing purpose
+ return argument;
- var delta = currentDt - createdTime;
- var createdTick = (uint)currentTick - (uint)delta.TotalMilliseconds;
+ //
+ // var tick = (uint)Environment.TickCount;
+ // var key = tick & 0xFFFF_0000; // only the high nibble is used
- // only the high nibble is used.
- return createdTick & 0xFFFF_0000;
+ // var encryptedArgument = new EncryptedArgument(argument, key);
+ // return encryptedArgument.ToString();
}
-
- private static ArgumentBuilder ReadArgumentFromProcess(Process process)
- {
- var arguments = process.ReadArguments();
-
- if (arguments.Length < 2)
- {
- throw new BootstrapException($"Process id {process.GetPid()} does not have any arguments to parse.");
- }
-
- var argument = arguments[1];
-
- if (EncryptedArgument.TryParse(argument, out var encryptedArgument))
- {
- var key = RecoverKey(process);
- argument = encryptedArgument.Decrypt(key);
- }
-
- return ArgumentBuilder.Parse(argument);
- }
-
+
///
/// Injects Dalamud into the process. See remarks for process state prerequisites.
///
diff --git a/Dalamud.Bootstrap/GameProcess.cs b/Dalamud.Bootstrap/GameProcess.cs
new file mode 100644
index 000000000..5140c541f
--- /dev/null
+++ b/Dalamud.Bootstrap/GameProcess.cs
@@ -0,0 +1,83 @@
+using System;
+using Dalamud.Bootstrap.SqexArg;
+using Dalamud.Bootstrap.Windows;
+
+namespace Dalamud.Bootstrap
+{
+ internal sealed class GameProcess : IDisposable
+ {
+ private Process m_process;
+
+ public GameProcess(Process process)
+ {
+ m_process = process;
+ }
+
+ public static GameProcess 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 // we don't need it for now
+ | PROCESS_ACCESS_RIGHT.PROCESS_QUERY_LIMITED_INFORMATION
+ | PROCESS_ACCESS_RIGHT.PROCESS_QUERY_INFORMATION
+ | PROCESS_ACCESS_RIGHT.PROCESS_CREATE_THREAD
+ | PROCESS_ACCESS_RIGHT.PROCESS_TERMINATE;
+
+ // TODO: unfuck VM_WRITE
+
+ var process = Process.Open(pid, access);
+
+ return new GameProcess(process);
+ }
+
+ public void Dispose()
+ {
+ m_process?.Dispose();
+ m_process = null!;
+ }
+
+ ///
+ /// Recovers a key used in encrypting process arguments.
+ ///
+ /// A key recovered from the time when the process was created.
+ ///
+ /// This is possible because the key to encrypt arguments is just a high nibble value from GetTickCount() at the time when the process was created.
+ /// (Thanks Wintermute!)
+ ///
+ private uint GetArgumentEncryptionKey()
+ {
+ var createdTime = m_process.GetCreationTime();
+
+ // Get current tick
+ var currentDt = DateTime.Now;
+ var currentTick = Environment.TickCount;
+
+ // We know that GetTickCount() is just a system uptime in milliseconds.
+ var delta = currentDt - createdTime;
+ var createdTick = (uint)currentTick - (uint)delta.TotalMilliseconds;
+
+ // only the high nibble is used.
+ return createdTick & 0xFFFF_0000;
+ }
+
+ public ArgumentBuilder ReadArguments()
+ {
+ var arguments = m_process.ReadArguments();
+
+ if (arguments.Length < 2)
+ {
+ throw new BootstrapException($"Process id {m_process.GetPid()} have no arguments to parse.");
+ }
+
+ var argument = arguments[1];
+
+ if (EncryptedArgument.TryParse(argument, out var encryptedArgument))
+ {
+ var key = GetArgumentEncryptionKey();
+ argument = encryptedArgument.Decrypt(key);
+ }
+
+ return ArgumentBuilder.Parse(argument);
+ }
+ }
+}
diff --git a/Dalamud.Bootstrap/Windows/Process.cs b/Dalamud.Bootstrap/Windows/Process.cs
index fbfc3b20f..e7bfc3d21 100644
--- a/Dalamud.Bootstrap/Windows/Process.cs
+++ b/Dalamud.Bootstrap/Windows/Process.cs
@@ -8,7 +8,7 @@ using System.Text;
namespace Dalamud.Bootstrap
{
///
- /// TODO
+ /// A class that provides a wrapper over operations on Win32 process.
///
internal sealed partial class Process : IDisposable
{
@@ -29,16 +29,8 @@ namespace Dalamud.Bootstrap
m_handle = null!;
}
- public static Process Open(uint pid)
+ public static Process Open(uint pid, PROCESS_ACCESS_RIGHT access)
{
- const PROCESS_ACCESS_RIGHT access = PROCESS_ACCESS_RIGHT.PROCESS_VM_OPERATION
- | PROCESS_ACCESS_RIGHT.PROCESS_VM_READ
- // | PROCESS_ACCESS_RIGHT.PROCESS_VM_WRITE // we don't need it for now
- | 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)
diff --git a/Dalamud.Injector/Program.cs b/Dalamud.Injector/Program.cs
index 41ed53458..25569445b 100644
--- a/Dalamud.Injector/Program.cs
+++ b/Dalamud.Injector/Program.cs
@@ -10,18 +10,6 @@ namespace Dalamud.Injector
{
private static void Main(string[] args)
{
- var pid = 12336u;
- var binDirectory = "";
- var rootDirectory = "";
-
- var boot = new Bootstrapper(new BootstrapperOptions
- {
- BinaryDirectory = "",
- RootDirectory = "",
- });
-
- boot.Relaunch(pid);
-
Parser.Default.ParseArguments(args)
.WithParsed(Inject)
.WithParsed(Launch);