Skip to content

Instantly share code, notes, and snippets.

@Nenkai
Created October 2, 2025 23:14
Show Gist options
  • Save Nenkai/a4ff1b29ebdcea985a23bdbad48e6289 to your computer and use it in GitHub Desktop.
Save Nenkai/a4ff1b29ebdcea985a23bdbad48e6289 to your computer and use it in GitHub Desktop.
private unsafe void HookCreateProcess()
{
var kernel32 = PInvoke.GetModuleHandle("kernel32.dll");
if (kernel32 is null)
{
_logger.WriteLine($"[{_modConfig.ModId}] Could not load kernel32 module - exception handler won't be removed", _logger.ColorRed);
return;
}
var createProcessA = PInvoke.GetProcAddress(kernel32, "CreateProcessA");
if (createProcessA.IsNull)
{
_logger.WriteLine($"[{_modConfig.ModId}] SetUnhandledExceptionFilter not found in kernel32 module - exception handler won't be removed", _logger.ColorRed);
return;
}
if (_hooks is null)
{
_logger.WriteLine($"[{_modConfig.ModId}] IReloadedHooks is null? Reloaded.SharedLib.Hooks was not loaded?", _logger.ColorRed);
return;
}
CreateProcessHook = _hooks.CreateHook<CreateProcessADelegate>(CreateProcessImpl, createProcessA).Activate();
}
private unsafe nint CreateProcessImpl(char* lpApplicationName, char* lpCommandLine, SECURITY_ATTRIBUTES* lpProcessAttributes, SECURITY_ATTRIBUTES* lpThreadAttributes,
nint bInheritHandles, PROCESS_CREATION_FLAGS dwCreationFlags,
void* lpEnvironment, string lpCurrentDirectory, STARTUPINFOW* lpStartupInfo, PROCESS_INFORMATION* lpProcessInformation)
{
string commandLine = Marshal.PtrToStringAnsi((nint)lpCommandLine);
int exeExtIndex = commandLine.IndexOf(".exe") + 4;
string exeToLaunch = commandLine.Substring(0, exeExtIndex);
string argumentsOnly = commandLine.Substring(exeExtIndex, commandLine.Length - exeExtIndex);
var config = IConfig<LoaderConfig>.FromPathOrDefault(Paths.LoaderConfigPath);
if (config is null)
{
_logger.WriteLine($"[{_modConfig.ModId}] Failed to locate Reloaded-II, unable to handle game mode transition!", _logger.ColorRed);
return 0;
}
exeToLaunch = exeToLaunch.Replace("//", "/");
var configurations = ApplicationConfig.GetAllApplications(config.GetApplicationConfigDirectory());
foreach (var configuration in configurations)
{
var application = configuration.Config;
var appLocation = ApplicationConfig.GetAbsoluteAppLocation(configuration);
if (Path.GetFileName(appLocation).Equals(Path.GetFileName(exeToLaunch), StringComparison.OrdinalIgnoreCase))
{
Process? process = Process.Start(new ProcessStartInfo()
{
FileName = config.LauncherPath,
Arguments = $"--launch \"{appLocation}\" --arguments \"{argumentsOnly}\" --working-directory \"{Path.GetDirectoryName(appLocation)}\"",
UseShellExecute = false,
WorkingDirectory = Path.GetDirectoryName(config.LauncherPath),
});
process.OutputDataReceived += (s, e) => _logger.WriteLine($"[{_modConfig.ModId}] [Launcher] {e.Data}");
return 1;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment