漲姿勢系列之——核心環境下花式獲得CSRSS程式id

Ox9A82發表於2016-06-02

這個是翻別人的程式碼時看到的,所以叫漲姿勢系列。作者寫了一個獲取CSRSS程式PID的函式,結果我看了好久才看懂是這麼一個作用。先放上程式碼

 1 HANDLE GetCsrPid()
 2 {
 3     HANDLE Process, hObject;
 4     HANDLE CsrId = (HANDLE)0;
 5     OBJECT_ATTRIBUTES obj;
 6     CLIENT_ID cid;
 7     UCHAR Buff[0x100];
 8     POBJECT_NAME_INFORMATION ObjName = (PVOID)&Buff;
 9     PSYSTEM_HANDLE_INFORMATION_EX Handles;
10     ULONG r;
11 
12     Handles = GetInfoTable(SystemHandleInformation);
13 
14     if (!Handles) return CsrId;
15 
16     for (r = 0; r < Handles->NumberOfHandles; r++)
17     {
18         if (Handles->Information[r].ObjectTypeNumber == 21) //Port object
19         {
20             InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
21 
22             cid.UniqueProcess = (HANDLE)Handles->Information[r].ProcessId;
23             cid.UniqueThread = 0;
24 
25             if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid)))
26             {
27                 if (NT_SUCCESS(ZwDuplicateObject(Process, (HANDLE)Handles->Information[r].Handle,NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ACCESS)))
28                 {
29                     if (NT_SUCCESS(ZwQueryObject(hObject, ObjectNameInformation, ObjName, 0x100, NULL)))
30                     {
31                         if (ObjName->Name.Buffer && !wcsncmp(L"\\Windows\\ApiPort", ObjName->Name.Buffer, 20))
32                         {
33                             CsrId = (HANDLE)Handles->Information[r].ProcessId;
34                         } 
35                     }
36 
37                     ZwClose(hObject);
38                 }
39 
40                 ZwClose(Process);
41             }
42         }
43     }
44 
45     ExFreePool(Handles);
46     return CsrId;
47 }

作者幹了以下這幾件事:執行ZwQuerySystemInfo函式的第16號功能,這個第16號功能就是SystemHandleInformation,作用是獲取控制程式碼表。之前沒用過這個功能號,MSDN上的頁面也找不到了,找不到頁面大概是因為這個函式現在已經不被支援了吧(Win8)。搜了半天找到了這個功能的結構

typedef struct _SYSTEM_HANDLE_INFORMATION_EX 
{
ULONG NumberOfHandles;
SYSTEM_HANDLE_INFORMATION Information[1];
}SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
typedef struct _SYSTEM_HANDLE_INFORMATION 
{
ULONG ProcessId;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
}SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

就是說每個控制程式碼項都被解釋成

  • 控制程式碼所屬程式的PID
  • 控制程式碼對應物件的型別
  • 控制程式碼值(數字)
  • 控制程式碼對應的物件指標

這個函式查到控制程式碼後,匹配所有的port物件的控制程式碼。然後把這些控制程式碼dump到本程式(因為只有這樣才可以操作控制程式碼),用ZwQueryObject查詢port物件的名稱,匹配\\Windows\\ApiPort,而這個port物件正是csrss程式建立的,也就說只有csrss程式的控制程式碼表中才會有這個控制程式碼,這樣就實現了查詢的csrss程式的目的。

其實我覺得不需要把控制程式碼複製到自己的程式中了,因為已經有物件的指標了,可以直接獲取物件名了。這個做法對我來說比較新鮮,即用控制程式碼來查詢程式。

相關文章