为何Windows进程需用GetCurrentProcess而非GetCurrentProcessId自终止?
为什么Windows进程自终止必须用GetCurrentProcess而非GetCurrentProcessId?
我正在学习Windows内核相关知识,发现Windows没有类Unix系统中的_exit系统调用,进程需通过TerminateProcess/NtTerminateProcess实现自终止。ExitProcess/RtlExitUserProcess API在自终止前会执行清理操作。
测试发现,TerminateProcess/NtTerminateProcess配合GetCurrentProcess/NtCurrentProcess/(HANDLE)-1可正常工作,但使用GetCurrentProcessId/gs:[0x40]时却无法生效,相关代码示例如下:
C代码示例
#include <windows.h> int main(void) { TerminateProcess(GetCurrentProcess(), 0); // 可正常运行 TerminateProcess(GetCurrentProcessId(), 0); // 无法运行 }
汇编代码示例
mov rcx, -1 xor edx, edx call TerminateProcess ; 此段可正常运行 call GetCurrentProcessId mov ecx, eax xor edx, edx call TerminateProcess ; 此段无法运行
核心原因:参数类型与内核对象标识的本质区别
TerminateProcess的参数要求明确
TerminateProcess函数的第一个参数必须是进程句柄(HANDLE类型),而非进程ID(DWORD类型):GetCurrentProcess()返回的是固定值为(HANDLE)-1的伪句柄,系统会在调用时自动将其解析为当前进程的有效句柄,默认具备终止自身的权限。GetCurrentProcessId()返回的是DWORD类型的进程ID,它只是内核标记进程的唯一编号,不能直接作为句柄传递给需要HANDLE参数的API。
句柄与进程ID的本质差异
- 句柄是进程对内核对象的引用,包含对象的访问权限信息,系统通过句柄定位并操作对应的内核对象。
- 进程ID仅用于标识进程的唯一性,本身不包含权限或对象引用信息。如果要通过进程ID获取可用于终止的句柄,必须调用
OpenProcess函数,指定PROCESS_TERMINATE权限来获取有效句柄。
伪句柄的特殊性
GetCurrentProcess()返回的伪句柄是系统预定义的特殊值,无需手动关闭,系统会在每次使用时自动将其映射到当前进程的真实句柄,因此可以直接用于TerminateProcess调用。
内容的提问来源于stack exchange,提问作者Ex-Kyuto
相关产品推荐
相关产品推荐

