X64进程遍历并获取进程主线程

    xiaoxiao2021-12-14  35

    x64下windbg显示的进程结构体

    1: kd> dt _SYSTEM_PROCESS_INFORMATION ole32!_SYSTEM_PROCESS_INFORMATION    +0x000 NextEntryOffset  : Uint4B    +0x004 NumberOfThreads  : Uint4B    +0x008 WorkingSetPrivateSize : _LARGE_INTEGER    +0x010 HardFaultCount   : Uint4B    +0x014 NumberOfThreadsHighWatermark : Uint4B    +0x018 CycleTime        : Uint8B    +0x020 CreateTime       : _LARGE_INTEGER    +0x028 UserTime         : _LARGE_INTEGER    +0x030 KernelTime       : _LARGE_INTEGER    +0x038 ImageName        : _UNICODE_STRING    +0x048 BasePriority     : Int4B    +0x050 UniqueProcessId  : Ptr64 Void    +0x058 InheritedFromUniqueProcessId : Ptr64 Void    +0x060 HandleCount      : Uint4B    +0x064 SessionId        : Uint4B    +0x068 UniqueProcessKey : Uint8B    +0x070 PeakVirtualSize  : Uint8B    +0x078 VirtualSize      : Uint8B    +0x080 PageFaultCount   : Uint4B    +0x088 PeakWorkingSetSize : Uint8B    +0x090 WorkingSetSize   : Uint8B    +0x098 QuotaPeakPagedPoolUsage : Uint8B    +0x0a0 QuotaPagedPoolUsage : Uint8B    +0x0a8 QuotaPeakNonPagedPoolUsage : Uint8B    +0x0b0 QuotaNonPagedPoolUsage : Uint8B    +0x0b8 PagefileUsage    : Uint8B    +0x0c0 PeakPagefileUsage : Uint8B    +0x0c8 PrivatePageCount : Uint8B    +0x0d0 ReadOperationCount : _LARGE_INTEGER    +0x0d8 WriteOperationCount : _LARGE_INTEGER    +0x0e0 OtherOperationCount : _LARGE_INTEGER    +0x0e8 ReadTransferCount : _LARGE_INTEGER    +0x0f0 WriteTransferCount : _LARGE_INTEGER    +0x0f8 OtherTransferCount : _LARGE_INTEGER

     kd> dt    _IO_COUNTERS ole32!_IO_COUNTERS    +0x000 ReadOperationCount : Uint8B    +0x008 WriteOperationCount : Uint8B    +0x010 OtherOperationCount : Uint8B    +0x018 ReadTransferCount : Uint8B    +0x020 WriteTransferCount : Uint8B    +0x028 OtherTransferCount : Uint8B

    kd> dt _VM_COUNTERS ole32!_VM_COUNTERS    +0x000 PeakVirtualSize  : Uint8B    +0x008 VirtualSize      : Uint8B    +0x010 PageFaultCount   : Uint4B    +0x018 PeakWorkingSetSize : Uint8B    +0x020 WorkingSetSize   : Uint8B    +0x028 QuotaPeakPagedPoolUsage : Uint8B    +0x030 QuotaPagedPoolUsage : Uint8B    +0x038 QuotaPeakNonPagedPoolUsage : Uint8B    +0x040 QuotaNonPagedPoolUsage : Uint8B    +0x048 PagefileUsage    : Uint8B    +0x050 PeakPagefileUsage : Uint8B

     kd> dt _SYSTEM_THREAD_INFORMATION ole32!_SYSTEM_THREAD_INFORMATION    +0x000 KernelTime       : _LARGE_INTEGER    +0x008 UserTime         : _LARGE_INTEGER    +0x010 CreateTime       : _LARGE_INTEGER    +0x018 WaitTime         : Uint4B    +0x020 StartAddress     : Ptr64 Void    +0x028 ClientId         : _CLIENT_ID    +0x038 Priority         : Int4B    +0x03c BasePriority     : Int4B    +0x040 ContextSwitches  : Uint4B    +0x044 ThreadState      : Uint4B    +0x048 WaitReason       : Uint4B 实际测试发现windbg列出的这个进程结构不完整,需要通过一项Reserved14个字节来补齐才行。后面列出我的代码。

    #include "stdafx.h" #include "windows.h" #pragma pack(8) #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) #define STATUS_SUCCESS         ((NTSTATUS) 0x00000000) #define SystemProcessesAndThreadsInformation    5 // 功能号 #define NTAPI    __stdcall // 线程状态的枚举常量 typedef enum _THREAD_STATE {     StateInitialized , // 初始化状态     StateReady , // 准备状态     StateRunning , // 运行状态     StateStandby , //     StateTerminated ,//关闭     StateWait , // 等待     StateTransition , // 切换???     StateUnknown }THREAD_STATE; // 线程处于等待的原因的枚举常量 typedef enum _KWAIT_REASON {     Executive ,     FreePage ,     PageIn ,     PoolAllocation ,     DelayExecution ,     Suspended ,     UserRequest ,     WrExecutive ,     WrFreePage ,     WrPageIn ,     WrPoolAllocation ,     WrDelayExecution ,     WrSuspended ,     WrUserRequest ,     WrEventPair ,     WrQueue ,     WrLpcReceive ,     WrLpcReply ,     WrVirtualMemory ,     WrPageOut ,     WrRendezvous ,     Spare2 ,     Spare3 ,     Spare4 ,     Spare5 ,     Spare6 ,     WrKernel ,     MaximumWaitReason }KWAIT_REASON; typedef LONG   NTSTATUS; typedef LONG    KPRIORITY; typedef struct _UNICODE_STRING {     USHORT Length;     USHORT MaximumLength;     PWSTR  Buffer;

    } UNICODE_STRING, *PUNICODE_STRING;

    typedef struct _CLIENT_ID_64 {     ULONG64 UniqueProcess;     ULONG64 UniqueThread; }CLIENT_ID_64, *PCLIENT_ID_64; typedef struct _VM_COUNTERS {     ULONG64        PeakVirtualSize;     ULONG64        VirtualSize;     ULONG         PageFaultCount;     ULONG64        PeakWorkingSetSize;     ULONG64        WorkingSetSize;     ULONG64        QuotaPeakPagedPoolUsage;     ULONG64        QuotaPagedPoolUsage;     ULONG64        QuotaPeakNonPagedPoolUsage;     ULONG64        QuotaNonPagedPoolUsage;     ULONG64        PagefileUsage;     ULONG64        PeakPagefileUsage; } VM_COUNTERS; // 线程信息结构体 typedef struct _SYSTEM_THREAD_INFORMATION {     LARGE_INTEGER   KernelTime;     LARGE_INTEGER   UserTime;     LARGE_INTEGER   CreateTime;     ULONG64         WaitTime;     ULONG64         StartAddress;     CLIENT_ID_64    ClientId;     KPRIORITY       Priority;     KPRIORITY       BasePriority;     ULONG           ContextSwitchCount;     LONG            State;// 状态,是THREAD_STATE枚举类型中的一个值     LONG            WaitReason;//等待原因, KWAIT_REASON中的一个值 } SYSTEM_THREAD_INFORMATION , *PSYSTEM_THREAD_INFORMATION; // 进程信息结构体 typedef struct _SYSTEM_PROCESS_INFORMATION {     ULONG            NextEntryDelta; // 指向下一个结构体的指针     ULONG            ThreadCount; // 本进程的总线程数     LARGE_INTEGER    WorkingSetPrivateSize;     ULONG            HardFaultCount;       ULONG            NumberOfThreadsHighWatermark;     LARGE_INTEGER    CycleTime;     LARGE_INTEGER    CreateTime; // 进程的创建时间     LARGE_INTEGER    UserTime; // 在用户层的使用时间     LARGE_INTEGER    KernelTime; // 在内核层的使用时间     UNICODE_STRING   ProcessName; // 进程名     KPRIORITY        BasePriority; //     ULONG64          ProcessId; // 进程ID     ULONG64          InheritedFromProcessId;     ULONG            HandleCount; // 进程的句柄总数     ULONG            SessionId;       ULONG64          UniqueProcessKey;     VM_COUNTERS      VmCounters;     IO_COUNTERS      IoCounters;     ULONG            Reserved1;     SYSTEM_THREAD_INFORMATION Threads[1]; // 子线程信息数组 }SYSTEM_PROCESS_INFORMATION , *PSYSTEM_PROCESS_INFORMATION; #pragma pack() // NtQuerySystemInformation 函数的原型 // 由于该没有导出,所以得自己定义函数的原型 typedef DWORD(WINAPI* PQUERYSYSTEM)(UINT , PVOID , DWORD , PDWORD); DWORD __stdcall GetMainThread(DWORD dwProcessId) {     int nRet = 0;     NTSTATUS Status = 0;     DWORD dwThreadId = 0;     PQUERYSYSTEM NtQuerySystemInformation = NULL;     PSYSTEM_PROCESS_INFORMATION pInfo = { 0 };     // 获取函数地址     NtQuerySystemInformation = (PQUERYSYSTEM)GetProcAddress(LoadLibrary(L"ntdll.dll") , "NtQuerySystemInformation");     DWORD   dwSize = 0;     // 获取信息所需的缓冲区大小     Status = NtQuerySystemInformation(SystemProcessesAndThreadsInformation ,//要获取的信息的类型         NULL , // 用于接收信息的缓冲区         0 ,  // 缓冲区大小         &dwSize         );     // 申请缓冲区     char* pBuff = new char[dwSize];     pInfo = (PSYSTEM_PROCESS_INFORMATION)pBuff ;     if(pInfo == NULL)         return -1;     // 再次调用函数, 获取信息     Status = NtQuerySystemInformation(SystemProcessesAndThreadsInformation ,//要获取的信息的类型         pInfo , // 用于接收信息的缓冲区         dwSize ,  // 缓冲区大小         &dwSize         );     if(!NT_SUCCESS(Status)) {/*如果函数执行失败*/         printf("失败\n");         delete[] pInfo;         return -1;     }     // 遍历结构体,找到对应的进程     while(1)     {         // 判断是否还有下一个进程         if(pInfo->NextEntryDelta == 0)             break;         // 判断是否找到了ID         if(pInfo->ProcessId == dwProcessId)         {

                //这里罗列出所有的进程中活着的线程。

                for(int i = 0 ; i<pInfo->ThreadCount; i ++)             {                 dwThreadId = (DWORD)pInfo->Threads[i].ClientId.UniqueThread;

                    printf("thread id = %d",dwThreadId);

                }

                dwThreadId = (DWORD)pInfo->Threads[0].ClientId.UniqueThread;   //这个是主线程的ID                      break;         }         // 迭代到下一个节点         pInfo = (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pInfo) + pInfo->NextEntryDelta);     }     delete[] pBuff;     return dwThreadId; } int _tmain(int argc, _TCHAR* argv[]) {     GetMainThread(6592); }
    转载请注明原文地址: https://ju.6miu.com/read-969470.html

    最新回复(0)