c ++我如何获得当前的控制台conhost进程
c++ how do i get the current console conhost process
我在 "how i get the conhost process"
之后搜索了很多网站,但没有一个是我真正想要的。
我搜索过
superuser/Whosebug
when-is-conhost-exe-actually-necessary
Whosebug
how-can-a-win32-process-get-the-pid-of-its-parent
Whosebug
c-how-to-fetch-parent-process-id
Whosebug
c-how-to-determine-if-a-windows-process-is-running
Whosebug
get-full-running-process-list-visual-c
Whosebug
ms-c-get-pid-of-current-process
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
我找不到关于 "how to get the conhost process"
的任何信息。
我有一些适用于当前 "cmd.exe / program.exe"
的代码,它给了我 "PID, NAME, PATH, READ/WRITE ADDRESS"
.
我可以得到 parent
过程,但那不是 conhost.exe
。
代码"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;
}
而且我想不出获取当前 conhost
进程的方法。
当您打开使用控制台的 program
时,会创建一个 conhost.exe
进程。
我的问题是如何获得 conhost.exe
流程...
谢谢! :)
想到的一种方法是获取CMD.EXE进程的开始时间。然后遍历所有 CONHOST 进程,寻找相同(或非常接近)的开始时间。
作为概念验证,下载并安装 Process Explorer。在 ProcExp 中找到您的 CMD.EXE 进程,然后查看“属性”、“图像”选项卡。注意开始时间。然后查看每个 CONHOST 进程,寻找同时启动的进程。
请注意,ProcExp 显示 1 秒的分辨率,但是 API ProcExp 使用的任何底层都可能具有更好的分辨率。
您可能需要 google 了解一些 API(s) ProcExp 使用什么来收集进程启动时间。此外,您还可以使用多种工具来查看 API 可执行文件(在本例中为 ProcExp)导入的内容。您可以从 ProcExp 导入的 API 个名称中推断出哪些名称将提供进程的开始时间。
如果您仍然需要它(阅读评论后),这里有一段代码可以获取 conhost.exe 进程。请注意,我写它只是为了演示目的(检查 [MSDN]: Tool Help Functions 是否可以用于这种情况),所以不要介意它的结构或其他编码 NO-NOs.
code.c:
#include <Windows.h>
#include <TlHelp32.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.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 = INVALID_HANDLE_VALUE;
char c = 0;
if (argc > 1) {
pid = atoi(argv[1]);
} else {
pid = GetCurrentProcessId();
}
printf("PID: %d\n", pid);
snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, pid);
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 ((proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, cPid)) == INVALID_HANDLE_VALUE) {
printf("OpenProcess failed: %d\n", GetLastError());
return -3;
}
printf("Conhost handle: 0x%08X\n", proc);
CloseHandle(proc);
printf("Press a key to exit...\n");
c = getch();
return 0;
}
输出(作为 VStudio 2010、控制台应用程序(调试 - Win 10 上的 x86):
e:\Work\Dev\Whosebug\q035102238>ver
Microsoft Windows [Version 10.0.17134.48]
e:\Work\Dev\Whosebug\q035102238>"Debug\q035102238.exe"
PID: 22388
Idx: 00 PID: 19892 PPID: 20164 Name: conhost.exe
Idx: 01 PID: 21128 PPID: 21120 Name: conhost.exe
Idx: 02 PID: 1144 PPID: 20572 Name: conhost.exe
Idx: 03 PID: 8184 PPID: 19572 Name: conhost.exe
Idx: 04 PID: 10976 PPID: 20608 Name: conhost.exe
Idx: 05 PID: 21284 PPID: 8792 Name: conhost.exe
Idx: 06 PID: 8172 PPID: 20444 Name: conhost.exe
Idx: 07 PID: 4396 PPID: 19484 Name: conhost.exe
Idx: 08 PID: 12484 PPID: 2580 Name: conhost.exe
Idx: 09 PID: 18636 PPID: 11552 Name: conhost.exe
Idx: 10 PID: 21456 PPID: 21016 Name: conhost.exe
Idx: 11 PID: 960 PPID: 3528 Name: conhost.exe
Idx: 12 PID: 20616 PPID: 18404 Name: conhost.exe
Idx: 13 PID: 21548 PPID: 21528 Name: conhost.exe
Idx: 14 PID: 20192 PPID: 8316 Name: conhost.exe
Idx: 15 PID: 2496 PPID: 9284 Name: conhost.exe
Idx: 16 PID: 5820 PPID: 23140 Name: conhost.exe
Idx: 17 PID: 6032 PPID: 26512 Name: conhost.exe
Connhost handle: 0x00000000
Press a key to exit...
所以,可以枚举所有运行conhost.exe个进程,也可以PROCESS_ALL_ACCESS
到与我当前关联的进程应用程序(我必须在这里提到我的 Win 用户拥有完全的管理权限)。
@EDIT0:
- 正如@BladeMight 所注意到的,在 Win 7 all conhost.exe 进程是 crss.exe 的 children(在 ProcExp 中也可以看到)
输出:
c:\Work\Dev\Whosebug\q035102238>ver
Microsoft Windows [Version 6.1.7601]
c:\Work\Dev\Whosebug\q035102238>q035102238.exe
PID: 1548
Idx: 00 PID: 4960 PPID: 3472 Name: conhost.exe
Idx: 01 PID: 5024 PPID: 3472 Name: conhost.exe
Idx: 02 PID: 5076 PPID: 3472 Name: conhost.exe
Idx: 03 PID: 2676 PPID: 3472 Name: conhost.exe
Idx: 04 PID: 1888 PPID: 3472 Name: conhost.exe
Connhost handle: 0x00000000
Press a key to exit...
这里有一些令人难以置信的令人费解的答案。使用进程资源管理器获取控制台应用程序的pid,然后在kd -kl
中执行以下操作
lkd> !process 0n16592 0
Searching for Process with Cid == 40d0
Cid handle table at fffff8a001db8000 with 4368 entries in use
PROCESS fffffa8042eb9590
.
.
.
lkd> .process /P fffffa8042eb9590
Implicit process is now fffffa80`42eb9590
lkd> !peb
PEB at 000007fffffd3000
.
.
.
ProcessParameters: 0000000000202880
.
.
.
lkd> dt nt!_RTL_USER_PROCESS_PARAMETERS 0000000000202880
.
.
.
+0x010 ConsoleHandle : 0x00000000`00003d98 Void
+0x018 ConsoleFlags : 0
+0x020 StandardInput : 0x00000000`00000003 Void
+0x028 StandardOutput : 0x00000000`00000007 Void
+0x030 StandardError : 0x00000000`0000000b Void
.
.
.
.
lkd> ? 0x3d98
Evaluate expression: 15768 = 00000000`00003d98
这是它附加到的 conhost 进程的 pid。在 C++ 中,您必须获取当前的 PEB,看看如何以编程方式完成 here, study the structure of the PEB and ParameterBlock and then you'll know how to get the parameter block and at what offset it is in the parameter block. You can use the type definition for _PEB
and _RTL_USER_PROCESS_PARAMETERS
in winternl.h
or the one here,或者使用 ntkrnlmp.pdb 符号编写您自己的 PEB。
我在 "how i get the conhost process"
之后搜索了很多网站,但没有一个是我真正想要的。
我搜索过
superuser/Whosebug
when-is-conhost-exe-actually-necessaryWhosebug
how-can-a-win32-process-get-the-pid-of-its-parentWhosebug
c-how-to-fetch-parent-process-idWhosebug
c-how-to-determine-if-a-windows-process-is-runningWhosebug
get-full-running-process-list-visual-cWhosebug
ms-c-get-pid-of-current-processcodeproject
Get-Parent-Process-PIDcplusplus
Getting list of running processesmsdn.microsoft
GetModuleFileNameExmsdn.microsoft
GetModuleFileNamemsdn.microsoft
GetCurrentProcessIdmsdn.microsoft
GetProcessIdmsdn.microsoft
GetModuleHandlemsdn.microsoft
GetConsoleWindowmsdn.microsoft
Tool Helpmsdn.microsoft
CreateToolhelp32Snapshotmsdn.microsoft
NextModule32msdn.microsoft
DebugActiveProcessmsdn.microsoft
Enumerating All Modules For a Process
我找不到关于 "how to get the conhost process"
的任何信息。
我有一些适用于当前 "cmd.exe / program.exe"
的代码,它给了我 "PID, NAME, PATH, READ/WRITE ADDRESS"
.
我可以得到 parent
过程,但那不是 conhost.exe
。
代码"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;
}
而且我想不出获取当前 conhost
进程的方法。
当您打开使用控制台的 program
时,会创建一个 conhost.exe
进程。
我的问题是如何获得 conhost.exe
流程...
谢谢! :)
想到的一种方法是获取CMD.EXE进程的开始时间。然后遍历所有 CONHOST 进程,寻找相同(或非常接近)的开始时间。
作为概念验证,下载并安装 Process Explorer。在 ProcExp 中找到您的 CMD.EXE 进程,然后查看“属性”、“图像”选项卡。注意开始时间。然后查看每个 CONHOST 进程,寻找同时启动的进程。
请注意,ProcExp 显示 1 秒的分辨率,但是 API ProcExp 使用的任何底层都可能具有更好的分辨率。
您可能需要 google 了解一些 API(s) ProcExp 使用什么来收集进程启动时间。此外,您还可以使用多种工具来查看 API 可执行文件(在本例中为 ProcExp)导入的内容。您可以从 ProcExp 导入的 API 个名称中推断出哪些名称将提供进程的开始时间。
如果您仍然需要它(阅读评论后),这里有一段代码可以获取 conhost.exe 进程。请注意,我写它只是为了演示目的(检查 [MSDN]: Tool Help Functions 是否可以用于这种情况),所以不要介意它的结构或其他编码 NO-NOs.
code.c:
#include <Windows.h>
#include <TlHelp32.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.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 = INVALID_HANDLE_VALUE;
char c = 0;
if (argc > 1) {
pid = atoi(argv[1]);
} else {
pid = GetCurrentProcessId();
}
printf("PID: %d\n", pid);
snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, pid);
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 ((proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, cPid)) == INVALID_HANDLE_VALUE) {
printf("OpenProcess failed: %d\n", GetLastError());
return -3;
}
printf("Conhost handle: 0x%08X\n", proc);
CloseHandle(proc);
printf("Press a key to exit...\n");
c = getch();
return 0;
}
输出(作为 VStudio 2010、控制台应用程序(调试 - Win 10 上的 x86):
e:\Work\Dev\Whosebug\q035102238>ver Microsoft Windows [Version 10.0.17134.48] e:\Work\Dev\Whosebug\q035102238>"Debug\q035102238.exe" PID: 22388 Idx: 00 PID: 19892 PPID: 20164 Name: conhost.exe Idx: 01 PID: 21128 PPID: 21120 Name: conhost.exe Idx: 02 PID: 1144 PPID: 20572 Name: conhost.exe Idx: 03 PID: 8184 PPID: 19572 Name: conhost.exe Idx: 04 PID: 10976 PPID: 20608 Name: conhost.exe Idx: 05 PID: 21284 PPID: 8792 Name: conhost.exe Idx: 06 PID: 8172 PPID: 20444 Name: conhost.exe Idx: 07 PID: 4396 PPID: 19484 Name: conhost.exe Idx: 08 PID: 12484 PPID: 2580 Name: conhost.exe Idx: 09 PID: 18636 PPID: 11552 Name: conhost.exe Idx: 10 PID: 21456 PPID: 21016 Name: conhost.exe Idx: 11 PID: 960 PPID: 3528 Name: conhost.exe Idx: 12 PID: 20616 PPID: 18404 Name: conhost.exe Idx: 13 PID: 21548 PPID: 21528 Name: conhost.exe Idx: 14 PID: 20192 PPID: 8316 Name: conhost.exe Idx: 15 PID: 2496 PPID: 9284 Name: conhost.exe Idx: 16 PID: 5820 PPID: 23140 Name: conhost.exe Idx: 17 PID: 6032 PPID: 26512 Name: conhost.exe Connhost handle: 0x00000000 Press a key to exit...
所以,可以枚举所有运行conhost.exe个进程,也可以PROCESS_ALL_ACCESS
到与我当前关联的进程应用程序(我必须在这里提到我的 Win 用户拥有完全的管理权限)。
@EDIT0:
- 正如@BladeMight 所注意到的,在 Win 7 all conhost.exe 进程是 crss.exe 的 children(在 ProcExp 中也可以看到)
输出:
c:\Work\Dev\Whosebug\q035102238>ver Microsoft Windows [Version 6.1.7601] c:\Work\Dev\Whosebug\q035102238>q035102238.exe PID: 1548 Idx: 00 PID: 4960 PPID: 3472 Name: conhost.exe Idx: 01 PID: 5024 PPID: 3472 Name: conhost.exe Idx: 02 PID: 5076 PPID: 3472 Name: conhost.exe Idx: 03 PID: 2676 PPID: 3472 Name: conhost.exe Idx: 04 PID: 1888 PPID: 3472 Name: conhost.exe Connhost handle: 0x00000000 Press a key to exit...
这里有一些令人难以置信的令人费解的答案。使用进程资源管理器获取控制台应用程序的pid,然后在kd -kl
lkd> !process 0n16592 0
Searching for Process with Cid == 40d0
Cid handle table at fffff8a001db8000 with 4368 entries in use
PROCESS fffffa8042eb9590
.
.
.
lkd> .process /P fffffa8042eb9590
Implicit process is now fffffa80`42eb9590
lkd> !peb
PEB at 000007fffffd3000
.
.
.
ProcessParameters: 0000000000202880
.
.
.
lkd> dt nt!_RTL_USER_PROCESS_PARAMETERS 0000000000202880
.
.
.
+0x010 ConsoleHandle : 0x00000000`00003d98 Void
+0x018 ConsoleFlags : 0
+0x020 StandardInput : 0x00000000`00000003 Void
+0x028 StandardOutput : 0x00000000`00000007 Void
+0x030 StandardError : 0x00000000`0000000b Void
.
.
.
.
lkd> ? 0x3d98
Evaluate expression: 15768 = 00000000`00003d98
这是它附加到的 conhost 进程的 pid。在 C++ 中,您必须获取当前的 PEB,看看如何以编程方式完成 here, study the structure of the PEB and ParameterBlock and then you'll know how to get the parameter block and at what offset it is in the parameter block. You can use the type definition for _PEB
and _RTL_USER_PROCESS_PARAMETERS
in winternl.h
or the one here,或者使用 ntkrnlmp.pdb 符号编写您自己的 PEB。