使用TerminateProcess函数实现结束指定进程

Theheartoflove

发布日期: 2018-12-20 12:08:25 浏览量: 1160
评分:
star star star star star star star star_border star_border star_border
*转载请注明来自write-bug.com

背景

对于计算机上面的进程我们比较熟悉了,每次只要我们想关闭那些关闭掉的窗口或程序的时候,我们就会打开任务管理器,然后在里面选中进程,右击结束进程,那么程序就会关掉了。

本文要介绍的,正是如何使用 TerminateProcess 函数结束进程,实现与任务管理器相同的结束进程功能。现在,我就把程序实现的过程和原理整理成文档,分享给大家。

函数介绍

OpenProcess 函数

打开现有的本地进程对象。

函数声明

  1. HANDLE WINAPI OpenProcess(
  2. _In_ DWORD dwDesiredAccess,
  3. _In_ BOOL bInheritHandle,
  4. _In_ DWORD dwProcessId
  5. );

参数

  • dwDesiredAccess [in]
    访问进程对象。此访问权限针对进程的安全描述符进行检查。此参数可以是一个或多个进程访问权限。如果调用该函数的进程启用了SeDebugPrivilege权限,则无论安全描述符的内容如何,都会授予所请求的访问权限。
  • bInheritHandle [in]
    若此值为TRUE,则此进程创建的进程将继承该句柄。否则,进程不会继承此句柄。
  • dwProcessId [in]
    要打开的本地进程的标识符。
    如果指定的进程是系统进程(0x00000000),则该函数失败,最后一个错误代码为ERROR_INVALID_PARAMETER。如果指定的进程是空闲进程或CSRSS进程之一,则此功能将失败,并且最后一个错误代码为ERROR_ACCESS_DENIED,因为它们的访问限制会阻止用户级代码打开它们。
    如果您使用GetCurrentProcessId作为此函数的参数,请考虑使用GetCurrentProcess而不是OpenProcess,以提高性能。

返回值

  • 如果函数成功,则返回值是指定进程的打开句柄。
  • 如果函数失败,返回值为NULL。 要获取扩展错误信息,请调用GetLastError。

TerminateProcess 函数

终止指定的进程及其所有线程。

函数声明

  1. BOOL WINAPI TerminateProcess(
  2. _In_ HANDLE hProcess,
  3. _In_ UINT uExitCode
  4. );

参数

  • hProcess [in]
    要终止的进程的句柄。
    句柄必须具有PROCESS_TERMINATE访问权限。
  • uExitCode [in]
    进程使用的退出代码和作为此调用的结果而终止的线程。

返回值

  • 如果函数成功,则返回值不为零。
  • 如果函数失败,返回值为零。 要获取扩展错误信息,请调用GetLastError。

实现过程

从上面的函数介绍知道,要想使用 TerminateProcess 函数,首先,我们先要获取进程句柄。那么,获取进程的句柄,我们可以调用 OpenProcess 函数根据进程的 PID 打开进程并获取进程句柄。

对于 OpenProcess 函数,第 1 个参数表示设置访问进程的权限,本文指定了权限 PROCESS_TERMINATE ,是因为 TerminateProcess 函数要求进程句柄要有访问权限 PROCESS_TERMINATE;第 2 个参数表示是否继承句柄,FALSE表示不继承;第 3 个参数表示要打开进程的PID。 在 OpenProcess 函数成功执行后,便返回进程句柄。

  1. // 打开进程, 获取进程句柄
  2. HANDLE hProcess = ::OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessId);
  3. if (NULL == hProcess)
  4. {
  5. ShowError("OpenProcess");
  6. return FALSE;
  7. }

然后,我们使用 TerminateProcess 函数结束进程。其中,第 1 个参数表示进程的句柄,要求进程句柄包含有 PROCESS_TERMINATE 访问权限;第 2 个参数表示设置一个退出代码,这个值可以任意设值。

  1. // 结束进程
  2. BOOL bRet = ::TerminateProcess(hProcess, 0);
  3. if (FALSE == bRet)
  4. {
  5. ::CloseHandle(hProcess);
  6. ShowError("TerminateProcess");
  7. return FALSE;
  8. }

这样,经过上面的两步操作,就可以实现将指定进程结束掉。

编程实现

  1. BOOL TerminateProcessTest(DWORD dwProcessId)
  2. {
  3. // 打开进程, 获取进程句柄
  4. HANDLE hProcess = ::OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessId);
  5. if (NULL == hProcess)
  6. {
  7. ShowError("OpenProcess");
  8. return FALSE;
  9. }
  10. // 结束进程
  11. BOOL bRet = ::TerminateProcess(hProcess, 0);
  12. if (FALSE == bRet)
  13. {
  14. ::CloseHandle(hProcess);
  15. ShowError("TerminateProcess");
  16. return FALSE;
  17. }
  18. // 关闭进程句柄
  19. ::CloseHandle(hProcess);
  20. return TRUE;
  21. }

程序测试

我们直接运行程序,输入要结束进程的PID,指定进程成功被结束。

总结

要注意的是,使用 OpenProcess 函数打开进程的时候,设置的访问权限一定要包含 PROCESS_TERMINATE 权限,否则调用 TerminateProcess 函数会出错。

这个程序可以结束普通权限的进程,也可以结束一些以管理员权限运行的进程。但是,对于一些系统进程,或者进行进程保护处理的程序,则超过此程序的功能范围了。

参考

参考自《Windows黑客编程技术详解》一书

上传的附件 cloud_download TerminateProcess_Test.7z ( 151.59kb, 5次下载 )

发送私信

昨日渐多,明日渐少,这就是人生

13
文章数
26
评论数
最近文章
eject