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); }