C++ 获取父进程PID

通过使用ntdll.dll中的NtQueryInformationProcess函数,结合OpenProcess获取进程句柄,可以获取到进程的基本信息,包括父进程的PID。在调用时,设置参数为ProcessBasicInformation,然后从返回的结构体中提取InheritedFromUniqueProcessId字段,即可得到父进程的唯一标识。

我们可以使用ntddl.dll中有一个函数叫NtQueryInformationProcess,用它可以将指定类型的进程信息拷贝到某个缓冲。其原型如下:

NTSYSAPI
NTSTATUS
NTAPI
NtQueryInformationProcess (
IN HANDLE ProcessHandle, // 进程句柄
IN PROCESSINFOCLASS InformationClass, // 信息类型
OUT PVOID ProcessInformation, // 缓冲指针
IN ULONG ProcessInformationLength, // 以字节为单位的缓冲大小
OUT PULONG ReturnLength OPTIONAL // 写入缓冲的字节数
);

第一个参数是希望操作的进程句柄,这个句柄必须以PROCESS_QUERY_INFORMATION模式存取。为了取得一个句柄,我们必须用OpenProcess函数:

HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,dwProcessID);

第二个参数是请求信息的类型,这个参数可以有许多个值,本文例子中将用ProcessBasicInformation (值为0)。
因此,如果第二个参数是ProcessBasicInformation的话,则第三个参数必须为一个指针指向结构

PROCESS_BASIC_INFORMATION:
typedef struct
{
      DWORD ExitStatus; // 接收进程终止状态
      DWORD PebBaseAddress; // 接收进程环境块地址
      DWORD AffinityMask; // 接收进程关联掩码
      DWORD BasePriority; // 接收进程的优先级类
      ULONG UniqueProcessId; // 接收进程ID
      ULONG InheritedFromUniqueProcessId; //接收父进程ID
} PROCESS_BASIC_INFORMATION;

这个结构的最后一个参数是InheritedFromUniqueProcessId,它就是我们所要的东西。

// parent.cpp (Windows NT/2000)
//
// This example will show the method how you can retrieve the parent
// process ID on Windows NT/2000 using the NT Native API
// 
//
// (c)1999 Ashot Oganesyan K, SmartLine, Inc
// mailto:ashot@aha.ru, http://www.protect-me.com, http://www.codepile.com

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

#define ProcessBasicInformation 0

typedef struct
{
    DWORD ExitStatus;
    DWORD PebBaseAddress;
    DWORD AffinityMask;
    DWORD BasePriority;
    ULONG UniqueProcessId;
    ULONG InheritedFromUniqueProcessId;
}   PROCESS_BASIC_INFORMATION;


// ntdll!NtQueryInformationProcess (NT specific!)
//
// The function copies the process information of the
// specified type into a buffer
//
// NTSYSAPI
// NTSTATUS
// NTAPI
// NtQueryInformationProcess(
//    IN HANDLE ProcessHandle,              // handle to process
//    IN PROCESSINFOCLASS InformationClass, // information type
//    OUT PVOID ProcessInformation,         // pointer to buffer
//    IN ULONG ProcessInformationLength,    // buffer size in bytes
//    OUT PULONG ReturnLength OPTIONAL      // pointer to a 32-bit
//                                          // variable that receives
//                                          // the number of bytes
//                                          // written to the buffer 
// );
typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);


PROCNTQSIP NtQueryInformationProcess;

DWORD GetParentProcessID(DWORD dwId);

void main(int argc, char* argv[])
{
    if (argc<2)
    {
       printf("Usage:\n\nparent.exe ProcId\n");
       return;
    }

    NtQueryInformationProcess = (PROCNTQSIP)GetProcAddress(
                                            GetModuleHandle("ntdll"),
                                            "NtQueryInformationProcess"
                                            );

    if (!NtQueryInformationProcess)
       return;

    DWORD dwId;
    sscanf(argv[1],"%lu",&dwId);

    printf("Parent PID for %lu is %lu\n",dwId,GetParentProcessID(dwId));

}

DWORD GetParentProcessID(DWORD dwId)
{
    LONG                      status;
    DWORD                     dwParentPID = (DWORD)-1;
    HANDLE                    hProcess;
    PROCESS_BASIC_INFORMATION pbi;

    // Get process handle
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,dwId);
    if (!hProcess)
       return (DWORD)-1;

    // Retrieve information
    status = NtQueryInformationProcess( hProcess,
                                        ProcessBasicInformation,
                                        (PVOID)&pbi,
                                        sizeof(PROCESS_BASIC_INFORMATION),
                                        NULL
                                      );

    // Copy parent Id on success
    if  (!status)
        dwParentPID = pbi.InheritedFromUniqueProcessId;

    CloseHandle (hProcess);

   return dwParentPID;
}
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值