杀毒软件的简单实现 -- quoted

#define DEBUGMSG

#include <windows.h>
#include <windef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "Psapi.h"

#pragma comment (lib,"Psapi.lib")

#define erron GetLastError ()

#define FIVE 50
#define HIGH 255

TCHAR name[FIVE]={0};    //保存虫虫的文件名+路径
FILE *Gfp=NULL;          //输出到文件

BOOL ScanVXER (LPTSTR V_FileName,long V_FileOffset,int V_Length,TCHAR *V_Contents);
//匹配特征码函数

BOOL ScanFileVXER (LPTSTR FileName);
//文件遍历函数

BOOL ProcessVXER (void);
//枚举进程函数

BOOL KillProc (DWORD ProcessID);
//杀进程函数

BOOL EnablePrivilege(LPTSTR PrivilegeName);
//提升权限函数

BOOL RegDelVXER (void);
//删除注册表项函数

void Usage (LPCTSTR Parameter);
//帮助函数

int main (int argc, TCHAR *argv[])
{
   if (argc!=2)
   {
       Usage(argv[0]);
       return 0;
   }

   #ifdef DEBUGMSG
          Gfp=fopen("VXER.txt","a+");

          if (Gfp==NULL)
          {
              printf("Open /"VXER.txt/" fail/n");
              return 0;
          }

          fprintf(Gfp,"%s/n/n","[-------------------------File list-------------------------]");
   #endif

   if (strlen(argv[1])>10)
   {
       printf("Fine name no larger than /"10/"/n");
       return 0;
   }

   if (!(ScanFileVXER(argv[1])))
   {
       #ifdef DEBUGMSG
              printf("ScanFileVXER() GetLastError reports %d/n",erron);
       #endif
       fclose(Gfp);
       return 0;
   }
   
   if (!(ProcessVXER()))
   {
       #ifdef DEBUGMSG
              printf("ProcessesVXER() GetLastError reports %d/n",erron);
       #endif
       fclose(Gfp);
       return 0;
   }

   if (!(RegDelVXER()))
   {
       #ifdef DEBUGMSG
              printf("RegDelVXER() GetLastError reports %d/n",erron);
       #endif
       fclose(Gfp);    
       return 0;
   }

   fclose(Gfp);
   return 0;
}

BOOL ScanFileVXER (LPTSTR FileName)
{
    WIN32_FIND_DATA FindFileData;
    DWORD lpBufferLength=HIGH;
    TCHAR lpBuffer[HIGH]={0};
    TCHAR DirBuffer[HIGH]={0};
    HANDLE hFind=NULL;
    UINT count=0;

    long FileOffset=0x1784;  //偏移地址
    int FileLength=0x77;     //长度

    TCHAR Contents[]={
    0x49, 0x20, 0x6A, 0x75, 0x73, 0x74, 0x20, 0x77, 0x61, 0x6E, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x73,
    0x61, 0x79, 0x20, 0x4C, 0x4F, 0x56, 0x45, 0x20, 0x59, 0x4F, 0x55, 0x20, 0x53, 0x41, 0x4E, 0x21,
    0x21, 0x20, 0x62, 0x69, 0x6C, 0x6C, 0x79, 0x20, 0x67, 0x61, 0x74, 0x65, 0x73, 0x20, 0x77, 0x68,
    0x79, 0x20, 0x64, 0x6F, 0x20, 0x79, 0x6F, 0x75, 0x20, 0x6D, 0x61, 0x6B, 0x65, 0x20, 0x74, 0x68,
    0x69, 0x73, 0x20, 0x70, 0x6F, 0x73, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x20, 0x3F, 0x20, 0x53, 0x74,
    0x6F, 0x70, 0x20, 0x6D, 0x61, 0x6B, 0x69, 0x6E, 0x67, 0x20, 0x6D, 0x6F, 0x6E, 0x65, 0x79, 0x20,
    0x61, 0x6E, 0x64, 0x20, 0x66, 0x69, 0x78, 0x20, 0x79, 0x6F, 0x75, 0x72, 0x20, 0x73, 0x6F, 0x66,
    0x74, 0x77, 0x61, 0x72, 0x65, 0x21, 0x21};
    //从冲击波中提取出来的,用做特征码

    //获取系统目录的完整路径
    if (GetSystemDirectory(DirBuffer,lpBufferLength)!=0)
    {
        if (SetCurrentDirectory(DirBuffer)!=0) //设置为当前目录
        {
            hFind=FindFirstFile(FileName,&FindFileData);  //查找文件
            if (hFind==INVALID_HANDLE_VALUE)
            {
                #ifdef DEBUGMSG
                       printf("FindFirstFile() GetLastError reports %d/n",erron);
                #endif
                if (hFind!=NULL)
                    FindClose(hFind);
                return FALSE;
            }
            else
            {
                count++;

                //获得文件的完整路径
                if (GetFullPathName(FindFileData.cFileName,lpBufferLength,lpBuffer,NULL)!=0)
                {
                    #ifdef DEBUGMSG
                           fprintf(Gfp,"File:/t/t%s/n",lpBuffer);
                    #else
                           printf("File:/t/t%s/n",lpBuffer);
                    #endif
                }
                else
                {
                    #ifdef DEBUGMSG
                           printf("GetFullPathName() GetLastError reports %d/n",erron);
                    #endif
                    if (hFind!=NULL)
                        FindClose(hFind);
                    return FALSE;
                }
            }
           
            //进行特征码匹配工作
            ScanVXER(FindFileData.cFileName,FileOffset,FileLength,Contents);
        }
    }

    while (FindNextFile(hFind,&FindFileData))  //继续查找文件
    {
           count++;

           //以"."和".."除外
           if (strcmp(".",FindFileData.cFileName)==0||strcmp("..",FindFileData.cFileName)==0)
           {
               #ifdef DEBUGMSG
                      printf("File no include /"./" and /"../"/n");
               #endif
               if (hFind!=NULL)
                   FindClose(hFind);

               fclose(Gfp);
               exit(0);
           }

           if (GetFullPathName(FindFileData.cFileName,lpBufferLength,lpBuffer,NULL)!=0)
           {
               #ifdef DEBUGMSG
                      fprintf(Gfp,"Next File:/t%s/n",lpBuffer);
               #else
                      printf("Next File:/t%s/n",lpBuffer);
               #endif
           }
           else
           {
               #ifdef DEBUGMSG
                      printf("GetFullPathName() GetLastError reports %d/n",erron);
               #endif
               if (hFind!=NULL)
                   FindClose(hFind);

               fclose(Gfp);
               exit(0);
           }
           
           ScanVXER(FindFileData.cFileName,FileOffset,FileLength,Contents);
       
    }

    fprintf(Gfp,"/nFile Total:%d/n/n",count);
    fprintf(Gfp,"%s/n/n","[-------------------------File end---------------------------]/n");

    printf("File Total:%d/n",count);  //打印出查找到的文件各数

    if (hFind!=NULL)
        FindClose(hFind);               //关闭搜索句柄
    return TRUE;
}

BOOL ScanVXER (
LPTSTR V_FileName,  //文件名
long V_FileOffset, //偏移地址
int V_Length,      //长度
TCHAR *V_Contents)  //具体内容
{
    TCHAR FileContents[HIGH]={0};
    int cmpreturn=0;
    FILE *fp=NULL;

    fp=fopen(V_FileName,"rb");  //以二进制只读方式打开

    if (fp==NULL)
    {
        #ifdef DEBUGMSG
               printf("fopen() File open FAIL/n");
        #endif
        fclose(fp);
        return FALSE;
    }

    fseek(fp,V_FileOffset,SEEK_SET);  //把文件指针指向特征码在文件的偏移地址处
    fread(FileContents,V_Length,1,fp);//读取长度为特征码长度的内容
    cmpreturn=memcmp(V_Contents,FileContents,V_Length);
    //进行特征码匹配。失败返回FALSE

    if (cmpreturn==0)
    {
        #ifdef DEBUGMSG
               printf("File match completely/n"); //打印文件匹配消息
        #endif
        strcpy(name,V_FileName);                  //将文件名保存在全局变量name中
        if (fp!=NULL)
            fclose(fp);
        return TRUE;
    }
    else
    {
        fclose(fp);
        return FALSE;
    }

}

BOOL ProcessVXER (void)
{
    DWORD lpidProcess[1024]={0};
    DWORD cbNeeded_1,cbNeeded_2;
    HANDLE hProc=NULL;
    HMODULE hMod[1024]={0};
    TCHAR ProcFile[MAX_PATH];
    TCHAR FileName[FIVE]={0};
    UINT Pcount=0;
    int i=0;

    EnablePrivilege(SE_DEBUG_NAME);   //提升调试进程权限

    fprintf(Gfp,"%s/n/n","[------------------------Process list--------------------------]");

    strcpy(FileName,"C://WINNT//system32//");
    strcat(FileName,name);//把文件名+路径复制到FileName变量中

    //枚举进程
    if (!(EnumProcesses(lpidProcess,sizeof(lpidProcess),&cbNeeded_1)))
    {
        #ifdef DEBUGMSG
               printf("EnumProcesses() GetLastError reports %d/n",erron);
        #endif
        if (hProc!=NULL)
            CloseHandle(hProc);
        return FALSE;
    }

    for (i=0;i<(int)cbNeeded_1/4;i++)
    {
         //打开找到的第一个进程
         hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,lpidProcess[i]);

         if (hProc)
         {
             //枚举进程模块
             if (EnumProcessModules(hProc,hMod,sizeof(hMod),&cbNeeded_2))
             {
                 //枚举进程模块文件名,包含全路径
                 if (GetModuleFileNameEx(hProc,hMod[0],ProcFile,sizeof(ProcFile)))
                 {
                     #ifdef DEBUGMSG
                            fprintf(Gfp,"[%5d]/t%s/n",lpidProcess[i],ProcFile);
                     #else
                            printf("[%5d]/t%s/n",lpidProcess[i],ProcFile); //输出进程
                     #endif
                     //可以考虑将其注释掉,这样就不会输出进程列表了
                     Pcount++;

                     //查找进程中是否包含FileName
                     if (strcmp(FileName,ProcFile)==0)
                     {
                         //如果包含,则杀掉。KillProc为自定义的杀进程函数
                         if (!(KillProc(lpidProcess[i])))
                         {
                             #ifdef DEBUGMSG
                                    printf("KillProc() GetLastError reports %d/n",erron);
                             #endif
                             if (hProc!=NULL)
                                 CloseHandle(hProc);

                             fclose(Gfp);
                             exit(0);
                         }

                         DeleteFile(FileName); //进程杀掉后,再将文件删除
                     }
                 }
             }
         }
    }

    if (hProc!=NULL)
        CloseHandle(hProc);                //关闭进程句柄

    fprintf(Gfp,"/nProcess total:%d/n/n",Pcount);
    fprintf(Gfp,"%s/n/n","[------------------------Process end----------------------------]");

    printf("/nProcess total:%d/n/n",Pcount);  //打印进程各数

    return TRUE;
}

BOOL KillProc (DWORD ProcessID)
{
    HANDLE hProc=NULL;

    //打开由ProcessVXER()传递的进程PID
    hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,ProcessID);

    if (hProc!=NULL)
    {
        //终止进程
        if (!(TerminateProcess(hProc,0)))
        {
            #ifdef DEBUGMSG
                   printf("TerminateProcess() GetLastError reports %d/n",erron);
            #endif
            CloseHandle(hProc);
            return FALSE;
        }
    }
    else
    {
        #ifdef DEBUGMSG
               printf("OpenProcess() GetLastError reports %d/n",erron);
        #endif
        return FALSE;
    }

    if (hProc!=NULL)
        CloseHandle(hProc);

    return TRUE;
}

BOOL EnablePrivilege(LPTSTR PrivilegeName)
{
    HANDLE hProc=NULL,hToken=NULL;
    TOKEN_PRIVILEGES TP;
    hProc=GetCurrentProcess();  //打开当前进程的一个伪句柄

    //打开进程访问令牌,hToken表示新打开的访问令牌标识
    if(!OpenProcessToken(hProc,TOKEN_ADJUST_PRIVILEGES,&hToken))
    {
       #ifdef DEBUGMSG
              printf("OpenProcessToken() GetLastError reports %d/n",erron);
       #endif
       goto Close;
    }

    //提升权限
    if(!LookupPrivilegeValue(NULL,PrivilegeName,&TP.Privileges[0].Luid))
    {
        #ifdef DEBUGMSG
               printf("LookupPrivilegeValue() GetLastError reports %d/n",erron);
        #endif
        goto Close;
    }

    TP.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
    TP.PrivilegeCount=1;

    //允许权限,主要根据TP这个结构
    if(!AdjustTokenPrivileges(hToken,FALSE,&TP,sizeof(TP),0,0))
    {
        #ifdef DEBUGMSG
               printf("AdjustTokenPrivileges() GetLastError reports %d/n",erron);
        #endif
        goto Close;
    }

    Close:

          if (hProc!=NULL)
              CloseHandle(hProc);

          if (hToken!=NULL)
              CloseHandle(hToken);

          return FALSE;

    if (hProc!=NULL)
        CloseHandle(hProc);

    if (hToken!=NULL)
        CloseHandle(hToken);

    return TRUE;
}

BOOL RegDelVXER (void)
{
   HKEY hkey;
   DWORD ret=0;

   //打开注册表的Run项
   ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                    "SOFTWARE//Microsoft//Windows//CurrentVersion//Run//",
                    0,
                    KEY_ALL_ACCESS,
                    &hkey);

   if (!(ret==ERROR_SUCCESS))
   {
       #ifdef DEBUGMSG
              printf("RegOpenKeyEx() GetLastError reports %d/n",erron);
       #endif
       return FALSE;
   }

   //删除键值windows auto update。
   ret=RegDeleteValue(hkey,"windows auto update");

   if (ret==ERROR_SUCCESS)
   {
       #ifdef DEBUGMSG
              printf("Success Delete/n");
       #endif
   }
   else
   {
       #ifdef DEBUGMSG
              printf("RegDeleteValue() GetLastError reports %d/n",erron);
       #endif
       RegCloseKey(hkey);
       //exit(0);
   }

   RegCloseKey(hkey);  //关闭打开的注册表项
   return TRUE;
}

void Usage (LPCTSTR Parameter)
{
    LPCTSTR Path="%SystemRoot%//system32//";

    fprintf(stderr,"============================================================================/n"
            "      杀毒软件的简单实现/n"
            "环境:Win2K Adv Server + Visual C++ 6.0/n"
            "作者:dahubaobao/n"
            "主页:www.RingZ.org/n"
            "OICQ:382690/n"
            "邮件:382690@qq.com/n"
            "声明:本帖由环行区(RingZ)原创,转载请注明出处,谢谢!/n/n"
            "使用方法:/n"
            "%s 文件名。例如:%s msblast.exe or %s *.exe /n/n"
            "注意事项:/n"
            "本程序只是简单介绍杀毒软件的编写方法,所以有很多不完善的地方,包括:/n"
            "1,本程序是以冲击波蠕虫做的例子/n"
            "2,文件遍历只搜索了%s目录下的文件/n"
            "3,本程序不能查杀冲击波变种/n/n"
            "本程序只是用做代码交流,如有错误,还请多多包含!/n"
            "============================================================================"
            ,Parameter,Parameter,Parameter,Path);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
一款可以自已定制病特征库的软件,可以用此软件变种为任意的病工具。界面及病特征库均可自行定制编辑,支持最大100个线程扫描文件,方式可自行设定,支持对每一种病特征码设置一种方式。采用文件二进制比对的方式查电脑上的文件,可以对电脑文件中含有病特征码的文件执行删除文件、清除文件病码字节、用空格替换文件病码字节、用0x00替换文件病码字节,用指定字符替换文件病码字节等等方式。病特征码可以资源共享。 目前版本的实质为:多线程文件内容比对查找及修改替换工具。程序未加入主动防御、恶意行为拦截等功能,程序特别适合作为病工具,可以对程序作小的改动即可实现变种。 本程序规模不大,易读懂,程序全为业余书写,几乎没有经过什么测试,可能存在许多错误。软件在www.csdn.net首页的“创新无极限,软件你来选”中申报成功(开源类),请下载了源码的用户在2010年1月1日到2010年1月21日期间投此软件一票,以示对作者开源的支持。 作者开源的另一作品“文本语音朗读组件”全套VC++源码,也欢迎用户下载并投作者一票。你可以对上面两款软件源码重新改进形成功能各异的属于你的作品。 作者已没有时间对上述程序进行深度开发和升级,只是希望
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值