欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

进程隐藏与进程保护(SSDT Hook 实现)(三)

程序员文章站 2022-07-13 16:36:50
...

文章目录:         

1. 引子:

2. 获取当前系统下所有进程:

3. 服务管理(安装,启动,停止,卸载):

4. 应用程序和内核程序通信:

5. 小结:

                

1. 引子:                         

关于这个 SSDT Hook 实现进程隐藏和进程保护呢,这是最后一篇博文了,

在文章的结尾处呢你可以下载到整个项目的实例程序以及代码,

程序可以在 XP、Server、Win7 上运行的,当然我是说的 32 位操作系统。       

                  

《进程隐藏与进程保护(SSDT Hook 实现)(一)》呢把 SSDT Hook 的原理说得差不多了,

博文地址:http://www.cnblogs.com/BoyXiao/archive/2011/09/03/2164574.html

《进程隐藏与进程保护(SSDT Hook 实现)(二)》则把 SSDT Hook 的实现说得差不多了,

博文地址:http://www.cnblogs.com/BoyXiao/archive/2011/09/04/2166596.html

             

这一篇博文介绍的则是在 Ring3 下编写 MFC 应用程序,并且让应用程序与内核程序通信,

即由应用程序将需要隐藏的进程或者是需要保护的进程的 PID 传递给内核程序,

然后在内核程序中就会将传递进来的这个 PID 进行隐藏或者保护 ~

在这里再给出这个应用程序的一张截图:

进程隐藏与进程保护(SSDT Hook 实现)(三)

        

                

2. 获取当前系统下所有进程:

                 

前面提到过,要想获取到系统下的所有进程,有三种方法,

第一种即是使用 ToolHelp 来获取,

第二种则是使用 PSAPI 来获取,

第三种则是使用 ntdll.dll 中的未文档化的 NtQuerySystemInformation 之类的 API 来获取(比较麻烦)。

而在这里我使用最简单的方式,即通过 PSAPI 中的 EnumProcesses 这个 API 来获取,

EnumProcesses API 可以获取到当前系统下所有进程的 PID,并且将 PID 存放在作为输出参数的数组当中,

其原型如下(可以看 MSDN):

<span style="color:black"><span style="color:black"><span style="color:#606060">   1:  </span>BOOL WINAPI EnumProcesses(</span></span>
   2:    __out         DWORD* pProcessIds,
<span style="color:black"><span style="color:black"><span style="color:#606060">   3:  </span>  __in          DWORD cb,</span></span>
   4:    __out         DWORD* pBytesReturned
<span style="color:black"><span style="color:black"><span style="color:#606060">   5:  </span>);</span></span>
   6:   

     

代码中使用(将获取到所有的 PID,然后将 PID 保存到 vector 容器中):

<span style="color:black"><span style="color:black"><span style="color:#606060">   1:  </span><span style="color:#008000">//遍历当前所有的进程,并且将进程 ID 填充到容器 vectorPID 中</span></span></span>
   2:  void CSSDTProcessDlg::FillPIDVector()
<span style="color:black"><span style="color:black"><span style="color:#606060">   3:  </span>{</span></span>
   4:      DWORD dwPIDArray[MAX_PROCESS_COUNT];
<span style="color:black"><span style="color:black"><span style="color:#606060">   5:  </span>    DWORD dwNeededBytes;</span></span>
   6:      DWORD dwProcCount;
<span style="color:black"><span style="color:black"><span style="color:#606060">   7:  </span> </span></span>
   8:      dwNeededBytes = 0;
<span style="color:black"><span style="color:black"><span style="color:#606060">   9:  </span>    dwProcCount = 0;</span></span>
  10:      memset(dwPIDArray, 0, sizeof(DWORD) * MAX_PROCESS_COUNT);
<span style="color:black"><span style="color:black"><span style="color:#606060">  11:  </span>    <span style="color:#0000ff">if</span>(NULL != EnumProcesses(dwPIDArray, <span style="color:#0000ff">sizeof</span>(dwPIDArray), &dwNeededBytes))</span></span>
  12:      {
<span style="color:black"><span style="color:black"><span style="color:#606060">  13:  </span>        dwProcCount = dwNeededBytes / <span style="color:#0000ff">sizeof</span>(DWORD);</span></span>
  14:      }
<span style="color:black"><span style="color:black"><span style="color:#606060">  15:  </span> </span></span>
  16:      BubbleSort(dwPIDArray, dwProcCount);
<span style="color:black"><span style="color:black"><span style="color:#606060">  17:  </span> </span></span>
  18:      ClearVector();
<span style="color:black"><span style="color:black"><span style="color:#606060">  19:  </span>    <span style="color:#0000ff">for</span>(<span style="color:#0000ff">int</span> i=0; i<dwProcCount; i++)</span></span>
  20:      {
<span style="color:black"><span style="color:black"><span style="color:#606060">  21:  </span>        PROCESS_BIND procBind;</span></span>
  22:          procBind.dwPID = dwPIDArray[i];
<span style="color:black"><span style="color:black"><span style="color:#606060">  23:  </span>        <span style="color:#0000ff">if</span>(dwPIDArray[i] == 0)</span></span>
  24:          {
<span style="color:black"><span style="color:black"><span style="color:#606060">  25:  </span>            procBind.state = ProcessStateUnknown;</span></span>
  26:          }
<span style="color:black"><span style="color:black"><span style="color:#606060">  27:  </span>        <span style="color:#0000ff">else</span></span></span>
  28:          {
<span style="color:black"><span style="color:black"><span style="color:#606060">  29:  </span>            procBind.state = ProcessStateGeneral;</span></span>
  30:          }
<span style="color:black"><span style="color:black"><span style="color:#606060">  31:  </span>        <span style="color:#0000ff">this</span>->m_vctAllProcess.push_back(procBind);</span></span>
  32:      }
<span style="color:black"><span style="color:black"><span style="color:#606060">  33:  </span>}</span></span>

        

                

3. 服务管理(安装,启动,停止,卸载):

             

在 Windows 内核程序中,现在大体可以分为三类了,

第一类是 NT 式驱动程序;

第二类为 WDM 驱动程序;

第三类为 WDF 驱动程序;

其中,对于 NT 式驱动程序,其安装方式是很简单的,因为你可以将 NT 式驱动程序看做一个服务,

既然是服务的话,自然在 Windows 中可以通过 SCM API 来完成其安装,启动,停止和卸载等功能 ~

而至于 WDM 和 WDF 的话,如果其中涉及到了设备的话,还必须使用 INF 文件来实现安装 ~

而我们前面的那个 SSDT 内核程序就是基于 NT 式的驱动程序,所以可以通过 SCM API 来实现上面的这些功能,

至于如何使用 SCM API 来完成服务的安装、启动、停止和卸载功能的话,

可以参见笔者的另外一篇博文《Windows 服务(附服务开发辅助工具)》,

博文地址为:http://www.cnblogs.com/BoyXiao/archive/2011/08/07/2130208.html

下面就只是将服务的安装 API、启动 API、停止 API 和卸载 API 贴出来了 ~

至于这些代码的细细道来的话,可以参加上面给出的那篇博文的 ~

<span style="color:black"><span style="color:black"><span style="color:#606060">   1:  </span><span style="color:#008000">//=====================================================================================//</span></span></span>
   2:  //Name: bool InstallSvc()                                                              //
<span style="color:black"><span style="color:black"><span style="color:#606060">   3:  </span><span style="color:#008000">//                                                                                     //</span></span></span>
   4:  //Descripion: 安装服务                                                                 //
<span style="color:black"><span style="color:black"><span style="color:#606060">   5:  </span><span style="color:#008000">//            lpszSvcName 为服务名称,                                                 //</span></span></span>
   6:  //            lpszDisplay 为显示在服务控制管理器中的名称,                             //
<span style="color:black"><span style="color:black"><span style="color:#606060">   7:  </span><span style="color:#008000">//            lpszSvcBinaryPath 为服务映像文件所在路径,                               //</span></span></span>
   8:  //            dwSvcType 为服务类型                                                     //
<span style="color:black"><span style="color:black"><span style="color:#606060">   9:  </span><span style="color:#008000">//            dwStartType 为服务启动类型                                               //</span></span></span>
  10:  //=====================================================================================//
<span style="color:black"><span style="color:black"><span style="color:#606060">  11:  </span><span style="color:#0000ff">bool</span> CSSDTProcessDlg::InstallSvc(LPTSTR lpszSvcName, LPTSTR lpszDisplayName,</span></span>
  12:          LPTSTR lpszSvcBinaryPath, DWORD dwSvcType, DWORD dwStartType)
<span style="color:black"><span style="color:black"><span style="color:#606060">  13:  </span>{</span></span>
  14:      SC_HANDLE hSCM = NULL;
<span style="color:black"><span style="color:black"><span style="color:#606060">  15:  </span>    SC_HANDLE hSvc = NULL;</span></span>
  16:   
<span style="color:black"><span style="color:black"><span style="color:#606060">  17:  </span>    AdjustProcessTokenPrivilege();</span></span>
  18:   
<span style="color:black"><span style="color:black"><span style="color:#606060">  19:  </span>    hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);</span></span>
  20:      if(NULL == hSCM)
<span style="color:black"><span style="color:black"><span style="color:#606060">  21:  </span>    {</span></span>
  22:          OutputErrorMessage(TEXT("InstallSvc - OpenSCManager Failed , Error Code Is %d , Error Message Is %s !"));
<span style="color:black"><span style="color:black"><span style="color:#606060">  23:  </span> </span></span>
  24:          return FALSE;
<span style="color:black"><span style="color:black"><span style="color:#606060">  25:  </span>    }</span></span>
  26:   
<span style="color:black"><span style="color:black"><span style="color:#606060">  27:  </span>    <span style="color:#0000ff">for</span>(<span style="color:#0000ff">int</span> i = 0; i < 3 && (NULL == hSvc); i++)</span></span>
  28:      {
<span style="color:black"><span style="color:black"><span style="color:#606060">  29:  </span>        <span style="color:#008000">//SERVICE_WIN32_OWN_PROCESS  | SERVICE_INTERACTIVE_PROCESS</span></span></span>
  30:          hSvc = CreateService(hSCM, lpszSvcName, lpszDisplayName, SERVICE_ALL_ACCESS, 
<span style="color:black"><span style="color:black"><span style="color:#606060">  31:  </span>            dwSvcType, dwStartType, SERVICE_ERROR_NORMAL, </span></span>
  32:              lpszSvcBinaryPath, NULL, NULL, NULL, NULL, NULL);
<span style="color:black"><span style="color:black"><span style="color:#606060">  33:  </span>        <span style="color:#0000ff">if</span>(NULL != hSvc)</span></span>
  34:          {
<span style="color:black"><span style="color:black"><span style="color:#606060">  35:  </span>            <span style="color:#0000ff">if</span>(NULL != hSvc)</span></span>
  36:              {
<span style="color:black"><span style="color:black"><span style="color:#606060">  37:  </span>                CloseServiceHandle(hSvc);</span></span>
  38:              }
<span style="color:black"><span style="color:black"><span style="color:#606060">  39:  </span>            CloseServiceHandle(hSCM);</span></span>
  40:              return TRUE;
<span style="color:black"><span style="color:black"><span style="color:#606060">  41:  </span>        }</span></span>
  42:      }
<span style="color:black"><span style="color:black"><span style="color:#606060">  43:  </span> </span></span>
  44:      OutputErrorMessage(TEXT("InstallSvc - CreateService Failed , Error Code Is %d , Error Message Is %s !"));
<span style="color:black"><span style="color:black"><span style="color:#606060">  45:  </span> </span></span>
  46:      CloseServiceHandle(hSCM);
<span style="color:black"><span style="color:black"><span style="color:#606060">  47:  </span> </span></span>
  48:      return FALSE;
<span style="color:black"><span style="color:black"><span style="color:#606060">  49:  </span>}</span></span>
  50:   
<span style="color:black"><span style="color:black"><span style="color:#606060">  51:  </span> </span></span>
  52:  //=====================================================================================//
<span style="color:black"><span style="color:black"><span style="color:#606060">  53:  </span><span style="color:#008000">//Name: bool UnInstallSvc()                                                            //</span></span></span>
  54:  //                                                                                     //
<span style="color:black"><span style="color:black"><span style="color:#606060">  55:  </span><span style="color:#008000">//Descripion: 实现卸载服务                                                             //</span></span></span>
  56:  //=====================================================================================//
<span style="color:black"><span style="color:black"><span style="color:#606060">  57:  </span><span style="color:#0000ff">bool</span> CSSDTProcessDlg::UnInstallSvc(LPTSTR lpszSvcName)</span></span>
  58:  {
<span style="color:black"><span style="color:black"><span style="color:#606060">  59:  </span>    SC_HANDLE hSCM = NULL;</span></span>
  60:      SC_HANDLE hSvc = NULL;
<span style="color:black"><span style="color:black"><span style="color:#606060">  61:  </span>    <span style="color:#0000ff">bool</span> rtResult = FALSE;</span></span>
  62:   
<span style="color:black"><span style="color:black"><span style="color:#606060">  63:  </span>    AdjustProcessTokenPrivilege();</span></span>
  64:   
<span style="color:black"><span style="color:black"><span style="color:#606060">  65:  </span>    hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);</span></span>
  66:      if(NULL == hSCM)
<span style="color:black"><span style="color:black"><span style="color:#606060">  67:  </span>    {</span></span>
  68:          OutputErrorMessage(TEXT("UnInstallSvc - OpenSCManager Failed , Error Code Is %d , Error Message Is %s !"));
<span style="color:black"><span style="color:black"><span style="color:#606060">  69:  </span> </span></span>
  70:          return FALSE;
<span style="color:black"><span style="color:black"><span style="color:#606060">  71:  </span>    }</span></span>
  72:   
<span style="color:black"><span style="color:black"><span style="color:#606060">  73:  </span>    hSvc = OpenService(hSCM, lpszSvcName, SERVICE_ALL_ACCESS);</span></span>
  74:      if(NULL == hSvc)
<span style="color:black"><span style="color:black"><span style="color:#606060">  75:  </span>    {</span></span>
  76:          OutputErrorMessage(TEXT("UnInstallSvc - OpenService Failed , Error Code Is %d , Error Message Is %s !"));
<span style="color:black"><span style="color:black"><span style="color:#606060">  77:  </span> </span></span>
  78:          CloseServiceHandle(hSCM);
<span style="color:black"><span style="color:black"><span style="color:#606060">  79:  </span> </span></span>
  80:          return FALSE;
<span style="color:black"><span style="color:black"><span style="color:#606060">  81:  </span>    }</span></span>
  82:   
<span style="color:black"><span style="color:black"><span style="color:#606060">  83:  </span>    rtResult = DeleteService(hSvc);</span></span>
  84:   
<span style="color:black"><span style="color:black"><span style="color:#606060">  85:  </span>    CloseServiceHandle(hSvc);</span></span>
  86:      CloseServiceHandle(hSCM);
<span style="color:black"><span style="color:black"><span style="color:#606060">  87:  </span> </span></span>
  88:      return rtResult;
<span style="color:black"><span style="color:black"><span style="color:#606060">  89:  </span>}</span></span>
  90:   
<span style="color:black"><span style="color:black"><span style="color:#606060">  91:  </span> </span></span>
  92:  //=====================================================================================//
<span style="color:black"><span style="color:black"><span style="color:#606060">  93:  </span><span style="color:#008000">//Name: bool StartSvc()                                                                //</span></span></span>
  94:  //                                                                                     //
<span style="color:black"><span style="color:black"><span style="color:#606060">  95:  </span><span style="color:#008000">//Descripion: 实现启动服务                                                             //</span></span></span>
  96:  //=====================================================================================//
<span style="color:black"><span style="color:black"><span style="color:#606060">  97:  </span><span style="color:#0000ff">bool</span> CSSDTProcessDlg::StartSvc(LPTSTR lpszSvcName)</span></span>
  98:  {
<span style="color:black"><span style="color:black"><span style="color:#606060">  99:  </span>    SC_HANDLE hSCM = NULL;</span></span>
 100:      SC_HANDLE hSvc = NULL;
<span style="color:black"><span style="color:black"><span style="color:#606060"> 101:  </span>    <span style="color:#0000ff">bool</span> rtResult = FALSE;</span></span>
 102:   
<span style="color:black"><span style="color:black"><span style="color:#606060"> 103:  </span>    AdjustProcessTokenPrivilege();</span></span>
 104:   
<span style="color:black"><span style="color:black"><span style="color:#606060"> 105:  </span>    hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);</span></span>
 106:      if(NULL == hSCM)
<span style="color:black"><span style="color:black"><span style="color:#606060"> 107:  </span>    {</span></span>
 108:          OutputErrorMessage(TEXT("StartSvc - OpenSCManager Failed , Error Code Is %d , Error Message Is %s !"));
<span style="color:black"><span style="color:black"><span style="color:#606060"> 109:  </span> </span></span>
 110:          return FALSE;
<span style="color:black"><span style="color:black"><span style="color:#606060"> 111:  </span>    }</span></span>
 112:   
<span style="color:black"><span style="color:black"><span style="color:#606060"> 113:  </span>    hSvc = OpenService(hSCM, lpszSvcName, SERVICE_ALL_ACCESS);</span></span>
 114:      if(NULL == hSvc)
<span style="color:black"><span style="color:black"><span style="color:#606060"> 115:  </span>    {</span></span>
 116:          OutputErrorMessage(TEXT("StartSvc - OpenService Failed , Error Code Is %d , Error Message Is %s !"));
<span style="color:black"><span style="color:black"><span style="color:#606060"> 117:  </span> </span></span>
 118:          CloseServiceHandle(hSCM);
<span style="color:black"><span style="color:black"><span style="color:#606060"> 119:  </span> </span></span>
 120:          return FALSE;
<span style="color:black"><span style="color:black"><span style="color:#606060"> 121:  </span>    }</span></span>
 122:   
<span style="color:black"><span style="color:black"><span style="color:#606060"> 123:  </span>    rtResult = StartService(hSvc, NULL, NULL);</span></span>
 124:   
<span style="color:black"><span style="color:black"><span style="color:#606060"> 125:  </span>    CloseServiceHandle(hSvc);</span></span>
 126:      CloseServiceHandle(hSCM);
<span style="color:black"><span style="color:black"><span style="color:#606060"> 127:  </span> </span></span>
 128:      if(FALSE == rtResult)
<span style="color:black"><span style="color:black"><span style="color:#606060"> 129:  </span>    {</span></span>
 130:          if(ERROR_SERVICE_ALREADY_RUNNING == GetLastError())
<span style="color:black"><span style="color:black"><span style="color:#606060"> 131:  </span>        {</span></span>
 132:              return TRUE;
<span style="color:black"><span style="color:black"><span style="color:#606060"> 133:  </span>        }</span></span>
 134:          else
<span style="color:black"><span style="color:black"><span style="color:#606060"> 135:  </span>        {</span></span>
 136:              OutputErrorMessage(TEXT("StartSvc - StartService Failed , Error Code Is %d , Error Message Is %s !"));
<span style="color:black"><span style="color:black"><span style="color:#606060"> 137:  </span> </span></span>
 138:              return FALSE;
<span style="color:black"><span style="color:black"><span style="color:#606060"> 139:  </span>        }</span></span>
 140:      }
<span style="color:black"><span style="color:black"><span style="color:#606060"> 141:  </span>    <span style="color:#0000ff">else</span></span></span>
 142:      {
<span style="color:black"><span style="color:black"><span style="color:#606060"> 143:  </span>        <span style="color:#0000ff">return</span> TRUE;</span></span>
 144:      }
<span style="color:black"><span style="color:black"><span style="color:#606060"> 145:  </span>}</span></span>
 146:   
<span style="color:black"><span style="color:black"><span style="color:#606060"> 147:  </span> </span></span>
 148:  //=====================================================================================//
<span style="color:black"><span style="color:black"><span style="color:#606060"> 149:  </span><span style="color:#008000">//Name: bool StopSvc()                                                                 //</span></span></span>
 150:  //                                                                                     //
<span style="color:black"><span style="color:black"><span style="color:#606060"> 151:  </span><span style="color:#008000">//Descripion: 实现停止服务                                                             //</span></span></span>
 152:  //=====================================================================================//
<span style="color:black"><span style="color:black"><span style="color:#606060"> 153:  </span><span style="color:#0000ff">bool</span> CSSDTProcessDlg::StopSvc(LPTSTR lpszSvcName)</span></span>
 154:  {
<span style="color:black"><span style="color:black"><span style="color:#606060"> 155:  </span>    SC_HANDLE hSCM = NULL;</span></span>
 156:      SC_HANDLE hSvc = NULL;
<span style="color:black"><span style="color:black"><span style="color:#606060"> 157:  </span>    <span style="color:#0000ff">bool</span> rtResult = FALSE;</span></span>
 158:   
<span style="color:black"><span style="color:black"><span style="color:#606060"> 159:  </span>    SERVICE_STATUS svcStatus;</span></span>
 160:   
<span style="color:black"><span style="color:black"><span style="color:#606060"> 161:  </span>    AdjustProcessTokenPrivilege();</span></span>
 162:   
<span style="color:black"><span style="color:black"><span style="color:#606060"> 163:  </span>    hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);</span></span>
 164:      if(NULL == hSCM)
<span style="color:black"><span style="color:black"><span style="color:#606060"> 165:  </span>    {</span></span>
 166:          OutputErrorMessage(TEXT("StopSvc - OpenSCManager Failed , Error Code Is %d , Error Message Is %s !"));
<span style="color:black"><span style="color:black"><span style="color:#606060"> 167:  </span> </span></span>
 168:          return FALSE;
<span style="color:black"><span style="color:black"><span style="color:#606060"> 169:  </span>    }</span></span>
 170:   
<span style="color:black"><span style="color:black"><span style="color:#606060"> 171:  </span>    hSvc = OpenService(hSCM, lpszSvcName, SERVICE_ALL_ACCESS);</span></span>
 172:      if(NULL == hSvc)
<span style="color:black"><span style="color:black"><span style="color:#606060"> 173:  </span>    {</span></span>
 174:          OutputErrorMessage(TEXT("StopSvc - OpenService Failed , Error Code Is %d , Error Message Is %s !"));
<span style="color:black"><span style="color:black"><span style="color:#606060"> 175:  </span> </span></span>
 176:          CloseServiceHandle(hSCM);
<span style="color:black"><span style="color:black"><span style="color:#606060"> 177:  </span> </span></span>
 178:          return FALSE;
<span style="color:black"><span style="color:black"><span style="color:#606060"> 179:  </span>    }</span></span>
 180:   
<span style="color:black"><span style="color:black"><span style="color:#606060"> 181:  </span>    rtResult = ControlService(hSvc, SERVICE_CONTROL_STOP, &svcStatus);</span></span>
 182:      if(rtResult == FALSE)
<span style="color:black"><span style="color:black"><span style="color:#606060"> 183:  </span>    {</span></span>
 184:          OutputErrorMessage(TEXT("StopSvc - ControlService Failed , Error Code Is %d , Error Message Is %s !"));
<span style="color:black"><span style="color:black"><span style="color:#606060"> 185:  </span>    }</span></span>
 186:      CloseServiceHandle(hSvc);
<span style="color:black"><span style="color:black"><span style="color:#606060"> 187:  </span>    CloseServiceHandle(hSCM);</span></span>
 188:   
<span style="color:black"><span style="color:black"><span style="color:#606060"> 189:  </span>    <span style="color:#0000ff">return</span> rtResult;</span></span>
 190:  }

       

那么服务的安装和启动放在那里比较合适,而服务的关闭和卸载又放在那里比较合适呢 ?

由于这个应用程序采用 MFC 开发,自然可以在 OnInitDialog()中安装和启动服务比较合适,

而后可以在对话框类的析构函数中关闭和卸载掉服务 ~

安装和启动服务:

<span style="color:black"><span style="color:black"><span style="color:#606060">   1:  </span>    wstring wStrSysPath = GetSysFilePath();</span></span>
   2:      BOOL bResult = InstallSvc(((LPTSTR)(LPCTSTR)SSDT01_SERVICE_NAME), 
<span style="color:black"><span style="color:black"><span style="color:#606060">   3:  </span>                              ((LPTSTR)(LPCTSTR)SSDT01_SERVICE_NAME), </span></span>
   4:                                ((LPTSTR)(LPCTSTR)wStrSysPath.c_str()), 
<span style="color:black"><span style="color:black"><span style="color:#606060">   5:  </span>                              SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START);</span></span>
   6:      if(FALSE == bResult)
<span style="color:black"><span style="color:black"><span style="color:#606060">   7:  </span>    {</span></span>
   8:          MessageBox(_TEXT(" Install SSDT Service Failed , Application Auto Exit !  "),
<span style="color:black"><span style="color:black"><span style="color:#606060">   9:  </span>                   _TEXT(<span style="color:#006080">"Application Error"</span>), MB_OK | MB_ICONSTOP);</span></span>
  10:          CDialogEx::OnCancel();        
<span style="color:black"><span style="color:black"><span style="color:#606060">  11:  </span>        <span style="color:#0000ff">return</span> FALSE;</span></span>
  12:      }
<span style="color:black"><span style="color:black"><span style="color:#606060">  13:  </span>    <span style="color:#0000ff">else</span></span></span>
  14:      {
<span style="color:black"><span style="color:black"><span style="color:#606060">  15:  </span>        bResult = StartSvc(SSDT01_SERVICE_NAME);</span></span>
  16:          if(FALSE == bResult)
<span style="color:black"><span style="color:black"><span style="color:#606060">  17:  </span>        {</span></span>
  18:              MessageBox(_TEXT(" Start SSDT Service Failed , Application Auto Exit !  "), 
<span style="color:black"><span style="color:black"><span style="color:#606060">  19:  </span>                       _TEXT(<span style="color:#006080">"Application Error"</span>), MB_OK | MB_ICONSTOP);</span></span>
  20:              CDialogEx::OnCancel();
<span style="color:black"><span style="color:black"><span style="color:#606060">  21:  </span>            <span style="color:#0000ff">return</span> FALSE;</span></span>
  22:          }
<span style="color:black"><span style="color:black"><span style="color:#606060">  23:  </span>    }</span></span>

           

停止并且将服务卸载掉:

<span style="color:black"><span style="color:black"><span style="color:#606060">   1:  </span>    ~CSSDTProcessDlg()</span></span>
   2:      {
<span style="color:black"><span style="color:black"><span style="color:#606060">   3:  </span>        <span style="color:#008000">//在析构函数中关闭 SSDT 设备句柄</span></span></span>
   4:          if(this->m_hDevice)
<span style="color:black"><span style="color:black"><span style="color:#606060">   5:  </span>        {</span></span>
   6:              CloseHandle(this->m_hDevice);
<span style="color:black"><span style="color:black"><span style="color:#606060">   7:  </span>        }</span></span>
   8:   
<span style="color:black"><span style="color:black"><span style="color:#606060">   9:  </span>        <span style="color:#008000">//当发生析构函数时,停止服务并且卸载服务</span></span></span>
  10:          StopSvc(SSDT01_SERVICE_NAME);
<span style="color:black"><span style="color:black"><span style="color:#606060">  11:  </span>        UnInstallSvc(SSDT01_SERVICE_NAME);</span></span>
  12:      }

        

                

4. 应用程序和内核程序通信:

           

由前面的第二篇博文,可以知道,应用程序和内核程序的通信我是通过 DeviceIoControl 来完成的,

开发过内核程序的都清楚,应用程序和内核程序的通信最普遍的也就通过三个 API 来实现,

一个 ReadFile,一个 WriteFile,一个 DeviceIoContrl,

当然其中属 DeviceIoControl 功能最为强大,完全可以用其替换掉 ReadFile 和 WriteFile,

DeviceIoControl 原型(详细信息可以参考 MSDN):

<span style="color:black"><span style="color:black"><span style="color:#606060">   1:  </span>BOOL WINAPI DeviceIoControl(</span></span>
   2:    __in          HANDLE hDevice,
<span style="color:black"><span style="color:black"><span style="color:#606060">   3:  </span>  __in          DWORD dwIoControlCode,</span></span>
   4:    __in          LPVOID lpInBuffer,
<span style="color:black"><span style="color:black"><span style="color:#606060">   5:  </span>  __in          DWORD nInBufferSize,</span></span>
   6:    __out         LPVOID lpOutBuffer,
<span style="color:black"><span style="color:black"><span style="color:#606060">   7:  </span>  __in          DWORD nOutBufferSize,</span></span>
   8:    __out         LPDWORD lpBytesReturned,
<span style="color:black"><span style="color:black"><span style="color:#606060">   9:  </span>  __in          LPOVERLAPPED lpOverlapped</span></span>
  10:  );
<span style="color:black"><span style="color:black"><span style="color:#606060">  11:  </span> </span></span>

         

至于如何实现应用程序和内核程序的通信的话,在我的 Demo 中是这样做处理的,

首先在 OnInitDialog 事件中通过 CreateFile 打开我们所安装的服务中创建的设备,

(在 NT 式驱动程序中我创建了一个设备,这个设备用来实现应用程序和内核程序的通信),

然后在对话框类中保存有一个全局变量,这个全局变量即代表所打开的这个设备的句柄,

进程隐藏与进程保护(SSDT Hook 实现)(三)

       

既然这个全局变量是保存的我们的设备的句柄,自然我们需要来获取到设备的句柄,并且将句柄赋值给该全局变量,

而这个呢,又是在 OnInitDialog 中完成的 ~

<span style="color:black"><span style="color:black"><span style="color:#606060">   1:  </span>    <span style="color:#0000ff">this</span>->m_hDevice = CreateFile(SSDT01_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, </span></span>
   2:                                   NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
<span style="color:black"><span style="color:black"><span style="color:#606060">   3:  </span>    <span style="color:#0000ff">if</span>(INVALID_HANDLE_VALUE == <span style="color:#0000ff">this</span>->m_hDevice)</span></span>
   4:      {
<span style="color:black"><span style="color:black"><span style="color:#606060">   5:  </span>        MessageBox(_TEXT(<span style="color:#006080">" Open SSDT Device Failed , Application Auto Exit !  "</span>), </span></span>
   6:                     _TEXT("Application Error"), MB_OK | MB_ICONSTOP);
<span style="color:black"><span style="color:black"><span style="color:#606060">   7:  </span> </span></span>
   8:          CDialogEx::OnCancel();
<span style="color:black"><span style="color:black"><span style="color:#606060">   9:  </span>        <span style="color:#0000ff">return</span> FALSE;</span></span>
  10:      }

        

有了这个设备句柄,我们就可以通过其来实现和内核程序的通信了,

因为通过在应用程序中调用 DeviceIoControl 可以产生 IRP_MJ_DEVICE_CONTROL 的 IRP,

然后该 IRP 可以被驱动程序中的 DeviceIoControl 分发函数所处理 ~

我们的应用程序只需要将我们所要隐藏或者是需要保护的进程的 PID 通过 DeviceIoControl 传递给内核程序即可 !!!

所以我们在应用程序中只需要调用 DeviceIoContrl 即可 ~

下面给出的代码比较凌乱(重点请看 DeviceIoControl 的调用)

<span style="color:black"><span style="color:black"><span style="color:#606060">   1:  </span><span style="color:#008000">//隐藏进程或者取消对进程的隐藏</span></span></span>
   2:  void CSSDTProcessDlg::OnBnClickedBtnHideorunhide()
<span style="color:black"><span style="color:black"><span style="color:#606060">   3:  </span>{</span></span>
   4:      int nIndex;
<span style="color:black"><span style="color:black"><span style="color:#606060">   5:  </span>    DWORD dwPID;</span></span>
   6:      CString cStrText;
<span style="color:black"><span style="color:black"><span style="color:#606060">   7:  </span>    CString cStrState;</span></span>
   8:      
<span style="color:black"><span style="color:black"><span style="color:#606060">   9:  </span>    DWORD dwOutput;</span></span>
  10:      BOOL bRet;
<span style="color:black"><span style="color:black"><span style="color:#606060">  11:  </span>    CHAR inBuffer[10];</span></span>
  12:      CHAR outBuffer[10];
<span style="color:black"><span style="color:black"><span style="color:#606060">  13:  </span>    memset(inBuffer, 0, 10);</span></span>
  14:      memset(outBuffer, 0, 10);
<span style="color:black"><span style="color:black"><span style="color:#606060">  15:  </span> </span></span>
  16:      dwPID = this->GetDlgItemInt(IDC_STATIC_SELECTED_PID);
<span style="color:black"><span style="color:black"><span style="color:#606060">  17:  </span>    <span style="color:#0000ff">this</span>->GetDlgItemText(ID_BTN_HIDEORUNHIDE, cStrText);</span></span>
  18:   
<span style="color:black"><span style="color:black"><span style="color:#606060">  19:  </span>    ultoa(dwPID, inBuffer, 10);</span></span>
  20:   
<span style="color:black"><span style="color:black"><span style="color:#606060">  21:  </span>    nIndex = QueryItemIndexByPID(dwPID);</span></span>
  22:      cStrState = this->m_ListCtrlProcess.GetItemText(nIndex, 4);
<span style="color:black"><span style="color:black"><span style="color:#606060">  23:  </span> </span></span>
  24:      if(cStrText.CompareNoCase(_TEXT("Hide")) == 0)
<span style="color:black"><span style="color:black"><span style="color:#606060">  25:  </span>    {</span></span>
  26:          //隐藏 dwPID
<span style="color:black"><span style="color:black"><span style="color:#606060">  27:  </span>        bRet = DeviceIoControl(<span style="color:#0000ff">this</span>->m_hDevice, IO_INSERT_HIDE_PROCESS, inBuffer, 10, </span></span>
  28:               &outBuffer, 10, &dwOutput, NULL);
<span style="color:black"><span style="color:black"><span style="color:#606060">  29:  </span>        <span style="color:#0000ff">if</span>(bRet)</span></span>
  30:          {
<span style="color:black"><span style="color:black"><span style="color:#606060">  31:  </span>            <span style="color:#0000ff">this</span>->SetDlgItemText(ID_BTN_HIDEORUNHIDE, _TEXT(<span style="color:#006080">"UnHide"</span>));</span></span>
  32:              if(cStrState.CompareNoCase(_TEXT("Protect")) == 0)
<span style="color:black"><span style="color:black"><span style="color:#606060">  33:  </span>            {</span></span>
  34:                  this->m_ListCtrlProcess.SetItemText(nIndex, 4, _TEXT("HideAndProtect"));
<span style="color:black"><span style="color:black"><span style="color:#606060">  35:  </span>            }</span></span>
  36:              else
<span style="color:black"><span style="color:black"><span style="color:#606060">  37:  </span>            {</span></span>
  38:                  this->m_ListCtrlProcess.SetItemText(nIndex, 4, _TEXT("Hide"));
<span style="color:black"><span style="color:black"><span style="color:#606060">  39:  </span>            }</span></span>
  40:              MessageBox(_TEXT(" Hide Process Sucess !  "), _TEXT("Information"), MB_OK | 
<span style="color:black"><span style="color:black"><span style="color:#606060">  41:  </span>                     MB_ICONINFORMATION);</span></span>
  42:          }
<span style="color:black"><span style="color:black"><span style="color:#606060">  43:  </span>        <span style="color:#0000ff">else</span></span></span>
  44:          {
<span style="color:black"><span style="color:black"><span style="color:#606060">  45:  </span>            MessageBox(_TEXT(<span style="color:#006080">" Hide Process Failed !  "</span>), _TEXT(<span style="color:#006080">"Warning"</span>), MB_OK | MB_ICONERROR);</span></span>
  46:          }
<span style="color:black"><span style="color:black"><span style="color:#606060">  47:  </span>    }</span></span>
  48:      else
<span style="color:black"><span style="color:black"><span style="color:#606060">  49:  </span>    {</span></span>
  50:          //解除 dwPID 隐藏
<span style="color:black"><span style="color:black"><span style="color:#606060">  51:  </span>        bRet = DeviceIoControl(<span style="color:#0000ff">this</span>->m_hDevice, IO_REMOVE_HIDE_PROCESS, inBuffer, 10, </span></span>
  52:               &outBuffer, 10, &dwOutput, NULL);
<span style="color:black"><span style="color:black"><span style="color:#606060">  53:  </span>        <span style="color:#0000ff">if</span>(bRet)</span></span>
  54:          {
<span style="color:black"><span style="color:black"><span style="color:#606060">  55:  </span>            <span style="color:#0000ff">this</span>->SetDlgItemText(ID_BTN_HIDEORUNHIDE, _TEXT(<span style="color:#006080">"Hide"</span>));</span></span>
  56:              if(cStrState.CompareNoCase(_TEXT("Protect")) == 0 || 
<span style="color:black"><span style="color:black"><span style="color:#606060">  57:  </span>               cStrState.CompareNoCase(_TEXT(<span style="color:#006080">"HideAndProtect"</span>))== 0)</span></span>
  58:              {
<span style="color:black"><span style="color:black"><span style="color:#606060">  59:  </span>                <span style="color:#0000ff">this</span>->m_ListCtrlProcess.SetItemText(nIndex, 4, _TEXT(<span style="color:#006080">"Protect"</span>));</span></span>
  60:              }
<span style="color:black"><span style="color:black"><span style="color:#606060">  61:  </span>            <span style="color:#0000ff">else</span></span></span>
  62:              {
<span style="color:black"><span style="color:black"><span style="color:#606060">  63:  </span>                <span style="color:#0000ff">this</span>->m_ListCtrlProcess.SetItemText(nIndex, 4, _TEXT(<span style="color:#006080">"General"</span>));</span></span>
  64:              }
<span style="color:black"><span style="color:black"><span style="color:#606060">  65:  </span>            MessageBox(_TEXT(<span style="color:#006080">" UnHide Process Sucess !  "</span>), _TEXT(<span style="color:#006080">"Information"</span>), MB_OK | </span></span>
  66:                    MB_ICONINFORMATION);
<span style="color:black"><span style="color:black"><span style="color:#606060">  67:  </span>        }</span></span>
  68:          else
<span style="color:black"><span style="color:black"><span style="color:#606060">  69:  </span>        {</span></span>
  70:              MessageBox(_TEXT(" UnHide Process Failed !  "), _TEXT("Warning"), MB_OK | MB_ICONERROR);
<span style="color:black"><span style="color:black"><span style="color:#606060">  71:  </span>        }</span></span>
  72:      }
<span style="color:black"><span style="color:black"><span style="color:#606060">  73:  </span>}</span></span>
  74:   
<span style="color:black"><span style="color:black"><span style="color:#606060">  75:  </span> </span></span>
  76:  //保护进程或者取消对进程的保护操作
<span style="color:black"><span style="color:black"><span style="color:#606060">  77:  </span><span style="color:#0000ff">void</span> CSSDTProcessDlg::OnBnClickedBtnProtectorunprotect()</span></span>
  78:  {
<span style="color:black"><span style="color:black"><span style="color:#606060">  79:  </span>    <span style="color:#0000ff">int</span> nIndex;</span></span>
  80:      DWORD dwPID;
<span style="color:black"><span style="color:black"><span style="color:#606060">  81:  </span>    CString cStrText;</span></span>
  82:      CString cStrState;
<span style="color:black"><span style="color:black"><span style="color:#606060">  83:  </span> </span></span>
  84:      DWORD dwOutput;
<span style="color:black"><span style="color:black"><span style="color:#606060">  85:  </span>    BOOL bRet;</span></span>
  86:      CHAR inBuffer[10];
<span style="color:black"><span style="color:black"><span style="color:#606060">  87:  </span>    CHAR outBuffer[10];</span></span>
  88:      memset(inBuffer, 0, 10);
<span style="color:black"><span style="color:black"><span style="color:#606060">  89:  </span>    memset(outBuffer, 0, 10);</span></span>
  90:   
<span style="color:black"><span style="color:black"><span style="color:#606060">  91:  </span>    dwPID = <span style="color:#0000ff">this</span>->GetDlgItemInt(IDC_STATIC_SELECTED_PID);</span></span>
  92:      this->GetDlgItemText(ID_BTN_PROTECTORUNPROTECT, cStrText);
<span style="color:black"><span style="color:black"><span style="color:#606060">  93:  </span> </span></span>
  94:      ultoa(dwPID, inBuffer, 10);
<span style="color:black"><span style="color:black"><span style="color:#606060">  95:  </span> </span></span>
  96:      nIndex = QueryItemIndexByPID(dwPID);
<span style="color:black"><span style="color:black"><span style="color:#606060">  97:  </span>    cStrState = <span style="color:#0000ff">this</span>->m_ListCtrlProcess.GetItemText(nIndex, 4);</span></span>
  98:   
<span style="color:black"><span style="color:black"><span style="color:#606060">  99:  </span>    <span style="color:#0000ff">if</span>(cStrText.CompareNoCase(_TEXT(<span style="color:#006080">"Protect"</span>)) == 0)</span></span>
 100:      {
<span style="color:black"><span style="color:black"><span style="color:#606060"> 101:  </span>        <span style="color:#008000">//保护 dwPID 保护</span></span></span>
 102:          bRet = DeviceIoControl(this->m_hDevice, IO_INSERT_PROTECT_PROCESS, inBuffer, 10, 
<span style="color:black"><span style="color:black"><span style="color:#606060"> 103:  </span>             &outBuffer, 10, &dwOutput, NULL);</span></span>
 104:          if(bRet)
<span style="color:black"><span style="color:black"><span style="color:#606060"> 105:  </span>        {</span></span>
 106:              this->SetDlgItemText(ID_BTN_PROTECTORUNPROTECT, _TEXT("UnProtect"));
<span style="color:black"><span style="color:black"><span style="color:#606060"> 107:  </span>            <span style="color:#0000ff">if</span>(cStrState.CompareNoCase(_TEXT(<span style="color:#006080">"Hide"</span>))== 0)</span></span>
 108:              {
<span style="color:black"><span style="color:black"><span style="color:#606060"> 109:  </span>                <span style="color:#0000ff">this</span>->m_ListCtrlProcess.SetItemText(nIndex, 4, _TEXT(<span style="color:#006080">"HideAndProtect"</span>));</span></span>
 110:              }
<span style="color:black"><span style="color:black"><span style="color:#606060"> 111:  </span>            <span style="color:#0000ff">else</span></span></span>
 112:              {
<span style="color:black"><span style="color:black"><span style="color:#606060"> 113:  </span>                <span style="color:#0000ff">this</span>->m_ListCtrlProcess.SetItemText(nIndex, 4, _TEXT(<span style="color:#006080">"Protect"</span>));</span></span>
 114:              }
<span style="color:black"><span style="color:black"><span style="color:#606060"> 115:  </span>            MessageBox(_TEXT(<span style="color:#006080">" Protect Process Sucess !  "</span>), _TEXT(<span style="color:#006080">"Information"</span>), MB_OK | </span></span>
 116:                    MB_ICONINFORMATION);
<span style="color:black"><span style="color:black"><span style="color:#606060"> 117:  </span>        }</span></span>
 118:          else
<span style="color:black"><span style="color:black"><span style="color:#606060"> 119:  </span>        {</span></span>
 120:              MessageBox(_TEXT(" Protect Process Failed !  "), _TEXT("Warning"), MB_OK | MB_ICONERROR);
<span style="color:black"><span style="color:black"><span style="color:#606060"> 121:  </span>        }</span></span>
 122:      }
<span style="color:black"><span style="color:black"><span style="color:#606060"> 123:  </span>    <span style="color:#0000ff">else</span></span></span>
 124:      {
<span style="color:black"><span style="color:black"><span style="color:#606060"> 125:  </span>        <span style="color:#008000">//解除 dwPID 保护</span></span></span>
 126:          bRet = DeviceIoControl(this->m_hDevice, IO_REMOVE_PROTECT_PROCESS, inBuffer, 10, 
<span style="color:black"><span style="color:black"><span style="color:#606060"> 127:  </span>             &outBuffer, 10, &dwOutput, NULL);</span></span>
 128:          if(bRet)
<span style="color:black"><span style="color:black"><span style="color:#606060"> 129:  </span>        {</span></span>
 130:              this->SetDlgItemText(ID_BTN_PROTECTORUNPROTECT, _TEXT("Protect"));
<span style="color:black"><span style="color:black"><span style="color:#606060"> 131:  </span>            <span style="color:#0000ff">if</span>(cStrState.CompareNoCase(_TEXT(<span style="color:#006080">"Hide"</span>)) == 0 || </span></span>
 132:                   cStrState.CompareNoCase(_TEXT("HideAndProtect")) == 0)
<span style="color:black"><span style="color:black"><span style="color:#606060"> 133:  </span>            {</span></span>
 134:                  this->m_ListCtrlProcess.SetItemText(nIndex, 4, _TEXT("Hide"));
<span style="color:black"><span style="color:black"><span style="color:#606060"> 135:  </span>            }</span></span>
 136:              else
<span style="color:black"><span style="color:black"><span style="color:#606060"> 137:  </span>            {</span></span>
 138:                  this->m_ListCtrlProcess.SetItemText(nIndex, 4, _TEXT("General"));
<span style="color:black"><span style="color:black"><span style="color:#606060"> 139:  </span>            }</span></span>
 140:              MessageBox(_TEXT(" UnProtect Process Sucess !  "), _TEXT("Information"), MB_OK | 
<span style="color:black"><span style="color:black"><span style="color:#606060"> 141:  </span>                  MB_ICONINFORMATION);</span></span>
 142:          }
<span style="color:black"><span style="color:black"><span style="color:#606060"> 143:  </span>        <span style="color:#0000ff">else</span></span></span>
 144:          {
<span style="color:black"><span style="color:black"><span style="color:#606060"> 145:  </span>            MessageBox(_TEXT(<span style="color:#006080">" UnProtect Process Failed !  "</span>), _TEXT(<span style="color:#006080">"Warning"</span>), MB_OK | MB_ICONERROR);</span></span>
 146:          }
<span style="color:black"><span style="color:black"><span style="color:#606060"> 147:  </span>    }</span></span>
 148:  }
          
 

5. 小结:

          

介绍这个应用程序呢,还真是不好写,因为感觉整个 Demo 里面却是没有什么好介绍的,

无非就是获取到所有的进程,然后通过一个 ListCtrl 来显示这些数据,

然后用户选择一个进程,单击一下隐藏呢,我就在这个按钮的消息处理函数中和内核程序通过 DeviceIoControl 通信一下,

将这个进程的 PID 传递给内核程序,其他的就都不需要理会了 ~ 所以转来转去的,也没什么好些的,干脆就写到这里得了,

等下将整个 Demo 打个包,直接提供下载,我这里说得口干舌燥也没什么用,感兴趣的自己下载了源码去慢慢玩得了 ~

最后再总结一个 SSDT Hook 的优点,那就是 SSDT Hook 无论你是 Windows XP 还是 Server 或者 Vista 或者 Win7,

你都是可以很好的运行程序的,所以你下载的 Demo 你可以放心的在上面的这些操作系统上运行,当然 64 位的除外,

64 位的操作系统虽然我没有做过测试,但是我估摸着会蓝屏的 ~ 有兴趣的可以去蓝一次 ~

           

下载 Demo Source Code

相关标签: SSDT Hook