ScopedThreadExclusive::ScopedThreadExclusive(const std::vector<uintptr_t>& oldIPs, const std::vector<uintptr_t>& newIPs) { assert(("ScopedThreadExclusive::ctor", (oldIPs.size() == newIPs.size()))); GetThreads(threads_); Freeze(threads_, oldIPs, newIPs); }
TEST(libbacktrace, ptrace_threads) { pid_t pid; if ((pid = fork()) == 0) { for (size_t i = 0; i < NUM_PTRACE_THREADS; i++) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_t thread; ASSERT_TRUE(pthread_create(&thread, &attr, PtraceThreadLevelRun, NULL) == 0); } ASSERT_NE(test_level_one(1, 2, 3, 4, NULL, NULL), 0); exit(1); } // Check to see that all of the threads are running before unwinding. std::vector<pid_t> threads; uint64_t start = NanoTime(); do { usleep(US_PER_MSEC); threads.clear(); GetThreads(pid, &threads); } while ((threads.size() != NUM_PTRACE_THREADS + 1) && ((NanoTime() - start) <= 5 * NS_PER_SEC)); ASSERT_EQ(threads.size(), static_cast<size_t>(NUM_PTRACE_THREADS + 1)); ASSERT_TRUE(ptrace(PTRACE_ATTACH, pid, 0, 0) == 0); WaitForStop(pid); for (std::vector<int>::const_iterator it = threads.begin(); it != threads.end(); ++it) { // Skip the current forked process, we only care about the threads. if (pid == *it) { continue; } VerifyProcTest(pid, *it, ReadyLevelBacktrace, VerifyLevelDump); } ASSERT_TRUE(ptrace(PTRACE_DETACH, pid, 0, 0) == 0); kill(pid, SIGKILL); int status; ASSERT_EQ(waitpid(pid, &status, 0), pid); }
GETKBLAYOUT_DLL_API HKL GetConsoleAppKbLayout(DWORD console_pid) { if (Init == FALSE) return 0; int conhost_count; DWORD *conhost = FindConhost(&conhost_count); if (conhost == NULL) { OutputDebugString(TEXT("Can't enum conhost processes\n")); return 0; } if (conhost_count == 0) { OutputDebugString(TEXT("Can't find any conhost processes\n")); return 0; } DWORD conhost_pid = GetRelevantPID(conhost, conhost_count, console_pid); free(conhost); if (conhost_pid == 0) { OutputDebugString(TEXT("Can't find related conhost process\n")); return 0; } DWORD *threads = GetThreads(conhost_pid); if (threads == NULL) { OutputDebugString(TEXT("Error enumerating threads for conhost\n")); return 0; } // it seems that second thread is relevant for GetKeyboardLayout(). // second thread might be with lower TID, but it's always second in enumeration if (threads[1] == NULL) { OutputDebugString(TEXT("Too few threads in conhost process\n")); return 0; } DWORD th = threads[1]; free(threads); return GetKeyboardLayout(th); }
BOOL SuspendOtherThreads() { BOOL success = TRUE; auto myThreadId = GetCurrentThreadId(); if (!myThreadId) { printError("myThreadId = GetThreadId"); return FALSE; } auto threads = GetThreads(GetCurrentProcessId()); if (threads.size() == 0) return FALSE; for (auto t : threads) if (t.th32ThreadID != myThreadId) { HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, false, t.th32ThreadID); if (!hThread) { printError("OpenThread"); success = FALSE; continue; } if (-1 == SuspendThread(hThread)) { printError("SuspendThread"); success = FALSE; } CloseHandle(hThread); } return success; }
int _tmain(int argc, _TCHAR* argv[]) { DWORD console_pid; NTSTATUS status; if (argc != 2 || (console_pid = _wtoi(argv[1])) == 0) { printhelp(); return 0; } if ( GetConhostInit() ) { printf ( "Can't get pointers to necessary routines from ntdll.dll\n" ); return 1; } // Is not necessary to have SeDebugPrivilege to open process owned by the same user. // Normally lack of SeDebugPrivilege is not a problem. For intended use in ahk even if ahk itself is run // as administrator from nonadmin user account it will still be able to access processes // of this user account (but not processes run from admin account itself). // On the other hand on system with default settings it is impossible to get SeDebugPrivilege anyway, even for admin. status = EnableSeDebug(); if ( status != STATUS_SUCCESS ) { printf("Can't adjust privileges, code %X\n", status); } int conhost_count; DWORD *conhost = FindConhost(&conhost_count); if (conhost == NULL) { printf("Can't enum conhost processes\n"); return 1; } if (conhost_count == 0) { printf("Can't find any conhost processes\n"); return 1; } DWORD conhost_pid = GetRelevantPID(conhost, conhost_count, console_pid); free(conhost); if (conhost_pid == 0) { printf("Can't find related conhost process\n"); return 0; } DWORD *threads = GetThreads(conhost_pid); if (threads == NULL) { printf("Error enumerating threads for conhost\n"); return 0; } int i = 0; while (threads[i] != NULL) { // it seems that second thread is relevant for GetKeyboardLayout(). // second thread might be with lower TID, but it's always second in enumeration printf("TID:%04X KeyboardLayout:%04X\n", threads[i], GetKeyboardLayout(threads[i])); ++i; } free(threads); // wait scanf("%d", &i); return 0; }