Skip to content

Instantly share code, notes, and snippets.

@frankyueh
Last active May 26, 2024 08:24
Show Gist options
  • Save frankyueh/52ea65bd1fd841efd226 to your computer and use it in GitHub Desktop.
Save frankyueh/52ea65bd1fd841efd226 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)
// 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