首先感谢 cyxvc 老哥,他的代码可读性超高,精简有用以理解,我找这方面的资料好久了,这篇文章对我帮助很大。
参考代码:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138#include "stdafx.h" #include <Windows.h> extern void DirectoryString(DWORD dwIndex); int _tmain(int argc, _TCHAR* argv[]) { //获取文件句柄 HANDLE hFile = CreateFile( _T("D:\PE.exe"), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); //获取文件大小 DWORD dwFileSize = GetFileSize(hFile, NULL); CHAR *pFileBuf = new CHAR[dwFileSize]; //将文件读取到内存 DWORD ReadSize = 0; ReadFile(hFile, pFileBuf, dwFileSize, &ReadSize, NULL); //判断是否为PE文件 PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuf; if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { //不是PE printf("不是PE文件n"); system("pause"); return 0; } PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuf + pDosHeader->e_lfanew); if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { //不是PE文件 printf("不是PE文件n"); system("pause"); return 0; } //获取基本PE头信息 //获取信息所用到的两个结构体指针 (这两个结构体都属于NT头) PIMAGE_FILE_HEADER pFileHeader = &(pNtHeader->FileHeader); PIMAGE_OPTIONAL_HEADER pOptionalHeader = &(pNtHeader->OptionalHeader); //输出PE头信息 printf("================== 基 本 P E 头 信 息 ==================nn"); printf("入 口 点:t%08Xt", pOptionalHeader->AddressOfEntryPoint); printf("子 系 统:t%04Xn", pOptionalHeader->Subsystem); printf("镜像基址:t%08Xt", pOptionalHeader->ImageBase); printf("区段数目:t%04Xn", pFileHeader->NumberOfSections); printf("镜像大小:t%08Xt", pOptionalHeader->SizeOfImage); printf("日期时间标志:t%08Xn", pFileHeader->TimeDateStamp); printf("代码基址:t%08Xt", pOptionalHeader->BaseOfCode); printf("部首大小:t%08Xn", pOptionalHeader->SizeOfHeaders); printf("数据基址:t%08Xt", pOptionalHeader->BaseOfData); printf("特 征 值:t%04Xn", pFileHeader->Characteristics); printf("块 对 齐:t%08Xt", pOptionalHeader->SectionAlignment); printf("校 验 和:t%08Xn", pOptionalHeader->CheckSum); printf("文件块对齐:t%08Xt", pOptionalHeader->FileAlignment); printf("可选头部大小:t%04Xn", pFileHeader->SizeOfOptionalHeader); printf("标 志 字:t%04Xtt", pOptionalHeader->Magic); printf("RVA数及大小:t%08Xnn", pOptionalHeader->NumberOfRvaAndSizes); printf("======================= 目 录 表 =======================n"); //获取目录表头指针 PIMAGE_DATA_DIRECTORY pDataDirectory = pOptionalHeader->DataDirectory; printf("tt RAVtt 大小n"); for (DWORD i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) { DirectoryString(i); printf("%08Xt%08Xn", pDataDirectory[i].VirtualAddress, pDataDirectory[i].Size); } printf("======================= 区 段 表 =======================n"); //获取区段表头指针 PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeader); printf("名称 VOffset VSize ROffset RSize 标志n"); //获取区段个数 DWORD dwSectionNum = pFileHeader->NumberOfSections; //根据区段个数遍历区段信息 for (DWORD i = 0; i < dwSectionNum; i++, pSectionHeader++) { for (DWORD j = 0; j < IMAGE_SIZEOF_SHORT_NAME; j++) { printf("%c", pSectionHeader->Name[j]); } printf(" %08X %08X %08X %08X %08Xn", pSectionHeader->VirtualAddress, pSectionHeader->Misc.VirtualSize, pSectionHeader->PointerToRawData, pSectionHeader->SizeOfRawData, pSectionHeader->Characteristics); } printf("n"); system("pause"); return 0; } void DirectoryString(DWORD dwIndex) { switch (dwIndex) { case 0:printf("输出表:tt"); break; case 1:printf("输入表:tt"); break; case 2:printf("资源:tt"); break; case 3:printf("异常:tt"); break; case 4:printf("安全:tt"); break; case 5:printf("重定位:tt"); break; case 6:printf("调试:tt"); break; case 7:printf("版权:tt"); break; case 8:printf("全局指针:t"); break; case 9:printf("TLS表:tt"); break; case 10:printf("载入配置:t"); break; case 11:printf("输入范围:t"); break; case 12:printf("IAT:tt"); break; case 13:printf("延迟输入:t"); break; case 14:printf("COM:tt"); break; case 15:printf("保留:tt"); break; } }
效果图:
另外附上我的代码。???? 获取某指定区段的信息:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33HANDLE hFile = CreateFile(_T("C:\Windows\SysNative\ntoskrnl.exe"), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { cout << "CreateFile failed:" << GetLastError() << endl; return false; } DWORD dwFileSize = GetFileSize(hFile, NULL); CHAR* pFileBuf = new CHAR[dwFileSize]; DWORD ReadSize = 0; if (!ReadFile(hFile, pFileBuf, dwFileSize, &ReadSize, NULL)) { cout << "ReadFile failed:" << GetLastError() << endl; return false; } PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuf; PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(pFileBuf + pDosHeader->e_lfanew); PIMAGE_FILE_HEADER pFileHeader = &(pNtHeader->FileHeader); PIMAGE_OPTIONAL_HEADER pOptionalHeader = &(pNtHeader->OptionalHeader); PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeader); DWORD dwSectionNum = pFileHeader->NumberOfSections; int page_vaddr = 0, page_roff = 0; for (DWORD i = 0; i < dwSectionNum; i++, pSectionHeader++) { string s_name; for (DWORD j = 0; j < IMAGE_SIZEOF_SHORT_NAME; j++) { if (pSectionHeader->Name[j]) { s_name += pSectionHeader->Name[j]; } } if (s_name == "PAGE") { page_vaddr = pSectionHeader->VirtualAddress; page_roff = pSectionHeader->PointerToRawData; break; } } if (page_vaddr == 0 || page_roff == 0) { cout << "没有找到 PAGE 区段" << endl; return false; }
最后
以上就是舒心汉堡最近收集整理的关于C++ 获取 PE 文件的各种信息的全部内容,更多相关C++内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复