Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ how do i get the current console conhost process

i have searched on so many websites after "how i get the conhost process", and nothing is really what i'm looking for.

i have searched on.

  • superuser/stackoverflow when-is-conhost-exe-actually-necessary
  • stackoverflow how-can-a-win32-process-get-the-pid-of-its-parent
  • stackoverflow c-how-to-fetch-parent-process-id
  • stackoverflow c-how-to-determine-if-a-windows-process-is-running
  • stackoverflow get-full-running-process-list-visual-c
  • stackoverflow ms-c-get-pid-of-current-process
  • stackoverflow get-list-of-dlls-loaded-in-current-process-with-their-reference-counts
  • codeproject Get-Parent-Process-PID
  • cplusplus Getting list of running processes
  • msdn.microsoft GetModuleFileNameEx
  • msdn.microsoft GetModuleFileName
  • msdn.microsoft GetCurrentProcessId
  • msdn.microsoft GetProcessId
  • msdn.microsoft GetModuleHandle
  • msdn.microsoft GetConsoleWindow
  • msdn.microsoft Tool Help
  • msdn.microsoft CreateToolhelp32Snapshot
  • msdn.microsoft NextModule32
  • msdn.microsoft DebugActiveProcess
  • msdn.microsoft Enumerating All Modules For a Process

and i can't find anything about "how to get the conhost process".

i have some code that works for the current "cmd.exe / program.exe" and that gives me the "PID, NAME, PATH, READ/WRITE ADDRESS".

i can get the parent process but that is not conhost.exe.

code "need to link library 'psapi' first":

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <psapi.h>
#include <iostream>
#include <tlhelp32.h>

int PrintModules(DWORD processID) {
    HMODULE hMods[1024];
    HANDLE hProcess;
    DWORD cbNeeded;
    unsigned int i;

    printf( "\nProcess ID: %u\n", processID);

    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
    if(NULL == hProcess) return 1;

    if(EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) {
        for(i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
            TCHAR szModName[MAX_PATH];

            if(GetModuleFileNameEx(hProcess, hMods[i], szModName,sizeof(szModName) / sizeof(TCHAR))) {
                _tprintf( TEXT("  %s (0x%08X)\n"), szModName, hMods[i]);
            }
        }
    }

    CloseHandle(hProcess);

    return 0;
}

int main(void) {
    DWORD cpid = GetCurrentProcessId();
    PrintModules(cpid);

    int ppid = -1;
    HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    PROCESSENTRY32 pe = { 0 };
    pe.dwSize = sizeof(PROCESSENTRY32);
    if(Process32First(h, &pe)) {
        do {
            if(pe.th32ProcessID == cpid) {
                printf("PID: %i; PPID: %i\n", cpid, pe.th32ParentProcessID);
                ppid = pe.th32ParentProcessID;
            }
        } while(Process32Next(h, &pe));
    }
    PrintModules(ppid);
    CloseHandle(h);
    std::cin.get();
    return 0;
}

and i can't figure out a way to get the current conhost process.

when you open a program that uses the console, a conhost.exe process is created. and my question is how do i get that conhost.exe process...

Thanks! :)

like image 385
HardCoded Avatar asked Oct 15 '25 10:10

HardCoded


2 Answers

In case you still need it (after reading the comments), here's a piece of code that gets ConHost (conhost.exe) processes. Please note that I only wrote it for demonstrative purposes (to check whether [MS.Learn]: Tool Help Functions can be used for this scenario), so don't mind its structure or other coding NO-NOs.

code00.c:

#include <Windows.h>
#include <TlHelp32.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <winternl.h>


int main(int argc, char **argv)
{
    DWORD pid = 0, i = 0, cPid = 0;
    PROCESSENTRY32 pe32;
    BOOL res = FALSE;
    HANDLE snap = INVALID_HANDLE_VALUE, proc = NULL;
    char c = 0;
    if (argc > 1) {
        pid = atoi(argv[1]);
    } else {
        pid = GetCurrentProcessId();
    }
    printf("PID: %d\n", pid);
    snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (snap == INVALID_HANDLE_VALUE) {
        printf("CreateToolhelp32Snapshot failed: %d\n", GetLastError());
        return -1;
    }
    pe32.dwSize = sizeof(PROCESSENTRY32);
    res = Process32First(snap, &pe32);
    if (res == FALSE) {
        printf("Process32First failed: %d\n", GetLastError());
        CloseHandle(snap);
        return -2;
    }
    do {
        if (_tcscmp(pe32.szExeFile, TEXT("conhost.exe")) == 0) {
            _tprintf(TEXT("    Idx: %02d,  PId: %5d,  PPId: %5d,  Name: %s\n"), i++, pe32.th32ProcessID, pe32.th32ParentProcessID, pe32.szExeFile);
            if (pe32.th32ParentProcessID == pid) {
                cPid = pe32.th32ProcessID;
            }
        }
    } while ((res = Process32Next(snap, &pe32)));
    CloseHandle(snap);

    if (cPid) {
        if ((proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, cPid)) == NULL) {
            printf("OpenProcess failed: %d\n", GetLastError());
            //return -3;
        } else {
            printf("ConHost handle: 0x%08X\n", proc);
            CloseHandle(proc);
        }
    }

    printf("Press a key to exit...\n");
    c = _getch();
    return 0;
}

So, it is possible to enumerate all running conhost.exe processes, and also get PROCESS_ALL_ACCESS to the one associated with my current application (I have to mention here that my Win user has full administrative privileges)

  • As @BladeMight noticed, on Win 7 all ConHost processes are children of crss.exe (as it can be also seen in ProcExp)

Output:

  • 1st run:

    [cfati@CFATI-5510-0:e:\Work\Dev\StackExchange\StackOverflow\q035102238]> ver
    
    Microsoft Windows [Version 10.0.19045.4355]
    
    [cfati@CFATI-5510-0:e:\Work\Dev\StackExchange\StackOverflow\q035102238]> Debug\q35102238.exe
    PID: 21460
        Idx: 00,  PId: 15004,  PPId:  6636,  Name: conhost.exe
        Idx: 01,  PId:  1996,  PPId: 14992,  Name: conhost.exe
        Idx: 02,  PId:  6964,  PPId:  7908,  Name: conhost.exe
        Idx: 03,  PId:  9620,  PPId:  3168,  Name: conhost.exe
        Idx: 04,  PId: 11828,  PPId:  3040,  Name: conhost.exe
        Idx: 05,  PId: 15832,  PPId: 15732,  Name: conhost.exe
        Idx: 06,  PId:  3276,  PPId: 11808,  Name: conhost.exe
        Idx: 07,  PId: 17336,  PPId: 17316,  Name: conhost.exe
        Idx: 08,  PId: 16284,  PPId: 15020,  Name: conhost.exe
        Idx: 09,  PId: 16908,  PPId: 16760,  Name: conhost.exe
        Idx: 10,  PId: 11220,  PPId:  5224,  Name: conhost.exe
        Idx: 11,  PId: 11832,  PPId: 15764,  Name: conhost.exe
        Idx: 12,  PId: 17460,  PPId: 17440,  Name: conhost.exe
        Idx: 13,  PId: 17808,  PPId: 17788,  Name: conhost.exe
        Idx: 14,  PId: 18216,  PPId: 18196,  Name: conhost.exe
        Idx: 15,  PId: 15736,  PPId:  3724,  Name: conhost.exe
        Idx: 16,  PId: 17852,  PPId: 17900,  Name: conhost.exe
        Idx: 17,  PId: 13068,  PPId:  6908,  Name: conhost.exe
        Idx: 18,  PId: 14116,  PPId: 12172,  Name: conhost.exe
        Idx: 19,  PId:  1564,  PPId: 10668,  Name: conhost.exe
        Idx: 20,  PId:  9592,  PPId:  9612,  Name: conhost.exe
        Idx: 21,  PId:  1364,  PPId:  9848,  Name: conhost.exe
        Idx: 22,  PId:  7040,  PPId: 16308,  Name: conhost.exe
        Idx: 23,  PId: 15484,  PPId: 22092,  Name: conhost.exe
        Idx: 24,  PId: 18996,  PPId:  2668,  Name: conhost.exe
        Idx: 25,  PId: 11108,  PPId: 19440,  Name: conhost.exe
        Idx: 26,  PId:  4792,  PPId: 25404,  Name: conhost.exe
        Idx: 27,  PId: 14948,  PPId: 20596,  Name: conhost.exe
    Press a key to exit...
    
  • Processes layout:

    Img00

  • 2nd run - passing 2668 (parent Cmd PId):

    [cfati@CFATI-5510-0:e:\Work\Dev\StackExchange\StackOverflow\q035102238]> Debug\q35102238.exe 2668
    PID: 2668
        Idx: 00,  PId: 15004,  PPId:  6636,  Name: conhost.exe
        Idx: 01,  PId:  1996,  PPId: 14992,  Name: conhost.exe
        Idx: 02,  PId:  6964,  PPId:  7908,  Name: conhost.exe
        Idx: 03,  PId:  9620,  PPId:  3168,  Name: conhost.exe
        Idx: 04,  PId: 11828,  PPId:  3040,  Name: conhost.exe
        Idx: 05,  PId: 15832,  PPId: 15732,  Name: conhost.exe
        Idx: 06,  PId:  3276,  PPId: 11808,  Name: conhost.exe
        Idx: 07,  PId: 17336,  PPId: 17316,  Name: conhost.exe
        Idx: 08,  PId: 16284,  PPId: 15020,  Name: conhost.exe
        Idx: 09,  PId: 16908,  PPId: 16760,  Name: conhost.exe
        Idx: 10,  PId: 11220,  PPId:  5224,  Name: conhost.exe
        Idx: 11,  PId: 11832,  PPId: 15764,  Name: conhost.exe
        Idx: 12,  PId: 17460,  PPId: 17440,  Name: conhost.exe
        Idx: 13,  PId: 17808,  PPId: 17788,  Name: conhost.exe
        Idx: 14,  PId: 18216,  PPId: 18196,  Name: conhost.exe
        Idx: 15,  PId: 15736,  PPId:  3724,  Name: conhost.exe
        Idx: 16,  PId: 17852,  PPId: 17900,  Name: conhost.exe
        Idx: 17,  PId: 13068,  PPId:  6908,  Name: conhost.exe
        Idx: 18,  PId: 14116,  PPId: 12172,  Name: conhost.exe
        Idx: 19,  PId:  1564,  PPId: 10668,  Name: conhost.exe
        Idx: 20,  PId:  9592,  PPId:  9612,  Name: conhost.exe
        Idx: 21,  PId:  1364,  PPId:  9848,  Name: conhost.exe
        Idx: 22,  PId:  7040,  PPId: 16308,  Name: conhost.exe
        Idx: 23,  PId: 15484,  PPId: 22092,  Name: conhost.exe
        Idx: 24,  PId: 18996,  PPId:  2668,  Name: conhost.exe
        Idx: 25,  PId: 11108,  PPId: 19440,  Name: conhost.exe
        Idx: 26,  PId:  4792,  PPId: 25404,  Name: conhost.exe
        Idx: 27,  PId: 14948,  PPId: 20596,  Name: conhost.exe
        Idx: 28,  PId: 23172,  PPId: 15672,  Name: conhost.exe
        Idx: 29,  PId: 23516,  PPId: 13352,  Name: conhost.exe
    ConHost handle: 0x000000DC
    Press a key to exit...
    
like image 125
CristiFati Avatar answered Oct 17 '25 01:10

CristiFati


One method that comes to mind is to obtain the start time of the CMD.EXE process. Then iterate through all of the CONHOST processes looking for the same (or very close) start time.

As a proof of concept download and install Process Explorer. Find your CMD.EXE process in ProcExp, then look at Properties, Image tab. Note the start time. Then look through each CONHOST process looking for one that starts at the same time.

Note that ProcExp displays 1 second resolution, but whatever underlying API ProcExp uses probably has better resolution.

You may need to google some to get an idea what API(s) ProcExp uses to gather the process start time. Additionally there are a variety of tools you can use to see what APIs an executable (ProcExp in this case) import. You may be able to deduce from the API names that ProcExp imports which one(s) would provide a process' start time.

like image 34
Χpẘ Avatar answered Oct 17 '25 01:10

Χpẘ