您的位置:首页 > 其它

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

2013-02-28 17:25 357 查看
文章目录:

                 

1.引子:

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

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

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

5.小结:

              
 

1.引子:

                         

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

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

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


                  

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

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

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

博文地址: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来获取,

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

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

1:BOOLWINAPIEnumProcesses(

2:__outDWORD*pProcessIds,

3:__inDWORDcb,

4:__outDWORD*pBytesReturned

5:);

6:


     

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

1://遍历当前所有的进程,并且将进程ID填充到容器vectorPID中

2:voidCSSDTProcessDlg::FillPIDVector()

3:{

4:DWORDdwPIDArray[MAX_PROCESS_COUNT];

5:DWORDdwNeededBytes;

6:DWORDdwProcCount;

7:

8:dwNeededBytes=0;

9:dwProcCount=0;

10:memset(dwPIDArray,0,sizeof(DWORD)*MAX_PROCESS_COUNT);

11:if(NULL!=EnumProcesses(dwPIDArray,sizeof(dwPIDArray),&dwNeededBytes))

12:{

13:dwProcCount=dwNeededBytes/sizeof(DWORD);

14:}

15:

16:BubbleSort(dwPIDArray,dwProcCount);

17:

18:ClearVector();

19:for(inti=0;i<dwProcCount;i++)

20:{

21:PROCESS_BINDprocBind;

22:procBind.dwPID=dwPIDArray[i];

23:if(dwPIDArray[i]==0)

24:{

25:procBind.state=ProcessStateUnknown;

26:}

27:else

28:{

29:procBind.state=ProcessStateGeneral;

30:}

31:this->m_vctAllProcess.push_back(procBind);

32:}

33:}


        

              
 

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

             

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

第一类是NT式驱动程序;

第二类为WDM驱动程序;

第三类为WDF驱动程序;

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

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

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

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

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

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

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

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

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


1://=====================================================================================//

2://Name:boolInstallSvc()//

3:////

4://Descripion:安装服务//

5://lpszSvcName为服务名称,//

6://lpszDisplay为显示在服务控制管理器中的名称,//

7://lpszSvcBinaryPath为服务映像文件所在路径,//

8://dwSvcType为服务类型//

9://dwStartType为服务启动类型//

10://=====================================================================================//

11:boolCSSDTProcessDlg::InstallSvc(LPTSTRlpszSvcName,LPTSTRlpszDisplayName,

12:LPTSTRlpszSvcBinaryPath,DWORDdwSvcType,DWORDdwStartType)

13:{

14:SC_HANDLEhSCM=NULL;

15:SC_HANDLEhSvc=NULL;

16:

17:AdjustProcessTokenPrivilege();

18:

19:hSCM=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

20:if(NULL==hSCM)

21:{

22:OutputErrorMessage(TEXT("InstallSvc-OpenSCManagerFailed,ErrorCodeIs%d,ErrorMessageIs%s!"));

23:

24:returnFALSE;

25:}

26:

27:for(inti=0;i<3&&(NULL==hSvc);i++)

28:{

29://SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS

30:hSvc=CreateService(hSCM,lpszSvcName,lpszDisplayName,SERVICE_ALL_ACCESS,

31:dwSvcType,dwStartType,SERVICE_ERROR_NORMAL,

32:lpszSvcBinaryPath,NULL,NULL,NULL,NULL,NULL);

33:if(NULL!=hSvc)

34:{

35:if(NULL!=hSvc)

36:{

37:CloseServiceHandle(hSvc);

38:}

39:CloseServiceHandle(hSCM);

40:returnTRUE;

41:}

42:}

43:

44:OutputErrorMessage(TEXT("InstallSvc-CreateServiceFailed,ErrorCodeIs%d,ErrorMessageIs%s!"));

45:

46:CloseServiceHandle(hSCM);

47:

48:returnFALSE;

49:}

50:

51:

52://=====================================================================================//

53://Name:boolUnInstallSvc()//

54:////

55://Descripion:实现卸载服务//

56://=====================================================================================//

57:boolCSSDTProcessDlg::UnInstallSvc(LPTSTRlpszSvcName)

58:{

59:SC_HANDLEhSCM=NULL;

60:SC_HANDLEhSvc=NULL;

61:boolrtResult=FALSE;

62:

63:AdjustProcessTokenPrivilege();

64:

65:hSCM=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

66:if(NULL==hSCM)

67:{

68:OutputErrorMessage(TEXT("UnInstallSvc-OpenSCManagerFailed,ErrorCodeIs%d,ErrorMessageIs%s!"));

69:

70:returnFALSE;

71:}

72:

73:hSvc=OpenService(hSCM,lpszSvcName,SERVICE_ALL_ACCESS);

74:if(NULL==hSvc)

75:{

76:OutputErrorMessage(TEXT("UnInstallSvc-OpenServiceFailed,ErrorCodeIs%d,ErrorMessageIs%s!"));

77:

78:CloseServiceHandle(hSCM);

79:

80:returnFALSE;

81:}

82:

83:rtResult=DeleteService(hSvc);

84:

85:CloseServiceHandle(hSvc);

86:CloseServiceHandle(hSCM);

87:

88:returnrtResult;

89:}

90:

91:

92://=====================================================================================//

93://Name:boolStartSvc()//

94:////

95://Descripion:实现启动服务//

96://=====================================================================================//

97:boolCSSDTProcessDlg::StartSvc(LPTSTRlpszSvcName)

98:{

99:SC_HANDLEhSCM=NULL;

100:SC_HANDLEhSvc=NULL;

101:boolrtResult=FALSE;

102:

103:AdjustProcessTokenPrivilege();

104:

105:hSCM=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

106:if(NULL==hSCM)

107:{

108:OutputErrorMessage(TEXT("StartSvc-OpenSCManagerFailed,ErrorCodeIs%d,ErrorMessageIs%s!"));

109:

110:returnFALSE;

111:}

112:

113:hSvc=OpenService(hSCM,lpszSvcName,SERVICE_ALL_ACCESS);

114:if(NULL==hSvc)

115:{

116:OutputErrorMessage(TEXT("StartSvc-OpenServiceFailed,ErrorCodeIs%d,ErrorMessageIs%s!"));

117:

118:CloseServiceHandle(hSCM);

119:

120:returnFALSE;

121:}

122:

123:rtResult=StartService(hSvc,NULL,NULL);

124:

125:CloseServiceHandle(hSvc);

126:CloseServiceHandle(hSCM);

127:

128:if(FALSE==rtResult)

129:{

130:if(ERROR_SERVICE_ALREADY_RUNNING==GetLastError())

131:{

132:returnTRUE;

133:}

134:else

135:{

136:OutputErrorMessage(TEXT("StartSvc-StartServiceFailed,ErrorCodeIs%d,ErrorMessageIs%s!"));

137:

138:returnFALSE;

139:}

140:}

141:else

142:{

143:returnTRUE;

144:}

145:}

146:

147:

148://=====================================================================================//

149://Name:boolStopSvc()//

150:////

151://Descripion:实现停止服务//

152://=====================================================================================//

153:boolCSSDTProcessDlg::StopSvc(LPTSTRlpszSvcName)

154:{

155:SC_HANDLEhSCM=NULL;

156:SC_HANDLEhSvc=NULL;

157:boolrtResult=FALSE;

158:

159:SERVICE_STATUSsvcStatus;

160:

161:AdjustProcessTokenPrivilege();

162:

163:hSCM=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

164:if(NULL==hSCM)

165:{

166:OutputErrorMessage(TEXT("StopSvc-OpenSCManagerFailed,ErrorCodeIs%d,ErrorMessageIs%s!"));

167:

168:returnFALSE;

169:}

170:

171:hSvc=OpenService(hSCM,lpszSvcName,SERVICE_ALL_ACCESS);

172:if(NULL==hSvc)

173:{

174:OutputErrorMessage(TEXT("StopSvc-OpenServiceFailed,ErrorCodeIs%d,ErrorMessageIs%s!"));

175:

176:CloseServiceHandle(hSCM);

177:

178:returnFALSE;

179:}

180:

181:rtResult=ControlService(hSvc,SERVICE_CONTROL_STOP,&svcStatus);

182:if(rtResult==FALSE)

183:{

184:OutputErrorMessage(TEXT("StopSvc-ControlServiceFailed,ErrorCodeIs%d,ErrorMessageIs%s!"));

185:}

186:CloseServiceHandle(hSvc);

187:CloseServiceHandle(hSCM);

188:

189:returnrtResult;

190:}


       

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

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

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


安装和启动服务:

1:wstringwStrSysPath=GetSysFilePath();

2:BOOLbResult=InstallSvc(((LPTSTR)(LPCTSTR)SSDT01_SERVICE_NAME),

3:((LPTSTR)(LPCTSTR)SSDT01_SERVICE_NAME),

4:((LPTSTR)(LPCTSTR)wStrSysPath.c_str()),

5:SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START);

6:if(FALSE==bResult)

7:{

8:MessageBox(_TEXT("InstallSSDTServiceFailed,ApplicationAutoExit!"),

9:_TEXT("ApplicationError"),MB_OK|MB_ICONSTOP);

10:CDialogEx::OnCancel();

11:returnFALSE;

12:}

13:else

14:{

15:bResult=StartSvc(SSDT01_SERVICE_NAME);

16:if(FALSE==bResult)

17:{

18:MessageBox(_TEXT("StartSSDTServiceFailed,ApplicationAutoExit!"),

19:_TEXT("ApplicationError"),MB_OK|MB_ICONSTOP);

20:CDialogEx::OnCancel();

21:returnFALSE;

22:}

23:}


           

停止并且将服务卸载掉:


1:~CSSDTProcessDlg()

2:{

3://在析构函数中关闭SSDT设备句柄

4:if(this->m_hDevice)

5:{

6:CloseHandle(this->m_hDevice);

7:}

8:

9://当发生析构函数时,停止服务并且卸载服务

10:StopSvc(SSDT01_SERVICE_NAME);

11:UnInstallSvc(SSDT01_SERVICE_NAME);

12:}


        

              
 

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

           

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

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

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

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

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

1:BOOLWINAPIDeviceIoControl(

2:__inHANDLEhDevice,

3:__inDWORDdwIoControlCode,

4:__inLPVOIDlpInBuffer,

5:__inDWORDnInBufferSize,

6:__outLPVOIDlpOutBuffer,

7:__inDWORDnOutBufferSize,

8:__outLPDWORDlpBytesReturned,

9:__inLPOVERLAPPEDlpOverlapped

10:);

11:


         

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

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

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

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





       

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

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


1:this->m_hDevice=CreateFile(SSDT01_DEVICE_NAME,GENERIC_READ|GENERIC_WRITE,0,

2:NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

3:if(INVALID_HANDLE_VALUE==this->m_hDevice)

4:{

5:MessageBox(_TEXT("OpenSSDTDeviceFailed,ApplicationAutoExit!"),

6:_TEXT("ApplicationError"),MB_OK|MB_ICONSTOP);

7:

8:CDialogEx::OnCancel();

9:returnFALSE;

10:}


        

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

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

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


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

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


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

1://隐藏进程或者取消对进程的隐藏

2:voidCSSDTProcessDlg::OnBnClickedBtnHideorunhide()

3:{

4:intnIndex;

5:DWORDdwPID;

6:CStringcStrText;

7:CStringcStrState;

8:

9:DWORDdwOutput;

10:BOOLbRet;

11:CHARinBuffer[10];

12:CHARoutBuffer[10];

13:memset(inBuffer,0,10);

14:memset(outBuffer,0,10);

15:

16:dwPID=this->GetDlgItemInt(IDC_STATIC_SELECTED_PID);

17:this->GetDlgItemText(ID_BTN_HIDEORUNHIDE,cStrText);

18:

19:ultoa(dwPID,inBuffer,10);

20:

21:nIndex=QueryItemIndexByPID(dwPID);

22:cStrState=this->m_ListCtrlProcess.GetItemText(nIndex,4);

23:

24:if(cStrText.CompareNoCase(_TEXT("Hide"))==0)

25:{

26://隐藏dwPID

27:bRet=DeviceIoControl(this->m_hDevice,IO_INSERT_HIDE_PROCESS,inBuffer,10,

28:&outBuffer,10,&dwOutput,NULL);

29:if(bRet)

30:{

31:this->SetDlgItemText(ID_BTN_HIDEORUNHIDE,_TEXT("UnHide"));

32:if(cStrState.CompareNoCase(_TEXT("Protect"))==0)

33:{

34:this->m_ListCtrlProcess.SetItemText(nIndex,4,_TEXT("HideAndProtect"));

35:}

36:else

37:{

38:this->m_ListCtrlProcess.SetItemText(nIndex,4,_TEXT("Hide"));

39:}

40:MessageBox(_TEXT("HideProcessSucess!"),_TEXT("Information"),MB_OK|

41:MB_ICONINFORMATION);

42:}

43:else

44:{

45:MessageBox(_TEXT("HideProcessFailed!"),_TEXT("Warning"),MB_OK|MB_ICONERROR);

46:}

47:}

48:else

49:{

50://解除dwPID隐藏

51:bRet=DeviceIoControl(this->m_hDevice,IO_REMOVE_HIDE_PROCESS,inBuffer,10,

52:&outBuffer,10,&dwOutput,NULL);

53:if(bRet)

54:{

55:this->SetDlgItemText(ID_BTN_HIDEORUNHIDE,_TEXT("Hide"));

56:if(cStrState.CompareNoCase(_TEXT("Protect"))==0||

57:cStrState.CompareNoCase(_TEXT("HideAndProtect"))==0)

58:{

59:this->m_ListCtrlProcess.SetItemText(nIndex,4,_TEXT("Protect"));

60:}

61:else

62:{

63:this->m_ListCtrlProcess.SetItemText(nIndex,4,_TEXT("General"));

64:}

65:MessageBox(_TEXT("UnHideProcessSucess!"),_TEXT("Information"),MB_OK|

66:MB_ICONINFORMATION);

67:}

68:else

69:{

70:MessageBox(_TEXT("UnHideProcessFailed!"),_TEXT("Warning"),MB_OK|MB_ICONERROR);

71:}

72:}

73:}

74:

75:

76://保护进程或者取消对进程的保护操作

77:voidCSSDTProcessDlg::OnBnClickedBtnProtectorunprotect()

78:{

79:intnIndex;

80:DWORDdwPID;

81:CStringcStrText;

82:CStringcStrState;

83:

84:DWORDdwOutput;

85:BOOLbRet;

86:CHARinBuffer[10];

87:CHARoutBuffer[10];

88:memset(inBuffer,0,10);

89:memset(outBuffer,0,10);

90:

91:dwPID=this->GetDlgItemInt(IDC_STATIC_SELECTED_PID);

92:this->GetDlgItemText(ID_BTN_PROTECTORUNPROTECT,cStrText);

93:

94:ultoa(dwPID,inBuffer,10);

95:

96:nIndex=QueryItemIndexByPID(dwPID);

97:cStrState=this->m_ListCtrlProcess.GetItemText(nIndex,4);

98:

99:if(cStrText.CompareNoCase(_TEXT("Protect"))==0)

100:{

101://保护dwPID保护

102:bRet=DeviceIoControl(this->m_hDevice,IO_INSERT_PROTECT_PROCESS,inBuffer,10,

103:&outBuffer,10,&dwOutput,NULL);

104:if(bRet)

105:{

106:this->SetDlgItemText(ID_BTN_PROTECTORUNPROTECT,_TEXT("UnProtect"));

107:if(cStrState.CompareNoCase(_TEXT("Hide"))==0)

108:{

109:this->m_ListCtrlProcess.SetItemText(nIndex,4,_TEXT("HideAndProtect"));

110:}

111:else

112:{

113:this->m_ListCtrlProcess.SetItemText(nIndex,4,_TEXT("Protect"));

114:}

115:MessageBox(_TEXT("ProtectProcessSucess!"),_TEXT("Information"),MB_OK|

116:MB_ICONINFORMATION);

117:}

118:else

119:{

120:MessageBox(_TEXT("ProtectProcessFailed!"),_TEXT("Warning"),MB_OK|MB_ICONERROR);

121:}

122:}

123:else

124:{

125://解除dwPID保护

126:bRet=DeviceIoControl(this->m_hDevice,IO_REMOVE_PROTECT_PROCESS,inBuffer,10,

127:&outBuffer,10,&dwOutput,NULL);

128:if(bRet)

129:{

130:this->SetDlgItemText(ID_BTN_PROTECTORUNPROTECT,_TEXT("Protect"));

131:if(cStrState.CompareNoCase(_TEXT("Hide"))==0||

132:cStrState.CompareNoCase(_TEXT("HideAndProtect"))==0)

133:{

134:this->m_ListCtrlProcess.SetItemText(nIndex,4,_TEXT("Hide"));

135:}

136:else

137:{

138:this->m_ListCtrlProcess.SetItemText(nIndex,4,_TEXT("General"));

139:}

140:MessageBox(_TEXT("UnProtectProcessSucess!"),_TEXT("Information"),MB_OK|

141:MB_ICONINFORMATION);

142:}

143:else

144:{

145:MessageBox(_TEXT("UnProtectProcessFailed!"),_TEXT("Warning"),MB_OK|MB_ICONERROR);

146:}

147:}

148:}




5.小结:

          

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

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

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

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

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

最后再总结一个SSDTHook的优点,那就是SSDTHook无论你是WindowsXP还是Server或者Vista或者Win7,

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

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


           

下载DemoSourceCode


转载自 
[b]Zachary.XiaoZhen-梦想的天空
[/b]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: