不学网

 找回密码
 立即注册

只需一步,快速开始

手机号码,快捷登录

查看: 87|回复: 4

[c/c++] 仿LordPE获取PE结构

[复制链接]
BiaoGe 发表于 2018-7-25 17:57:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
本帖最后由 BiaoGe 于 2018-7-25 18:03 编辑

乍一看LordPE一个小工具一般般,真的动手做起来才知道技术含量高的很。
当前只是获取到PE结构并打印,仅此而已。
PE.h
  1. #pragma once
  2. #include <stdio.h>
  3. #include <stdarg.h>

  4. #include <Windows.h>
  5. #include <time.h>


  6. HANDLE m_hFile = NULL;                                        // 文件句柄
  7. HANDLE m_hMap = NULL;                                        // 文件映射句柄
  8. LPVOID m_lpBase = NULL;                                        // 映射基址
  9. DWORD m_dwLen = 0;                                                // 文件数据大小
  10. IMAGE_DOS_HEADER *m_pDosHeader = NULL;        // Dos头
  11. IMAGE_NT_HEADERS *m_pNtHeaders = NULL;        // NT头
  12. IMAGE_SECTION_HEADER *m_pSecHeader = NULL;

  13. /*
  14.         读取PE磁盘文件
  15.         fileUrl:文件路径
  16.         lpSaveData:保存数据的指针
  17.         成功返回数据大小,失败返回0.
  18. */
  19. DWORD ReadPeFile(char *fileUrl, LPVOID lpSaveData);

  20. VOID DestroryFunc(void);
复制代码
PE.cpp
  1. #include "PE.h"

  2. DWORD ReadPeFile(char *fileUrl, LPVOID lpSaveData)
  3. {
  4.         m_hFile = CreateFile(fileUrl, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  5.         if (m_hFile == INVALID_HANDLE_VALUE)
  6.         {
  7.                 printf("[ReadPeFile]:Can't open file!\n");
  8.                 return 0;
  9.         }
  10.         m_hMap = CreateFileMapping(m_hFile, NULL, PAGE_READWRITE | SEC_IMAGE, 0, 0, 0);
  11.         if (!m_hMap)
  12.         {
  13.                 printf("[ReadPeFile]:Can't create filemap!\n");
  14.                 return 0;
  15.         }
  16.         m_lpBase = MapViewOfFile(m_hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
  17.         if (!m_lpBase)
  18.         {
  19.                 printf("[ReadPeFile]:MapViewOfFile bad!\n");
  20.                 return 0;
  21.         }
  22.         m_dwLen = GetFileSize(m_hFile, &m_dwLen);
  23.         m_pDosHeader = (PIMAGE_DOS_HEADER)m_lpBase;
  24.         if (m_pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
  25.         {
  26.                 printf("[ReadPeFile]:Not is pe file!\n");
  27.                 return 0;
  28.         }
  29.         m_pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)m_lpBase + m_pDosHeader->e_lfanew);
  30.         if (m_pNtHeaders->Signature != IMAGE_NT_SIGNATURE)
  31.         {
  32.                 printf("[ReadPeFile]:Not is execut programmer!\n");
  33.                 return 0;
  34.         }
  35.         m_pSecHeader = (PIMAGE_SECTION_HEADER)((DWORD)&(m_pNtHeaders->OptionalHeader) + m_pNtHeaders->FileHeader.SizeOfOptionalHeader);
  36.         return m_dwLen;
  37. }

  38. VOID DestroryFunc(void)
  39. {
  40.         CloseHandle(m_hMap);
  41.         CloseHandle(m_hFile);
  42.         UnmapViewOfFile(m_lpBase);
  43. }

  44. LPCSTR _getMachineName(WORD wMachine)
  45. {
  46.         char *name = (char *)malloc(125);

  47.         switch (wMachine)
  48.         {
  49.         case 0:
  50.                 lstrcpy(name, "Unknown");
  51.                 break;
  52.         case 0x14c:
  53.                 lstrcpy(name, "Intel 386");
  54.                 break;
  55.         case 0x0162:
  56.                 lstrcpy(name, "MIPS little-endian, 0x160 big-endian");
  57.                 break;
  58.         case 0x0166:
  59.                 lstrcpy(name, "MIPS little-endian");
  60.                 break;
  61.         case 0x0168:
  62.                 lstrcpy(name, "MIPS little-endian");
  63.                 break;
  64.         case 0x0169:
  65.                 lstrcpy(name, "MIPS little-endian WCE v2");
  66.                 break;
  67.         case 0x0184:
  68.                 lstrcpy(name, "Alpha_AXP");
  69.                 break;
  70.         case 0x01a2:
  71.                 lstrcpy(name, "SH3 little-endian");
  72.                 break;
  73.         case 0x01a4:
  74.                 lstrcpy(name, "SH3E little-endian");
  75.                 break;
  76.         case 0x01a6:
  77.                 lstrcpy(name, "SH4 little-endian");
  78.                 break;
  79.         case 0x01a8:
  80.                 lstrcpy(name, "SH5");
  81.                 break;
  82.         case 0x01c0:
  83.                 lstrcpy(name, "ARM Little-Endian");
  84.                 break;
  85.         case 0x01c2:
  86.                 lstrcpy(name, "ARM Thumb/Thumb-2 Little-Endian");
  87.                 break;
  88.         case 0x01c4:
  89.                 lstrcpy(name, "ARM Thumb-2 Little-Endian");
  90.                 break;
  91.         case 0x01F0:
  92.                 lstrcpy(name, "IBM PowerPC Little-Endian");
  93.                 break;
  94.         case 0x0200:
  95.                 lstrcpy(name, "Intel 64");
  96.                 break;
  97.         case 0x0266:
  98.                 lstrcpy(name, "MIPS");
  99.                 break;
  100.         case 0x0284:
  101.                 lstrcpy(name, "ALPHA64");
  102.                 break;
  103.         case 0x0366:
  104.                 lstrcpy(name, "MIPS");
  105.                 break;
  106.         case 0x0466:
  107.                 lstrcpy(name, "MIPS");
  108.                 break;
  109.         case 0x0520:
  110.                 lstrcpy(name, "Infineon");
  111.                 break;
  112.         case 0x0EBC:
  113.                 lstrcpy(name, "EFI Byte Code");
  114.                 break;
  115.         case 0x8664:
  116.                 lstrcpy(name, "AMD64 (K8)");
  117.                 break;
  118.         case 0x9041:
  119.                 lstrcpy(name, "M32R little-endian");
  120.                 break;
  121.         default:
  122.                 free(name);
  123.                 return NULL;
  124.                 break;
  125.         }
  126.         return name;
  127. }

  128. VOID _printFormat(char *dataName, WORD *dataAddr, int nSize)
  129. {
  130.         printf("\t%s:", dataName);
  131.         for (int i = 0; i < (int)(13 - strlen(dataName)); i++)
  132.         {
  133.                 printf(" ");
  134.         }
  135.         printf("0x");
  136.         for (int i = 0; i < nSize; i++)
  137.         {
  138.                 printf("%04X", dataAddr[i]);
  139.         }
  140.         printf("\n");
  141. }

  142. VOID test_PrintPeInfo(void)
  143. {
  144.         char infoTmp[50] = { 0 };

  145.         printf("->DOS Header\n");
  146.         _printFormat("e_magic", &m_pDosHeader->e_magic, 1);
  147.         _printFormat("e_cblp", &m_pDosHeader->e_cblp, 1);
  148.         _printFormat("e_cp", &m_pDosHeader->e_cp, 1);
  149.         _printFormat("e_crlc", &m_pDosHeader->e_crlc, 1);
  150.         _printFormat("e_cparhdr", &m_pDosHeader->e_cparhdr, 1);
  151.         _printFormat("e_minalloc", &m_pDosHeader->e_minalloc, 1);
  152.         _printFormat("e_maxalloc", &m_pDosHeader->e_maxalloc, 1);
  153.         _printFormat("e_ss", &m_pDosHeader->e_ss, 1);
  154.         _printFormat("e_sp", &m_pDosHeader->e_sp, 1);
  155.         _printFormat("e_csum", &m_pDosHeader->e_csum, 1);
  156.         _printFormat("e_ip", &m_pDosHeader->e_ip, 1);
  157.         _printFormat("e_cs", &m_pDosHeader->e_cs, 1);
  158.         _printFormat("e_lfarlc", &m_pDosHeader->e_lfarlc, 1);
  159.         _printFormat("e_ovno", &m_pDosHeader->e_ovno, 1);
  160.         _printFormat("e_res", m_pDosHeader->e_res, 4);
  161.         _printFormat("e_oeminfo", &m_pDosHeader->e_oemid, 1);
  162.         _printFormat("e_oeminfo", &m_pDosHeader->e_oeminfo, 1);
  163.         _printFormat("e_res2", m_pDosHeader->e_res2, 10);
  164.         printf("\te_lfanew:     0x%08X\n\n", m_pDosHeader->e_lfanew);
  165.        
  166.         printf("->File Header\n");
  167.         printf("\tMachine:              0x%04X  (%s)\n", m_pNtHeaders->FileHeader.Machine,_getMachineName(m_pNtHeaders->FileHeader.Machine));
  168.         printf("\tNumberOfSections:     0x%04X\n", m_pNtHeaders->FileHeader.NumberOfSections);
  169.         struct tm Tm = { 0 };
  170.         gmtime_s(&Tm, (time_t *)&(m_pNtHeaders->FileHeader.TimeDateStamp));
  171.         printf("\tTimeDateStamp:        0x%04X  (%d/%d/%d %d:%d:%d)\n", m_pNtHeaders->FileHeader.TimeDateStamp, Tm.tm_year + 1900, Tm.tm_mon + 1, Tm.tm_mday, Tm.tm_hour, Tm.tm_min, Tm.tm_sec);
  172.         printf("\tPointerToSymbolTable: 0x%04X\n", m_pNtHeaders->FileHeader.PointerToSymbolTable);
  173.         printf("\tNumberOfSymbols:      0x%04X\n", m_pNtHeaders->FileHeader.NumberOfSymbols);
  174.         printf("\tSizeOfOptionalHeader: 0x%04X\n", m_pNtHeaders->FileHeader.SizeOfOptionalHeader);
  175.         printf("\tCharacteristics:      0x%04X\n\n", m_pNtHeaders->FileHeader.Characteristics);

  176.         printf("->Optional Header\n");
  177.         printf("\tMagic:                       0x%04X",m_pNtHeaders->OptionalHeader.Magic);
  178.         switch (m_pNtHeaders->OptionalHeader.Magic)
  179.         {
  180.         case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
  181.                 printf("  (HDR32_MAGIC)\n");
  182.                 break;
  183.         case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
  184.                 printf("  (HDR64_MAGIC)\n");
  185.                 break;
  186.         case IMAGE_ROM_OPTIONAL_HDR_MAGIC:
  187.                 printf("  (ROM_MAGIC)\n");
  188.                 break;
  189.         default:
  190.                 printf("  (Unknown)\n");
  191.                 break;
  192.         }
  193.         printf("\tMajorLinkerVersion:          0x%02X\n", m_pNtHeaders->OptionalHeader.MajorLinkerVersion);
  194.         printf("\tMinorLinkerVersion:          0x%02X  -> %d.%02d\n", m_pNtHeaders->OptionalHeader.MinorLinkerVersion,m_pNtHeaders->OptionalHeader.MajorLinkerVersion,m_pNtHeaders->OptionalHeader.MinorLinkerVersion);
  195.         printf("\tSizeOfCode:                  0x%08X\n", m_pNtHeaders->OptionalHeader.SizeOfCode);
  196.         printf("\tSizeOfInitializedData:       0x%08X\n", m_pNtHeaders->OptionalHeader.SizeOfInitializedData);
  197.         printf("\tSizeOfUninitializedData:     0x%08X\n", m_pNtHeaders->OptionalHeader.SizeOfUninitializedData);
  198.         printf("\tAddressOfEntryPoint:         0x%08X\n", m_pNtHeaders->OptionalHeader.AddressOfEntryPoint);
  199.         printf("\tBaseOfCode:                  0x%08X\n", m_pNtHeaders->OptionalHeader.BaseOfCode);
  200.         printf("\tBaseOfData:                  0x%08X\n", m_pNtHeaders->OptionalHeader.BaseOfData);
  201.         printf("\tImageBase:                   0x%08X\n", m_pNtHeaders->OptionalHeader.ImageBase);
  202.         printf("\tSectionAlignment:            0x%08X\n", m_pNtHeaders->OptionalHeader.SectionAlignment);
  203.         printf("\tFileAlignment:               0x%08X\n", m_pNtHeaders->OptionalHeader.FileAlignment);
  204.         printf("\tMajorOperatingSystemVersion: 0x%08X\n", m_pNtHeaders->OptionalHeader.MajorOperatingSystemVersion);
  205.         printf("\tMinorOperatingSystemVersion: 0x%08X  -> %d.%02d\n", m_pNtHeaders->OptionalHeader.MinorOperatingSystemVersion, m_pNtHeaders->OptionalHeader.MajorOperatingSystemVersion, m_pNtHeaders->OptionalHeader.MinorOperatingSystemVersion);
  206.         printf("\tMajorImageVersion:           0x%08X\n", m_pNtHeaders->OptionalHeader.MajorImageVersion);
  207.         printf("\tMinorImageVersion:           0x%08X  -> %d.%02d\n", m_pNtHeaders->OptionalHeader.MinorImageVersion, m_pNtHeaders->OptionalHeader.MajorImageVersion, m_pNtHeaders->OptionalHeader.MinorImageVersion);
  208.         printf("\tMajorSubsystemVersion:       0x%08X\n", m_pNtHeaders->OptionalHeader.MajorSubsystemVersion);
  209.         printf("\tMinorSubsystemVersion:       0x%08X  -> %d.%02d\n", m_pNtHeaders->OptionalHeader.MinorSubsystemVersion, m_pNtHeaders->OptionalHeader.MajorSubsystemVersion, m_pNtHeaders->OptionalHeader.MinorSubsystemVersion);
  210.         printf("\tWin32VersionValue:           0x%08X\n", m_pNtHeaders->OptionalHeader.Win32VersionValue);
  211.         printf("\tSizeOfImage:                 0x%08X\n", m_pNtHeaders->OptionalHeader.SizeOfImage);
  212.         printf("\tSizeOfHeaders:               0x%08X\n", m_pNtHeaders->OptionalHeader.SizeOfHeaders);
  213.         printf("\tCheckSum:                    0x%08X\n", m_pNtHeaders->OptionalHeader.CheckSum);
  214.         printf("\tSubsystem:                   0x%04X", m_pNtHeaders->OptionalHeader.Subsystem);
  215.         switch (m_pNtHeaders->OptionalHeader.Subsystem)
  216.         {
  217.         case IMAGE_SUBSYSTEM_UNKNOWN:
  218.                 printf("  (Unknown)\n");
  219.                         break;
  220.         case IMAGE_SUBSYSTEM_NATIVE:
  221.                 printf("  (Driver And SysPro)\n");
  222.                 break;
  223.         case IMAGE_SUBSYSTEM_WINDOWS_GUI:
  224.                 printf("  (Windows_GUI)\n");
  225.                 break;
  226.         case IMAGE_SUBSYSTEM_WINDOWS_CUI:
  227.                 printf("  (Windows_CUI)\n");
  228.                 break;
  229.         case IMAGE_SUBSYSTEM_OS2_CUI:
  230.                 printf("  (OS/2_CUI)\n");
  231.                 break;
  232.         case IMAGE_SUBSYSTEM_POSIX_CUI:
  233.                 printf("  (POSIX_CUI)\n");
  234.                 break;
  235.         case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
  236.                 printf("  (WinCE_GUI)\n");
  237.                 break;
  238.         case IMAGE_SUBSYSTEM_EFI_APPLICATION:
  239.                 printf("  (EFI)\n");
  240.                 break;
  241.         case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
  242.                 printf("  (EFI_Driver)\n");
  243.                 break;
  244.         case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
  245.                 printf("  (EFI_Dirver Run-Time)\n");
  246.                 break;
  247.         case IMAGE_SUBSYSTEM_EFI_ROM:
  248.                 printf("  (EFI_ROM)\n");
  249.                 break;
  250.         case IMAGE_SUBSYSTEM_XBOX:
  251.                 printf("  (XBox)\n");
  252.                 break;
  253.         case IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION:
  254.                 printf("  (Boot Application)\n");
  255.                 break;
  256.         default:
  257.                 printf("  (Unknown!)");
  258.                 break;
  259.         }
  260.         printf("\tDllCharacteristics:          0x%04X\n", m_pNtHeaders->OptionalHeader.DllCharacteristics);
  261.         printf("\tSizeOfStackReserve:          0x%08X\n", m_pNtHeaders->OptionalHeader.SizeOfStackReserve);
  262.         printf("\tSizeOfStackCommit:           0x%08X\n", m_pNtHeaders->OptionalHeader.SizeOfStackCommit);
  263.         printf("\tSizeOfHeapReserve:           0x%08X\n", m_pNtHeaders->OptionalHeader.SizeOfHeapReserve);
  264.         printf("\tLoaderFlags:                 0x%08X\n", m_pNtHeaders->OptionalHeader.LoaderFlags);
  265.         printf("\tNumberOfRvaAndSizes:         0x%08X\n\n", m_pNtHeaders->OptionalHeader.NumberOfRvaAndSizes);

  266.         printf("\tDataDirectory(16)            RVA        Size\n");
  267.         printf("\t-----------------            ---------- ----------\n");
  268.         for (DWORD dwI = 0; dwI < m_pNtHeaders->OptionalHeader.NumberOfRvaAndSizes; dwI++)
  269.         {
  270.                 switch (dwI)
  271.                 {
  272.                 case 0:
  273.                         printf("\t%-29s", "ExportTable");
  274.                         break;
  275.                 case 1:
  276.                         printf("\t%-29s", "ImportTable");
  277.                         break;
  278.                 case 2:
  279.                         printf("\t%-29s", "Resource");
  280.                         break;
  281.                 case 3:
  282.                         printf("\t%-29s", "Exception");
  283.                         break;
  284.                 case 4:
  285.                         printf("\t%-29s", "Security");
  286.                         break;
  287.                 case 5:
  288.                         printf("\t%-29s", "Relocation");
  289.                         break;
  290.                 case 6:
  291.                         printf("\t%-29s", "Debug");
  292.                         break;
  293.                 case 7:
  294.                         printf("\t%-29s", "Copyright");
  295.                         break;
  296.                 case 8:
  297.                         printf("\t%-29s", "GlobalPtr");
  298.                         break;
  299.                 case 9:
  300.                         printf("\t%-29s", "TLSTable");
  301.                         break;
  302.                 case 10:
  303.                         printf("\t%-29s", "LoadConfig");
  304.                         break;
  305.                 case 11:
  306.                         printf("\t%-29s", "BoundImport");
  307.                         break;
  308.                 case 12:
  309.                         printf("\t%-29s", "IAT");
  310.                         break;
  311.                 case 13:
  312.                         printf("\t%-29s", "DelayImport");
  313.                         break;
  314.                 case 14:
  315.                         printf("\t%-29s", "COM");
  316.                         break;
  317.                 case 15:
  318.                         printf("\t%-29s", "Reserved");
  319.                         break;
  320.                 default:
  321.                         printf("\t%-29s", "Unknown");
  322.                         break;
  323.                 }
  324.                 printf("0x%08X 0x%08X", m_pNtHeaders->OptionalHeader.DataDirectory[dwI].VirtualAddress, m_pNtHeaders->OptionalHeader.DataDirectory[dwI].Size);
  325.                 for (WORD wI = 0; wI < m_pNtHeaders->FileHeader.NumberOfSections; wI++)
  326.                 {
  327.                         // 如果该数据目录的起始地址>某节起始地址 && 该数据目录的结束地址<某节结束地址,那么就说明该数据目录存在此节中.
  328.                         if ((m_pSecHeader[wI].VirtualAddress <= m_pNtHeaders->OptionalHeader.DataDirectory[dwI].VirtualAddress) && ((m_pSecHeader[wI].VirtualAddress + m_pSecHeader[wI].Misc.VirtualSize) >= (m_pNtHeaders->OptionalHeader.DataDirectory[dwI].VirtualAddress + m_pNtHeaders->OptionalHeader.DataDirectory[dwI].Size)))
  329.                         {
  330.                                 printf("  ("%s")", m_pSecHeader[wI].Name);
  331.                                 break;
  332.                         }
  333.                 }
  334.                 printf("\n");
  335.         }
  336.         return;
  337. }

  338. int main(void)
  339. {

  340.         LPVOID lpData = NULL;
  341.         printf("Hello Pe!\n");
  342.         ReadPeFile("C:\\Users\\Hades\\Desktop\\测试程序.exe", lpData);
  343.         test_PrintPeInfo();
  344.         DestroryFunc();
  345.         system("pause");
  346.         return 0;
  347. }
复制代码

效果图:

以后有机会我要一步步的仿造出LordPE的所有功能。


回复

使用道具 举报

小船 发表于 2018-7-25 21:32:25 来自手机 | 显示全部楼层
感谢分享,沙发做的很舒服
回复

使用道具 举报

admin 发表于 2018-7-26 21:30:54 | 显示全部楼层
很厉害  增强对pe文件的理解
回复

使用道具 举报

 楼主| BiaoGe 发表于 2018-7-28 17:29:26 | 显示全部楼层
admin 发表于 2018-7-26 21:30
很厉害  增强对pe文件的理解

真的好TM难啊,结构体大到令人发指!
回复

使用道具 举报

admin 发表于 2018-7-31 15:43:44 | 显示全部楼层
BiaoGe 发表于 2018-7-28 09:29
真的好TM难啊,结构体大到令人发指!

是的  都要边做边查
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|不学网

GMT+8, 2018-8-18 10:41

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表