1.PspCidTable中存放的對象是系統中所有的進線程對象,其索引就是PID和TID
2.PspCidTable中存放的直接是對象體(EPROCESS和ETHREAD),而每個進程私有的句柄表則存放的是對象頭(OBJECT_HEADER)
3.PspCidTable是一個獨立的句柄表,而每個進程私有的句柄表以一個雙鏈連接起來
PspCidTable相關的調用:
1.系統初始化時調用PspInitPhase0()初始化進程管理子系統,此時創建PspCidTable
- PspCidTable = ExCreateHandleTable (NULL); //創建!
- if (PspCidTable == NULL) {
- return FALSE;
- }
- //
- // Set PID and TID reuse to strict FIFO. This isn't absolutely needed but
- // it makes tracking audits easier.
- //
- ExSetHandleTableStrictFIFO (PspCidTable );
- ExRemoveHandleTable (PspCidTable
); //使得PspCidTable獨立於其它句柄表
2.進程創建時,PspCreateProcess()在PspCidTable中以進程對象創建句柄,是爲PID
//
// Create the process ID
- //
- CidEntry.Object = Process;
- CidEntry.GrantedAccess = 0;
- Process->UniqueProcessId = ExCreateHandle (PspCidTable , &CidEntry); //進程的PID是這麼來的
- if (Process->UniqueProcessId == NULL) {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto exit_and_deref;
- }
3.線程創建時,PspCreateThread()在PspCidTable中以線程對象創建句柄,是爲TID
- Thread->ThreadsProcess = Process;
- Thread->Cid.UniqueProcess = Process->UniqueProcessId;
- CidEntry.Object = Thread;
- CidEntry.GrantedAccess = 0;
- Thread->Cid.UniqueThread = ExCreateHandle (PspCidTable , &CidEntry); //線程的TID
- if (Thread->Cid.UniqueThread == NULL) {
- ObDereferenceObject (Thread);
- return (STATUS_INSUFFICIENT_RESOURCES);
- }
這兒可以清楚地知道:PID和TID分別是EPROCESS和ETHREAD對象在PspCidTable這個句柄表中的索引
4.進程和線程的查詢,主要是以下三個函數,按照給定的PID或TID從PspCidTable從查找相應的進線程對象
PsLookupProcessThreadByCid()
PsLookupProcessByProcessId()
PsLookupThreadByThreadId()
其中有如下調用:
CidEntry = ExMapHandleToPointer(PspCidTable
, ProcessId);
CidEntry = ExMapHandleToPointer(PspCidTable
, ThreadId);
從而獲取Object
5.線程退出時,PspThreadDelete()在PspCidTable中銷燬句柄
- if (Thread->Cid.UniqueThread != NULL) {
- if (!ExDestroyHandle (PspCidTable , Thread->Cid.UniqueThread, NULL)) {
- KeBugCheck(CID_HANDLE_DELETION);
- }
- }
6.進程退出時,PspProcessDelete()在PspCidTable中銷燬句柄
- if (Process->UniqueProcessId) {
- if (!(ExDestroyHandle (PspCidTable , Process->UniqueProcessId, NULL))) {
- KeBugCheck (CID_HANDLE_DELETION);
- }
- }
這裏要注意,如果進線程退出時,銷燬句柄卻發現句柄不存在造成ExDestroyHandle返回失敗,可是要藍屏滴~
所以抹了PspCidTable來隱藏的進程,在退出時必須把進線程對象再放回去,欲知後事如何,請看下回分解~~