From 4cfe39ff05cfd9917509e7e6f7971e0a4054b702 Mon Sep 17 00:00:00 2001 From: Adam Simon Date: Sun, 10 Apr 2022 20:14:16 +0200 Subject: [PATCH] introduces DetourUpdateAllOtherThreads --- src/detours.cpp | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ src/detours.h | 2 ++ 2 files changed, 74 insertions(+) diff --git a/src/detours.cpp b/src/detours.cpp index 954050f7..a6f39e97 100644 --- a/src/detours.cpp +++ b/src/detours.cpp @@ -1524,6 +1524,28 @@ struct DetourThread { DetourThread * pNext; HANDLE hThread; + BOOL fCloseThreadHandleOnDestroy; + + DetourThread() + { + pNext = NULL; + hThread = NULL; + fCloseThreadHandleOnDestroy = FALSE; + } + + DetourThread(const DetourThread&) = delete; + DetourThread& operator= (const DetourThread&) = delete; + + ~DetourThread() + { + if (hThread) { + if (fCloseThreadHandleOnDestroy) { + CloseHandle(hThread); + } + + hThread = NULL; + } + } }; struct DetourOperation @@ -1946,6 +1968,11 @@ typedef ULONG_PTR DETOURS_EIP_TYPE; } LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread) +{ + return DetourUpdateThreadEx(hThread, FALSE); +} + +LONG WINAPI DetourUpdateThreadEx(_In_ HANDLE hThread, _In_ BOOL fCloseThreadHandleOnDestroy) { LONG error; @@ -1980,12 +2007,57 @@ LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread) } t->hThread = hThread; + t->fCloseThreadHandleOnDestroy = fCloseThreadHandleOnDestroy; t->pNext = s_pPendingThreads; s_pPendingThreads = t; return NO_ERROR; } +#ifndef NT_SUCCESS +#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +#endif + +#define STATUS_NO_MORE_ENTRIES 0x8000001A + +typedef NTSTATUS(NTAPI *_NtGetNextThread)( + _In_ HANDLE ProcessHandle, + _In_ HANDLE ThreadHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ ULONG HandleAttributes, + _In_ ULONG Flags, + _Out_ PHANDLE NewThreadHandle +); + +LONG WINAPI DetourUpdateAllOtherThreads() +{ + _NtGetNextThread NtGetNextThread = (_NtGetNextThread)GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtGetNextThread"); + if (!NtGetNextThread) { + DETOUR_TRACE("Failed to determine NtGetNextThread address.\r\n"); + return GetLastError(); + } + + DWORD currentThreadId = GetCurrentThreadId(); + + HANDLE hThread = NULL; + for (;;) { + NTSTATUS status = NtGetNextThread(GetCurrentProcess(), hThread, THREAD_QUERY_LIMITED_INFORMATION | THREAD_SUSPEND_RESUME, 0, 0, &hThread); + + if (!NT_SUCCESS(status)) { + if (status != STATUS_NO_MORE_ENTRIES) { + DETOUR_TRACE("Failed to enumerate process threads.\r\n"); + return ERROR_FUNCTION_FAILED; + } + + return NO_ERROR; + } + + if (currentThreadId != GetThreadId(hThread)) { + DetourUpdateThreadEx(hThread, TRUE); + } + } +} + ///////////////////////////////////////////////////////////// Transacted APIs. // LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer, diff --git a/src/detours.h b/src/detours.h index 38b3dc81..463f0476 100644 --- a/src/detours.h +++ b/src/detours.h @@ -558,6 +558,8 @@ LONG WINAPI DetourTransactionCommit(VOID); LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer); LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread); +LONG WINAPI DetourUpdateThreadEx(_In_ HANDLE hThread, _In_ BOOL fCloseThreadHandleOnDestroy); +LONG WINAPI DetourUpdateAllOtherThreads(); LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer, _In_ PVOID pDetour);