-
-
Save datadiode/a56bc5237a0f642b8514bb78b34c881d to your computer and use it in GitHub Desktop.
Find Tmmon hooked thread and kill it (CPU usage too high...) (Use task manager to execute it as System previlege)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// KillTmmonThread.cpp : Defines the entry point for the console application. | |
// | |
#include "stdafx.h" | |
#include <stdio.h> | |
#include <windows.h> | |
#include <tlhelp32.h> | |
#include <tchar.h> | |
#include <Shlwapi.h> | |
#include <string> | |
#include <psapi.h> | |
FILE *ob; | |
bool bkg = false; | |
void GetProcessName( DWORD processID, __out_bcount(MAX_PATH + 1) LPTSTR lpstrModule ) | |
{ | |
// Get a handle to the process. | |
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | | |
PROCESS_VM_READ, | |
FALSE, processID ); | |
// Get the process name. | |
if (NULL != hProcess ) | |
{ | |
HMODULE hMod; | |
DWORD cbNeeded; | |
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), | |
&cbNeeded) ) | |
{ | |
GetModuleBaseName( hProcess, hMod, lpstrModule, | |
MAX_PATH + 1 ); | |
} | |
} | |
CloseHandle( hProcess ); | |
} | |
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) | |
#define ThreadQuerySetWin32StartAddress 9 | |
typedef NTSTATUS (WINAPI *NTQUERYINFOMATIONTHREAD)(HANDLE, LONG, DWORD_PTR*, ULONG, PULONG); | |
BOOL MatchAddressToModule(__in DWORD dwProcId, __out_bcount(MAX_PATH + 1) LPTSTR lpstrModule, __in DWORD_PTR pThreadStartAddr, __out_opt DWORD_PTR *pModuleStartAddr) // by Echo | |
{ | |
BOOL bRet = FALSE; | |
HANDLE hSnapshot; | |
MODULEENTRY32 moduleEntry32; | |
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE |TH32CS_SNAPMODULE32 | TH32CS_SNAPALL, dwProcId); | |
if (hSnapshot != INVALID_HANDLE_VALUE) | |
{ | |
moduleEntry32.dwSize = sizeof(MODULEENTRY32); | |
moduleEntry32.th32ModuleID = 1; | |
if(Module32First(hSnapshot, &moduleEntry32)){ | |
if(pThreadStartAddr >= (DWORD_PTR)moduleEntry32.modBaseAddr && pThreadStartAddr <= ((DWORD_PTR)moduleEntry32.modBaseAddr + moduleEntry32.modBaseSize)){ | |
_tcscpy(lpstrModule, moduleEntry32.szModule); | |
bRet = TRUE; | |
}else{ | |
while(Module32Next(hSnapshot, &moduleEntry32)){ | |
if(pThreadStartAddr >= (DWORD_PTR)moduleEntry32.modBaseAddr && pThreadStartAddr <= ((DWORD_PTR)moduleEntry32.modBaseAddr + moduleEntry32.modBaseSize)){ | |
_tcscpy(lpstrModule, moduleEntry32.szModule); | |
bRet = TRUE; | |
break; | |
} | |
if (bkg) Sleep(1); | |
} | |
} | |
} | |
if(pModuleStartAddr) *pModuleStartAddr = (DWORD_PTR)moduleEntry32.modBaseAddr; | |
CloseHandle(hSnapshot); | |
} | |
return bRet; | |
} | |
DWORD_PTR WINAPI GetThreadStartAddress(__in HANDLE hThread) // by Echo | |
{ | |
NTSTATUS ntStatus; | |
DWORD_PTR pThreadStartAddr = 0; | |
HANDLE hPeusdoCurrentProcess, hNewThreadHandle; | |
NTQUERYINFOMATIONTHREAD NtQueryInformationThread; | |
if((NtQueryInformationThread = (NTQUERYINFOMATIONTHREAD)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryInformationThread"))){ | |
hPeusdoCurrentProcess = GetCurrentProcess(); | |
if(DuplicateHandle(hPeusdoCurrentProcess, hThread, hPeusdoCurrentProcess, &hNewThreadHandle, THREAD_QUERY_INFORMATION, FALSE, 0)){ | |
ntStatus = NtQueryInformationThread(hNewThreadHandle, ThreadQuerySetWin32StartAddress, &pThreadStartAddr, sizeof(DWORD_PTR), NULL); | |
CloseHandle(hNewThreadHandle); | |
if(ntStatus != STATUS_SUCCESS) return 0; | |
} | |
} | |
return pThreadStartAddr; | |
} | |
int _tmain(int argc, _TCHAR* argv[]) | |
{ | |
if (argc > 1 && argv[1][0]) | |
ob = _wfopen(argv[1], L"w"); | |
else | |
ob = stdout; | |
if (argc > 2 && argv[2][0] == L'b') | |
bkg = true; | |
if (bkg) | |
SetPriorityClass(GetCurrentProcess(), PROCESS_MODE_BACKGROUND_BEGIN); | |
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); | |
if (h != INVALID_HANDLE_VALUE) { | |
THREADENTRY32 te; | |
te.dwSize = sizeof(te); | |
if (Thread32First(h, &te)) { | |
std::wstring procName; | |
do { | |
if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + | |
sizeof(te.th32OwnerProcessID)) { | |
TCHAR lpstrProcessName[MAX_PATH + 1] = {0}; | |
GetProcessName(te.th32OwnerProcessID, lpstrProcessName); | |
if (procName != lpstrProcessName) | |
fprintf(ob, "Process 0x%08x %ls \n", te.th32OwnerProcessID, lpstrProcessName); | |
procName = lpstrProcessName; | |
HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION | THREAD_TERMINATE, FALSE, te.th32ThreadID); | |
if (hThread) | |
{ | |
DWORD_PTR pThreadStartAddr = GetThreadStartAddress(hThread); | |
if (pThreadStartAddr) | |
{ | |
DWORD_PTR pModuleBaseAddr; | |
TCHAR lpstrModuleName[MAX_PATH + 1] = {0}; | |
if (MatchAddressToModule(te.th32OwnerProcessID, lpstrModuleName, pThreadStartAddr, &pModuleBaseAddr)) | |
{ | |
std::wstring module = lpstrModuleName; | |
if (module == L"tmmon.dll" || module == L"tmmonmgr.dll" || | |
module == L"tmmon64.dll" || module == L"tmmonmgr64.dll") | |
{ | |
BOOL killed = TerminateThread(hThread, 0L); | |
fprintf(ob, "\t [%s] Thread 0x%08x %ls+0x%016x\n", | |
killed ? "KILLED" : "FAILED", te.th32ThreadID, module.c_str(), (DWORD_PTR)pThreadStartAddr - pModuleBaseAddr); | |
} | |
} | |
} | |
CloseHandle(hThread); | |
} | |
} | |
te.dwSize = sizeof(te); | |
if (bkg) Sleep(1); | |
} while (Thread32Next(h, &te)); | |
} | |
CloseHandle(h); | |
} | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment