修正後的SYSTEM_THREADS與SYSTEM_PROCESSES結構體

whatday發表於2013-08-07

由於最近有個32位程式需要向64位系統移植,其中程式中使用了ZwQuerySystemInformation函式來列舉系統中的程式與執行緒資訊,但是移植後的程式在Windows x64下工作不正常。現象是獲取到的程式/執行緒資訊混亂,不正確。通過查詢WRK以及Win2k原始碼,將結構體中的成員進行了修改,最終編譯出的程式可以正常顯示。

由於ZwQuerySystemInformation屬於Windows的未文件化函式,網路上可以搜尋到的結構體都是基於Win32下逆向得到的,因此可能有些偏差。

最明顯的問題就是HANDLE與ULONG的區別。在Windows下,HANDLE型別被定義為typedef HANDLE PVOID *      。在32位平臺下,sizeof(HANDLE) == sizeof(ULONG) == 4,因此可能是當時逆向的人沒有多想就把HANDLE型別寫成了ULONG型別,這樣寫在32位平臺下是不會出錯的,但是到了64位平臺下,HANDLE型別就變成了8位元組,而ULONG型別在編譯器中被定義為ULONG32型別即32位無符號整數,造成了結構體內成員偏移的偏差。

在Windows下,程式ID是HANDLE型別表示的,而不是ULONG型別。在平臺移植的時候是需要注意的!因為太多人喜歡把程式ID用ULONG型別進行表示了

typedef struct _SYSTEM_THREADS
{
 LARGE_INTEGER  KernelTime;
 LARGE_INTEGER  UserTime;
 LARGE_INTEGER  CreateTime;
 ULONG    WaitTime;
 PVOID    StartAddress;
 CLIENT_ID   ClientID;
 KPRIORITY   Priority;
 KPRIORITY   BasePriority;
 ULONG    ContextSwitchCount;
 ULONG    ThreadState;
 KWAIT_REASON  WaitReason;
 ULONG    Reserved; //Add
}SYSTEM_THREADS,*PSYSTEM_THREADS;

typedef struct _SYSTEM_PROCESSES
{
 ULONG    NextEntryDelta;
 ULONG    ThreadCount;
 ULONG    Reserved[6];
 LARGE_INTEGER  CreateTime;
 LARGE_INTEGER  UserTime;
 LARGE_INTEGER  KernelTime;
 UNICODE_STRING  ProcessName;
 KPRIORITY   BasePriority;
 HANDLE   ProcessId;  //Modify
 HANDLE   InheritedFromProcessId;//Modify

 ULONG    HandleCount;
 ULONG    SessionId;
 ULONG_PTR  PageDirectoryBase;
 VM_COUNTERS VmCounters;
 SIZE_T    PrivatePageCount;//Add
 IO_COUNTERS  IoCounters; //windows 2000 only
 struct _SYSTEM_THREADS Threads[1];
}SYSTEM_PROCESSES,*PSYSTEM_PROCESSES;

相關文章