如何获取conhost.exe进程ID?

时间:2019-04-26 01:18:39

标签: delphi winapi freepascal windows-console

在进行了一些研究并查看了ProcessHacker的源代码之后,似乎获得conhost.exe的进程ID的方法是使用NtQuerySystemInformation。

我为测试目的编写了以下小程序,但它不起作用,我也看不出为什么。

{$APPTYPE CONSOLE}

{$TYPEDADDRESS ON}

program _QueryInformationProcess_ProcessConsoleHostProcess;

uses
  Windows,
  sysutils
  ;

{$ifdef VER90}
type
  ptrint  = longint;
  ptruint = DWORD;

const
  DELETE                   = $00010000;
  READ_CONTROL             = $00020000;
  WRITE_DAC                = $00040000;
  WRITE_OWNER              = $00080000;
  SYNCHRONIZE              = $00100000;

  STANDARD_RIGHTS_REQUIRED = $000F0000;

  STANDARD_RIGHTS_READ     = READ_CONTROL;
  STANDARD_RIGHTS_WRITE    = READ_CONTROL;
  STANDARD_RIGHTS_EXECUTE  = READ_CONTROL;

  STANDARD_RIGHTS_ALL      = $001F0000;
  SPECIFIC_RIGHTS_ALL      = $0000FFFF;

  PROCESS_ALL_ACCESS        = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $FFF;
{$endif}

const
  ntdll = 'ntdll.dll';

  { process information class(es) used in QueryInformationProcess             }

type
  PROCESSINFOCLASS =
  (
    {  0 }  ProcessBasicInformation,                      // q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION
    {  1 }  ProcessQuotaLimits,                           // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX
    {  2 }  ProcessIoCounters,                            // q: IO_COUNTERS
    {  3 }  ProcessVmCounters,                            // q: VM_COUNTERS, VM_COUNTERS_EX, VM_COUNTERS_EX2
    {  4 }  ProcessTimes,                                 // q: KERNEL_USER_TIMES
    {  5 }  ProcessBasePriority,                          // s: KPRIORITY
    {  6 }  ProcessRaisePriority,                         // s: ULONG
    {  7 }  ProcessDebugPort,                             // q: HANDLE
    {  8 }  ProcessExceptionPort,                         // s: HANDLE
    {  9 }  ProcessAccessToken,                           // s: PROCESS_ACCESS_TOKEN
    { 10 }  ProcessLdtInformation,                        // qs: PROCESS_LDT_INFORMATION                                                               // 10
    { 11 }  ProcessLdtSize,                               // s: PROCESS_LDT_SIZE
    { 12 }  ProcessDefaultHardErrorMode,                  // qs: ULONG
    { 13 }  ProcessIoPortHandlers,                        // (kernel-mode only)
    { 14 }  ProcessPooledUsageAndLimits,                  // q: POOLED_USAGE_AND_LIMITS
    { 15 }  ProcessWorkingSetWatch,                       // q: PROCESS_WS_WATCH_INFORMATION[]; s: void
    { 16 }  ProcessUserModeIOPL,
    { 17 }  ProcessEnableAlignmentFaultFixup,             // s: BOOLEAN
    { 18 }  ProcessPriorityClass,                         // qs: PROCESS_PRIORITY_CLASS
    { 19 }  ProcessWx86Information,
    { 20 }  ProcessHandleCount,                           // q: ULONG, PROCESS_HANDLE_INFORMATION                                                               // 20
    { 21 }  ProcessAffinityMask,                          // s: KAFFINITY
    { 22 }  ProcessPriorityBoost,                         // qs: ULONG
    { 23 }  ProcessDeviceMap,                             // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX
    { 24 }  ProcessSessionInformation,                    // q: PROCESS_SESSION_INFORMATION
    { 25 }  ProcessForegroundInformation,                 // s: PROCESS_FOREGROUND_BACKGROUND
    { 26 }  ProcessWow64Information,                      // q: ULONG_PTR
    { 27 }  ProcessImageFileName,                         // q: UNICODE_STRING
    { 28 }  ProcessLUIDDeviceMapsEnabled,                 // q: ULONG
    { 29 }  ProcessBreakOnTermination,                    // qs: ULONG
    { 30 }  ProcessDebugObjectHandle,                     // q: HANDLE                                                               // 30
    { 31 }  ProcessDebugFlags,                            // qs: ULONG
    { 32 }  ProcessHandleTracing,                         // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enables
    { 33 }  ProcessIoPriority,                            // qs: IO_PRIORITY_HINT
    { 34 }  ProcessExecuteFlags,                          // qs: ULONG
    { 35 }  ProcessResourceManagement,
    { 36 }  ProcessCookie,                                // q: ULONG
    { 37 }  ProcessImageInformation,                      // q: SECTION_IMAGE_INFORMATION
    { 38 }  ProcessCycleTime,                             // q: PROCESS_CYCLE_TIME_INFORMATION                                                               // since VISTA
    { 39 }  ProcessPagePriority,                          // q: ULONG
    { 40 }  ProcessInstrumentationCallback,               // 40
    { 41 }  ProcessThreadStackAllocation,                 // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX
    { 42 }  ProcessWorkingSetWatchEx,                     // q: PROCESS_WS_WATCH_INFORMATION_EX[]
    { 43 }  ProcessImageFileNameWin32,                    // q: UNICODE_STRING
    { 44 }  ProcessImageFileMapping,                      // q: HANDLE (input)
    { 45 }  ProcessAffinityUpdateMode,                    // qs: PROCESS_AFFINITY_UPDATE_MODE
    { 46 }  ProcessMemoryAllocationMode,                  // qs: PROCESS_MEMORY_ALLOCATION_MODE
    { 47 }  ProcessGroupInformation,                      // q: USHORT[]
    { 48 }  ProcessTokenVirtualizationEnabled,            // s: ULONG
    { 49 }  ProcessConsoleHostProcess,                    // q: ULONG_PTR
    { 50 }  ProcessWindowInformation,                     // q: PROCESS_WINDOW_INFORMATION                                                               // 50
    { 51 }  ProcessHandleInformation,                     // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION                                                               // since WIN8
    { 52 }  ProcessMitigationPolicy,                      // s: PROCESS_MITIGATION_POLICY_INFORMATION
    { 53 }  ProcessDynamicFunctionTableInformation,
    { 54 }  ProcessHandleCheckingMode,
    { 55 }  ProcessKeepAliveCount,                        // q: PROCESS_KEEPALIVE_COUNT_INFORMATION
    { 56 }  ProcessRevokeFileHandles,                     // s: PROCESS_REVOKE_FILE_HANDLES_INFORMATION
    { 57 }  ProcessWorkingSetControl,                     // s: PROCESS_WORKING_SET_CONTROL
    { 58 }  ProcessHandleTable,                           // since WINBLUE
    { 59 }  ProcessCheckStackExtentsMode,
    { 60 }  ProcessCommandLineInformation,                // q: UNICODE_STRING                                                               // 60
    { 61 }  ProcessProtectionInformation,                 // q: PS_PROTECTION
    { 62 }  ProcessMemoryExhaustion,                      // PROCESS_MEMORY_EXHAUSTION_INFO                                                               // since THRESHOLD
    { 63 }  ProcessFaultInformation,                      // PROCESS_FAULT_INFORMATION
    { 64 }  ProcessTelemetryIdInformation,                // PROCESS_TELEMETRY_ID_INFORMATION
    { 65 }  ProcessCommitReleaseInformation,              // PROCESS_COMMIT_RELEASE_INFORMATION
    { 66 }  ProcessDefaultCpuSetsInformation,
    { 67 }  ProcessAllowedCpuSetsInformation,
    { 68 }  ProcessReserved1Information,
    { 69 }  ProcessReserved2Information,
    { 70 }  ProcessSubsystemProcess,                      // 70
    { 71 }  ProcessJobMemoryInformation,                  // PROCESS_JOB_MEMORY_INFO
    { 72 }  ProcessInPrivate,                             // since THRESHOLD2
    { 73 }  ProcessRaiseUMExceptionOnInvalidHandleClose,
    { 74 }  MaxProcessInfoClass
  );

type
  NTSTATUS                    = DWORD;

{-----------------------------------------------------------------------------}

function NtQueryInformationProcess(ProcessHandle            : THANDLE;
                                   ProcessInformationClass  : DWORD;
                                   ProcessInformation       : pointer;
                                   ProcessInformationLength : DWORD;
                                   ReturnLength             : PDWORD)
         : NTSTATUS; stdcall; external ntdll;

{-----------------------------------------------------------------------------}

procedure EndProgram(ExitCode : ptruint);
begin
  writeln('Exit code : ', ExitCode);
  writeln('Press <enter>/<return> to end this program.');

  readln;
end;

{-----------------------------------------------------------------------------}

var
  ProcessHandle      : THANDLE;

  ReturnLength       : DWORD;
  NtResult           : NTSTATUS;

  { upon success should contain the conhost.exe process id                    }

  ConsoleHostProcess : ptruint;

begin
  writeln;

  writeln('GetCurrentProcessId : ', GetCurrentProcessId()); { not conhost's   }

  // since we are dealing with our own process we can specify PROCESS_ALL_ACCESS

  ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS,
                               FALSE,
                               GetCurrentProcessId());

  if ProcessHandle = 0 then EndProgram(1);


  // use the process handle to obtain conhost.exe process id

  ReturnLength := 0;  { for good measure }
  NtResult     := 0;

  NtResult := NtQueryInformationProcess(ProcessHandle,
                                        DWORD(ProcessConsoleHostProcess),
                                        @ConsoleHostProcess,
                                        sizeof(ConsoleHostProcess),
                                        nil);
                                        //@ReturnLength);

  { returns 0xC0000003 STATUS_INVALID_INFO_CLASS                              }
  { [Invalid Parameter] The specified information class is not a valid        }
  { information class for the specified object.                               }

  writeln('NTSTATUS           : ', IntToHex(NtResult, 0));
  writeln('ReturnLength       : ', ReturnLength);

  writeln;
  writeln('Press <enter>/<result> to end this program.');
  readln;
end.

如程序注释中所述,我得到NTSTATUS-0xC0000003 STATUS_INVALID_INFO_CLASS

这意味着:

[无效参数]指定的信息类对于指定的对象不是有效的信息类。

但是,我看不到,我的错误在哪里?

谢谢您的帮助。

1 个答案:

答案 0 :(得分:2)

似乎参数ProcessConsoleHostProcess(49)在32位中不受支持,我可以在64位程序中使用它。您可以尝试使用x64进行编译。

document

中也有提醒
  

为保持应用程序的兼容性,最好使用   说明中提到的公共职能   而是使用ProcessInformationClass参数。

或者您也可以使用Tool Help Functions以另一种方式获得它。这是相关的sample