线程创建和进程要做的事情稍微多一点, 但是线程退出和进程退出要做的事情就不多了. 再加上上一篇我们已经分析了几个调试辅助函数, 所以这篇有营养的内容其实不多.

有创建就有销毁, 发起销毁调用的是PspExitThread, 下面摘抄一段他的代码.

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
//
// 如果调试端口不为空, 那么调用调试支持函数. 
//
if (Process->DebugPort != NULL) {
    //
    // Don't report system thread exit to the debugger as we don't report them.
    //
    if (!IS_SYSTEM_THREAD (Thread)) {
        if (LastThread) {
            DbgkExitProcess (Process->ExitStatus);
        } else {
            DbgkExitThread (ExitStatus);
        }
    }
}

事实上, 销毁这边的代码是非常的简单的. 都不多. 这是线程退出的代码DbgkExitThread, 来自ReactOS.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
VOID
NTAPI
DbgkExitThread(IN NTSTATUS ExitStatus)
{
    DBGKM_MSG ApiMessage;
    PDBGKM_EXIT_THREAD ExitThread = &ApiMessage.ExitThread;
    PEPROCESS Process = PsGetCurrentProcess();
    PETHREAD Thread = PsGetCurrentThread();
    BOOLEAN Suspended;
    PAGED_CODE();

	//
    // 一些参数检测, 没有什么营养
    //
    if ((Thread->HideFromDebugger) ||
        !(Process->DebugPort) ||
        (Thread->DeadThread))
    {
        /* Don't notify the debugger */
        return;
    }

	//
    // 填充线程退出信息结构
    //
    ExitThread->ExitStatus = ExitStatus;

    /* Setup the API Message */
    ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
                             (8 + sizeof(DBGKM_EXIT_THREAD));
    ApiMessage.h.u2.ZeroInit = 0;
    ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT;
    ApiMessage.ApiNumber = DbgKmExitThreadApi;

	//
  	// 挂起除了本线程外的所有线程, 其实是脱裤子放屁, DbgkpSuspendProcess也有这个代码
  	//
    Suspended = DbgkpSuspendProcess();

    /* Send the message */
    DbgkpSendApiMessage(&ApiMessage, FALSE);

    /* Resume the process if needed */
    if (Suspended)
    {
    	DbgkpResumeProcess();
    }
}

下面是DbgkExitProcess的代码, 也没有做太多事情..

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
VOID
NTAPI
DbgkExitProcess(IN NTSTATUS ExitStatus)
{
    DBGKM_MSG ApiMessage;
    PDBGKM_EXIT_PROCESS ExitProcess = &ApiMessage.ExitProcess;
    PEPROCESS Process = PsGetCurrentProcess();
    PETHREAD Thread = PsGetCurrentThread();
    PAGED_CODE();

   	// 参数判断
    if ((Thread->HideFromDebugger) ||
        !(Process->DebugPort) ||
        (Thread->DeadThread))
    {
        /* Don't notify the debugger */
        return;
    }

	//
    // 填写调试信息结构
    //
    ExitProcess->ExitStatus = ExitStatus;

    /* Setup the API Message */
    ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
                             (8 + sizeof(DBGKM_EXIT_PROCESS));
    ApiMessage.h.u2.ZeroInit = 0;
    ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT;
    ApiMessage.ApiNumber = DbgKmExitProcessApi;

    /* Set the current exit time */
    KeQuerySystemTime(&Process->ExitTime);

    /* Send the message */
    DbgkpSendApiMessage(&ApiMessage, FALSE);
}