3
I want to suspend a specific thread from a C++ process by Startaddress. My code already suspends some threads of the process, but others do not... It seems that this only happens to address that have something after the extension other than the address.
An example of the thread I want to suspend: https://prnt.sc/m9vcef
MY PROBLEM
It works only on some start address, example: "Calc.exe+0x1b9b8", now if it’s, "Calc.exe! globalDllIndex+0xac3b08" doesn’t work.
Please can anyone see my code and see what’s missing? I have no idea what it is.
My code:
#pragma comment( lib, "psapi" )
enum THREADINFOCLASS
{
ThreadQuerySetWin32StartAddress = 9,
};
typedef NTSTATUS(__stdcall * f_NtQueryInformationThread)(HANDLE, THREADINFOCLASS, void*, ULONG_PTR, ULONG_PTR*);
ULONG_PTR GetThreadStartAddress(HANDLE hThread)
{
auto NtQueryInformationThread = reinterpret_cast<f_NtQueryInformationThread>(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryInformationThread"));
if (!NtQueryInformationThread)
return 0;
ULONG_PTR ulStartAddress = 0;
NTSTATUS Ret = NtQueryInformationThread(hThread, ThreadQuerySetWin32StartAddress, &ulStartAddress, sizeof(ULONG_PTR), nullptr);
if (Ret)
return 0;
return ulStartAddress;
}
bool SuspendThreadByStartaddress(ULONG_PTR StartAddress, DWORD dwProcId)
{
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (!hSnap)
return false;
THREADENTRY32 TE32 = { 0 };
TE32.dwSize = sizeof(THREADENTRY32);
BOOL Ret = Thread32First(hSnap, &TE32);
while (Ret)
{
if (TE32.th32OwnerProcessID == dwProcId)
{
HANDLE hTempThread = OpenThread(THREAD_ALL_ACCESS, FALSE, TE32.th32ThreadID);
if (!hTempThread)
continue;
if (StartAddress == GetThreadStartAddress(hTempThread))
{
SuspendThread(hTempThread);
CloseHandle(hTempThread);
CloseHandle(hSnap);
return true;
}
}
Ret = Thread32Next(hSnap, &TE32);
}
CloseHandle(hSnap);
return false;
}
uintptr_t dwGetModuleBaseAddress(DWORD procId, const char* modName)
{
uintptr_t modBaseAddr = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
if (hSnap != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 modEntry;
modEntry.dwSize = sizeof(modEntry);
if (Module32First(hSnap, &modEntry))
{
do
{
if (strcmp(modEntry.szModule, modName) == 0)
{
modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
break;
}
} while (Module32Next(hSnap, &modEntry));
}
}
CloseHandle(hSnap);
return modBaseAddr;
}
int main()
{
HWND tibiaWindow;
HANDLE hProcess;
DWORD PID;
tibiaWindow = FindWindow(NULL, "TitleName Process");
if (!tibiaWindow) {
cout << "Cannot found process...\n";
}
else {;
GetWindowThreadProcessId(tibiaWindow, &PID);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
uintptr_t base = dwGetModuleBaseAddress(PID, "MyModuleDll.dll");
SuspendThreadByStartaddress(base + 0xac3b08, PID);
}
getchar();
}
Anyone have any suggestions? Thanks
How do you know you’re not getting the thread suspended? My code does exactly that and it works.
– lsalamon
Could you send a printscreen? It only works on some start address, example: "Calc.exe+0x1b9b8", now if it is, "Calc.exe! globalDllIndex+0xac3b08" does not work. You can help me?
– Dansh
In my case I use only the ID of the thread I want to suspend, without entering the merit of addresses. So it always works. Try looking at the application source code Process Hacker. Good luck.
– lsalamon