仿LordPE获取PE结构

乍一看LordPE一个小工具一般般,真的动手做起来才知道技术含量高的很。

当前只是获取到PE结构并打印,仅此而已。

PE.h

 1 #pragma once
 2 #include <stdio.h>
 3 #include <stdarg.h>
 4 
 5 #include <Windows.h>
 6 #include <time.h>
 7 
 8 
 9 HANDLE m_hFile = NULL;                    // 文件句柄
10 HANDLE m_hMap = NULL;                    // 文件映射句柄
11 LPVOID m_lpBase = NULL;                    // 映射基址
12 DWORD m_dwLen = 0;                        // 文件数据大小
13 IMAGE_DOS_HEADER *m_pDosHeader = NULL;    // Dos头
14 IMAGE_NT_HEADERS *m_pNtHeaders = NULL;    // NT头
15 IMAGE_SECTION_HEADER *m_pSecHeader = NULL;
16 
17 /*
18     读取PE磁盘文件
19     fileUrl:文件路径
20     lpSaveData:保存数据的指针
21     成功返回数据大小,失败返回0.
22 */
23 DWORD ReadPeFile(char *fileUrl, LPVOID lpSaveData);
24 
25 VOID DestroryFunc(void);

PE.cpp

  1 #include "PE.h"
  2 
  3 DWORD ReadPeFile(char *fileUrl, LPVOID lpSaveData)
  4 {
  5     m_hFile = CreateFile(fileUrl, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  6     if (m_hFile == INVALID_HANDLE_VALUE)
  7     {
  8         printf("[ReadPeFile]:Can't open file!\n");
  9         return 0;
 10     }
 11     m_hMap = CreateFileMapping(m_hFile, NULL, PAGE_READWRITE | SEC_IMAGE, 0, 0, 0);
 12     if (!m_hMap)
 13     {
 14         printf("[ReadPeFile]:Can't create filemap!\n");
 15         return 0;
 16     }
 17     m_lpBase = MapViewOfFile(m_hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
 18     if (!m_lpBase)
 19     {
 20         printf("[ReadPeFile]:MapViewOfFile bad!\n");
 21         return 0;
 22     }
 23     m_dwLen = GetFileSize(m_hFile, &m_dwLen);
 24     m_pDosHeader = (PIMAGE_DOS_HEADER)m_lpBase;
 25     if (m_pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
 26     {
 27         printf("[ReadPeFile]:Not is pe file!\n");
 28         return 0;
 29     }
 30     m_pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)m_lpBase + m_pDosHeader->e_lfanew);
 31     if (m_pNtHeaders->Signature != IMAGE_NT_SIGNATURE)
 32     {
 33         printf("[ReadPeFile]:Not is execut programmer!\n");
 34         return 0;
 35     }
 36     m_pSecHeader = (PIMAGE_SECTION_HEADER)((DWORD)&(m_pNtHeaders->OptionalHeader) + m_pNtHeaders->FileHeader.SizeOfOptionalHeader);
 37     return m_dwLen;
 38 }
 39 
 40 VOID DestroryFunc(void)
 41 {
 42     CloseHandle(m_hMap);
 43     CloseHandle(m_hFile);
 44     UnmapViewOfFile(m_lpBase);
 45 }
 46 
 47 LPCSTR _getMachineName(WORD wMachine)
 48 {
 49     char *name = (char *)malloc(125);
 50 
 51     switch (wMachine)
 52     {
 53     case 0:
 54         lstrcpy(name, "Unknown");
 55         break;
 56     case 0x14c:
 57         lstrcpy(name, "Intel 386");
 58         break;
 59     case 0x0162:
 60         lstrcpy(name, "MIPS little-endian, 0x160 big-endian");
 61         break;
 62     case 0x0166:
 63         lstrcpy(name, "MIPS little-endian");
 64         break;
 65     case 0x0168:
 66         lstrcpy(name, "MIPS little-endian");
 67         break;
 68     case 0x0169:
 69         lstrcpy(name, "MIPS little-endian WCE v2");
 70         break;
 71     case 0x0184:
 72         lstrcpy(name, "Alpha_AXP");
 73         break;
 74     case 0x01a2:
 75         lstrcpy(name, "SH3 little-endian");
 76         break;
 77     case 0x01a4:
 78         lstrcpy(name, "SH3E little-endian");
 79         break;
 80     case 0x01a6:
 81         lstrcpy(name, "SH4 little-endian");
 82         break;
 83     case 0x01a8:
 84         lstrcpy(name, "SH5");
 85         break;
 86     case 0x01c0:
 87         lstrcpy(name, "ARM Little-Endian");
 88         break;
 89     case 0x01c2:
 90         lstrcpy(name, "ARM Thumb/Thumb-2 Little-Endian");
 91         break;
 92     case 0x01c4:
 93         lstrcpy(name, "ARM Thumb-2 Little-Endian");
 94         break;
 95     case 0x01F0:
 96         lstrcpy(name, "IBM PowerPC Little-Endian");
 97         break;
 98     case 0x0200:
 99         lstrcpy(name, "Intel 64");
100         break;
101     case 0x0266:
102         lstrcpy(name, "MIPS");
103         break;
104     case 0x0284:
105         lstrcpy(name, "ALPHA64");
106         break;
107     case 0x0366:
108         lstrcpy(name, "MIPS");
109         break;
110     case 0x0466:
111         lstrcpy(name, "MIPS");
112         break;
113     case 0x0520:
114         lstrcpy(name, "Infineon");
115         break;
116     case 0x0EBC:
117         lstrcpy(name, "EFI Byte Code");
118         break;
119     case 0x8664:
120         lstrcpy(name, "AMD64 (K8)");
121         break;
122     case 0x9041:
123         lstrcpy(name, "M32R little-endian");
124         break;
125     default:
126         free(name);
127         return NULL;
128         break;
129     }
130     return name;
131 }
132 
133 VOID _printFormat(char *dataName, WORD *dataAddr, int nSize)
134 {
135     printf("\t%s:", dataName);
136     for (int i = 0; i < (int)(13 - strlen(dataName)); i++)
137     {
138         printf(" ");
139     }
140     printf("0x");
141     for (int i = 0; i < nSize; i++)
142     {
143         printf("%04X", dataAddr[i]);
144     }
145     printf("\n");
146 }
147 
148 VOID test_PrintPeInfo(void)
149 {
150     char infoTmp[50] = { 0 };
151 
152     printf("->DOS Header\n");
153     _printFormat("e_magic", &m_pDosHeader->e_magic, 1);
154     _printFormat("e_cblp", &m_pDosHeader->e_cblp, 1);
155     _printFormat("e_cp", &m_pDosHeader->e_cp, 1);
156     _printFormat("e_crlc", &m_pDosHeader->e_crlc, 1);
157     _printFormat("e_cparhdr", &m_pDosHeader->e_cparhdr, 1);
158     _printFormat("e_minalloc", &m_pDosHeader->e_minalloc, 1);
159     _printFormat("e_maxalloc", &m_pDosHeader->e_maxalloc, 1);
160     _printFormat("e_ss", &m_pDosHeader->e_ss, 1);
161     _printFormat("e_sp", &m_pDosHeader->e_sp, 1);
162     _printFormat("e_csum", &m_pDosHeader->e_csum, 1);
163     _printFormat("e_ip", &m_pDosHeader->e_ip, 1);
164     _printFormat("e_cs", &m_pDosHeader->e_cs, 1);
165     _printFormat("e_lfarlc", &m_pDosHeader->e_lfarlc, 1);
166     _printFormat("e_ovno", &m_pDosHeader->e_ovno, 1);
167     _printFormat("e_res", m_pDosHeader->e_res, 4);
168     _printFormat("e_oeminfo", &m_pDosHeader->e_oemid, 1);
169     _printFormat("e_oeminfo", &m_pDosHeader->e_oeminfo, 1);
170     _printFormat("e_res2", m_pDosHeader->e_res2, 10);
171     printf("\te_lfanew:     0x%08X\n\n", m_pDosHeader->e_lfanew);
172     
173     printf("->File Header\n");
174     printf("\tMachine:              0x%04X  (%s)\n", m_pNtHeaders->FileHeader.Machine,_getMachineName(m_pNtHeaders->FileHeader.Machine));
175     printf("\tNumberOfSections:     0x%04X\n", m_pNtHeaders->FileHeader.NumberOfSections);
176     struct tm Tm = { 0 };
177     gmtime_s(&Tm, (time_t *)&(m_pNtHeaders->FileHeader.TimeDateStamp));
178     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);
179     printf("\tPointerToSymbolTable: 0x%04X\n", m_pNtHeaders->FileHeader.PointerToSymbolTable);
180     printf("\tNumberOfSymbols:      0x%04X\n", m_pNtHeaders->FileHeader.NumberOfSymbols);
181     printf("\tSizeOfOptionalHeader: 0x%04X\n", m_pNtHeaders->FileHeader.SizeOfOptionalHeader);
182     printf("\tCharacteristics:      0x%04X\n\n", m_pNtHeaders->FileHeader.Characteristics);
183 
184     printf("->Optional Header\n");
185     printf("\tMagic:                       0x%04X",m_pNtHeaders->OptionalHeader.Magic);
186     switch (m_pNtHeaders->OptionalHeader.Magic)
187     {
188     case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
189         printf("  (HDR32_MAGIC)\n");
190         break;
191     case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
192         printf("  (HDR64_MAGIC)\n");
193         break;
194     case IMAGE_ROM_OPTIONAL_HDR_MAGIC:
195         printf("  (ROM_MAGIC)\n");
196         break;
197     default:
198         printf("  (Unknown)\n");
199         break;
200     }
201     printf("\tMajorLinkerVersion:          0x%02X\n", m_pNtHeaders->OptionalHeader.MajorLinkerVersion);
202     printf("\tMinorLinkerVersion:          0x%02X  -> %d.%02d\n", m_pNtHeaders->OptionalHeader.MinorLinkerVersion,m_pNtHeaders->OptionalHeader.MajorLinkerVersion,m_pNtHeaders->OptionalHeader.MinorLinkerVersion);
203     printf("\tSizeOfCode:                  0x%08X\n", m_pNtHeaders->OptionalHeader.SizeOfCode);
204     printf("\tSizeOfInitializedData:       0x%08X\n", m_pNtHeaders->OptionalHeader.SizeOfInitializedData);
205     printf("\tSizeOfUninitializedData:     0x%08X\n", m_pNtHeaders->OptionalHeader.SizeOfUninitializedData);
206     printf("\tAddressOfEntryPoint:         0x%08X\n", m_pNtHeaders->OptionalHeader.AddressOfEntryPoint);
207     printf("\tBaseOfCode:                  0x%08X\n", m_pNtHeaders->OptionalHeader.BaseOfCode);
208     printf("\tBaseOfData:                  0x%08X\n", m_pNtHeaders->OptionalHeader.BaseOfData);
209     printf("\tImageBase:                   0x%08X\n", m_pNtHeaders->OptionalHeader.ImageBase);
210     printf("\tSectionAlignment:            0x%08X\n", m_pNtHeaders->OptionalHeader.SectionAlignment);
211     printf("\tFileAlignment:               0x%08X\n", m_pNtHeaders->OptionalHeader.FileAlignment);
212     printf("\tMajorOperatingSystemVersion: 0x%08X\n", m_pNtHeaders->OptionalHeader.MajorOperatingSystemVersion);
213     printf("\tMinorOperatingSystemVersion: 0x%08X  -> %d.%02d\n", m_pNtHeaders->OptionalHeader.MinorOperatingSystemVersion, m_pNtHeaders->OptionalHeader.MajorOperatingSystemVersion, m_pNtHeaders->OptionalHeader.MinorOperatingSystemVersion);
214     printf("\tMajorImageVersion:           0x%08X\n", m_pNtHeaders->OptionalHeader.MajorImageVersion);
215     printf("\tMinorImageVersion:           0x%08X  -> %d.%02d\n", m_pNtHeaders->OptionalHeader.MinorImageVersion, m_pNtHeaders->OptionalHeader.MajorImageVersion, m_pNtHeaders->OptionalHeader.MinorImageVersion);
216     printf("\tMajorSubsystemVersion:       0x%08X\n", m_pNtHeaders->OptionalHeader.MajorSubsystemVersion);
217     printf("\tMinorSubsystemVersion:       0x%08X  -> %d.%02d\n", m_pNtHeaders->OptionalHeader.MinorSubsystemVersion, m_pNtHeaders->OptionalHeader.MajorSubsystemVersion, m_pNtHeaders->OptionalHeader.MinorSubsystemVersion);
218     printf("\tWin32VersionValue:           0x%08X\n", m_pNtHeaders->OptionalHeader.Win32VersionValue);
219     printf("\tSizeOfImage:                 0x%08X\n", m_pNtHeaders->OptionalHeader.SizeOfImage);
220     printf("\tSizeOfHeaders:               0x%08X\n", m_pNtHeaders->OptionalHeader.SizeOfHeaders);
221     printf("\tCheckSum:                    0x%08X\n", m_pNtHeaders->OptionalHeader.CheckSum);
222     printf("\tSubsystem:                   0x%04X", m_pNtHeaders->OptionalHeader.Subsystem);
223     switch (m_pNtHeaders->OptionalHeader.Subsystem)
224     {
225     case IMAGE_SUBSYSTEM_UNKNOWN:
226         printf("  (Unknown)\n");
227             break;
228     case IMAGE_SUBSYSTEM_NATIVE:
229         printf("  (Driver And SysPro)\n");
230         break;
231     case IMAGE_SUBSYSTEM_WINDOWS_GUI:
232         printf("  (Windows_GUI)\n");
233         break;
234     case IMAGE_SUBSYSTEM_WINDOWS_CUI:
235         printf("  (Windows_CUI)\n");
236         break;
237     case IMAGE_SUBSYSTEM_OS2_CUI:
238         printf("  (OS/2_CUI)\n");
239         break;
240     case IMAGE_SUBSYSTEM_POSIX_CUI:
241         printf("  (POSIX_CUI)\n");
242         break;
243     case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
244         printf("  (WinCE_GUI)\n");
245         break;
246     case IMAGE_SUBSYSTEM_EFI_APPLICATION:
247         printf("  (EFI)\n");
248         break;
249     case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
250         printf("  (EFI_Driver)\n");
251         break;
252     case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
253         printf("  (EFI_Dirver Run-Time)\n");
254         break;
255     case IMAGE_SUBSYSTEM_EFI_ROM:
256         printf("  (EFI_ROM)\n");
257         break;
258     case IMAGE_SUBSYSTEM_XBOX:
259         printf("  (XBox)\n");
260         break;
261     case IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION:
262         printf("  (Boot Application)\n");
263         break;
264     default:
265         printf("  (Unknown!)");
266         break;
267     }
268     printf("\tDllCharacteristics:          0x%04X\n", m_pNtHeaders->OptionalHeader.DllCharacteristics);
269     printf("\tSizeOfStackReserve:          0x%08X\n", m_pNtHeaders->OptionalHeader.SizeOfStackReserve);
270     printf("\tSizeOfStackCommit:           0x%08X\n", m_pNtHeaders->OptionalHeader.SizeOfStackCommit);
271     printf("\tSizeOfHeapReserve:           0x%08X\n", m_pNtHeaders->OptionalHeader.SizeOfHeapReserve);
272     printf("\tLoaderFlags:                 0x%08X\n", m_pNtHeaders->OptionalHeader.LoaderFlags);
273     printf("\tNumberOfRvaAndSizes:         0x%08X\n\n", m_pNtHeaders->OptionalHeader.NumberOfRvaAndSizes);
274 
275     printf("\tDataDirectory(16)            RVA        Size\n");
276     printf("\t-----------------            ---------- ----------\n");
277     for (DWORD dwI = 0; dwI < m_pNtHeaders->OptionalHeader.NumberOfRvaAndSizes; dwI++)
278     {
279         switch (dwI)
280         {
281         case 0:
282             printf("\t%-29s", "ExportTable");
283             break;
284         case 1:
285             printf("\t%-29s", "ImportTable");
286             break;
287         case 2:
288             printf("\t%-29s", "Resource");
289             break;
290         case 3:
291             printf("\t%-29s", "Exception");
292             break;
293         case 4:
294             printf("\t%-29s", "Security");
295             break;
296         case 5:
297             printf("\t%-29s", "Relocation");
298             break;
299         case 6:
300             printf("\t%-29s", "Debug");
301             break;
302         case 7:
303             printf("\t%-29s", "Copyright");
304             break;
305         case 8:
306             printf("\t%-29s", "GlobalPtr");
307             break;
308         case 9:
309             printf("\t%-29s", "TLSTable");
310             break;
311         case 10:
312             printf("\t%-29s", "LoadConfig");
313             break;
314         case 11:
315             printf("\t%-29s", "BoundImport");
316             break;
317         case 12:
318             printf("\t%-29s", "IAT");
319             break;
320         case 13:
321             printf("\t%-29s", "DelayImport");
322             break;
323         case 14:
324             printf("\t%-29s", "COM");
325             break;
326         case 15:
327             printf("\t%-29s", "Reserved");
328             break;
329         default:
330             printf("\t%-29s", "Unknown");
331             break;
332         }
333         printf("0x%08X 0x%08X", m_pNtHeaders->OptionalHeader.DataDirectory[dwI].VirtualAddress, m_pNtHeaders->OptionalHeader.DataDirectory[dwI].Size);
334         for (WORD wI = 0; wI < m_pNtHeaders->FileHeader.NumberOfSections; wI++)
335         {
336             // 如果该数据目录的起始地址>某节起始地址 && 该数据目录的结束地址<某节结束地址,那么就说明该数据目录存在此节中.
337             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)))
338             {
339                 printf("  (\"%s\")", m_pSecHeader[wI].Name);
340                 break;
341             }
342         }
343         printf("\n");
344     }
345     return;
346 }
347 
348 int main(void)
349 {
350 
351     LPVOID lpData = NULL;
352     printf("Hello Pe!\n");
353     ReadPeFile("C:\\Users\\Hades\\Desktop\\测试程序.exe", lpData);
354     test_PrintPeInfo();
355     DestroryFunc();
356     system("pause");
357     return 0;
358 }

 

效果图:

 

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

posted @ 2018-07-25 17:53  BiaoGe  阅读(623)  评论(0编辑  收藏  举报