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