有人说PE结构很重要,也有人说不重要。不同的人站在不同的角度有不同的看法。而我对PE结构仅仅是想有所了解,于是就有了下面一系列文章的出现。
PE文件中DOS Header的具体结构如下所示:(下面的定义在winnt.h文件中,这个文件需要安装编程环境,至少我将VC 6.0卸载后就找不到这个文件了。推荐使用一个编译环境直接go to definition来查看,毕竟这样方便快捷)
typedef struct _IMAGE_DOS_HEADER {
WORD e_magic;
WORD e_cblp;
WORD e_cp;
WORD e_crlc;
WORD e_cparhdr;
WORD e_minalloc;
WORD e_maxalloc;
WORD e_ss;
WORD e_sp;
WORD e_csum;
WORD e_ip;
WORD e_cs;
WORD e_lfarlc;
WORD e_ovno;
WORD e_res[4];
WORD e_oemid;
WORD e_oeminfo;
WORD e_res2[10];
LONG e_lfanew;
} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
其中WORD定义如下:
typedef unsigned short WORD;
也就是说一个WORD就是一个unsigned short啦,其占用两个字节,具体占用多少字节需要根据编译环境来决定。
我想了解这块的绝大多数人应该都是学过C语言的,所以我就用C语言写了个比较简单的程序,具体代码如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
void ReadDosHeader();
int main()
{
FILE *fp;
char fname[30] = "C:\\masm32\\cpicker.exe";
fp = fopen(fname,"rb");
if(fp == NULL)
{
printf("文件打开失败");
return 0;
}
ReadDosHeader(fp);
fclose(fp);
return 0;
}
void ReadDosHeader(FILE *fp)
{
IMAGE_DOS_HEADER dosheader;
int cnt = sizeof(IMAGE_DOS_HEADER);
fread(&dosheader,1,cnt,fp);
printf("%04X\r\n",dosheader.e_magic);
printf("%08X\r\n",dosheader.e_lfanew);
//将文件定位到PE Header位置
fseek(fp,dosheader.e_lfanew,SEEK_SET);
}
开发工具使用的是CodeBlock 13.12,使用的编译器为gcc,调试自然是gdb了。主要是安装VC体积太大。(以上代码可以直接保存为一个文件然后运行)
运行结果如下图所示:
具体读取文件的16进制如下图所示:(使用工具为010 Editor试用版,也可以使用UltraEdit等16进制工具,如果有兴趣的话也可以自己编写一个)
其中用红色框框中的分别为Dos Header中的WORD e_magic;和LONG e_lfanew;
其中e_magic为4D 5A,为啥读取出来是5A 4D这个就涉及到计算机存储文件的大端和小端的问题了
e_lfanew为00 00 00 80。