Native API乃Windows用戶模式中為上層Win32 API提供接口的本機(jī)系統(tǒng)服務(wù)。平常我們總是調(diào)用MS為我們提供的公用的Win32 API函數(shù)來實(shí)現(xiàn)來實(shí)現(xiàn) 我們系統(tǒng)的功能。今天我們要談的是如何通過本機(jī)系統(tǒng)服務(wù)(Native API)來探測本機(jī)系統(tǒng)信息。當(dāng)然,微軟沒有為我們提供關(guān)于本機(jī)系統(tǒng)服務(wù)的文檔 (Undocumented),也就是不會(huì)為對它的使用提供任何的保證,所以我們不提倡使用Native API來開發(fā)軟件。不過在特殊情況下,本機(jī)系統(tǒng)服務(wù)卻為我們提供了通向“秘密”的捷徑。本文提到的信息僅在Windows2000/XP/2003上測試過。
今天,我們主要討論的是一個(gè)函數(shù)NtQuerySystemInformation(ZwQuerySystemInformation)。當(dāng)然,你不要小看這么一個(gè)函數(shù),它卻為我們提供了豐富的系統(tǒng)信息,同時(shí)還包括對某些信息的控制和設(shè)置。以下是這個(gè)函數(shù)的原型:
typedef NTSTATUS (__stdcall *NTQUERYSYSTEMINFORMATION)
(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL);
NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;
從中可以看到,SystemInformationClass是一個(gè)類型信息,它大概提供了50余種信息,也就是我們可以通過這個(gè)函數(shù)對大約50多種的系統(tǒng)信息進(jìn)行探測或設(shè)置。SystemInformation是一個(gè)LPVOID型的指針,它為我們提供需要獲得的信息,或是我們需要設(shè)置的系統(tǒng)信息。SystemInformationLength是SystemInformation的長度,它根據(jù)探測的信息類型來決定。至于ReturnLength則是系統(tǒng)返回的需要的長度,通??梢栽O(shè)置為空指針(NULL)。
首先,我們來看看大家比較熟悉的系統(tǒng)進(jìn)程/線程相關(guān)的信息。這個(gè)題目在網(wǎng)上已經(jīng)討論了N多年了,所以我就不在老生常談了,呵呵。那么就提出這個(gè)結(jié)構(gòu)類型的定義:
typedef struct _SYSTEM_PROCESSES
{
ULONG NextEntryDelta; //構(gòu)成結(jié)構(gòu)序列的偏移量;
ULONG ThreadCount; //線程數(shù)目;
ULONG Reserved1[6];
LARGE_INTEGER CreateTime; //創(chuàng)建時(shí)間;
LARGE_INTEGER UserTime; //用戶模式(Ring 3)的CPU時(shí)間;
LARGE_INTEGER KernelTime; //內(nèi)核模式(Ring 0)的CPU時(shí)間;
UNICODE_STRING ProcessName; //進(jìn)程名稱;
KPRIORITY BasePriority; //進(jìn)程優(yōu)先權(quán);
ULONG ProcessId; //進(jìn)程標(biāo)識符;
ULONG InheritedFromProcessId; //父進(jìn)程的標(biāo)識符;
ULONG HandleCount; //句柄數(shù)目;
ULONG Reserved2[2];
VM_COUNTERS VmCounters; //虛擬存儲(chǔ)器的結(jié)構(gòu),見下;
IO_COUNTERS IoCounters; //IO計(jì)數(shù)結(jié)構(gòu),見下;
SYSTEM_THREADS Threads[1]; //進(jìn)程相關(guān)線程的結(jié)構(gòu)數(shù)組,見下;
}SYSTEM_PROCESSES,*PSYSTEM_PROCESSES;
typedef struct _SYSTEM_THREADS
{
LARGE_INTEGER KernelTime; //CPU內(nèi)核模式使用時(shí)間;
LARGE_INTEGER UserTime; //CPU用戶模式使用時(shí)間;
LARGE_INTEGER CreateTime; //線程創(chuàng)建時(shí)間;
ULONG WaitTime; //等待時(shí)間;
PVOID StartAddress; //線程開始的虛擬地址;
CLIENT_ID ClientId; //線程標(biāo)識符;
KPRIORITY Priority; //線程優(yōu)先級;
KPRIORITY BasePriority; //基本優(yōu)先級;
ULONG ContextSwitchCount; //環(huán)境切換數(shù)目;
THREAD_STATE State; //當(dāng)前狀態(tài);
KWAIT_REASON WaitReason; //等待原因;
}SYSTEM_THREADS,*PSYSTEM_THREADS;
typedef struct _VM_COUNTERS
{
ULONG PeakVirtualSize; //虛擬存儲(chǔ)峰值大??;
ULONG VirtualSize; //虛擬存儲(chǔ)大??;
ULONG PageFaultCount; //頁故障數(shù)目;
ULONG PeakWorkingSetSize; //工作集峰值大??;
ULONG WorkingSetSize; //工作集大??;
ULONG QuotaPeakPagedPoolUsage; //分頁池使用配額峰值;
ULONG QuotaPagedPoolUsage; //分頁池使用配額;
ULONG QuotaPeakNonPagedPoolUsage; //非分頁池使用配額峰值;
ULONG QuotaNonPagedPoolUsage; //非分頁池使用配額;
ULONG PagefileUsage; //頁文件使用情況;
ULONG PeakPagefileUsage; //頁文件使用峰值;
}VM_COUNTERS,*PVM_COUNTERS;
typedef struct _IO_COUNTERS
{
LARGE_INTEGER ReadOperationCount; //I/O讀操作數(shù)目;
LARGE_INTEGER WriteOperationCount; //I/O寫操作數(shù)目;
LARGE_INTEGER OtherOperationCount; //I/O其他操作數(shù)目;
LARGE_INTEGER ReadTransferCount; //I/O讀數(shù)據(jù)數(shù)目;
LARGE_INTEGER WriteTransferCount; //I/O寫數(shù)據(jù)數(shù)目;
LARGE_INTEGER OtherTransferCount; //I/O其他操作數(shù)據(jù)數(shù)目;
}IO_COUNTERS,*PIO_COUNTERS;
今天,我們主要討論的是一個(gè)函數(shù)NtQuerySystemInformation(ZwQuerySystemInformation)。當(dāng)然,你不要小看這么一個(gè)函數(shù),它卻為我們提供了豐富的系統(tǒng)信息,同時(shí)還包括對某些信息的控制和設(shè)置。以下是這個(gè)函數(shù)的原型:
typedef NTSTATUS (__stdcall *NTQUERYSYSTEMINFORMATION)
(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL);
NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;
從中可以看到,SystemInformationClass是一個(gè)類型信息,它大概提供了50余種信息,也就是我們可以通過這個(gè)函數(shù)對大約50多種的系統(tǒng)信息進(jìn)行探測或設(shè)置。SystemInformation是一個(gè)LPVOID型的指針,它為我們提供需要獲得的信息,或是我們需要設(shè)置的系統(tǒng)信息。SystemInformationLength是SystemInformation的長度,它根據(jù)探測的信息類型來決定。至于ReturnLength則是系統(tǒng)返回的需要的長度,通??梢栽O(shè)置為空指針(NULL)。
首先,我們來看看大家比較熟悉的系統(tǒng)進(jìn)程/線程相關(guān)的信息。這個(gè)題目在網(wǎng)上已經(jīng)討論了N多年了,所以我就不在老生常談了,呵呵。那么就提出這個(gè)結(jié)構(gòu)類型的定義:
typedef struct _SYSTEM_PROCESSES
{
ULONG NextEntryDelta; //構(gòu)成結(jié)構(gòu)序列的偏移量;
ULONG ThreadCount; //線程數(shù)目;
ULONG Reserved1[6];
LARGE_INTEGER CreateTime; //創(chuàng)建時(shí)間;
LARGE_INTEGER UserTime; //用戶模式(Ring 3)的CPU時(shí)間;
LARGE_INTEGER KernelTime; //內(nèi)核模式(Ring 0)的CPU時(shí)間;
UNICODE_STRING ProcessName; //進(jìn)程名稱;
KPRIORITY BasePriority; //進(jìn)程優(yōu)先權(quán);
ULONG ProcessId; //進(jìn)程標(biāo)識符;
ULONG InheritedFromProcessId; //父進(jìn)程的標(biāo)識符;
ULONG HandleCount; //句柄數(shù)目;
ULONG Reserved2[2];
VM_COUNTERS VmCounters; //虛擬存儲(chǔ)器的結(jié)構(gòu),見下;
IO_COUNTERS IoCounters; //IO計(jì)數(shù)結(jié)構(gòu),見下;
SYSTEM_THREADS Threads[1]; //進(jìn)程相關(guān)線程的結(jié)構(gòu)數(shù)組,見下;
}SYSTEM_PROCESSES,*PSYSTEM_PROCESSES;
typedef struct _SYSTEM_THREADS
{
LARGE_INTEGER KernelTime; //CPU內(nèi)核模式使用時(shí)間;
LARGE_INTEGER UserTime; //CPU用戶模式使用時(shí)間;
LARGE_INTEGER CreateTime; //線程創(chuàng)建時(shí)間;
ULONG WaitTime; //等待時(shí)間;
PVOID StartAddress; //線程開始的虛擬地址;
CLIENT_ID ClientId; //線程標(biāo)識符;
KPRIORITY Priority; //線程優(yōu)先級;
KPRIORITY BasePriority; //基本優(yōu)先級;
ULONG ContextSwitchCount; //環(huán)境切換數(shù)目;
THREAD_STATE State; //當(dāng)前狀態(tài);
KWAIT_REASON WaitReason; //等待原因;
}SYSTEM_THREADS,*PSYSTEM_THREADS;
typedef struct _VM_COUNTERS
{
ULONG PeakVirtualSize; //虛擬存儲(chǔ)峰值大??;
ULONG VirtualSize; //虛擬存儲(chǔ)大??;
ULONG PageFaultCount; //頁故障數(shù)目;
ULONG PeakWorkingSetSize; //工作集峰值大??;
ULONG WorkingSetSize; //工作集大??;
ULONG QuotaPeakPagedPoolUsage; //分頁池使用配額峰值;
ULONG QuotaPagedPoolUsage; //分頁池使用配額;
ULONG QuotaPeakNonPagedPoolUsage; //非分頁池使用配額峰值;
ULONG QuotaNonPagedPoolUsage; //非分頁池使用配額;
ULONG PagefileUsage; //頁文件使用情況;
ULONG PeakPagefileUsage; //頁文件使用峰值;
}VM_COUNTERS,*PVM_COUNTERS;
typedef struct _IO_COUNTERS
{
LARGE_INTEGER ReadOperationCount; //I/O讀操作數(shù)目;
LARGE_INTEGER WriteOperationCount; //I/O寫操作數(shù)目;
LARGE_INTEGER OtherOperationCount; //I/O其他操作數(shù)目;
LARGE_INTEGER ReadTransferCount; //I/O讀數(shù)據(jù)數(shù)目;
LARGE_INTEGER WriteTransferCount; //I/O寫數(shù)據(jù)數(shù)目;
LARGE_INTEGER OtherTransferCount; //I/O其他操作數(shù)據(jù)數(shù)目;
}IO_COUNTERS,*PIO_COUNTERS;