再读PE 文件结构启发式学习

来源:互联网 发布:女的网络歌手有哪些 编辑:程序博客网 时间:2024/06/05 08:22
一: 再读PE 文件结构启发式学习。
该系列帖子是我初入看雪论坛时写的。时隔几年,再读。概要如下:
a. pe 结构有 文件头,节表,节构成。
 节表个数由 _IMAGE_FILE_HEADER.NumberOfSections 确定


二:几个数据结构

2.1 NT 文件头
typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;        //这里的标记是 PE00
    IMAGE_FILE_HEADER FileHeader;    //NT header 包含FILE header 和Option header
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

2.1.1 文件头
typedef struct _IMAGE_FILE_HEADER {
    WORD    Machine;            0x014c -- x86
    WORD    NumberOfSections;
    DWORD   TimeDateStamp;
    DWORD   PointerToSymbolTable;
    DWORD   NumberOfSymbols;
    WORD    SizeOfOptionalHeader;
    WORD    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

2.1.2 可选文件头
// 很多不重要, 有的也与其它定义,例如节表内容有重复嫌疑
typedef struct _IMAGE_OPTIONAL_HEADER {
    //
    // Standard fields.
    //

    WORD    Magic;      // 010b --  NT HDR32
    BYTE    MajorLinkerVersion;    //link version 不重要
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;      //代码段大小
    DWORD   SizeOfInitializedData;  //初始化数据大小
    DWORD   SizeOfUninitializedData;  //未初始化数据大小
    DWORD   AddressOfEntryPoint;  //程序入口点:  重要
    DWORD   BaseOfCode;      //代码基址(RVA)
    DWORD   BaseOfData;      //数据基址(RVA)

    //
    // NT additional fields.
    //

    DWORD   ImageBase;      //模块基址
    DWORD   SectionAlignment;    //内存对齐调整
    DWORD   FileAlignment;    //文件对齐调整
    WORD    MajorOperatingSystemVersion;  //版本信息,不重要
    WORD    MinorOperatingSystemVersion;
    WORD    MajorImageVersion;
    WORD    MinorImageVersion;
    WORD    MajorSubsystemVersion;
    WORD    MinorSubsystemVersion;
    DWORD   Win32VersionValue;
    DWORD   SizeOfImage;    //模块的大小
    DWORD   SizeOfHeaders;    //header的大小
    DWORD   CheckSum;      //未使用
    WORD    Subsystem;      //02 为gui, 03 是console
    WORD    DllCharacteristics;    //dll 用
    DWORD   SizeOfStackReserve;    //系统加载堆和栈初始化信息
    DWORD   SizeOfStackCommit;
    DWORD   SizeOfHeapReserve;
    DWORD   SizeOfHeapCommit;
    DWORD   LoaderFlags;z    // 不重要
    DWORD   NumberOfRvaAndSizes;  // 总是16
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];  //16个目录,重要
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

2.2 节表:
section header:
2 行半, 40 个字节, 8个dword + 8bytes 名字
可以实现文件偏移到rva 的地址转换。节中也包含重定位信息

section header 的结构是这样定义的 ,
#define IMAGE_SIZEOF_SHORT_NAME  8

typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
    union {
            DWORD   PhysicalAddress;
            DWORD   VirtualSize;
    } Misc;
    DWORD   VirtualAddress;
    DWORD   SizeOfRawData;
    DWORD   PointerToRawData;
    DWORD   PointerToRelocations;        // 重定位指针, 在exe 中为空
    DWORD   PointerToLinenumbers;        // 行号指针
    WORD    NumberOfRelocations;        // 重定位个数
    WORD    NumberOfLinenumbers;        // 行号个数
    DWORD   Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

2.3 导入表
名称和地址是重要的, 他们都是rva
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
    union {
        DWORD   Characteristics;            // 0 for terminating null import descriptor
        DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
    };
    DWORD   TimeDateStamp;                  // 0 if not bound,
    DWORD   ForwarderChain;                
    DWORD   Name;                            // RVA to name
    DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;

2.4 导入地址表, 它们都是RVA 地址项, 需要由loader 改写

0 0