进程隐藏与进程保护(SSDT Hook 实现)(三)
文章目录:
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 进行隐藏或者保护 ~
在这里再给出这个应用程序的一张截图:
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 式驱动程序中我创建了一个设备,这个设备用来实现应用程序和内核程序的通信),
然后在对话框类中保存有一个全局变量,这个全局变量即代表所打开的这个设备的句柄,
既然这个全局变量是保存的我们的设备的句柄,自然我们需要来获取到设备的句柄,并且将句柄赋值给该全局变量,
而这个呢,又是在 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
上一篇: 数据库程序设计8 触发器
下一篇: 自定义cell