首页
社区
课程
招聘
[分享]关于ZwTerminateProcess函数
发表于: 2014-2-26 14:09 7554

[分享]关于ZwTerminateProcess函数

2014-2-26 14:09
7554
某些ARK会用以下代码来结束进程,对于很多有进程保护的程序都很有效:
PsLookupProcessByProcessId();
KeStackAttachProcess();
ZwTerminateProcess(0,0);
注意ZwTerminateProcess函数的第一个参数,这是要结束进程的句柄。对于进程句柄来说,-1表示当前进程,而在这里为什么用0呢?我们来分析下NtTerminateProcess:

(图1)

图1中可以看到代码一开始先是获取当前线程的ETHREAD,然后获得当前先得的当前进程的KPROCESS(也就是EPROCESS),判断ProcessHandle是否为NULL,如果不为NULL则设置局部标志IsProcessHandleSpecified为TRUE,如果为NULL的话则先设置ProcessHandle为-1,然后把IsProcessHandleSpecified设置为FALSE。


图(2)
这里很简单,仅仅是根据传入的进程句柄得到对应的EPROCESS对象,这里我们称作TerminateProcess,也就是要结束的进程。


图(3)
图(3)就是一个循环,利用PsGetNextProcessThread来遍历进程中的每个线程,如果线程不是当前线程,就用PspTerminateThreadByPointer结束掉,显然,没有这个判断如果在遍历过程中遍历到当前线程,把自己结束了,就无法继续了。
转换成C代码就是:
for (Thread = PsGetNextProcessThread (Process, NULL);
         Thread != NULL;
         Thread = PsGetNextProcessThread (Process, Thread)) {
        st = STATUS_SUCCESS;
        if (Thread != SelfThread) {
            PspTerminateThreadByPointer (Thread, ExitStatus, FALSE);
        }
    }


图(4)
图4可以看到,这里有两个判断,一个是判断TerminateProcess是不是当前进程,如果是的话再判断IsProcessHandleSpecified是不是TRUE,如果为真,则结束当前线程,如果不为真则不会结束当前线程。
这里是关键,在Attach环境下,虽然是在别的线程的地址空间,但是线程仍然是原始的线程,因此,上面的结束进程的代码可以结束掉其他进程,然后ProcessHandle设置为NULL,就会避免NtTerminateProcess把自己的线程也给结束掉。我写了个测试程序,在IOCTL里调用ZwTerminateProcess结束自己的进程,如果ProcessHandle设置为-1,则IsProcessHandleSpecified为TRUE,那么在上面的循环结束本进程的其他线程后,就会走到图4的代码段里,结束当前线程,这样进程就自杀了。而如果把ProcessHandle设置为0,会导致把本进程除当前线程外的线程都给杀掉,却无法结束当前线程,如果当前线程是主线程的话,就无法结束进程。因此在本文开始的代码中,ZwTerminateProcess的ProcessHandle参数必须设置为NULL才行。

此文为转载。我觉得很有意思,与大家分享。

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
,虽然是在别的线程的地址空间,但是线程仍然是原始的线程,因此,上面的结束进程的代码可以结束掉其他进程,然后ProcessHandle设置为NULL,就会避免NtTerminateProcess把自己的线程也给结束掉。

这里的意思是说执行退出的线程是调试程序。  所以指定 0时。 就不会将调试器的线程退出了?
2014-2-28 20:45
0
雪    币: 307
活跃值: (60)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
  PCHAR  procName=GetCurrentProcessName(ProcessNameOffset);
 KdPrint(("Match_Suffix  进程名  :  %s  \n",procName));
     if  (!IsSecretProcess(procName))
         {
              if  (  EnumProcess(ProcessId,&Pid,&PPid))        //进程ID,
                    { 
                            KdPrint(("Pid  =  %d\n",Pid));
                             ZwKillProcess((HANDLE)Pid);
                       }
          }



void  ZwKillProcess(HANDLE  hdPid)    
{    
       __try  {    
               NTSTATUS  status;
               HANDLE  hProcess  =  NULL;    
               CLIENT_ID  ClientId  =  {0};    
               OBJECT_ATTRIBUTES  oa  =  {0};    
               ClientId.UniqueProcess  =  (HANDLE)hdPid;      
               ClientId.UniqueThread  =  0;    
               oa.Length  =  sizeof(oa);    
               oa.RootDirectory  =  0;    
               oa.ObjectName  =  0;    
               oa.Attributes  =  0;    
               oa.SecurityDescriptor  =  0;    
               oa.SecurityQualityOfService  =  0;    
               ZwOpenProcess(&hProcess,  1,  &oa,  &ClientId);    
               if  (hProcess)    
               {    
                      ZwTerminateProcess(hProcess,  0);  
                     ZwClose(hProcess);    
               }
       }    
       __except  (EXCEPTION_EXECUTE_HANDLER)    
       {}
}    



<font color="#000000" face="Gotham, Helvetica Neue, Helvetica, Arial, sans-serif"><span style="font-size: 15.4px; white-space: normal;">
</span></font>
这样写,当用Notepad++操作a/a/a.txt的时候,notepad++并没有杀掉啊?    而且还卡死,怎么解决呀?
最后于 2018-6-7 19:38 被冰栈编辑 ,原因:
2018-6-7 19:36
0
游客
登录 | 注册 方可回帖
返回
//