有人說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。