|
3 | 3 | * SPDX-License-Identifier: BSD-3-Clause |
4 | 4 | */ |
5 | 5 |
|
6 | | -#include <stdio.h> |
| 6 | + |
7 | 7 | #include <Windows.h> |
8 | 8 | #include <sddl.h> |
9 | 9 | #include <AclAPI.h> |
@@ -100,7 +100,7 @@ static DWORD WINAPI loading_thread_func(loading_data *arg) |
100 | 100 |
|
101 | 101 | int wmain(int argc, wchar_t *argv[]) |
102 | 102 | { |
103 | | - std::filesystem::path procName; |
| 103 | + std::filesystem::path procName; |
104 | 104 | wchar_t* processName = nullptr; |
105 | 105 | HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); |
106 | 106 | if (argc < 2) |
@@ -135,9 +135,7 @@ int wmain(int argc, wchar_t *argv[]) |
135 | 135 | PROCESSENTRY32W process = { sizeof(process) }; |
136 | 136 | for (BOOL next = Process32FirstW(snapshot, &process); next; next = Process32NextW(snapshot, &process)) |
137 | 137 | { |
138 | | - |
139 | | - // if (wcscmp(processName , process.szExeFile) <= 0) |
140 | | - if (wcsspn(process.szExeFile, processName ) == wcslen(process.szExeFile) - 4) |
| 138 | + if (wcsnicmp(process.szExeFile, processName, wcslen(processName)) == 0) |
141 | 139 | { |
142 | 140 | pid = process.th32ProcessID; |
143 | 141 | break; |
@@ -174,261 +172,22 @@ int wmain(int argc, wchar_t *argv[]) |
174 | 172 | } |
175 | 173 |
|
176 | 174 | loading_data arg; |
| 175 | + //if (argc < 3) |
| 176 | + //{ |
177 | 177 | GetCurrentDirectoryW(MAX_PATH, arg.load_path); |
178 | 178 | wcscat_s(arg.load_path, L"\\"); |
179 | 179 | wcscat_s(arg.load_path, remote_is_wow64 ? L"ReShade32.dll" : L"ReShade64.dll"); |
180 | | - |
181 | | - if (GetFileAttributesW(arg.load_path) == INVALID_FILE_ATTRIBUTES) |
182 | | - { |
183 | | - wprintf(L"\nFailed to find ReShade at \"%s\"!\n", arg.load_path); |
184 | | - return ERROR_FILE_NOT_FOUND; |
185 | | - } |
186 | | - |
187 | | - // Make sure the DLL has permissions set up for 'ALL_APPLICATION_PACKAGES' |
188 | | - update_acl_for_uwp(arg.load_path); |
189 | | - |
190 | | - // This happens to work because kernel32.dll is always loaded to the same base address, so the address of 'LoadLibrary' is the same in the target application and the current one |
191 | | - arg.GetLastError = GetLastError; |
192 | | - arg.LoadLibraryW = LoadLibraryW; |
193 | | - arg.SetEnvironmentVariableW = SetEnvironmentVariableW; |
194 | | - |
195 | | -#if RESHADE_LOADING_THREAD_FUNC |
196 | | - const auto loading_thread_func_size = 256; // An estimate of the size of the 'loading_thread_func' function |
197 | | -#else |
198 | | - const auto loading_thread_func_size = 0; |
199 | | -#endif |
200 | | - const auto load_param = VirtualAllocEx(remote_process, nullptr, loading_thread_func_size + sizeof(arg), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); |
201 | | -#if RESHADE_LOADING_THREAD_FUNC |
202 | | - const auto loading_thread_func_address = static_cast<LPBYTE>(load_param) + sizeof(arg); |
203 | | -#else |
204 | | - const auto loading_thread_func_address = arg.LoadLibraryW; |
205 | | -#endif |
206 | | - |
207 | | - // Write thread entry point function and 'LoadLibrary' call argument to target application |
208 | | - if (load_param == nullptr |
209 | | - || !WriteProcessMemory(remote_process, load_param, &arg, sizeof(arg), nullptr) |
210 | | -#if RESHADE_LOADING_THREAD_FUNC |
211 | | - || !WriteProcessMemory(remote_process, loading_thread_func_address, loading_thread_func, loading_thread_func_size, nullptr) |
212 | | -#endif |
213 | | - ) |
214 | | - { |
215 | | - wprintf(L"\nFailed to allocate and write 'LoadLibrary' argument in target application!\n"); |
216 | | - return GetLastError(); |
217 | | - } |
218 | | - |
219 | | - // Execute 'LoadLibrary' in target application |
220 | | - const scoped_handle load_thread = CreateRemoteThread(remote_process, nullptr, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(loading_thread_func_address), load_param, 0, nullptr); |
221 | | - if (load_thread == nullptr) |
222 | | - { |
223 | | - wprintf(L"\nFailed to execute 'LoadLibrary' in target application!\n"); |
224 | | - return GetLastError(); |
225 | | - } |
226 | | - |
227 | | - // Wait for loading to finish and clean up parameter memory afterwards |
228 | | - WaitForSingleObject(load_thread, INFINITE); |
229 | | - VirtualFreeEx(remote_process, load_param, 0, MEM_RELEASE); |
230 | | - |
231 | | - // Thread thread exit code will contain the module handle |
232 | | - if (DWORD exit_code; GetExitCodeThread(load_thread, &exit_code) && |
233 | | -#if RESHADE_LOADING_THREAD_FUNC |
234 | | - exit_code == ERROR_SUCCESS) |
235 | | -#else |
236 | | - exit_code != NULL) |
237 | | -#endif |
238 | | - { |
239 | | - wprintf(L"Succeeded!\n"); |
240 | | - return 0; |
241 | | - } |
242 | | - else |
243 | | - { |
244 | | -#if RESHADE_LOADING_THREAD_FUNC |
245 | | - wprintf(L"\nFailed to load ReShade in target application! Error code is 0x%x.\n", exit_code); |
246 | | - return exit_code; |
247 | | -#else |
248 | | - wprintf(L"\nFailed to load ReShade in target application!\n"); |
249 | | - return ERROR_MOD_NOT_FOUND; |
250 | | -#endif |
251 | | - } |
252 | | -} |
253 | | -/* |
254 | | - * Copyright (C) 2014 Patrick Mours |
255 | | - * SPDX-License-Identifier: BSD-3-Clause |
256 | | - */ |
257 | | - |
258 | | -#include <stdio.h> |
259 | | -#include <Windows.h> |
260 | | -#include <sddl.h> |
261 | | -#include <AclAPI.h> |
262 | | -#include <TlHelp32.h> |
263 | | - |
264 | | -#include <filesystem> |
265 | | -#include <iostream> |
266 | | - |
267 | | -#define RESHADE_LOADING_THREAD_FUNC 1 |
268 | | - |
269 | | -struct loading_data |
270 | | -{ |
271 | | - WCHAR load_path[MAX_PATH] = L""; |
272 | | - decltype(&GetLastError) GetLastError = nullptr; |
273 | | - decltype(&LoadLibraryW) LoadLibraryW = nullptr; |
274 | | - const WCHAR env_var_name[30] = L"RESHADE_DISABLE_LOADING_CHECK"; |
275 | | - const WCHAR env_var_value[2] = L"1"; |
276 | | - decltype(&SetEnvironmentVariableW) SetEnvironmentVariableW = nullptr; |
277 | | -}; |
278 | | - |
279 | | -struct scoped_handle |
280 | | -{ |
281 | | - HANDLE handle; |
282 | | - |
283 | | - scoped_handle() : |
284 | | - handle(INVALID_HANDLE_VALUE) {} |
285 | | - scoped_handle(HANDLE handle) : |
286 | | - handle(handle) {} |
287 | | - scoped_handle(scoped_handle &&other) : |
288 | | - handle(other.handle) { |
289 | | - other.handle = NULL; |
290 | | - } |
291 | | - ~scoped_handle() { if (handle != NULL && handle != INVALID_HANDLE_VALUE) CloseHandle(handle); } |
292 | | - |
293 | | - operator HANDLE() const { return handle; } |
294 | | - |
295 | | - HANDLE *operator&() { return &handle; } |
296 | | - const HANDLE *operator&() const { return &handle; } |
297 | | -}; |
298 | | - |
299 | | -static void update_acl_for_uwp(LPWSTR path) |
300 | | -{ |
301 | | - OSVERSIONINFOEX verinfo_windows7 = { sizeof(OSVERSIONINFOEX), 6, 1 }; |
302 | | - const bool is_windows7 = VerifyVersionInfo(&verinfo_windows7, VER_MAJORVERSION | VER_MINORVERSION, |
303 | | - VerSetConditionMask(VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL), VER_MINORVERSION, VER_EQUAL)) != FALSE; |
304 | | - if (is_windows7) |
305 | | - return; // There is no UWP on Windows 7, so no need to update DACL |
306 | | - |
307 | | - PACL old_acl = nullptr, new_acl = nullptr; |
308 | | - PSECURITY_DESCRIPTOR sd = nullptr; |
309 | | - SECURITY_INFORMATION siInfo = DACL_SECURITY_INFORMATION; |
310 | | - |
311 | | - // Get the existing DACL for the file |
312 | | - if (GetNamedSecurityInfo(path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nullptr, nullptr, &old_acl, nullptr, &sd) != ERROR_SUCCESS) |
313 | | - return; |
314 | | - |
315 | | - // Get the SID for 'ALL_APPLICATION_PACKAGES' |
316 | | - PSID sid = nullptr; |
317 | | - if (ConvertStringSidToSid(TEXT("S-1-15-2-1"), &sid)) |
318 | | - { |
319 | | - EXPLICIT_ACCESS access = {}; |
320 | | - access.grfAccessPermissions = GENERIC_READ | GENERIC_EXECUTE; |
321 | | - access.grfAccessMode = SET_ACCESS; |
322 | | - access.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; |
323 | | - access.Trustee.TrusteeForm = TRUSTEE_IS_SID; |
324 | | - access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; |
325 | | - access.Trustee.ptstrName = reinterpret_cast<LPTCH>(sid); |
326 | | - |
327 | | - // Update the DACL with the new entry |
328 | | - if (SetEntriesInAcl(1, &access, old_acl, &new_acl) == ERROR_SUCCESS) |
329 | | - { |
330 | | - SetNamedSecurityInfo(path, SE_FILE_OBJECT, siInfo, NULL, NULL, new_acl, NULL); |
331 | | - LocalFree(new_acl); |
332 | | - } |
333 | | - |
334 | | - LocalFree(sid); |
335 | | - } |
336 | | - |
337 | | - LocalFree(sd); |
338 | | -} |
339 | | - |
340 | | -#if RESHADE_LOADING_THREAD_FUNC |
341 | | -static DWORD WINAPI loading_thread_func(loading_data *arg) |
342 | | -{ |
343 | | - arg->SetEnvironmentVariableW(arg->env_var_name, arg->env_var_value); |
344 | | - if (arg->LoadLibraryW(arg->load_path) == NULL) |
345 | | - return arg->GetLastError(); |
346 | | - return ERROR_SUCCESS; |
347 | | -} |
348 | | -#endif |
349 | | - |
350 | | - |
351 | | - |
352 | | - |
353 | | -int wmain(int argc, wchar_t *argv[]) |
354 | | -{ |
355 | | - std::filesystem::path procName; |
356 | | - wchar_t* processName = nullptr; |
357 | | - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); |
358 | | - if (argc < 2) |
359 | | - { |
360 | | - wprintf(L"Enter exe name: "); |
361 | | - std::wstring proc; |
362 | | - std::getline(std::wcin, proc); |
363 | | - procName = std::filesystem::path(proc); |
364 | | - processName = new wchar_t[procName.stem().string().size() + 1]; |
365 | | - wcscpy_s(processName, procName.stem().string().size() + 1, procName.stem().c_str()); |
366 | | - |
367 | | - std::wcout << L"Start your game now..." << std::endl; |
368 | | - } |
369 | | - else |
370 | | - { |
371 | | - procName = std::filesystem::path(argv[1]); |
372 | | - processName = new wchar_t[procName.stem().string().size() + 1]; |
373 | | - |
374 | | - wcscpy_s(processName, procName.stem().string().size() + 1, procName.stem().c_str()); |
375 | | - } |
376 | | - |
377 | 180 |
|
378 | | - wprintf(L"Waiting for a '%s' process to spawn ...\n", processName ); |
379 | | - |
380 | | - DWORD pid = 0; |
381 | | - |
382 | | - // Wait for a process with the target name to spawn |
383 | | - while (!pid) |
384 | | - { |
385 | | - const scoped_handle snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); |
386 | | - |
387 | | - PROCESSENTRY32W process = { sizeof(process) }; |
388 | | - for (BOOL next = Process32FirstW(snapshot, &process); next; next = Process32NextW(snapshot, &process)) |
389 | | - { |
390 | | - |
391 | | - // if (wcscmp(processName , process.szExeFile) <= 0) |
392 | | - if (wcsspn(process.szExeFile, processName ) == wcslen(process.szExeFile) - 4) |
393 | | - { |
394 | | - pid = process.th32ProcessID; |
395 | | - break; |
396 | | - } |
397 | | - } |
398 | | - |
399 | | - Sleep(1); // Sleep a bit to not overburden the CPU |
400 | | - } |
401 | | - |
402 | | - wprintf(L"Found a matching process with PID %lu! Injecting ReShade ... ", pid); |
403 | | - |
404 | | - // Wait just a little bit for the application to initialize |
405 | | - Sleep(50); |
406 | | - |
407 | | - // Open target application process |
408 | | - const scoped_handle remote_process = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, pid); |
409 | | - if (remote_process == nullptr) |
410 | | - { |
411 | | - wprintf(L"\nFailed to open target application process!\n"); |
412 | | - return GetLastError(); |
413 | | - } |
| 181 | + //else |
| 182 | + //{ |
| 183 | + // auto load_path = std::filesystem::path(argv[2]); |
| 184 | + // if (load_path.has_stem()) |
| 185 | + // load_path = load_path.parent_path(); |
| 186 | + // SetCurrentDirectory(load_path.c_str()); |
| 187 | + // wcscat_s(arg.load_path, L"\\"); |
| 188 | + // wcscat_s(arg.load_path, remote_is_wow64 ? L"ReShade32.dll" : L"ReShade64.dll"); |
| 189 | + //} |
414 | 190 |
|
415 | | - // Check process architecture |
416 | | - BOOL remote_is_wow64 = FALSE; |
417 | | - IsWow64Process(remote_process, &remote_is_wow64); |
418 | | -#ifndef _WIN64 |
419 | | - if (remote_is_wow64 == FALSE) |
420 | | -#else |
421 | | - if (remote_is_wow64 != FALSE) |
422 | | -#endif |
423 | | - { |
424 | | - wprintf(L"\nProcess architecture does not match injection tool! Cannot continue.\n"); |
425 | | - return ERROR_IMAGE_MACHINE_TYPE_MISMATCH; |
426 | | - } |
427 | | - |
428 | | - loading_data arg; |
429 | | - GetCurrentDirectoryW(MAX_PATH, arg.load_path); |
430 | | - wcscat_s(arg.load_path, L"\\"); |
431 | | - wcscat_s(arg.load_path, remote_is_wow64 ? L"ReShade32.dll" : L"ReShade64.dll"); |
432 | 191 |
|
433 | 192 | if (GetFileAttributesW(arg.load_path) == INVALID_FILE_ATTRIBUTES) |
434 | 193 | { |
|
0 commit comments