亲密接触恶意代码之文件感染和内存驻留--7
这次,作者将和大家一起讨论病毒的感染技术。另外,从本文开始,我们将陆续接触到一些病毒的高级编码技术。例如,内存驻留、EPO(入口点模糊)技术、加密技术、多态和变形等。通过这些高级技巧,你将进一步感受到病毒技术的精华,从而更好的享受其中精妙的思想与编程技艺。
在解决了起始目录的问题之后,就可以从这些起始目录开始使用FindFirstFile和FindNextFile开始遍历其下以及其子目录下的所有文件和目录了,遍历方法可采用深度优先或广度优先搜索算法,较常用的还是深度优先算法。具体实现方式可采用递归搜索或非递归搜索两种实现方式。递归搜索需要占用栈空间,有可能造成栈空间耗竭而产生异常,不过在现实应用中这种情况很少出现,而非递归搜索则不存在此问题,但代码实现略复杂。在现实应用中,应用最多的还是递归遍历搜索。搜索时,可指定FindFirstFile的第一形参为*.*以搜索所有文件,根据搜索结果WIN32_FIND_DATA结构的dwFileAttributes成员判断是否为目录,若为目录则需要继续遍历该子目录,根据WIN32_FIND_DATA的cFileName中的文件名成员判断是否具有要感染的文件后缀以采取修改感染动作,以下代码实现了递归搜索某个目录及其下所有子目录的功能:
void enum_path(char *cpath){
WIN32_FIND_DATA wfd;
HANDLE hfd;
char cdir[MAX_PATH];
char subdir[MAX_PATH];
int r;
GetCurrentDirectory(MAX_PATH,cdir);
SetCurrentDirectory(cpath);
hfd = FindFirstFile("*.*",&wfd);
if(hfd!=INVALID_HANDLE_VALUE) {
do{
if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if(wfd.cFileName[0] != '.') {
// 合成完整路径名
sprintf(subdir,"%s//%s",cpath,wfd.cFileName);
// 递归枚举子目录
enum_path(subdir);
}
}else{
printf("%s//%s/n",cpath,wfd.cFileName);
// 病毒可根据后缀名判断是
// 否要感染相应的文件
}
}while(r=FindNextFile(hfd,&wfd),r!=0);
}
SetCurrentDirectory(cdir);
}
短短20 多行C 代码就实现了文件遍历的功能,Win32 API的强大功能不仅为开发者提供了便利,同时也为病毒敞开了方便之门。用汇编实现则稍微复杂一些,感兴趣的读者可参阅Elkern 中的enum_path部分,原理是一样的,限于篇幅这里不再给出相应的汇编代码。
非递归搜索不使用堆栈存储相关的信息,而使用显式分配的链表或栈等结构存储相关的信息,应用一个迭代循环完成递归遍历同样的功能,下面是使用链表以栈方式处理子目录列表的一个简单实现:
void nr_enum_path(char *cpath){
list<string> dir_list;
string cdir,subdir;
WIN32_FIND_DATA wfd;
HANDLE hfd;
int r;
dir_list.push_back(string(cpath));
while(dir_list.size()) {
cdir = dir_list.back();
dir_list.pop_back();
SetCurrentDirectory(cdir.c_str());
hfd = FindFirstFile("*.*",&wfd);
if(hfd!=INVALID_HANDLE_VALUE) {
do{
if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if(wfd.cFileName[0] != '.') {
// 合成完整路径名
subdir=cdir+"//"+wfd.cFileName;
cout<<"push subdir: "<<subdir<<endl;
// 递归枚举子目录
dir_list.push_back(string(subdir));
}
}else{
printf("%s//%s/n",cpath,wfd.cFileName);
// 病毒可根据后缀名判断
// 是否要感染相应的文件
}
}while(r=FindNextFile(hfd,&wfd),r!=0);
}
}//end while
}
在以汇编语言实现时,需要自己管理链表以及分配和释放相应的结构,因此较为烦琐,代码量也稍大,因此病毒多采用递归的方式进行搜索。值得注意的是搜索深层次的目录是很费时的,因此大部分病毒为避免CPU占用率过高,搜索一定数量的文件之后,都会调用Sleep 休眠一会,以避免被敏感的用户发觉。文件搜索和感染模块通常是以单独的线程运行的,在病毒获得控制权后,创建相应的搜索和感染线程,而将主现成的控制权交给原程序
本文来自CSDN博客http://blog.csdn.net/p123456789p/archive/2009/03/20/4006847.aspx