浅析三线程程序开发思路与实现
2010-05-12 20:35:44 来源:WEB开发网一、前言
中国黑客(worm.runouce)病毒在国内出现以后,各大反病毒公司都对其进行了“仔细”的分析,得出一个结论:“中国黑客”发现了全球首创的“三线程”结构。这是某公司对外的宣传词,我个人对病毒没什么研究,并且我对worm.runouce没有任何的个人看法,不过我可以确信的是很多反病毒公司往往在夸大事实,目的只有一个:让更多的用户觉得某某病毒很可怕,让更多的用户相信只有某某公司的杀毒软件才可以彻底将病毒清除掉。其实三线程并没有好高深的技术,不过ideal is wonderful。现在就让我们一步步揭开三线程程序开发的神秘面纱。
二、三线程程序开发思路
在操作系统中,进程是存储器,外设等资源的分配单位,同时也是处理器调度的对象,但为了提高进程内的并发性,windows系统中引入了线程这个概念(在很多其他操作系统中同样也有线程的概念,由于在2001年微软停止了window9x内核的研发,所以本文只针对windowx2000/xp操作系统),这时系统把线程作为处理器调度的对象,一个进程可以同时拥有多个并发的线程。通常情况下的简单程序就只有一个主线程,它是在进程创建时自动生成的。我们可以将想要执行的代码放在主线程里,然后再生成两个辅助线程,它们的功能就是实现对程序的保护功能,防止程序被用户关闭或删除。在此,称我们的可执行文件的进程为主进程。
主线程需要完成的任务有三个,它们分别是准备工作,创建辅助线程和程序主要功能的实现。准备工作当然是为程序运行过程中所需要的一些部件做好准备,其中包括文件复制和保存,一般情况下是把可执行文件复制到系统目录下。当然为了防止意外删除,我们可以将程序的可执行文件备份,不过要注意修改一些属性(文件类型,大小,日期,属性),这样就不容易被发现与我们的可执行文件有关联了。创建辅助线程包括两个线程,一个驻留在主进程体内,另一个通过创建远程线程驻留到其他正在运行的进程体内。这两个线程的功能就是监视其他进程或线程的运行情况,如果出现异常立即恢复。程序的主要功能就不用多说了,想干什么就干什么,一般是一些不想让用户关闭的程序。
驻留主进程体内的线程同时观察注册表和远程进程的情况。它实时查询注册表里 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run键下相关可执行文件的键值,如果被删除就立即将其添加上。这就是对注册表的实时监视,使得每次开机时都会运行我们的可执行文件。而另一个功能则是监视驻留在远程进程体内辅助线程的运行情况,如果该线程被关闭,立即通过创建远程线程将被关闭的线程驻留到特定的进程内。如果你知道了辅助线程是驻留在那个进程内的,你就可以将这个远程进程关闭掉。但是我们还是可以将辅助线程驻留到其他的远程进程内。至于选定哪个远程进程,完全视你的心情而定。
驻留在远程进程体内的辅助线程则监视主进程的运行情况,如果主进程被kill了,它会确认程序的可执行文件是否也被删除掉了。如果系统目录下的可执行文件不存在了,则用我们备份的文件恢复可执行文件,然后再重新启动程序,这样你在任务管理器里怎么也删除不了主进程。由于我们是创建远程线程,所以必须把线程的代码和线程所需要的参数都复制到远程进程的地址空间里。这是因为在windows2000/xp环境下,访问其他进程地址空间是违规的。我们把代码和参数复制过去后,线程就完全在远程进程的地址空间运行了。我们可以看到,通过两个辅助线程,就很难把主进程关闭或删除掉。
现在我们就以一个诱鼠器为例,来分析三线程的程序结构,如下图:
|---------->-----------|
remote ---<--- T-mouse --->--- watch --->--- Registry
|------------------<--------------------|
其中T-mouse为主进程/主线程,remote为创建的远程线程,watch为本地的辅助监视线程,Registry为注册表文件。T-mouse创建remote和watch两个线程,remote监视T-mouse主进程,watch监视注册表文件和remote线程。
三、核心代码分析
本文的程序仅针对windows2000/xp操作系统,程序中使用的UNICODE编码。测试环境:Windows2000 + SP2 + VC6.0。整个程序分主线程main,本地辅助监视线程watch,远程线程remote,还包括获得进程ID的processtopid和创建远程线程的createremote两个自定义函数。
1.主线程:main
GetSystemDirectory(syspath,MAX_PATH);
//获得操作系统的系统目录;
FindFirstFile(tname,&fdata);
//查询系统目录下的T-mouse.exe是否存在;
CopyFile(curname,tname,TRUE);
//如果系统目录下没有,在将正在运行的程序复制到系统目录下;
FindClose(ffhandle);
//在查询完毕后,关闭相关句柄;
CreateFile(kname,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
//打开系统目录下的备份文件kernel.dll;
SetFileTime(fchandle,&ftime,NULL,&ftime);
//修改kernel.dll的创建时间,修改时间;
SetFileAttributes(kname,FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM );
//设置kernel.dll的属性为只读,系统及隐藏;
CreateThread(NULL,0,watch,(LPVOID)rthread,0,NULL);
//创建驻留在主进程内的辅助监视线程
赞助商链接