欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创][开源]杀毒软件的框架设计

[原创][开源]杀毒软件的框架设计

首先推荐下上个帖子  有兴趣移步 哈哈 
网络编程通信方面:
http://bbs.pediy.com/showthread.php?p=1402027#post1402027
病毒查杀代码来自[部分更改]:
http://bbs.pediy.com/showthread.php?t=204845
服务管理代码来自][添加禁止/启动服务]:
http://bbs.pediy.com/showthread.php?t=205382
开始进入正题。 为了阅读体验,我源码尽量少贴,只贴关键性代码(我认为的)并不是故意  
环境VS2012 WIN10 X64
界面【具体操作有动画效果】:








  • 全面体检:
  •                  我们负责索引病毒查杀、软件卸载、启动项管理、垃圾清理、内存优化这几个类便是。
    
    HomePage.h     HomePage.cpp
    
    [索引即可,并不关键]
    
    

  • 病毒查杀:
  •                  采用MD5查杀,MD5计算来自网络,所以开源的好处就是可以帮助需要帮助的人。
    MDC的值为CHAR*类型  我们自己需要个病毒库,或云端、或本地,我并没有,所以也无法上传病毒库啦,但我怎么确定功能是否有效呢? 很简单,我们把计算好的.EXE\.TXT.MP3.AVI.XXX任意类型的MD5值认定为病毒! 然后查杀。这么一说是不是感觉so easy!
                      好了 既然简单也就没什么好说的了。
    全盘查杀:
    
    VirusScanner.h     VirusScanner.cpp
    
    DWORD WINAPI VirusScanner::AllProc(LPVOID lpThreadParameter)
    
    {
    
      m_this->isInThead=true;
    
      WCHAR DiskName[MAX_PATH] = {0};
    
      GetLogicalDriveStrings(MAX_PATH,DiskName);
    
      int i = 0,j=0;
    
      for (; DiskName[i]!='\0'&& i < MAX_PATH; i++,j++)
    
      {
    
        m_this->TraverseFolder(DiskName,L".txt.exe.dll");
    
        i+=wcslen(&DiskName[i]);
    
        
    
      }
    
      if (!m_this->m_ButtonState)
    
      {
    
      m_this->  m_BackgroundPic=IDB_BITMAP5;//背景图片
    
      m_this->  MovebkPic(m_this->m_BackgroundPic);
    
      m_this->  m_ButtonState=true;
    
      m_this->  isInThead=false;
    
        //  m_AllKill.ShowWindow(SW_SHOW);
    
        //  m_AssignButton.ShowWindow(SW_SHOW)
    
      m_this->  m_StartupVirus1.ShowWindow(SW_SHOW);
    
      m_this->  m_StartupVirus2.ShowWindow(SW_SHOW);
    
      }
    
      return 0;
    
    }
    
    

    闪电查杀:
    
    DWORD WINAPI VirusScanner::LightningProc(LPVOID lpThreadParameter)
    
    {
    
      //C:\\Program Files (x86)   C:\\Program Files  D:\Program Files
    
      m_this->isInThead=true;
    
      WCHAR DiskName[MAX_PATH][MAX_PATH] = {
    
                _T("C:\\Program Files (x86)"),    //闪电杀毒查杀的范围
    
                _T("C:\\Program Files"),
    
                _T("D:\\Program Files"),
    
                _T("D:\\Program Files (x86)"),
    
                _T("E:\\Program Files"),
    
                _T("E:\\Program Files (x86)"),
    
      };
    
      int i = 0;
    
      for (; i<7; i++)
    
      {
    
        m_this->TraverseFolder(DiskName[i],L".txt.exe.dll.mp3.avi");  //填写要扫描的类型
    
      }
    
      if (!m_this->m_ButtonState)
    
      {
    
      m_this->  m_BackgroundPic=IDB_BITMAP5;//背景图片
    
      m_this->  MovebkPic(m_this->m_BackgroundPic);
    
      m_this->  m_ButtonState=true;
    
      m_this->  isInThead=false;
    
        //  m_AllKill.ShowWindow(SW_SHOW);
    
        //  m_AssignButton.ShowWindow(SW_SHOW)
    
      m_this->  m_StartupVirus1.ShowWindow(SW_SHOW);
    
      m_this->  m_StartupVirus2.ShowWindow(SW_SHOW);
    
      }
    
      return 1;
    
    }
    
    

    指定位置查杀:
    
    索引AssignKill.h     AssignKill.cpp
    
    

    它们都用到的关键性函数:
    
    WIN32_FIND_DATAW findFileData={0};
    
      TCHAR szFind[MAX_PATH] = {_T("\0")};
    
      CString pipei=filetype;//pipei 匹配O(∩_∩)O~
    
      BOOL bRet;
    
      CString fileRootPath = szName;
    
      CString filePath = fileRootPath+_T("\\*.*");
    
      HANDLE hwnd=FindFirstFile(filePath,&findFileData);
    
      if (hwnd==INVALID_HANDLE_VALUE)//没找到文件
    
      {
    
        MessageBox(_T("该文件路径不存在"),_T("错误"),NULL);
    
        return;
    
      }
    
      while (true)
    
      {
    
        if (_tcscmp(findFileData.cFileName,_T("."))==0||
    
          _tcscmp(findFileData.cFileName,_T(".."))==0 )
    
        {
    
          bRet=FindNextFile(hwnd,&findFileData);
    
          if (!bRet)
    
          {
    
            break;
    
          }
    
          continue;
    
        }
    
        CString path = fileRootPath+ _T("\\")+ findFileData.cFileName;
    
        int index = path.ReverseFind(_T('.'));
    
        CString pix  = path.Right(path.GetLength()-index);
    
        if (pipei.Find(pix)!=-1)
    
        {
    
          char *MD5="bacf0d5cec1d91f252b42c39d0bea5ca";//你认为的文件是病毒的MD5的值  
    
          CStringA ff(path);
    
          char * h = md5FileValue(ff.GetBuffer());
    
          if (strcmp(h,MD5)==0)
    
          {
    
            //DeleteFile(path);
    
            MessageBox(L"已查杀");
    
          }
    
        }
    
        if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    
        {
    
          _tcscpy_s(szFind,MAX_PATH,szName);
    
          _tcscat_s(szFind,_T("\\"));
    
          _tcscat_s(szFind,findFileData.cFileName);
    
          TraverseFolder(szFind,pipei);
    
        }
    
        bRet=FindNextFile(hwnd,&findFileData);
    
        if (bRet==0)
    
        {
    
          break;
    
        }
    
      }
    
    

  • 服务管理:
  •                 用函数遍历服务ListControl显示   
    
    ServiceManagement.h     ServiceManagement.cpp
    
    [上个帖子有介绍]
    
    

  • 软件卸载:
  •                  这个操作关乎到注册表,所以我们要用到注册表相关函数 找到主键遍历子键删除键值就OK啦。
    
    UninstallTool.h     UninstallTool.cpp.cpp
    
    //加载软件信息
    
    void UninstallTool::UninstallIndex()
    
    {
    
      LONG nRet=RegOpenKeyEx(RootKey,lpSubKey,0,KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE,&hkResult);
    
      if (nRet!=ERROR_SUCCESS)
    
      {
    
        return ;
    
      }
    
      DWORD dwIndex=0;
    
      //循环遍历子键
    
      while (true)
    
      {
    
        DWORD dwKeyLen=MAX_KEY_LENGTH;
    
        //WCHAR szNewKeyName[MAX_PATH]={};
    
        TCHAR szNewKeyName[MAX_KEY_LENGTH] ;
    
        nRet=RegEnumKeyEx(hkResult,dwIndex,szNewKeyName,&dwKeyLen,NULL,NULL,NULL,NULL);
    
        if (nRet!=ERROR_SUCCESS)
    
        {
    
          break;    //可断点检查相应错误
    
        }
    
        //通过得到的子键组合新的子键路径
    
        WCHAR strMidReg[MAX_PATH]={};
    
        swprintf_s(strMidReg,L"%s%s%s",lpSubKey,L"\\",szNewKeyName);
    
        //打开新的子键获取句柄
    
        HKEY hkValueKey=0;
    
        RegOpenKeyEx(RootKey,strMidReg,0,KEY_QUERY_VALUE,&hkValueKey);
    
        //获取键值
    
        DWORD dwNameLen=255;
    
        DWORD dwtype;
    
        RegQueryValueEx(hkValueKey,L"DisplayName",0,&dwtype,(LPBYTE)SoftInfo.szSoftName,&dwNameLen);//软件名
    
        if(m_VecSoftInfo.size()>1)
    
        {
    
          if ((wcscmp(SoftInfo.szSoftName,m_VecSoftInfo[m_VecSoftInfo.size()-1].szSoftName)==0))
    
          {
    
            dwIndex++;
    
            continue;
    
          }
    
        }
    
        m_UniListCtrl.InsertItem(0,SoftInfo.szSoftName);
    
        dwNameLen=255;//如果没有重新赋值 下一次将获取不到路径 
    
        dwtype=0;           //也许dwtype并不要但是 重新赋值并无坏处吧
    
        RegQueryValueEx(hkValueKey,L"UninstallString",0,&dwtype,(LPBYTE)SoftInfo.szSoftUniPath,&dwNameLen);//卸载路径
    
        dwNameLen=255;
    
        dwtype=0;
    
        RegQueryValueEx(hkValueKey,L"DisplayIcon",0,&dwtype,(LPBYTE)SoftInfo.szSoftIco,&dwNameLen);//光标路径
    
        dwNameLen=255;
    
        dwtype=0;
    
        RegQueryValueEx(hkValueKey,L"DisplayVersion",0,&dwtype,(LPBYTE)SoftInfo.szSoftVer,&dwNameLen);//版本号
    
        m_UniListCtrl.SetItemText(0,1,SoftInfo.szSoftVer);
    
        dwNameLen=255;
    
        dwtype=0;
    
        RegQueryValueEx(hkValueKey,L"Publisher",0,&dwtype,(LPBYTE)SoftInfo.szSoftVenrel,&dwNameLen);//发布厂商
    
        m_UniListCtrl.SetItemText(0,3,SoftInfo.szSoftVenrel);
    
        dwNameLen=255;
    
        dwtype=0;
    
        RegQueryValueEx(hkValueKey,L"InstallDate",0,&dwtype,(LPBYTE)SoftInfo.szSoftDate,&dwNameLen);//安装日期
    
        m_UniListCtrl.SetItemText(0,2,SoftInfo.szSoftDate);
    
        dwNameLen=255;
    
        dwtype=0;
    
        RegQueryValueEx(hkValueKey,L"URLInfoAbout",0,&dwtype,(LPBYTE)SoftInfo.szURLInfo,&dwNameLen);//网站
    
        dwNameLen=255;
    
        dwtype=0;
    
        RegQueryValueEx(hkValueKey,L"HelpLink",0,&dwtype,(LPBYTE)SoftInfo.HelpLink,&dwNameLen);//网站
    
        dwNameLen=255;
    
        dwtype=0;
    
        RegQueryValueEx(hkValueKey,L"InstallLocation",0,&dwtype,(LPBYTE)SoftInfo.szSoftInsPath,&dwNameLen);//安装路径
    
        dwNameLen=255;
    
        dwIndex++;
    
        m_VecSoftInfo.push_back(SoftInfo);
    
      }
    
    }
    
    

  • 启动项管理:
  •                  这里里面最难的就是那个ListControl自绘,我们要在相应行创建按钮并响应相关消息
    处理这个消息。其实写完了回头看,就会有种并不是很难的感觉。 这个有明显BUG就是切换界面并不刷新界面,当然了 这个程序软件有很多很多BUG,细节处理的问题或其它,毕竟只做5天,也没时间在做下去了,要开始下个阶段的学习了
    
    void StartupManager::initListBox()
    
    {
    
      LONG nRet=RegOpenKeyEx(RootKey,lpStartupSubKey,0,KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE,&hkStartupResult);
    
      if (nRet!=ERROR_SUCCESS)
    
      {
    
        return ;
    
      }
    
      DWORD dwIndex=0;
    
      //循环遍历子键
    
      while (true)
    
      {
    
        
    
        DWORD dwKeyLen=MAX_KEY_LENGTH;
    
        nRet=RegEnumValue(hkStartupResult,dwIndex,info.szNewKeyName,&dwKeyLen,NULL,NULL,(PBYTE)info.szNewValueName,&dwKeyLen);
    
        if (nRet!=ERROR_SUCCESS)
    
        {
    
          break;    //可断点检查相应错误
    
        }
    
        TCHAR SynthesisStr[2048];    //合成字符串
    
        _stprintf_s(SynthesisStr,_T("[%s]%s"),info.szNewKeyName,info.szNewValueName);
    
        m_StartupListCtrl.InsertItem(dwIndex,SynthesisStr);
    
        m_StartupListCtrl.createItemButton(dwIndex, 
    
                          2,    //点击按钮(在第二例)处理的值  未做
    
                          this->GetSafeHwnd() );    //创建按钮
    
        dwIndex++;
    
        m_VecStartupInfo.push_back(info);    
    
      }
    
      RegCloseKey(hkStartupResult);
    
    }
    
    

  • 垃圾清理:
  •                  这里用到2个最主要的关键函数SHDeleteKey()及SHDeleteValue()和其它删除函数用法主要是传路径设置好权限该false的false 该NULL的NULL。也应该没什么太大的难度
    
    CleanSpace.h     CleanSpace.cpp
    
    /**清理垃圾回收站*/
    
    VOID CleanSpace::CleanRubbishStation()
    
    {
    
      SHEmptyRecycleBin(NULL, NULL, SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND);
    
    }
    
    /**清理运行记录*/
    
    VOID CleanSpace::CleanRunHistory()
    
    {
    
      SHDeleteKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU"));
    
    }
    
    /**清理文档记录*/
    
    VOID CleanSpace::CleanDocumentHistory()
    
    {
    
      CString strPath;                           
    
      BOOL bSuccess = SHGetSpecialFolderPath(NULL, strPath.GetBuffer(MAX_PATH), CSIDL_RECENT, FALSE);
    
      strPath.ReleaseBuffer();
    
      if (bSuccess)
    
      {
    
        EmptyDirectory(strPath);
    
      }
    
      SHDeleteKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs"));
    
    }
    
    /**清理上次用户登录记录*/
    
    VOID CleanSpace::CleanPrevUserHistory()
    
    {
    
      SHDeleteValue(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), 
    
        TEXT("DefaultUserName"));
    
      SHDeleteValue(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), 
    
        TEXT("AltDefaultUserName"));
    
      SHDeleteValue(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Winlogon"), 
    
        TEXT("DefaultUserName"));
    
    }
    
    

  • 内存优化:
  •                  我们在这清理内存并获得占用内存 关键代码也就几句吧。
    
    void MemoryOptimizer::ClenMemory()
    
    {
    
      MEMORYSTATUSEX stcMemStatusEx={};
    
      stcMemStatusEx.dwLength=sizeof(stcMemStatusEx);
    
      GlobalMemoryStatusEx(&stcMemStatusEx);
    
      DWORDLONG preUsedMem=stcMemStatusEx.ullTotalPhys-stcMemStatusEx.ullAvailPhys;
    
      m_Memzhanyong =(double)preUsedMem/1024/1024/1000;
    
      hh.Format(L"%0.2lf",m_Memzhanyong);
    
      //清理内存
    
      DWORD dwPIDList[1000]={0};
    
      DWORD bufSize=sizeof(dwPIDList);
    
      DWORD dwNeedSize=0;
    
      EnumProcesses(dwPIDList,bufSize,&dwNeedSize);
    
      for (DWORD i=0;i<dwNeedSize/sizeof(DWORD);i++)
    
      {
    
        HANDLE hProcess=OpenProcess(  PROCESS_SET_QUOTA,false,dwPIDList[i]);
    
        SetProcessWorkingSetSize(hProcess,-1,-1);
    
      }
    
      // 获取清理后的内存状态
    
      GlobalMemoryStatusEx(&stcMemStatusEx);
    
      DWORDLONG afterCleanUsedMem=stcMemStatusEx.ullTotalPhys-stcMemStatusEx.ullAvailPhys;
    
      m_delMemory=(preUsedMem-afterCleanUsedMem)/1024/1024;    //已删除内存
    
      hd.Format(L"%d",m_delMemory);
    
    }
    
    


    其它诸如:
    
    按钮自绘:
    
    ImageButton.h    ImageButton.cpp     全部
    
    ListControl按钮自绘:
    
    ListButton.h     ListButton.cpp            应用在启动项管理
    
    MyListCtrl.h      MyListCtrl.cpp            应用在启动项管理
    
    ListControl自绘 :
    
    ListCtrl.h     ListCtrl.cpp    应用在服务启动及软件卸载
    
    MD5值计算:
    
    Md5.h     Md5.cpp              网上开源  应用在病毒查杀
    
    flash控件:
    
    shockwaveflash1.h     shockwaveflash1.cpp  创建flash控件自动生成  应用在内存优化
    
    combo box控件:
    
    MyListBox.h     MyListBox.cpp         自绘失败 MyListCtrl与ListButton代替  不过代码未删
    
    TabControl控件:
    
    TabControl.h     TabControl.cpp     这个就不用多说啦  其实第二天我想放弃的 但是整个框架都搭建好了 又由于时间不够  我就放弃了 其实这个地方可以做成腾讯电脑管家下方显示的样式
    
    好了 应该都介绍完了。
    
    

     版主大大能给个优秀精华就好了 哈哈
    这几天做的挺累的  下午饭都不吃在教室写  晚上叫外卖 然后 晚上9:30下课 有俩天到了10点半左右我还在加班  然后回宿舍被宿舍阿姨关在外面 使劲按门铃才给开  好忧伤。。。
    现在在北京 过年回深圳

    待会上传源码吧 我休息会儿  编辑了大半个小时
    ---------------------------------------
    源码(分卷) :
    电脑管家.part01.rar
    电脑管家.part02.rar
    电脑管家.part03.rar
    电脑管家.part04.rar
    电脑管家.part05.rar
    百度云盘:
    【源码】http://pan.baidu.com/s/1ntjGTlf密码: 4f1n
    【资源】http://pan.baidu.com/s/1qOTD8 密码: hbi8
    有的资源单个3、4MB我都直接用了。。造成程序很大。你们也可以不用 反正资源这个东西可以随便改
    转载注明出处

    上传的附件 1.png
    2.png
    3.png
    4.png
    5.png
    6.png
    7.png
    eec843765eb4d0c.jpg
    电脑管家.part01.rar
    电脑管家.part02.rar
    电脑管家.part03.rar
    电脑管家.part04.rar
    电脑管家.part05.rar

    注意:上传附件及图片大小不得大于30M。

    ⚠️ 版权声明:
    本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
    未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

    0 0 0 举报
    复制成功