PE文件(一)

    xiaoxiao2026-09-22  1

    PE文件是指某一种格式的文件,exe,dll,sys等等 ,都是PE格式的文件。 PE文件大体可以分为两部分,头和主体,两个部分都会在内部进行细分,头由几个结构体组成,含这个文件一些描述信息,主体由多个段组成,包含文件的可执行代码和一些执行时要使用的资源,数据等等。 下面这张网上找的图作为参考 首先我们来看DOS头,DOS头是用来兼容DOS系统的,定义如下

    typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header WORD e_magic; // Magic number WORD e_cblp; // Bytes on last page of file WORD e_cp; // Pages in file WORD e_crlc; // Relocations WORD e_cparhdr; // Size of header in paragraphs WORD e_minalloc; // Minimum extra paragraphs needed WORD e_maxalloc; // Maximum extra paragraphs needed WORD e_ss; // Initial (relative) SS value WORD e_sp; // Initial SP value WORD e_csum; // Checksum WORD e_ip; // Initial IP value WORD e_cs; // Initial (relative) CS value WORD e_lfarlc; // File address of relocation table WORD e_ovno; // Overlay number WORD e_res[4]; // Reserved words WORD e_oemid; // OEM identifier (for e_oeminfo) WORD e_oeminfo; // OEM information; e_oemid specific WORD e_res2[10]; // Reserved words LONG e_lfanew; // File address of new exe header } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

    其中这个好几个成员 只需要记住第一个和最后一个就行,其他的大多已经没什么用了,其内容常年以0居多。

    第一个成员 e_magic ,是一个标记,DOS头标志位,其值恒为4D5A ,在系统中用宏定义为 :

    #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ

    这个成员的作用是可以作为判断一个文件是否为PE文件,下面我们来看代码

    #include "stdafx.h" #include <windows.h> bool IsPeFile(TCHAR Path[]) { HANDLE hFile =CreateFile( Path, GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); BOOL bSuccess = TRUE; DWORD dwFileSize = GetFileSize(hFile, 0); DWORD dwReadSize = 0; PBYTE buf = new BYTE[dwFileSize]; memset(buf, 0, dwFileSize); ReadFile(hFile, buf, dwFileSize, &dwReadSize, NULL); PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)buf; if (pDos->e_magic !=IMAGE_DOS_SIGNATURE) { bSuccess = FALSE; } PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + buf);//找到NT头 if (pNt->Signature != IMAGE_NT_SIGNATURE) { bSuccess = FALSE; } CloseHandle(hFile); delete buf; buf = nullptr; return bSuccess; } int _tmain(int argc, _TCHAR* argv[]) { bool bpe = IsPeFile(_T("E:\\FileCleaner2.0.exe"));//需要判断文件的路径 if (bpe) { printf("是"); } else { printf("不是"); } return 0; }

    有了以上的代码就可以判断一个文件是否为PE文件。 最后一个成员 e_lfanew 标识NT头部在文件中的偏移,有了它就可以找到后面NT头在文件中的位置,在上面的代码中其实已经用过了这个成员 在这里: PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + buf);

    上面的代码不但判定了DOS头的标记,还判断了NT头的一个成员Signature,这个成员也是判断PE文件的标记。 下篇文章会讲到。

    转载请注明原文地址: https://ju.6miu.com/read-1312230.html
    最新回复(0)