PE格式分析_6(IMAGE_SECTION_HEADER)
本文最后更新于 280 天前,其中的信息可能已经有所发展或是发生改变。

节表( IMAGE_SECTION_HEADER )
作用:描述PE文件与内存之间的映射关系,说明PE文件的指定内容拷贝至内存的哪个位置、拷贝大小及内存属性的设置。
一个结构体总大小: 0x 28 (40) 字节
节表位置: 置于选项头之后,位置 = 选项头( IMAGE_OPTIONAL_HEADER) 的地址 + 选项头( IMAGE_OPTIONAL_HEADER)的大小。


// IMAGE_SECTION_HEADER 节表结构体,大小40B
typedef struct _IMAGE_SECTION_HEADER {

  BYTE  Name[IMAGE_SIZEOF_SHORT_NAME];  // 节表名称:描述性字段  2个字节, 这个段写了区段名字(.text .rdata ....),但是系统不承认这个名字,名字随便改
                                        // 重要的是内存属性 不是名字, 调试器查看内存有区段显示,是从这里获取的  

  // 下方4个字段:从文件S1处开始,拷贝S2大小的数据,到内存S3处,有效数据占用内存S4大小
  union {
    DWORD PhysicalAddress;
    DWORD VirtualSize;          // S4:在内存中的大小
  } Misc;
  DWORD VirtualAddress;         // S3:内存地址:基于模块基址,与SectionAlignment对齐(0x1000)
  DWORD SizeOfRawData;          // S2:文件大小(从文件中取SizeOfRawData字节到VirtualAddress地址),与FileAlignment对齐(0x200)
  DWORD PointerToRawData;       // S1:文件偏移,与FileAlignment对齐(0x200)

  //跟调试相关  
  DWORD PointerToRelocations;   // 无用
  DWORD PointerToLinenumbers;   // 无用
  WORD  NumberOfRelocations;    // 无用
  WORD  NumberOfLinenumbers;    // 无用

  DWORD Characteristics;        // 节内存属性(可读 可写 可执行),取值IMAGE_SCN_...系列宏  分低位和高位
//32位: inter芯片 无法让一个内存不可读  无法让一段代码不可执行 芯片手册有这个表
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

把节表放到内存里的过程:
开头:从开头0到选项头的字段SizeOfHeaders(0x400),映射到这段内存 400000h ~ 00401000, 把节表也放进去了,节表就在内存里了;
检测总大小:遍历内存,内存里拿到节表,先把所有节的文件大小加起来(算的对齐值),判断是否超过选项头的SizeOfImage ,如果够了,开始映射
检测连续性:malloc申请地址 010Editor上看到没有数据,显示都是0,为什么? OS申请内存会初始化为0 是定义了一个未初始化的数据区 410000h ~ 00411000,
每个节的内存必须是连续的,否则系统拒绝加载
表搬到内存: 从PE的SizeOfHeaders(0x400)到PE的节表SizeOfRawData(56000) 搬到
0~SizeOfHeaders 400000h ~ 00401000
XXXX 00401000h ~ 00411000
400~5200 00411000 ~00417000
节在文件中是连续的,在内存中不是连续的(因为对齐的原因)


验证一下映射的流程:
ImageBase = 00400000
0x0000 – 0x0200 => 00400000 = 00401000 文件头映射
0x0200 – 0x0400 => 00401000 = 00402000 遍历节表,从0x0200开始,第一个表SizeOfRawData是200h,内存地址保持连续
0x0400 – 0x0600 => 00402000 = 00403000
0x0600 – 0x0800 => 00403000 = 00404000

0x0200 – 0x0400 => 00401000 = 00402000
这个映射关系不对应,内存中前面多了一些东西,是全局变量,全局变量被修改了
常量区也能改,修改节表属性Characteristics


010Editor的脚本, myPE.BT

typedef UINT64 ULONGLONG;

typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
    WORD   e_magic <format=hex,fgcolor=cRed> ;                     // 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 <format=hex,fgcolor=cRed>;                    // File address of new exe header
  } IMAGE_DOS_HEADER;

//枚举 需要加上类型  写上具体的数字大小
enum <ushort> FILE_MACHINE {
IMAGE_FILE_MACHINE_UNKNOWN=0,
IMAGE_FILE_MACHINE_I386=0x014c,
IMAGE_FILE_MACHINE_AMD64=0x8664
};

enum <ushort> OPTIONAL_MACHINE {
IMAGE_NT_OPTIONAL_HDR32_MAGIC=0x10b,
IMAGE_NT_OPTIONAL_HDR64_MAGIC=0x20b,
IMAGE_ROM_OPTIONAL_HDR_MAGIC=0x107
};

typedef struct _IMAGE_FILE_HEADER {
    FILE_MACHINE    Machine <format=hex,fgcolor=cRed>;
    WORD    NumberOfSections <format=hex,fgcolor=cRed>;
    DWORD   TimeDateStamp;
    DWORD   PointerToSymbolTable;
    DWORD   NumberOfSymbols;
    WORD    SizeOfOptionalHeader <format=hex,fgcolor=cRed>;
    WORD    Characteristics <format=hex,fgcolor=cRed>;
} IMAGE_FILE_HEADER;

#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16

typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD   VirtualAddress;
    DWORD   Size;
} IMAGE_DATA_DIRECTORY;

typedef struct _IMAGE_OPTIONAL_HEADER {
    //
    // Standard fields.
    //

    OPTIONAL_MACHINE    Magic <format=hex,fgcolor=cRed>;
    BYTE    MajorLinkerVersion;
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;
    DWORD   SizeOfInitializedData;
    DWORD   SizeOfUninitializedData;
    DWORD   AddressOfEntryPoint  <format=hex,fgcolor=cRed>;
    DWORD   BaseOfCode;
    DWORD   BaseOfData;

    //
    // NT additional fields.
    //

    DWORD   ImageBase <format=hex,fgcolor=cRed>;
    DWORD   SectionAlignment;
    DWORD   FileAlignment;
    WORD    MajorOperatingSystemVersion;
    WORD    MinorOperatingSystemVersion;
    WORD    MajorImageVersion;
    WORD    MinorImageVersion;
    WORD    MajorSubsystemVersion;
    WORD    MinorSubsystemVersion;
    DWORD   Win32VersionValue;
    DWORD   SizeOfImage;
    DWORD   SizeOfHeaders;
    DWORD   CheckSum;
    WORD    Subsystem;
    WORD    DllCharacteristics;
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    DWORD   SizeOfHeapReserve;
    DWORD   SizeOfHeapCommit;
    DWORD   LoaderFlags;
    DWORD   NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32;

#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16

typedef struct _IMAGE_OPTIONAL_HEADER64 {
    OPTIONAL_MACHINE        Magic <format=hex,fgcolor=cRed>;
    BYTE        MajorLinkerVersion;
    BYTE        MinorLinkerVersion;
    DWORD       SizeOfCode;
    DWORD       SizeOfInitializedData;
    DWORD       SizeOfUninitializedData;
    DWORD       AddressOfEntryPoint <format=hex,fgcolor=cRed>;
    DWORD       BaseOfCode;
    ULONGLONG   ImageBase;
    DWORD       SectionAlignment;
    DWORD       FileAlignment;
    WORD        MajorOperatingSystemVersion;
    WORD        MinorOperatingSystemVersion;
    WORD        MajorImageVersion;
    WORD        MinorImageVersion;
    WORD        MajorSubsystemVersion;
    WORD        MinorSubsystemVersion;
    DWORD       Win32VersionValue;
    DWORD       SizeOfImage;
    DWORD       SizeOfHeaders;
    DWORD       CheckSum;
    WORD        Subsystem;
    WORD        DllCharacteristics;
    ULONGLONG   SizeOfStackReserve;
    ULONGLONG   SizeOfStackCommit;
    ULONGLONG   SizeOfHeapReserve;
    ULONGLONG   SizeOfHeapCommit;
    DWORD       LoaderFlags;
    DWORD       NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER64;

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;

    local WORD Magic = ReadShort(FTell()); // 往后读两个字节
    if (Magic == 0x10b) 
    {
        IMAGE_OPTIONAL_HEADER32 OptionalHeader;
    }
    else if (Magic == 0x20b) 
    {
        IMAGE_OPTIONAL_HEADER64 OptionalHeader;
    }
} IMAGE_NT_HEADERS;

#define IMAGE_SIZEOF_SHORT_NAME              8

//使用位段的方式来表示,更加清晰
typedef struct
{
    DWORD res:28;
    DWORD IMAGE_SCN_MEM_SHARED:1;
    DWORD IMAGE_SCN_MEM_EXECUTE:1;
    DWORD IMAGE_SCN_MEM_READ:1;
    DWORD IMAGE_SCN_MEM_WRITE:1;
}IMAGE_SCN_MEM;

typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
    DWORD   VirtualSize;
    DWORD   VirtualAddress <format=hex,fgcolor=cRed>;
    DWORD   SizeOfRawData;
    DWORD   PointerToRawData;
    DWORD   PointerToRelocations;
    DWORD   PointerToLinenumbers;
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;
    if(PointerToRawData!=0)
    {
        local int old = FTell();
        FSeek(PointerToRawData);
        char data[SizeOfRawData];
        FSeek(old);
    }
} IMAGE_SECTION_HEADER <read=ShowSectionName>;

string ShowSectionName(IMAGE_SECTION_HEADER& s)
{
    local string msg;
    local char buf[10] = {0};
    SPrintf(buf,"%8s",s.Name);
    msg = buf;
    msg += " ";

    if (s.Characteristics & 0x10000000) 
        msg += "S"; 
    if (s.Characteristics & 0x20000000)
        msg += "E";
    if (s.Characteristics & 0x40000000)
        msg += "R";
    if (s.Characteristics & 0x80000000)
        msg += "W";

    return msg;
}

IsLittleEndian();
IMAGE_DOS_HEADER DosHeader;
char DosStub[DosHeader.e_lfanew - sizeof(IMAGE_DOS_HEADER)];
IMAGE_NT_HEADERS NtHeader;
IMAGE_SECTION_HEADER SectionHeades[NtHeader.FileHeader.NumberOfSections]; // 从文件头拿到节的数量
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇