From a8c696c565106d2324913bbcdcbef0271767674b Mon Sep 17 00:00:00 2001 From: redpolline <11156324-redpolline@users.noreply.gitlab.com> Date: Mon, 24 Jun 2024 03:57:16 -0400 Subject: [PATCH] Fix detours not attaching to all threads on startup. --- dll/base.cpp | 49 ++++++++++++++++++++++++++++++++++++++++--- dll/common_includes.h | 1 + 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/dll/base.cpp b/dll/base.cpp index 10d3622..5363e6d 100644 --- a/dll/base.cpp +++ b/dll/base.cpp @@ -841,16 +841,55 @@ HINTERNET WINAPI Mine_WinHttpOpenRequest( return Real_WinHttpOpenRequest(hConnect, pwszVerb, pwszObjectName, pwszVersion, pwszReferrer, ppwszAcceptTypes, dwFlags); } - - static bool network_functions_attached = false; +std::vector detours_threads; + BOOL WINAPI DllMain( HINSTANCE, DWORD dwReason, LPVOID ) { switch ( dwReason ) { case DLL_PROCESS_ATTACH: if (!file_exists(get_full_program_path() + "disable_lan_only.txt") && !file_exists(get_full_program_path() + "\\steam_settings\\disable_lan_only.txt")) { PRINT_DEBUG("Hooking lan only functions\n"); DetourTransactionBegin(); - DetourUpdateThread( GetCurrentThread() ); + HANDLE toolHelp = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if (toolHelp != INVALID_HANDLE_VALUE) { + THREADENTRY32 te; + te.dwSize = sizeof(THREADENTRY32); + if (Thread32First(toolHelp, &te)) { + bool bUpdatedThread = false; + DWORD myPID = GetCurrentProcessId(); + DWORD myTID = GetCurrentThreadId(); + HANDLE tHandle; + do { + if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32OwnerProcessID)) { + if (te.th32OwnerProcessID == myPID) { + if (te.th32ThreadID != myTID) { + tHandle = OpenThread(THREAD_ALL_ACCESS, false, te.th32ThreadID); + if (tHandle != NULL) { + PRINT_DEBUG("Hooking thread %d\n", te.th32ThreadID); + detours_threads.push_back( tHandle ); + DetourUpdateThread( tHandle ); + bUpdatedThread = true; + } else { + PRINT_DEBUG("Unable to hook thread %d\n", te.th32ThreadID); + } + } else {//hooking non-pseudo current thread handle is unsupported. + PRINT_DEBUG("Hooking thread %d\n", myTID); + DetourUpdateThread( GetCurrentThread() ); + bUpdatedThread = true; + } + } + } + te.dwSize = sizeof(THREADENTRY32); + } while (Thread32Next(toolHelp, &te)); + } else { + PRINT_DEBUG("Unable to iterate thread list, only hooking current thread\n"); + DetourUpdateThread( GetCurrentThread() ); + } + CloseHandle(toolHelp); + } else { + PRINT_DEBUG("Unable to get thread list, only hooking current thread\n"); + DetourUpdateThread( GetCurrentThread() ); + } DetourAttach( &(PVOID &)Real_SendTo, Mine_SendTo ); DetourAttach( &(PVOID &)Real_Connect, Mine_Connect ); DetourAttach( &(PVOID &)Real_WSAConnect, Mine_WSAConnect ); @@ -871,8 +910,12 @@ BOOL WINAPI DllMain( HINSTANCE, DWORD dwReason, LPVOID ) { break; case DLL_PROCESS_DETACH: + std::vector::iterator it; if (network_functions_attached) { DetourTransactionBegin(); + for (it = detours_threads.begin(); it != detours_threads.end(); it++) { + DetourUpdateThread( *it ); + } DetourUpdateThread( GetCurrentThread() ); DetourDetach( &(PVOID &)Real_SendTo, Mine_SendTo ); DetourDetach( &(PVOID &)Real_Connect, Mine_Connect ); diff --git a/dll/common_includes.h b/dll/common_includes.h index bf9b815..cf3e4c7 100644 --- a/dll/common_includes.h +++ b/dll/common_includes.h @@ -86,6 +86,7 @@ #ifdef EMU_EXPERIMENTAL_BUILD #include + #include #include "../detours/detours.h" #endif