查找父進程,進程的PEB 進程是否被調試 NtQueryInformationProcess


這個函數的功能很強大,可以用來查找進程的很多相關信息。
先看一下定義:

NTSTATUS WINAPI NtQueryInformationProcess(
  _In_      HANDLE           ProcessHandle,
  _In_      PROCESSINFOCLASS ProcessInformationClass,
  _Out_     PVOID            ProcessInformation,
  _In_      ULONG            ProcessInformationLength,
  _Out_opt_ PULONG           ReturnLength
);

該函數並沒有被微軟公開,它在Ntdll.dll 里導出的,所以要想調用此函數,得用LoadLibrary和GetProcAddress來加載。
用的時候要#include <winternl.h>頭文件
這里說一下參數介紹:
processHandle:查詢進程的句柄
ProcessInformationClass:想要查找的信息,他是一個 PROCESSINFOCLASS 的枚舉類型;可以取值:
                           ProcessBasicInformation   0
                           ProcessDebugPort          7 

                                                       ProcessWow64Information      26

                                                       ProcessImageFileName            27

                                                       ProcessBreakOnTermination   29

ProcessInformation:要存放查詢結果的緩沖區,這個結構要根據第二個參數來決定,
ProcessInformationLength:緩沖區大小
ReturnLength:實際返回的寫入緩沖區的字節數
我們看一下 ProcessBasicInformation  這個結構:
typedef struct _PROCESS_BASIC_INFORMATION {
    PVOID Reserved1;
    PPEB PebBaseAddress;
    PVOID Reserved2[2];
    ULONG_PTR UniqueProcessId;
    PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;
這是官方的定義,它其實就是下面的結構:
typedef struct

{

      DWORD ExitStatus; // 接收進程終止狀態

      DWORD PebBaseAddress; // 接收進程環境塊地址

      DWORD AffinityMask; // 接收進程關聯掩碼

      DWORD BasePriority; // 接收進程的優先級類

      ULONG UniqueProcessId; // 接收進程ID

      ULONG InheritedFromUniqueProcessId; //接收父進程ID

} PROCESS_BASIC_INFORMATION;
這個結構里面有父進程的ID,對應的官方的 Reserved3字段,
還有進程的PEB,看一下進程環境塊兒的定義:
typedef struct _PEB {
    BYTE Reserved1[2];
    BYTE BeingDebugged;  //該進程是否正在被調試,
    BYTE Reserved2[1];
    PVOID Reserved3[2];
    PPEB_LDR_DATA Ldr;
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    BYTE Reserved4[104];
    PVOID Reserved5[52];
    PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
    BYTE Reserved6[128];
    PVOID Reserved7[1];
    ULONG SessionId;      //會話ID
} PEB, *PPEB;
下面寫一段程序來看一下:

 

#include <windows.h>

#include <winternl.h>


//先定義函數指針

typedef NTSTATUS (WINAPI *PFUN_NtQueryInformationProcess)(
  _In_      HANDLE           ProcessHandle,
  _In_      PROCESSINFOCLASS ProcessInformationClass,
  _Out_     PVOID            ProcessInformation,
  _In_      ULONG            ProcessInformationLength,
  _Out_opt_ PULONG           ReturnLength
);

void main()

{

        DWORD dwCurrentProcessID;
	HANDLE hProcessThis;
	DWORD dwParentID; 

       //如果隨意申請一塊兒內存的話,不管內存多大,調用結果死活不成功,比如:UCHAR pbi[3000] = {0};這樣會導致失敗,還有待繼續探究

        PROCESS_BASIC_INFORMATION pbi = {0};
	ULONG dwReturnLen;
	ULONG dwData = sizeof(PROCESS_BASIC_INFORMATION);
	dwCurrentProcessID = GetCurrentProcessId();

         //打開進程一定要有  PROCESS_QUERY_INFORMATION 權限

	hProcessThis = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwCurrentProcessID);

	HMODULE hModule = LoadLibraryA("Ntdll.dll");
	PFUN_NtQueryInformationProcess pfun = (PFUNNtQueryInformationProcess)GetProcAddress(hModule, "NtQueryInformationProcess");
	NTSTATUS status = pfun(hProcessThis, ProcessBasicInformation, (PVOID)&pbi, dwData, &dwReturnLen);

        dwParentID = (DWORD)pbi.Reserved3; //dwParentID的值為devenv.exe 進程的句柄,即父進程的句柄

        PPEB peb = pbi.PebBaseAddress;

}

 

執行完這些語句后可以查看內存,下面是我的環境下的內存:
查找父進程,進程的PEB 進程是否被調試 NtQueryInformationProcess - Prairie - work labor and play
//說明:把Reserved3轉化為DWORD后一定會得到devenv.exe 進程的ID,dwParentID也可以說明問題

 

查找父進程,進程的PEB 進程是否被調試 NtQueryInformationProcess - Prairie - work labor and play

 //說明:這是peb字段,我們看到BeingDebugged字段已經被置為1,說明正在被調試,
             SessionId:字段也顯示出了該進程的會話ID

其它字段可以在深入的研究,現在自己也不太熟悉。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM