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

一: 再读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个目录,重要,其中第一个是导出表地址,大小,第二个是导入表地址大小,第三个是资源表地址大小,第13个是导入地址表地址大小.
} 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, 导入的dll 文件名称
    DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses), 指向导入函数地址表.
} IMAGE_IMPORT_DESCRIPTOR;

2.4 导入地址表,

    导入地址表中的每一项4个byte都是RVA 地址项, 需要由loader 改写, 指向导入函数名称

    该地址项在文件中指向一个import_by_name 结构,用来说明它是导入dll中的第几项, 导入函数名是什么.

   typedef struct _IMAGE_IMPORT_BY_NAME {
    WORD    Hint;
    BYTE    Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

     导入表和导入地址表共同占据着.rdata 段. 对用户而言,它们都是只读数据段.
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值