#ifndef PEINFO_H
#define PEINFO_H
#include
//调试信息类型
#define IMAGE_DEBUG_TYPE_UNKNOWN 0 //未知值,所有工具均忽略此值。
#define IMAGE_DEBUG_TYPE_COFF 1 //COFF调试信息(行号信息、符号表和字符串表)。文件头中也有相关域指向这种类型的调试信息。
#define IMAGE_DEBUG_TYPE_CODEVIEW 2 //Visual C++调试信息。
#define IMAGE_DEBUG_TYPE_FPO 3 //帧指针省略(FPO)信息。这种信息告诉调试器如何解释非标准栈帧,这种帧将EBP寄存器用于其它目的而不是作为帧指针。
#define IMAGE_DEBUG_TYPE_MISC 4 //DBG文件的位置。
#define IMAGE_DEBUG_TYPE_EXCEPTION 5 //.pdata节的副本。
#define IMAGE_DEBUG_TYPE_FIXUP 6 //保留。
#define IMAGE_DEBUG_TYPE_OMAP_TO_SRC 7 //从经过代码重排后的映像中的RVA到原映像中的RVA的映射。
#define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC 8 //从原映像中的RVA到经过代码重排后的映像中的RVA的映射。
#define IMAGE_DEBUG_TYPE_BORLAND 9 //保留,供Borland公司使用。
#define IMAGE_DEBUG_TYPE_RESERVED10 10 //保留。
#define IMAGE_DEBUG_TYPE_CLSID 11 //保留。
//延迟导入表结构
typedef struct _IMAGE_DELAY_IMPORT_DESCRIPTOR
{
DWORD Attributes;
DWORD Name;
DWORD ModuleHandle;
DWORD DelayIAT;
DWORD DelayINT;
DWORD BoundDelayIT;
DWORD UnloadDelayIT;
DWORD TimeStamp;
}IMAGE_DELAY_IMPORT_DESCRIPTOR;
void Analyse_File_Attr(WORD attribute);
#endif
/*cpp*/
#include "peInfo.h"
#include
#include
#include
#include
#include
#include
using namespace std;
IMAGE_DOS_HEADER dos_Header;
IMAGE_NT_HEADERS nt_Header;
IMAGE_IMPORT_DESCRIPTOR import;
int import_Num = 0;
string directory[16] =
{
"导出表地址:",
"导入表地址:",
"资源表地址:",
"异常表地址:",
"安全表地址:",
"重定位表表地址:",
"调试表地址:",
"版权表地址:",
"全局指针表地址:",
"线程本地存储表地址:",
"加载配置表地址:",
"绑定导入表地址:",
"IAT地址:",
"延迟导入表地址:",
"CLR表地址:",
"预留类型地址:",
};
string file_Attribute[16] =
{
"文件中不存在重定位信息",
"文件是可执行的",
"不存在行信息",
"不存在符号信息",
"调整工作集",
"应用程序可处理大于2G的地址",
"保留",
"小尾方式",
"只在32位平台上运行",
"不包含调试信息",
"不能从可移动盘运行",
"不能从网络运行",
"系统文件(驱动程序),不能直接运行",
"DLL文件",
"文件不能在多处理器上运行",
"大尾方式"
};
int pow_Exp[16] =
{
1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768
};
string Reverse_String(string str)
{
string Tem_Str;
copy(str.rbegin(), str.rend(),
back_insert_iterator
return Tem_Str;
}
string DecToHex(int num)
{
string str = "";
int divNum = 0;
while (num)
{
divNum = num %16;
switch(divNum)
{
case 0:
str += '0';
break;
case 1:
str += '1';
break;
case 2:
str += '2';
break;
case 3:
str += '3';
break;
case 4:
str += '4';
break;
case 5:
str += '5';
break;
case 6:
str += '6';
break;
case 7:
str += '7';
break;
case 8:
str += '8';
break;
case 9:
str += '9';
break;
case 10:
str += 'A';
break;
case 11:
str += 'B';
break;
case 12:
str += 'C';
break;
case 13:
str += 'D';
break;
case 14:
str += 'E';
break;
case 15:
str += 'F';
break;
}
num = num /16;
}
str += "x0";
return Reverse_String(str);
}
void WriteDosHeaderInfo(const IMAGE_DOS_HEADER *dos_header)
{
char magic[3];
if (dos_header == NULL)
{
return;
}
magic[0] = dos_header ->e_magic;
magic[1] = dos_header ->e_magic >>8;
magic[2] = '\0';
cout<<"exe标志:"<
for (int i = 0; i < 4; i++)
{
cout<
}
cout<
cout<<"oem标识符:"<
for (int i = 0; i < 10; i++)
{
cout<
}
cout<
void WriteNtHeaderInfo(const IMAGE_NT_HEADERS *nt_header)
{
char signature[5];
IMAGE_FILE_HEADER file_header;
IMAGE_OPTIONAL_HEADER option_header;
file_header = nt_header ->FileHeader;
option_header = nt_header ->OptionalHeader;
if (nt_header == NULL)
{
return;
}
signature[0] = nt_header ->Signature;
signature[1] = nt_header ->Signature >>8;
signature[2] = nt_header ->Signature >>16;
signature[3] = nt_header ->Signature >>24;
signature[4] = '\0';
cout<<""<
cout<<"运行平台:"<
文件创建日期和时间:"<
//IMAGE_FILE_MACHINE_ALPHA
cout<
cout<<"魔术字:"<
cout<
{
cout<
}
vo
id WriteSectionInfo(const IMAGE_SECTION_HEADER *section)
{
if (section == NULL)
{
return ;
}
for (int i = 0; i < nt_Header.FileHeader.NumberOfSections; i ++)
{
cout<<"节表名:"<
}
void Analyse_File_Attr(WORD attribute)
{
for (int i = 0; i < 16; i++)
{
if (attribute & pow_Exp[i])
{
cout<
}
}
DWORD RvaToFoa(const DWORD *rva, const IMAGE_SECTION_HEADER *sec)
{
DWORD sec_Rva[12], sec_Foa[12];
int index = 0;
DWORD offset = 0, foa_Addr = 0;
memset(sec_Rva, 0, sizeof(sec_Rva));
memset(sec_Foa, 0, sizeof(sec_Foa));
for(index = 0; index < nt_Header.FileHeader.NumberOfSections; index ++)
{
sec_Rva[index] = sec[index].VirtualAddress;
sec_Foa[index] = sec[index].PointerToRawData;
}
for(index = 0; index < nt_Header.FileHeader.NumberOfSections; index++)
{
if (*rva <= sec_Rva[index])
{
if (*rva == sec_Rva[index])
{
foa_Addr = sec_Foa[index];
}
else
{
offset = *rva - sec_Rva[index - 1];
foa_Addr = offset + sec_Foa[index - 1];
}
break;
}
}
return foa_Addr;
}
//读取导出表和导出函数
void Read_Export(FILE *file, const IMAGE_SECTION_HEADER *section)
{
DWORD export_VAddr = 0,
export_Addr = 0,
export_Size = 0,
current_Positon = 0;
DWORD func_Base = 0, //导出函数起始序列
func_Addr = 0, //导出函数地址表
func_Name_Addr = 0, //函数名称地址表;
func_Order_Addr = 0, //函数序列地址表(索引)
dll_NameV = 0;
int index = 0;
DWORD _func_Addr = 0;
IMAGE_EXPORT_DIRECTORY export_Dir;
if (file == NULL)
{
return;
}
//获取导出表虚拟地址和大小
export_VAddr = nt_Header.OptionalHeader.DataDirectory[0].VirtualAddress;
export_Size = nt_Header.OptionalHeader.DataDirectory[0].Size;
if (export_Size == 0 && export_VAddr == 0)
{
return;
}
//转换为文件偏移量
export_Addr = RvaToFoa(&export_VAddr, section);
//保存文件当前指针
current_Positon = ftell(file);
fseek(file, export_Addr, SEEK_SET);
fread(&export_Dir, sizeof(IMAGE_EXPORT_DIRECTORY), 1, file);
func_Base =
export_Dir.Base;
func_Name_Addr = RvaToFoa(&export_Dir.AddressOfNames, section);
func_Order_Addr = RvaToFoa(&export_Dir.AddressOfNameOrdinals, section);
func_Addr = RvaToFoa(&export_Dir.AddressOfFunctions, section);
dll_NameV = RvaToFoa(&export_https://www.doczj.com/doc/2c19324209.html,, section);
cout<<"所有导出函数个数:"<
//////////////////////////////////////////////////////////////////////////
//读取dll名称
DWORD file_Position = ftell(file);
string dll_Name = "";
BYTE dll_Byte = 0;
fseek(file, dll_NameV, SEEK_SET);
fread(&dll_Byte, 1, 1, file);
while(dll_Byte)
{
dll_Name += dll_Byte;
fread(&dll_Byte, 1, 1, file);
}
fseek(file, file_Position, SEEK_SET);
cout<
//////////////////////////////////////////////////////////////////////////
//读取导出函数名称
BYTE func_Byte = 0;
string func_name = "";
fseek(file, func_Name_Addr, SEEK_SET);
for (index = 0; index < export_Dir.NumberOfNames; index ++)
{
DWORD func_N_Addr = 0;
fread(&func_N_Addr, 4, 1, file);
file_Position = ftell(file);
fseek(file, RvaToFoa(&func_N_Addr, section), SEEK_SET);
func_name = "";
fread(&func_Byte, 1, 1, file);
while(func_Byte)
{
func_name += func_Byte;
fread(&func_Byte, 1, 1, file);
}
fseek(file, file_Position, SEEK_SET);
cout<
fseek(file, file_Position, SEEK_SET);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//读取函数序列
WORD order = 0;
fseek(file, func_Order_Addr, SEEK_SET);
for (index = 0; index < export_Dir.NumberOfNames; index ++)
{
fread(&order, 2, 1, file);
cout<
//////////////////////////////////////////////////////////////////////////
fseek(file, func_Addr, SEEK_SET);
for (index = 0; index < export_Dir.NumberOfFunctions; index ++)
{
DWORD func_Number = 0;
fread(&func_Number, 4, 1, file);
cout<
//////////////////////////////////////////////////////////////////////////
//返回文件初始位置
fseek(file, current_Positon, SEEK_SET);
}
//////////////////////////////////////////////////////////////////////////
//读取导入表
void Read_Import(FILE *file, const IMAGE_SECTION_HEADER *section)
{
DWORD Iat_VAddr = 0, Iat_Size = 0;
DWORD offset = 0, Iat_Addr = 0;
DWORD func_VAddr = 0, func_Addr = 0;
IMAGE_IMPORT_BY_NAME import_Name;
//读取导入表数据(根据IAT表)
Iat_VAddr = nt_Header.OptionalHeader.DataDirectory[12].VirtualAddress;
Iat_Size = nt_Header.OptionalHeader.DataDirectory[12].Size;
if (nt_Header.FileHeader.NumberOfSections <= 0)
{
return;
}
if (Iat_Size == 0 && Iat_VAd
dr == 0)
{
return;
}
Iat_Addr = RvaToFoa(&Iat_VAddr, section);
fseek(file, Iat_Addr, SEEK_SET);
fread(&func_VAddr, 4, 1, file);
Iat_Size -= 4;
while (func_VAddr)
{
BYTE ch;
string func_Name = "";
DWORD file_Position = ftell(file);
func_Addr = RvaToFoa(&func_VAddr, section);
fseek(file, func_Addr, SEEK_SET);
fread(&import_Name, sizeof(IMAGE_IMPORT_BY_NAME), 1, file);
cout<
func_Name += import_https://www.doczj.com/doc/2c19324209.html,[0];
while(ch)
{
func_Name += ch;
fread(&ch, 1, 1, file);
}
cout<
fread(&func_VAddr, 4, 1, file);
Iat_Size -= 4;
if (func_VAddr == 0 && Iat_Size != 0)
{
fread(&func_VAddr, 4, 1, file);
cout<
}
//////////////////////////////////////////////////////////////////////////
//读取导入函数(根据导入表)
IMAGE_IMPORT_DESCRIPTOR import_Desc;
DWORD import_VAddr = 0, import_Addr = 0;
DWORD import_Size = 0;
import_VAddr = nt_Header.OptionalHeader.DataDirectory[1].VirtualAddress;
import_Size = nt_Header.OptionalHeader.DataDirectory[1].Size;
import_Addr = RvaToFoa(&import_VAddr, section);
fseek(file, import_Addr, SEEK_SET);
fread(&import_Desc, sizeof(IMAGE_IMPORT_DESCRIPTOR), 1, file);
import_Size -= 20;
while (import_Size > 0)
{
import_Num ++;
cout<
string dll_Name = "";
DWORD file_Position = ftell(file);
DWORD import_Int_Addr = 0;
DWORD import_func_Addr = 0;
//读取dll库名字
DWORD dll_Name_Addr = RvaToFoa(&import_https://www.doczj.com/doc/2c19324209.html,, section);
fseek(file, dll_Name_Addr, SEEK_SET);
fread(&byte, 1, 1, file);
while(byte)
{
dll_Name += byte;
fread(&byte, 1, 1, file);
}
cout<
import_Int_Addr = RvaToFoa(&import_Desc.OriginalFirstThunk, section);
fseek(file, import_Int_Addr, SEEK_SET);
fread(&import_func_Addr, 4, 1, file);
while (import_func_Addr)
{
WORD func_Number = 0;
BYTE name_Byte = 0;
string func_Name = "";
DWORD func_Position = ftell(file);
fseek(file, RvaToFoa(&import_func_Addr, section), SEEK_SET);
//读取函数编号
fread(&func_Number, 2, 1, file);
//读取函数名
fread(&name_Byte, 1, 1, file);
while(name_Byte)
{
func_Name += name_Byte;
fread(&name_Byte, 1, 1, file);
}
cout<<"函数编号:"<
fseek(file, func_Position, SEEK_SET);
fread(&import_func_Addr, 4, 1, file);
}
fseek(file, file_Position, SEEK_SET);
fread(&import_Desc, sizeof(IMAGE_IMPORT_DESCRIPTOR), 1, file);
import_Size -= 20;
}
}
//////////////////////////////////////////////////////////////////////////
//读取重定位表
void Read_Relocation(FILE *file, const IMAGE_SECTION_HEADER *section)
{
DWORD reloc_Addr = 0, reloc_Size = 0;
IMAGE_BASE_RELOCAT
ION base_Reloc;
int index = 0;
if (file == NULL)
{
return;
}
//重定位数据在文件中偏移量
reloc_Addr = RvaToFoa(&nt_Header.OptionalHeader.DataDirectory[5].VirtualAddress, section);
reloc_Size = nt_Header.OptionalHeader.DataDirectory[5].Size;
if (reloc_Size == 0 && reloc_Addr == 0)
{
return;
}
//转到重定位数据
fseek(file, reloc_Addr, SEEK_SET);
//读取image_base_reloc结构
fread(&base_Reloc, sizeof(IMAGE_BASE_RELOCATION), 1, file);
while(base_Reloc.VirtualAddress)
{
for (index = 0; index < (base_Reloc.SizeOfBlock - 8)/2; index ++) //读取重定位信息
{
WORD reloc_VAddr = 0;
fread(&reloc_VAddr, 2, 1, file);
//cout<
//cout<
fread(&base_Reloc, sizeof(IMAGE_BASE_RELOCATION), 1, file);
}
}
//////////////////////////////////////////////////////////////////////////
//递归读取资源表
void Read_Res_Table(FILE *file, DWORD base_Addr, DWORD dir_Addr)
{
int res_Num = 0, index = 0;
IMAGE_RESOURCE_DIRECTORY res_Dir;
IMAGE_RESOURCE_DIRECTORY_ENTRY res_Dir_Entry;
fseek(file, dir_Addr, SEEK_SET);
fread(&res_Dir, sizeof(IMAGE_RESOURCE_DIRECTORY), 1, file);
//DWORD file_Position = ftell(file);
res_Num = res_Dir.NumberOfIdEntries + res_Dir.NumberOfNamedEntries;
for (int index = 0; index < res_Num; index ++)
{
fread(&res_Dir_Entry, sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY), 1, file);
//字段1
if (res_Dir_https://www.doczj.com/doc/2c19324209.html,IsString == 0) //ID值
{
cout<<"ID:"<
else
{
IMAGE_RESOURCE_DIR_STRING_U res_Dir_Str;
DWORD str_Size = 0;
WCHAR *u_Str;
DWORD file_Position = ftell(file);
fseek(file, base_Addr + res_Dir_https://www.doczj.com/doc/2c19324209.html,Offset, SEEK_SET);
cout<<"资源名地址:"<
u_Str = new WCHAR[str_Size + 1];
fread(u_Str, str_Size, 1, file);
u_Str[str_Size] = '\0';
for (int i = 0; i < str_Size; i++)
{
WORD sd = u_Str[i];
}
cout<<"资源名:"<
fseek(file, file_Position, SEEK_SET);
}
//字段2
if (res_Dir_Entry.DataIsDirectory == 1)//指向下一个目录
{
DWORD file_Position = ftell(file);
Read_Res_Table(file, base_Addr, base_Addr + res_Dir_Entry.OffsetToDirectory);
fseek(file, file_Position, SEEK_SET);
}
else //到达叶子
{
IMAGE_RESOURCE_DATA_ENTRY res_Data_Entry;
fseek(file, res_Dir_Entry.OffsetToData +base_Addr, SEEK_SET);
fread(&res_Data_Entry, sizeof(IMAGE_RESOURCE_DATA_ENTRY), 1, file);
cout<<"资源VAR"<
}
}
//fseek(file, file_Position, SEEK_SET);
}
void Read_Resource(FILE *file, const IMAGE_SECTION_HEADER *section)
{
DWORD res_Data_Addr = 0, res_Data_Size = 0;
if (file == NULL)
{
return;
}
//资源数据地址
res_Data_Addr = RvaToFoa(&nt_Header.OptionalHeader.DataDirectory[2].VirtualAddress, section);
res_Data_Size = nt_Header.OptionalHeader.DataDirectory[2].Size;
//fseek(file, res_Data_Addr, SEEK_SET);
cout<
}
void Read_Delay_Dll_Name(FILE *file, DWORD name_Addr)
{
fseek(file, name_Addr, SEEK_SET);
BYTE name_Byte = 0;
string name_Str = "";
for (int index = 0; index < import_Num; index ++)
{
name_Str = "";
fread(&name_Byte, 1, 1, file);
while(name_Byte)
{
name_Str += name_Byte;
fread(&name_Byte, 1, 1, file);
}
//dll名字以16字节对齐
fseek(file, 16 - ftell(file)%16, SEEK_CUR);
cout<
}
void Read_Delay_Import(FILE *file, IMAGE_SECTION_HEADER *section)
{
DWORD delay_Addr =0, delay_Size = 0;
DWORD name_Addr = 0, module_Addr = 0; //dll名称RVA,模块句柄RVA
DWORD delay_IAT_Addr = 0, delay_INT_Addr = 0; //IAT RVA, INT RVA
IMAGE_DELAY_IMPORT_DESCRIPTOR delay_Import;
if (file == NULL)
{
return;
}
// 读取延迟表数据地址
delay_Addr = RvaToFoa(&nt_Header.OptionalHeader.DataDirectory[13].VirtualAddress, section);
delay_Size = nt_Header.OptionalHeader.DataDirectory[13].Size;
//跳转到延迟数据表数据地址处
fseek(file, delay_Addr, SEEK_SET);
fread(&delay_Import, sizeof(IMAGE_DELAY_IMPORT_DESCRIPTOR), 1, file);
//地址赋值
name_Addr = RvaToFoa(&delay_https://www.doczj.com/doc/2c19324209.html,, section);
module_Addr = RvaToFoa(&delay_Import.ModuleHandle, section);
delay_IAT_Addr = RvaToFoa(&delay_Import.DelayIAT, section);
delay_INT_Addr = RvaToFoa(&delay_Import.DelayINT, section);
//////////////////////////////////////////////////////////////////////////
//读取dll名称
Read_Delay_Dll_Name(file, name_Addr);
//
}
void ReadDebug(FILE *file, IMAGE_SECTION_HEADER *section)
{
DWORD debug_Addr = 0, debug_Size = 0;
IMAGE_DEBUG_DIRECTORY debug_Dir;
if (file == NULL)
{
return ;
}
debug_Addr = RvaToFoa(&nt_Header.OptionalHeader.DataDirectory[6].VirtualAddress, section);
debug_Size = nt_Header.OptionalHeader.DataDirectory[6].Size;
fseek(file, debug_Addr, SEEK_SET);
fread(&debug_Dir, sizeof(IMAGE_DEBUG_DIRECTORY), 1, file);
}
void ReadConfig(FILE *file, IMAGE_SECTION_HEADER *section)
{
DWORD config_Addr = 0, config_Size = 0;
DWORD handle_Table = 0;
DWORD *tableArra = NULL;
IMAGE_LOAD_CONFIG_DIRECTORY config_Dir;
if (file == NULL)
{
return;
}
config_Addr = RvaToFoa(&nt_Header.OptionalHeader.DataDirectory[10].VirtualAddress, section);
config_Size = nt_Header.OptionalHeader.DataDirectory[10].Size;
if (config_Size == 0 && config_Addr == 0)
{
return;
}
fseek(file, config_Addr, SEEK_SET);
fread(&config_Dir, sizeof(IMAGE_LOAD_CONFIG_DIRECTORY), 1, file);
//读取SHEhandleTable
handle_Table =config_Dir.SEHandlerTable - nt_Header.OptionalHeader.ImageBase;
fseek(file, RvaToFoa(&handle_Table, section), SEEK_SET);
tableArra = new DWORD[config_Dir.SEHandlerCount];
for(int index = 0; index < config_Dir.SEHandlerCount; index ++)
{
fread(&tableArra[index], 4, 1, file);
cout<
delete []tableArra;
}
void ReadBoundImport(FILE *file, IMAGE_SECTION_HEADER *section)
{
}
int main()
{
DWORD Iat_VAddr = 0, Iat_Size = 0;
DWORD offset = 0, Iat_Addr = 0;
DWORD func_VAddr = 0, func_Addr = 0;
FILE *file;
IMAGE_SECTION_HEADER *section;
IMAGE_IMPORT_BY_NAME import_Name;
file = fopen("3D.exe", "rb");
if (file == NULL)
{
return 0;
}
//读取dos头
memset(&dos_Header, 0, sizeof(IMAGE_DOS_HEADER));
fread(&dos_Header, sizeof(IMAGE_DOS_HEADER), 1, file); //返回实际读取字节数
WriteDosHeaderInfo(&dos_Header);
fseek(file, dos_Header.e_lfanew, SEEK_SET);
//读取NT_HEADER
memset(&nt_Header, 0, sizeof(IMAGE_NT_HEADERS));
fread(&nt_Header, sizeof(IMAGE_NT_HEADERS), 1, file);
WriteNtHeaderInfo(&nt_Header);
//读取节表
section = new IMAGE_SECTION_HEADER[nt_Header.FileHeader.NumberOfSections];
fread(section, sizeof(IMAGE_SECTION_HEADER), nt_Header.FileHeader.NumberOfSections, file);
WriteSectionInfo(section);
//读取导入表
// Read_Import(file, section);
//读取导出表
//Read_Export(file, section);
//读取重定位表
//Read_Relocation(file, section);
//读取资源表
//Read_Resource(file, section);
//读取延迟表信息
Read_Delay_Import(file, section);
//读取调试信息
ReadDebug(file, section);
//读取配置信息
ReadConfig(file, section);
fclose(file);
delete []section;
system("pause");
}