当前位置: 首页 > 科技观察

网络安全编程:进程暂停和恢复

时间:2023-03-21 21:48:31 科技观察

在某些时候,进程必须暂停。例如,一个病毒有两个正在运行的进程,它们不断地相互检查。当一个病毒进程发现另一个病毒进程已经终止时,它会再次运行已终止的病毒进程。由于两个病毒进程的相互检测频率很高,因此很难结束两个病毒进程。因此,只有挂起这两个病毒进程后,才能终止这两个病毒进程。进程的挂起本质上就是线程的挂起,因为进程是一个资源容器,而线程实际占用的是CPU时间。如果需要暂停进程,则需要暂停进程中的所有线程。关于进程的挂起和恢复,本质就是挂起和恢复进程中的所有线程。1、挂起和恢复线程所需的函数用于挂起线程的API函数是SuspendThread(),定义如下:DWORDSuspendThread(HANDLEhThread//handletothread);这个函数只有一个参数,就是要挂起的线程句柄。获取线程句柄使用OpenThread()函数,函数定义如下:该函数的使用与OpenProcess()类似,只是第三个参数是dwThreadId,即线程ID。VC6默认提供的PSDK中不存在OpenThread()函数,必须安装更新更高版本的PSDK才能使用该函数。如果PSDK版本未更新,则需要使用LoadLibrary()和GetProcAddress()动态调用OpenThread()函数。如果你使用更高版本的VC开发环境,那么直接使用OpenThread()函数即可。要挂起进程中的所有线程,离不开枚举线程。枚举线程的函数是Thread32First()和Thread32Next()。在枚举线程之前,仍然需要使用CreateToolhelp32Snapshot()函数创建系统进程快照,但是该函数无法在指定进程中创建线程快照。因为无法创建指定进程中的线程快照,所以在挂起线程时,必须判断枚举的线程是否属于指定进程中的线程。在THREADENTRY32结构中,th32ThreadID表示当前枚举线程的线程ID,th32OwnerProcessID表示该线程所属的进程ID。这样,在枚举线程时,只要判断是否属于指定的进程,就可以进行suspend操作。线程挂起的反面是恢复挂起的线程。恢复挂起线程的函数是ResumeThread(),定义如下:DWORDResumeThread(HANDLEhThread//handletothread);该函数的使用方法与SuspendThread()相同。恢复挂起线程的方法与挂起线程的方法类似,不再赘述。2.线程挂起和回收代码线程挂起代码如下:voidCManageProcessDlg::OnBtnStop(){//TODO:AddyourcontrolnotificationhandlercodehereintnPid=-1;nPid=GetSelectPid();//进程ID为0,则返回if(nPid==(THREADENTRY32);BOOLbRet=Thread32First(hSnap,&Te32);//循环获取线程快照中的每一项while(bRet){//获取属于选中进程的线程if(Te32.th32OwnerProcessID==nPid){//开启线程HANDLEhThread=OpenThread(THREAD_ALL_ACCESS,FALSE,Te32.th32ThreadID);//挂起线程SuspendThread(hThread);CloseHandle(hThread);}bRet=Thread32Next(hSnap,&Te32);}CloseHandle(hSnap);}线程恢复代码如下:voidCManageProcessDlg::OnBtnResume(){//TODO:AddyourcontrolnotificationhandlercodehereintnPid=-1;nPid=GetSelectPid();//进程ID为0,则返回if(nPid==0){return;}//创建线程快照HANDLEhSnap=CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,nPid);if(hSnap==INVALID_HANDLE_VALUE){AfxMessageBox("CreateToolhelp32SnapshotError");return;}THREADENTRY32Te32={0};Te32.dwSize=sizeof(THREADENTRY32);BOOLbRet=Thread32First(hSnap,&Te32);//循环获取线程快照中的每一项while(bRet){//获取属于选中进程的线程if(Te32.th32OwnerProcessID==nPid){//开启线程HANDLEhThread=OpenThread(THREAD_ALL_ACCESS,FALSE,Te32.th32ThreadID);//挂起线程ResumeThread(hThread);CloseHandle(hThread);}bRet=Thread32Next(hSnap,&Te32);}}三、系统相关辅助工具介绍首先我们来看一个进程管理工具ProcessExplorer,该工具的界面如图1所示。图1ProcessExplorer界面,当启动一个进程或结束一个进程时,软件会高亮显示已启动或已结束的进程,当然它还有很多功能,大家可以自行研究挖掘,这里着重介绍一个小功能工具,点击菜单“选项”->“替换任务管理器”。该功能用于替换任务管理器系统的,即将ProcessExplorer设置为默认任务管理器。请按照上面的设置方法进行设置,然后按Ctrl+尝试使用Shift+Esc组合键。系统默认的任务管理器没有了,取而代之的是ProcessExplorer。系统的默认任务管理器已被ProcessExplorer取代。如果要恢复原来的任务管理器,只需再次点击“替换任务管理器”菜单项即可。更换任务管理器的功能是如何实现的?原理很简单,就是注册表被篡改了,但是怎么知道注册表做了哪些改动呢??另一个推荐的工具叫做RegMon,它是一个监控注册表变化的工具。软件如图2所示。图2RegMon界面打开RegMon工具后,按下Ctrl+L组合键,会出现“RegMonFilter”界面。在“Include”中填写“procexp.exe”(procexp.exe是ProcessExplorer工具的文件名),如图3所示。图3RegMonFilter界面设置好“RegMonFilter”界面后,点击“OK”按钮确认,返回ProcessExplorer工具,点击其菜单中的“ReplaceTaskManager”菜单项,即可看到RegMon抓取的注册表信息,如图4和图5所示。图4.ProcessExplorer修改注册表项。图5.ProcessExplorer修改注册表项值。打开注册表编辑器可以查看修改后的注册表键值内容,如图6所示。图6注册表中修改后的值在注册表中,HKLM\Software\Microsoft\WindowsNT\CurrentVersion\ImageFileExecution\taskmgr的值.exe\debugger就是D盘下的ProcExp.exe文件(这个文件就是ProcessExplorer的文件名),删除key,然后按Ctrl+Shift+Esc,出现默认的任务管理器。这就是著名的注册表镜像劫持,这是很多病毒、木马等恶意程序常用的手段。这里写的任务管理器可以加上替换系统任务管理器的功能来练习。

猜你喜欢