diff --git a/Dalamud.Bootstrap/Bootstrapper.cs b/Dalamud.Bootstrap/Bootstrapper.cs
index c4a08234c..2f1788833 100644
--- a/Dalamud.Bootstrap/Bootstrapper.cs
+++ b/Dalamud.Bootstrap/Bootstrapper.cs
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.IO.Pipes;
+using System.Text.RegularExpressions;
using CoreHook.BinaryInjection.RemoteInjection;
using CoreHook.BinaryInjection.RemoteInjection.Configuration;
using CoreHook.IPC.Platform;
@@ -61,7 +62,7 @@ namespace Dalamud.Bootstrap
var newTick = (uint)Environment.TickCount;
var newKey = newTick & 0xFFFF_0000; // only the high nibble is used
-
+
var newArgument = argument
.Remove("T")
.Add("T", $"{newTick}")
@@ -72,6 +73,9 @@ namespace Dalamud.Bootstrap
// 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();
}
@@ -93,12 +97,12 @@ namespace Dalamud.Bootstrap
{
var arguments = process.ReadArguments();
- if (arguments.Length < 1)
+ if (arguments.Length < 2)
{
throw new BootstrapException($"Process id {process.GetPid()} does not have any arguments to parse.");
}
- var argument = arguments[0];
+ var argument = arguments[1];
if (EncryptedArgument.TryParse(argument, out var encryptedArgument))
{
diff --git a/Dalamud.Bootstrap/Dalamud.Bootstrap.csproj b/Dalamud.Bootstrap/Dalamud.Bootstrap.csproj
index 17ed9d49c..900e7ad8e 100644
--- a/Dalamud.Bootstrap/Dalamud.Bootstrap.csproj
+++ b/Dalamud.Bootstrap/Dalamud.Bootstrap.csproj
@@ -9,8 +9,9 @@
+
-
+
diff --git a/Dalamud.Bootstrap/SqexArg/ArgumentBuilder.cs b/Dalamud.Bootstrap/SqexArg/ArgumentBuilder.cs
index 0ef3e210f..edc84c0b5 100644
--- a/Dalamud.Bootstrap/SqexArg/ArgumentBuilder.cs
+++ b/Dalamud.Bootstrap/SqexArg/ArgumentBuilder.cs
@@ -13,14 +13,19 @@ namespace Dalamud.Bootstrap.SqexArg
m_dict = new Dictionary();
}
+ public ArgumentBuilder(IEnumerable> collection)
+ {
+ m_dict = new Dictionary(collection);
+ }
+
///
/// Creates an argument builder from the argument (e.g. /T =1234)
///
///
///
- public static ArgumentBuilder Parse(string argument)
+ public static ArgumentBuilder Parse(ReadOnlySpan argument)
{
- throw new NotImplementedException("TODO");
+ return new ArgumentBuilder(ArgumentParser.Parse(argument));
}
public ArgumentBuilder Add(string key, string value)
diff --git a/Dalamud.Bootstrap/SqexArg/ArgumentParser.cs b/Dalamud.Bootstrap/SqexArg/ArgumentParser.cs
new file mode 100644
index 000000000..7830ecfc5
--- /dev/null
+++ b/Dalamud.Bootstrap/SqexArg/ArgumentParser.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using Pidgin;
+using static Pidgin.Parser;
+using static Pidgin.Parser;
+
+namespace Dalamud.Bootstrap.SqexArg
+{
+ public static class ArgumentParser
+ {
+ private static readonly Parser KeyMarkerNoEscape = String(" ");
+
+ private static readonly Parser KeyMarkerEscape = String(" /");
+
+ private static readonly Parser KeyMarker = Try(KeyMarkerEscape).Or(KeyMarkerNoEscape);
+
+ private static readonly Parser ValueMarker = String(" =");
+
+ private static readonly Parser EscapedSpace = String(" ").ThenReturn(' ');
+
+ //private static readonly Parser String = Try(EscapedSpace).Or(AnyCharExcept(' ')).ManyString();
+ private static readonly Parser String = Try(EscapedSpace).Or(AnyCharExcept(' ')).ManyString();
+
+ private static readonly Parser> KeyValue = Map
+ (
+ (_, key, _, value) => new KeyValuePair(key, value),
+ KeyMarker, String, ValueMarker, String
+ );
+
+ private static readonly Parser>> Parser = KeyValue.Many();
+
+ ///
+ /// Parses the argument
+ ///
+ ///
+ ///
+ /// Thrown when failed to parse the input.
+ public static IEnumerable> Parse(ReadOnlySpan input)
+ {
+ var test = KeyMarker.Parse(input);
+ var result = Parser.Parse(input);
+
+ if (!result.Success)
+ {
+ throw new SqexArgException($"Failed to parse the argument.\n{result.Error}");
+ }
+
+ return result.Value;
+ }
+ }
+}
diff --git a/Dalamud.Bootstrap/SqexArg/EncryptedArgument.cs b/Dalamud.Bootstrap/SqexArg/EncryptedArgument.cs
index 36706d4e0..9e4bdd1c3 100644
--- a/Dalamud.Bootstrap/SqexArg/EncryptedArgument.cs
+++ b/Dalamud.Bootstrap/SqexArg/EncryptedArgument.cs
@@ -1,6 +1,7 @@
using System;
using System.Buffers;
using System.Buffers.Text;
+using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using Dalamud.Bootstrap.Crypto;
@@ -90,7 +91,7 @@ namespace Dalamud.Bootstrap.SqexArg
// plainText <- utf8Bytes <- encryptedBytes(payload) <- base64(payloadStr)
// base64: 3 bytes per 4 characters
- // We also want the size to be aligned with the block size.
+ // We also want the size to be aligned with the block size. Usually this is not a problem but we don't know what payload is actually from.
var dataLength = (payload.Length / 4) * 3;
var alignedDataLength = AlignBufferLength(dataLength);
var encryptedData = new byte[alignedDataLength];
@@ -112,9 +113,14 @@ namespace Dalamud.Bootstrap.SqexArg
blowfish.Decrypt(encryptedData, decryptedData);
// utf8Bytes -> C# string
- var plainText = Encoding.UTF8.GetString(decryptedData[..dataLength]);
-
- return plainText;
+ // notice that decryptedData is a null terminated string.
+ unsafe
+ {
+ fixed (byte* pDecryptedData = decryptedData)
+ {
+ return Marshal.PtrToStringUTF8(new IntPtr(pDecryptedData));
+ }
+ }
}
///
diff --git a/Dalamud.Bootstrap/Windows/Process.cs b/Dalamud.Bootstrap/Windows/Process.cs
index 451d14434..fbfc3b20f 100644
--- a/Dalamud.Bootstrap/Windows/Process.cs
+++ b/Dalamud.Bootstrap/Windows/Process.cs
@@ -166,7 +166,7 @@ namespace Dalamud.Bootstrap
{
FileTime creationTime, exitTime, kernelTime, userTime;
- if (Win32.GetProcessTimes(m_handle, &creationTime, &exitTime, &kernelTime, &userTime))
+ if (!Win32.GetProcessTimes(m_handle, &creationTime, &exitTime, &kernelTime, &userTime))
{
ProcessException.ThrowLastOsError(GetPid());
}
diff --git a/Dalamud.Injector/Options.cs b/Dalamud.Injector/Options.cs
index ab473cc63..beaa0f949 100644
--- a/Dalamud.Injector/Options.cs
+++ b/Dalamud.Injector/Options.cs
@@ -8,10 +8,10 @@ namespace Dalamud.Injector
[Option('p', "pid", Required = true, HelpText = "A target process id to inject.")]
public uint Pid { get; set; }
- [Option("root", Required = false)]
+ [Option("root")]
public string? RootDirectory { get; set; }
- [Option("bin", Required = false)]
+ [Option("bin")]
public string? BinaryDirectory { get; set; }
}
diff --git a/Dalamud.Injector/Program.cs b/Dalamud.Injector/Program.cs
index 18ba8f4b0..41ed53458 100644
--- a/Dalamud.Injector/Program.cs
+++ b/Dalamud.Injector/Program.cs
@@ -10,13 +10,17 @@ 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.Launch("", "");
+ boot.Relaunch(pid);
Parser.Default.ParseArguments(args)
.WithParsed(Inject)
@@ -25,6 +29,7 @@ namespace Dalamud.Injector
private static void Inject(InjectOptions options)
{
+ var pid = options.Pid;
var binDirectory = options.BinaryDirectory ?? GetDefaultBinaryDirectory();
var rootDirectory = options.RootDirectory ?? GetDefaultRootDirectory();
@@ -34,7 +39,7 @@ namespace Dalamud.Injector
RootDirectory = rootDirectory,
});
- boot.Relaunch(options.Pid);
+ boot.Relaunch(pid);
}
private static void Launch(LaunchOptions options)