
安全模式下程序的强制运行方法探讨.doc
5页安全模式下程序的强制运行方法探讨杜永平张永亮(西安科技大学计算机系,西安,710054)摘要:在安全模式下启动程序可以通过修改WINDOWS注册表来实现修改注册表中Shell 的键值,把可执行程序的名字附在Shell犍值的后边,就可实现在安全模式下启动程序程 序不被任务管理器关闭的实现方法有很多,本文采用的是双进程的方法,即:两个进程相互 监测,其中一个被关闭,另一个就把它启动关键字:程序强制运行,安全模式,进程1引言有些程序需要在安全模式下白动加载运行,而且不能被任务管理器关闭像一些病毒 的监控程序就需要有这样的功能要实现这些功能,就需要了解Windows注册表的功能, windows安全模式以及Windows编程本文就讨论了实现这些功能的具体方法,最厉程序 实现的目标是,在正常模式下运行-程序,关闭计算机,重新启动计算机无论进入windows 正常模式还是安全模式,程序白动启动运行,而且在任务管理器中关不掉该程序安全模式启动计算机时,只连带启动显示卡和硕盘,而这两种设备一般不会产生冲突 在安全模式下,系统将不处理Config.sys和Autoexec.bat的内容,也不处理启动文件夹的任 何内容。
正常模式启动计算机时■,注册表是Windows系统的核心,在Windows操作系统的启动、 运行过程中起着至关重要的作用o Windows的注册表存储当前系统的软、硕件的有关配置和 状态信息,以及应用程序和资源管理器外壳的初始条件、首选项和卸载数据,还包括计算机 的整个系统的设置和各种许可,文件扩展名与应用程序的关联,换件的描述、状态和属性, 以及计算机性能纪录和底层的系统状态信息,以及种类其他数据每次启动时,会根据计算 机关机时创建的一系列文件创建注册表,注册表一旦载入内存,就会被一直维护着,注册表 实际上是一个系统参数的关系数据库2关键技术进入安全模式后,某一应用程序自动启动,本文通过修改注册表中 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogo 键值 K Shell的值来实现Shell值项是一个字符串值项,该值项用于指定可选的用户界而程序, 数值数据的默认值为Explorer.exe把要在安全模式下启动的程序名通过编程写在 Explorer.exe的后边,该程序就可以在每次计算机启动时自动运行了。
本文是采用双进程的方法來实现安全模式下程序的强制运行在操作系统中,进程是存 储器、外设等资源的分配单位,同时也是处理器调度的对象,但为了捉高进程内的并发性, windows系统中引入了线程这个概念,这吋系统把线程作为处理器调度的对象,一个进程可 以同时拥有多个并发的线程通常情况下的简单程序就只有一个主线程,它是在进程创建吋 白动生成的可以将希望执行的代码放在主线程里,然后再生成一个辅助线程在双进程中 的辅助线程功能就是运行一•个辅进程,辅进程对主进程起保护功能,防止主迹程被用户关闭 或删除创建双进程是为了更好的保护主进程白身不被关闭和删除两个进程相互实时监视, 如果监视对象被关闭了,就重新创建线程或进程这样,这两个进程就很难被杀死了,至少 用任务管理器不能杀死它们两个进程分别为主进程和辅助进程主进程的任务有:(1)检测并启动辅助进程和实 现主要功能2)自动将主程序(主进程)名写入注册表中的Shell键下3)在windows 中显示一•个动画窗口;辅助进程的任务主要是检测主进程是否被关闭,如果主进程被关闭, 辅助进程将会启动主进程运行,以保证主进程不能被关闭程序不被任务管理器关闭,可以实现的还方法有很多。
以下将对其中儿种进行介绍:(1) 在 win9x 卜川以利川两数 RegisterServiceProcess GetCurrentProcessId 来隐藏需要 强行运行的程序在任务管理器中看不到该程序,也就无法关闭了该方法的优点是程序简 单,易于实现,效果也好但是这个方法只适用于wii】9x系统,对其它系统不适用,通用性 不好2) 可以把需要强行运行的程序命名为系统文件名,例如system.exe、winlogo.exe等 等这些是系统文件,当要强行关闭时,系统会警告非法,无法关闭程序但这于在安全模 式下启动程序冲突,因为在安全模式卜启动程序,需要把程序放到system32文件夹下,命 名上有冲突3) 可以屏蔽掉Ctrl+ALT+DEL键,使用户在键盘上调不出任务管理器用户调不出 任务管理器,也就无法利用任务管理器來关闭程序但是该方法与题目要求不符,程序并不 是不能关闭,而是Windows的功能不能运用4) 三线程的方法在程序中创建三个线程,一个主线程,两个辅线程主线程需要 完成的任务有三个,分别是准备工作,创建辅助线程和程序上要功能的实现准备工作是为 程序运行过程中所需要的一些部件做好准备,其中包括文件复制和保存。
创建辅助线程包括 两个线程,一个驻留在主进程体内,另一个通过创建远程线程驻留到其他止在运行的进程体 内这两个线程的功能就是监视其他进程或线程的运行情况,如果出现异常立即恢复程序 的主要功能就是用户想要实现的功能驻留主进程体内的线程同时观察注册表和远程进程的情况它实时查询注册表里 HKEY LOCAL MACHlNE\Software\Microsoft\Windows\CurrentVersion\Run 键卜相关可执彳了 文件的键值,如果被删除就立即将其添加上这就是对注册表的实吋监视,使得每次开机时 都会运行我们的可执行文件而另•个功能则是监视驻留在远程进程体内辅助线程的运行情 况,如果该线程被关闭,立即通过创建远程线程将被关闭的线程驻留到特定的进程内驻留在远程进程体内的辅助线程则监视主进程的运行情况,如果主进程被关闭了,它 会确认程序的可执行文件是否也被删除掉了如果系统目录下的可执行•文件不存在了,则用 我们备份的文件恢复可执行文件,然后再重新启动程序,这样你在任务管理器里怎么也删除 不了主进程由于创建的是远程线程,所以必须把线程的代码和线程所需要的参数都复制到 远程进程的地址空间里。
这是因为在windows2000/xp环境卜,访问其他进程地址空间是违 规的把代码和参数复制过去厉,线程就完全在远程进程的地址空间运行•了可以看到,通 过两个辅助线程,就很难把主进程关闭或删除掉3程序实现具体实现通过以卜五个程序模块来实现,分别是画图两数、将对执行文件写入注册表函 数、检测辅助进程是否存在函数、创建辅助进程函数和拷贝函数具体各模块说明以及主要 程序代码如下:(1) void CCDlg::OnTimer(UINT nIDEvent)和 void CCDlg::f()用来创建一个圆和一•个轨 道,模拟天体运动,实现动画界面思路:每隔一定吋间画圆接着画…个矩形,矩形的人小 和窗口一•样大,此矩形用来覆盖客戶区,接着再在另一个位置从新画圆Void CCDLg::OnTimer(UINT nIDEvent){ 〃画圆函数)void CCDlg::f(){……〃画圆的运动轨道函数)(2) void CCDlg::aa()此函数用來把c.exe的可执行文件写入注册表当系统每次重启 时,系统自动检测c.exe,如果存在就启动c.exe可执行文件(无论是正常模式还是安全模式 都能自动启动)。
void CCDlg::aa(){〃将可执行文件写入注册表 if(RegOpenKey(HKEY_LOCAL_MACHINE,s,&h)==ERROR_SUCCESS) 〃按指定的路径打开注册表的键值;{::RegSetValueExCh/SheirAREG.SZ,(CONST BYTE *)s2.GetBuffer(0),s2.GetLength());〃设置打开的键值的值;)}(3) DWORD WINAPIThreadCheckProc(LPVOID IParam)此隊|数检测 as.exe 是否存在, 如果不存在就启动(as.exe这个执行文件用来检测c.exe是否存在如不存在就启动,这就 是双进程的互相检测,其中用到互斥量);DWORD WINAPI ThreadCheckProc(LPVOID IParam){〃检测函数hMutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,pName);〃打开一-个互斥量CloseHandle(pi.hThread);〃在指定路径中执行一个进程}(4) void CCDlg::as()j|J來创c.exe 的互斥最。
创趙线程 as.exevoid CCDlg::as(){//创建互斥量DWORD Threadld;CreateMutex(NULL,TRUE,"c.exeH);〃创建一个Mutex对象CreateThread(NULL,O,ThreadCheckProc,(LPVOID *)"as.exe",0,&ThreadId);〃创建指定线程}(5) voidCCDlg::gl()寻找 c.exe 的路径并拷贝到 C:\\WINDOWS\\system32void CCDlg::gl(){〃寻找路径::GetCunentDirectory(MAX_PATH, m_path.GetBuffer(MAX_PATH));〃得到当前程序的路径::CopyFile(sf,MC:\\WINDOWS\\system32\\c.exe,\FALSE);〃把当前程序拷贝到系统目录下}4结束语采用双进程的方法实现,程序代码简单、易懂,而且实现的功能完全符合题日要求另外,本文使用Visual C++编写程序,程序运行时有运行界而,可以清楚的卑见程序正在运 行但是程序并不是很完美,还有要改进的地方如果计算机用八找到可执行文件的所在并 删除可执行文件,并且把注册表中Shell的键值恢复,那么程序就无法运行了。
这就需要将 主进程备份保存,使用远程监控,也就是三线程的方法参考文[1]蔡振山沈怡麟李志玲Visual C++6编程宝典,清华大沖出版社2005.1.⑵张伟锋龙法宁,中文Windows 2000注册表编程最佳指南,浦东电子出版社,2001.4.[3] 。
