C++读取文件PE头

Home / C++ MrLee 2017-2-16 4870

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>
#include <stdio.h>
#include <iostream>
#ifndef _X_PE_H_
#define _X_PE_H_
//获取PE头基地址
#define SIZE_OF_NT_SIGNATURE sizeof(DWORD)
#define NTSIGNATURE(a) ((LPVOID)((BYTE *)a + ((PIMAGE_DOS_HEADER)a)->e_lfanew - 1))
#define PEFHDROFFSET(a) ((LPVOID)((BYTE *)a + ((PIMAGE_DOS_HEADER)a)->e_lfanew - 1 + SIZE_OF_NT_SIGNATURE))
#define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a + ((PIMAGE_DOS_HEADER)a)->e_lfanew - 1 + SIZE_OF_NT_SIGNATURE + sizeof(IMAGE_FILE_HEADER)))
DWORD WINAPI ImageFileType (LPVOID lpFile);
#endif
using namespace std;
//PE文件类型判断
DWORD WINAPI ImageFileType (LPVOID lpFile)
{
    /* 首先出现的是DOS文件标志 */
    if (*(USHORT *)lpFile == IMAGE_DOS_SIGNATURE)
    {
        /* 由DOS头部决定PE文件头部的位置 */
        if (LOWORD (*(DWORD *)NTSIGNATURE (lpFile)) ==
            IMAGE_OS2_SIGNATURE ||
            LOWORD (*(DWORD *)NTSIGNATURE (lpFile)) ==
            IMAGE_OS2_SIGNATURE_LE)
            return (DWORD)LOWORD(*(DWORD *)NTSIGNATURE (lpFile));
        else if (*(DWORD *)NTSIGNATURE (lpFile) ==
            IMAGE_NT_SIGNATURE)
            return IMAGE_NT_SIGNATURE;
        else
            return IMAGE_DOS_SIGNATURE;
    }
    else
        /* 不明文件种类 */
        return 0;
}
int main()
{
    //业务信息参考
    //http://www.vckbase.com/document/viewdoc/?id=1334
    CHAR szBuf[2048];
    FILE* pFile;
    fopen_s(&pFile,"F:\\SVN\\Debug\\LGT.exe","r");//这里加载一个PE文件
    int iRead=fread(szBuf,1,2048,pFile);
    //MZ-DOS头
    IMAGE_DOS_HEADER* dos;
    dos=(IMAGE_DOS_HEADER*)szBuf;
    cout.setf(ios::hex,ios::basefield);//设置十六进制显示数值
    cout.setf(ios::showbase|ios::uppercase);//设置0x头和大写
    cout<<"dos->e_magic="<<dos->e_magic<<endl;
    cout<<"dos->e_lfanew="<<dos->e_lfanew<<endl;
    cout<<"NTSIGNATURE="<<*(DWORD *)NTSIGNATURE(szBuf)<<endl;
    cout<<"ImageFileType="<<ImageFileType(szBuf)<<" is ";
    switch(ImageFileType(szBuf))
    {
    case IMAGE_DOS_SIGNATURE://MZ
        cout<<"IMAGE_DOS_SIGNATURE"<<endl;
        break;
    case IMAGE_OS2_SIGNATURE://NE
        cout<<"IMAGE_OS2_SIGNATURE"<<endl;
        break;
    case IMAGE_OS2_SIGNATURE_LE:
        cout<<"IMAGE_OS2_SIGNATURE_LE"<<endl;
        break;
    case IMAGE_NT_SIGNATURE:
        cout<<"IMAGE_NT_SIGNATURE"<<endl;
    }
    cout<<"PEFHDROFFSET="<<PEFHDROFFSET(szBuf)<<endl;
    //PE必选头
    PIMAGE_FILE_HEADER header =(PIMAGE_FILE_HEADER)PEFHDROFFSET(szBuf);
    cout<<"Machine="<<header->Machine<<endl;
    cout<<"区段数NumberOfSections="<<header->NumberOfSections<<endl;
    cout<<"建立时间TimeDateStamp="<<header->TimeDateStamp<<endl;
    cout<<"PointerToSymbolTable="<<header->PointerToSymbolTable<<endl;
    cout<<"可选头部大小SizeOfOptionalHeader="<<header->SizeOfOptionalHeader<<endl;
    cout<<"特征Characteristics="<<header->Characteristics<<endl;
    //PE可选头
    PIMAGE_OPTIONAL_HEADER opHeader=(PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET(szBuf);
    cout<<"魔术字Magic="<<opHeader->Magic<<endl;//0x010B为.EXE,0x0107为ROM映像
    cout<<"连接器主版本MajorLinkerVersion="<<(short)opHeader->MajorLinkerVersion<<endl;
    cout<<"连接器副版本MinorLinkerVersion="<<(short)opHeader->MinorLinkerVersion<<endl;
    cout<<"可执行代码大小SizeOfCode="<<opHeader->SizeOfCode<<endl;
    cout<<"已初始化的数据大小SizeOfInitializedData="<<opHeader->SizeOfInitializedData<<endl;
    cout<<"未初始化的数据大小SizeOfUninitializedData="<<opHeader->SizeOfUninitializedData<<endl;
    cout<<"入口点AddressOfEntryPoint="<<opHeader->AddressOfEntryPoint<<endl;
    cout<<"代码基址(.text段)BaseOfCode="<<opHeader->BaseOfCode<<endl;
    cout<<"数据基址(.bss段)BaseOfData="<<opHeader->BaseOfData<<endl;
    cout<<"映像基址ImageBase"<<opHeader->ImageBase<<endl;//进程映像地址空间中的首选基地址,Windows NT的Microsoft Win32 SDK链接器将这个值默认设为0x00400000,但是你可以使用-BASE:linker开关改变这个值。
    cout<<"区段对齐SectionAlignment="<<opHeader->SectionAlignment<<endl;
    cout<<"FileAlignment="<<opHeader->FileAlignment<<endl;
    cout<<"NT主版本号MajorOperatingSystemVersion="<<opHeader->MajorOperatingSystemVersion<<endl;
    cout<<"NT副版本号MinorOperatingSystemVersion="<<opHeader->MinorOperatingSystemVersion<<endl;
    cout<<"应用程序主版本号MajorImageVersion="<<opHeader->MajorImageVersion<<endl;
    cout<<"应用程序副版本号MinorImageVersion="<<opHeader->MinorImageVersion<<endl;
    cout<<"Win32子系统主版本号MajorSubsystemVersion="<<opHeader->MajorSubsystemVersion<<endl;
    cout<<"Win32子系统副版本号MinorSubsystemVersion="<<opHeader->MinorSubsystemVersion<<endl;
    cout<<"SizeOfImage="<<opHeader->SizeOfImage<<endl;
    cout<<"头大小SizeOfHeaders="<<opHeader->SizeOfHeaders<<endl;
    cout<<"校验和CheckSum="<<opHeader->CheckSum<<endl;//私有算法
    cout<<"子系统Subsystem="<<opHeader->Subsystem<<endl;
    cout<<"DllCharacteristics="<<opHeader->DllCharacteristics<<endl;
    cout<<"SizeOfStackReserve="<<opHeader->SizeOfStackReserve<<endl;
    cout<<"SizeOfStackCommit="<<opHeader->SizeOfStackCommit<<endl;
    cout<<"SizeOfHeapReserve="<<opHeader->SizeOfHeapReserve<<endl;
    cout<<"SizeOfHeapCommit="<<opHeader->SizeOfHeapCommit<<endl;
    cout<<"LoaderFlags="<<opHeader->LoaderFlags<<endl;
    cout<<"NumberOfRvaAndSizes="<<opHeader->NumberOfRvaAndSizes<<endl;
    cout<<"导出表RVA:"<<opHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress<<endl;
    cout<<"导出表大小:"<<opHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size<<endl;
    cout<<"导入表RVA:"<<opHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress<<endl;
    cout<<"导入表大小:"<<opHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size<<endl;
    cout<<"资源RVA:"<<opHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress<<endl;
    cout<<"资源大小:"<<opHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size<<endl;
    cout<<"TLSRVA:"<<opHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress<<endl;
    cout<<"TLS大小:"<<opHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size<<endl;
    cout<<"调试RVA:"<<opHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress<<endl;
    cout<<"调试:"<<opHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size<<endl;
    cout<<sizeof(IMAGE_OPTIONAL_HEADER)<<endl;
    PIMAGE_SECTION_HEADER ps=(PIMAGE_SECTION_HEADER)((BYTE*)opHeader+sizeof(IMAGE_OPTIONAL_HEADER));
    //打印所有的段信息
    for (int i=0;i<header->NumberOfSections;i++)
    {
        cout<<endl;
        cout<<"Name="<<ps[i].Name<<endl;
        cout<<"PhysicalAddress="<<ps[i].Misc.PhysicalAddress<<endl;
        cout<<"VirtualSize="<<ps[i].Misc.VirtualSize<<endl;
        cout<<"VirtualAddress="<<ps[i].VirtualAddress<<endl;
        cout<<"SizeOfRawData="<<ps[i].SizeOfRawData<<endl;
        cout<<"PointerToRawData="<<ps[i].PointerToRawData<<endl;
        cout<<"PointerToRelocations="<<ps[i].PointerToRelocations<<endl;
        cout<<"PointerToLinenumbers="<<ps[i].PointerToLinenumbers<<endl;
        cout<<"NumberOfRelocations="<<ps[i].NumberOfRelocations<<endl;
        cout<<"NumberOfLinenumbers="<<ps[i].NumberOfLinenumbers<<endl;
        cout<<"Characteristics="<<ps[i].Characteristics<<endl;
    }
    system("pause");
    return 0;
}

 

本文链接:https://it72.com:4443/11841.htm

推荐阅读
最新回复 (0)
返回