From eb0f03722120e979b995037f94312872e8494c10 Mon Sep 17 00:00:00 2001 From: num0005 Date: Sat, 20 Jul 2024 00:00:19 +0100 Subject: [PATCH] [DllInjector] Fix race condition in `GetLibraryProcAddress32`. --- Launcher/Utility/DLLInjector.cs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/Launcher/Utility/DLLInjector.cs b/Launcher/Utility/DLLInjector.cs index d6d95f3..2103340 100644 --- a/Launcher/Utility/DLLInjector.cs +++ b/Launcher/Utility/DLLInjector.cs @@ -134,8 +134,17 @@ private static bool IsProcessWow64(System.Diagnostics.Process process) static object _32bitLock = new(); static string? _32bitHelperPath = null; + static FileStream _32bitHelperPathLock = null; // filestream used to lock the file for write and delete static Dictionary<(string, string), FARPROC> _32bit_procs_cache = new(); + private static void _deploy_get_proc_helper() + { + + _32bitHelperPath = Path.Combine(App.TempFolder, "DllInjector.GetProcAddrHelper." + Guid.NewGuid().ToString() + ".exe"); + File.WriteAllBytes(_32bitHelperPath, Utility.Resources.GetProcAddrHelper); + _32bitHelperPathLock = new(_32bitHelperPath, FileMode.Open, FileAccess.Read, FileShare.Read); + } + /// /// Get the address of a procdure. Only works for a few special libararies that are mapped at the same address in all modules /// @@ -145,7 +154,7 @@ private static bool IsProcessWow64(System.Diagnostics.Process process) static private async Task GetLibraryProcAddress32(string moduleName, string procName) { System.Diagnostics.Process process; - var cacheKey = (moduleName, procName); + var cacheKey = (moduleName.ToUpperInvariant(), procName); // check cache first // this method only works for modules loaded at the same address in all processes anyways @@ -157,11 +166,8 @@ static private async Task GetLibraryProcAddress32(string moduleName, st lock (_32bitLock) { - if (_32bitHelperPath is null) - { - _32bitHelperPath = Path.Combine(App.TempFolder, "DllInjector.GetProcAddrHelper." + Guid.NewGuid().ToString() + ".exe"); - File.WriteAllBytes(_32bitHelperPath, Utility.Resources.GetProcAddrHelper); - } + if (_32bitHelperPath is null || !File.Exists(_32bitHelperPath)) + _deploy_get_proc_helper(); List args = new() { moduleName.Trim(), procName.Trim() }; process = System.Diagnostics.Process.Start(_32bitHelperPath, args); @@ -176,7 +182,7 @@ static private async Task GetLibraryProcAddress32(string moduleName, st { lock (_32bit_procs_cache) { - _32bit_procs_cache.Add(cacheKey, ptrProc); + _32bit_procs_cache[cacheKey] = ptrProc; } }