FILE
*
open_file(char
*
file_path,char
*
open_mode);
int
compute_file_size(
FILE
*
file_address);
char
*
allocate_buffer(
int
file_size);
char
*
readfile2memory(char
*
file_buffer,
int
file_size,
FILE
*
file_address);
void analysis_PE_head(char
*
File_buffer);
VOID PrintNTHeaders()
{
/
/
初始化
/
/
char file_path[]
=
"C:\\Windows\\System32\\notepad.exe"
;
char file_path[]
=
F_PATH;
char open_mode[]
=
"rb"
;
/
/
打开文件,返回文件指针
FILE
*
file_address
=
open_file(file_path,open_mode);
/
/
计算文件长度
int
file_size
=
compute_file_size(file_address);
/
/
分配内存
char
*
File_buffer
=
allocate_buffer(file_size);
/
/
写入内存,返回内存地址
File_buffer
=
readfile2memory(File_buffer,file_size,file_address);
/
/
打印PE头部信息
analysis_PE_head(File_buffer);
/
/
释放内存、关闭文件流
free(File_buffer);
fclose(file_address);
}
FILE
*
open_file(char
*
file_path,char
*
open_mode)
{
FILE
*
file_address
=
fopen(file_path,open_mode);
/
/
fopen() 参数是字符串也就是常量指针类型
if
(!file_address)
{
printf(
"打开文件失败!\r\n"
);
return
0
;
}
return
file_address;
}
int
compute_file_size(
FILE
*
file_address)
{
int
size
=
0
;
fseek(file_address,
0
,SEEK_END);
size
=
ftell(file_address);
fseek(file_address,
0
,SEEK_SET);
return
size;
}
char
*
allocate_buffer(
int
file_size)
{
char
*
file_buffer
=
(char
*
)malloc(file_size);
if
(!file_buffer)
{
printf(
"申请内存失败!\r\n"
);
return
0
;
}
memset(file_buffer,
0
,file_size);
return
file_buffer;
}
char
*
readfile2memory(char
*
file_buffer,
int
file_size,
FILE
*
file_address)
{
if
(!(fread(file_buffer,file_size,
1
,file_address)))
{
printf(
"从文件向内存中读取数据失败!\r\n"
);
return
0
;
}
return
file_buffer;
/
/
如果写入内存成功,则返回内地址
}
void analysis_PE_head(char
*
File_buffer)
{
/
/
实例化PE文件头几个结构体
PIMAGE_DOS_HEADER pDosHeader
=
NULL;
PIMAGE_NT_HEADERS pNTHeader
=
NULL;
PIMAGE_FILE_HEADER pPEHeader
=
NULL;
PIMAGE_OPTIONAL_HEADER32 pOptionHeader
=
NULL;
PIMAGE_SECTION_HEADER pSectionHeader
=
NULL;
/
/
强制类型转换
pDosHeader
=
(PIMAGE_DOS_HEADER)File_buffer;
/
/
判断是不是有效的MZ标志
if
(
*
((PWORD)pDosHeader) !
=
IMAGE_DOS_SIGNATURE)
{
printf(
"不是有效的MZ标志!\r\n"
);
free(File_buffer);
return
;
}
/
/
强制类型转换 PIMAGE_DOS_HEADER结构体
pDosHeader
=
(PIMAGE_DOS_HEADER)File_buffer;
/
/
打印DOS头
printf(
"=============================DOS头信息如下=============================\r\n"
);
printf(
"MZ标志:\t\t\t%04X\r\n"
,pDosHeader
-
>e_magic);
printf(
"PE偏移:\t\t\t%08X\r\n"
,pDosHeader
-
>e_lfanew);
/
/
判断是不是有效的PE标志
if
(
*
((PDWORD)((DWORD)File_buffer
+
pDosHeader
-
>e_lfanew)) !
=
IMAGE_NT_SIGNATURE)
{
printf(
"不是有效的PE标志!\r\n"
);
free(File_buffer);
return
;
}
/
/
强制类型转换 PIMAGE_NT_HEADERS结构体
pNTHeader
=
PIMAGE_NT_HEADERS((DWORD)File_buffer
+
pDosHeader
-
>e_lfanew);
/
/
打印NT头
printf(
"=============================NT头信息如下===============================\r\n"
);
printf(
"NT:\t\t\t\t%04X\r\n"
,pNTHeader
-
>Signature);
/
/
强制类型转换 PIMAGE_FILE_HEADER结构体
pPEHeader
=
(PIMAGE_FILE_HEADER)((DWORD)pNTHeader
+
4
);
/
/
打印标准PE文件头
printf(
"=============================标准PE头信息如下============================\r\n"
);
printf(
"PE_machine:\t\t\t%04X\r\n"
,pPEHeader
-
>Machine);
printf(
"NumberOfSections:\t\t%04X\n"
,pPEHeader
-
>NumberOfSections);
printf(
"SizeOfOptionalHeader:\t\t%04X\r\n"
,pPEHeader
-
>SizeOfOptionalHeader);
/
/
强制类型转换
pOptionHeader
=
(PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader
+
IMAGE_SIZEOF_FILE_HEADER);
/
/
/
/
打印可选PE头
printf(
"==============================可选PE头信息如下==============================\r\n"
);
printf(
"Magic:\t\t\t\t%04X\r\n"
,pOptionHeader
-
>Magic);
printf(
"AddressOfEntryPoint:\t\t%08X\r\n"
,pOptionHeader
-
>AddressOfEntryPoint);
printf(
"ImageBase:\t\t\t%08X\r\n"
,pOptionHeader
-
>ImageBase);
printf(
"SizeOfImage:\t\t\t%08X\r\n"
,pOptionHeader
-
>SizeOfImage);
printf(
"SizeOfHeaders:\t\t\t%08X\r\n"
,pOptionHeader
-
>SizeOfHeaders);
printf(
"SectionAlignment:\t\t%08X\r\n"
,pOptionHeader
-
>SectionAlignment);
printf(
"FileAlignment:\t\t\t%08X\r\n"
,pOptionHeader
-
>FileAlignment);
/
/
强制类型转换
pSectionHeader
=
(PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader
+
pPEHeader
-
>SizeOfOptionalHeader);
printf(
"==============================节表信息如下===============================\n"
);
/
/
printf(
"name:%s\n"
,pSectionHeader
-
>Misc);
DWORD dwNumberOfSection
=
pPEHeader
-
>NumberOfSections;
/
*
printf(
"%x\n"
,pPEHeader
-
>NumberOfSections);
printf(
"IMAGE_SIZEOF_SHORT_NAME:%x\n"
,IMAGE_SIZEOF_SHORT_NAME);
printf(
"option_add:%x\n"
,pOptionHeader);
printf(
"psection_add:%x\n"
,pSectionHeader);
printf(
"==============================================================\n"
);
*
/
for
(DWORD i
=
0
;i<dwNumberOfSection;i
+
+
,pSectionHeader
+
+
)
{
printf(
"========================第%d个节信息:===============================\n"
,i
+
1
);
printf(
"section_name:"
);
for
(DWORD j
=
0
;j<IMAGE_SIZEOF_SHORT_NAME;j
+
+
)
{
printf(
"%c"
,pSectionHeader
-
>Name[j]);
}
printf(
"\r\n"
);
printf(
"Misc:\t\t\t\t%08X\r\n"
,pSectionHeader
-
>Misc);
printf(
"VirtualAddress:\t\t\t%08X\r\n"
,pSectionHeader
-
>VirtualAddress);
printf(
"SizeOfRawData:\t\t\t%08X\r\n"
,pSectionHeader
-
>SizeOfRawData);
printf(
"PointerToRawData:\t\t%08X\r\n"
,pSectionHeader
-
>PointerToRawData);
printf(
"Characteristics:\t\t%08X\r\n"
,pSectionHeader
-
>Characteristics);
}
}
int
main(
int
argc, char
*
argv[])
{
PrintNTHeaders();
/
/
getchar();
return
0
;
}