• 查找父进程,进程的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

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

  • 相关阅读:
    Flex弹性盒模型
    响应式布局rem的使用
    京东首页如何实现pc端和移动端加载不同的html的?
    canvas绘制表盘时钟
    javascript实现ul中列表项随机排列
    使用 HTML5 视频事件
    Javascript获取当前鼠标在元素内的坐标定位
    移动 web 开发问题和优化小结
    关于fisher判别的一点理解
    机器学习第三课(EM算法和高斯混合模型)
  • 原文地址:https://www.cnblogs.com/priarieNew/p/9755826.html
Copyright © 2020-2023  润新知