Thread Enumerator

Este programa enumera todos los hilos (threads) pertenecientes a un proceso específico en Windows. Primero localiza el proceso objetivo por su nombre utilizando CreateToolhelp32Snapshot junto con las funciones Process32FirstW y Process32NextW para obtener su PID. Una vez encontrado el proceso, crea otro snapshot del sistema con la bandera TH32CS_SNAPTHREAD y recorre todos los hilos mediante Thread32First y Thread32Next, filtrando aquellos cuyo th32OwnerProcessID coincide con el PID del proceso objetivo. Por cada hilo encontrado, muestra su ID de hilo (Thread ID)

#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>

BOOL enumThreads(DWORD processID) {
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);

    if (hSnap == INVALID_HANDLE_VALUE) {
        puts("[!] Error obtaining thread processes");
        return FALSE;
    }

    THREADENTRY32 te;
    te.dwSize = sizeof(THREADENTRY32);

    if (!Thread32First(hSnap, &te)) {
        puts("[!] There is no first thread");
        CloseHandle(hSnap);
        return FALSE;
    }

    do {
        if (te.th32OwnerProcessID == processID) {
            printf("[*] Thread ID: %lu\n", te.th32ThreadID);
        }
    } while (Thread32Next(hSnap, &te));

    CloseHandle(hSnap);
    return TRUE;
}

BOOL getProcessId(LPCWSTR processName, DWORD *pidProcesoOut) {
    // Usando createtoolhelp para snapear procesos
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnap == INVALID_HANDLE_VALUE) {
        wprintf(L"[!] Error obtaining process snapshot\n");
        return FALSE;
    }

    PROCESSENTRY32W pe;
    pe.dwSize = sizeof(PROCESSENTRY32W);
    if (!Process32FirstW(hSnap, &pe)) {
        wprintf(L"[!] Error obtaining processes\n");
        CloseHandle(hSnap);
        return FALSE;
    }

    do {
        if (_wcsicmp(processName, pe.szExeFile) == 0) {
            wprintf(L"[*] Find: %ls\n", pe.szExeFile);
            *pidProcesoOut = pe.th32ProcessID;
            CloseHandle(hSnap);
            return TRUE;
        }
    } while (Process32NextW(hSnap, &pe));

    CloseHandle(hSnap);
    return FALSE;
}

int wmain(int argc, wchar_t *argv[]) {
    if (argc != 2) {
        fwprintf(stderr, L"Usage: %ls <process_name.exe>\n", argv[0]);
        fwprintf(stderr, L"Example: %ls Notion.exe\n", argv[0]);
        return 1;
    }

    LPCWSTR procName = argv[1];
    DWORD pid = 0;

    if (!getProcessId(procName, &pid)) {
        fwprintf(stderr, L"[!] Process not found: %ls\n", procName);
        return 2;
    }

    wprintf(L"[*] PID of %ls: %lu\n", procName, pid);

    if (!enumThreads(pid)) {
        fwprintf(stderr, L"[!] Failed to enumerate threads for PID %lu\n", pid);
        return 3;
    }

    return 0;
}

Última actualización