文件感染模型

来源:互联网 发布:网络现金赌博网站 编辑:程序博客网 时间:2024/06/08 13:52
文件感染类病毒的一个很重要的任务就是搜索全盘,找到需要感染的文件然后感染它.感染的速度越快,资源占用率越低,病毒的繁殖能力则越强,清除的难度也就越大.
    大部分病毒都是采用递归扫描方式扫描全盘,一旦扫描到可以感染的文件就立即感染.但是这样一方面效率会由于递归而大大折扣,另一方面会出现资源占用率不均衡现象.例如有的文件夹里可能都是一些文档,不需要感染,此时可能病毒比较空闲,占用系统资源比较少;但是有的文件夹可能都是PE文件,这时病毒的资源占用率就会很大.还有一个问题,就是递归扫描很难确定当前扫描状态,这样每次就必须从头扫描.因此,如果我们采用非递归扫描方式,并且利用多线程将扫描和感染分开,利用缓冲技术让他们协同工作,这样效率会大大提高.
    例如可以定义以下类实现文件感染:
class CHackfile {
public:
CHackfile();                               //构造函数
void Work();                               //开始工作
bool Up(unsigned char step);                        //增加延迟
bool Down(unsigned char step);                    //减少延迟
friend DWORD Managerfunc (LPVOID   lpVoid);   //管理线程
friend DWORD Scannerfunc (LPVOID   lpVoid);     //扫描线程
friend DWORD Pehackerfunc(LPVOID   lpVoid);    //感染线程
private:
void Get(void);                                    //获取磁盘信息
void Save(char *filename);                                  //保存磁盘信息
void Open(char *filename);                                //打开磁盘信息
private:
CStack *stack;                                       //缓冲堆栈
unsigned char disknum;                                 //可写磁盘数
struct strscanmsg {
  HANDLE   handle;                                    //扫描线程句柄
  unsigned long sptime;                                     //扫描线程自阻塞时间
  unsigned long xhtime;                                       //扫描磁盘一遍的时间
  char path[MAX_PATH];                                     //扫描线程当前路径
} *scanmsg;                                            //扫描信息
unsigned char hkernum;                                   //感染线程数
struct strhackmsg {
  bool effect;                                             //感染线程是否继续运行
  HANDLE   handle;                                     //感染线程句柄
  unsigned long sptime;                                       //感染线程自阻塞时间
  unsigned long hacknum;                                       //感染线程感染文件数
} *hackmsg;                                       //感染信息
};

    扫描线程组将扫描到的需要感染的文件名放入缓冲堆栈,感染线程组从缓冲堆栈中取出文件名然后感染。管理现成根据当前系统状况动态调节扫描线程组和感染线程组的工作力度和堆栈空间大小,达到动态平衡的效果。
    缓冲堆栈类的定义可以如下:
class CStack {
public:
CStack(unsigned int size=256);
bool Push(char *record);                                     //入栈
bool Pop (char *record);                                  //出栈
bool Chsize(unsigned int size);                            //改变栈大小

unsigned int fullnum;                                   //堆栈满次数
unsigned int emptynum;                                    //堆栈空次数
unsigned int size;                                    //栈大小
private:
bool LOCK;                                        //访问锁
char *stack[1024];                                                        //栈空间
unsigned int pos;                                                          //当前栈位置
};
原创粉丝点击