【问题标题】:Getting .text section header of PE file获取 PE 文件的 .text 节标题
【发布时间】:2015-03-25 17:02:02
【问题描述】:

我正在尝试获取 .text 部分的标题。 似乎起作用的是:

// Get the DOS header.
pDosHeader = (PIMAGE_DOS_HEADER) hMap;

// Get header of first section
pSectionHeader = (PIMAGE_SECTION_HEADER) ((DWORD) hMap + pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS));

// Get last section's header.
pLastSectionHeader = pSectionHeader + (pNtHeaders->FileHeader.NumberOfSections - 1);

但我不完全明白为什么。我原以为最后一条指令必须是:

// Get last section's header.
pLastSectionHeader = pSectionHeader + (pNtHeaders->FileHeader.NumberOfSections - 1) * sizeof(IMAGE_SECTION_HEADER);

以便指针移动section-header

另外,(pNtHeaders->FileHeader.NumberOfSections - 1) 真的是 .text 部分吗?

【问题讨论】:

  • 您查看的是 elf 文件还是其他目标文件格式?这是精灵格式信息的链接。请注意,它很长,并且包含几张图片,因此不能在 SO 上发布。 en.wikipedia.org/wiki/Executable_and_Linkable_Format>
  • 应该是exe格式。
  • 这里是 COFF 格式的链接:skyfree.org/linux/references/coff.pdf> 这里是 .exe 文件格式的链接:delorie.com/djgpp/doc/exe> 但是,请务必阅读此信息:
  • 这个指向 pdf 文件的链接更详细地说明了 windows 可执行文件与其他系统的不同之处。 : openwatcom.org/ftp/devel/docs/pecoff.pdf>
  • 我已经阅读了 Matt Pietrek 的文章,但这对我的实际实施没有多大帮助。

标签: c portable-executable


【解决方案1】:

原因

pLastSectionHeader = pSectionHeader + (pNtHeaders->FileHeader.NumberOfSections - 1);

是正确的,pSectionHeader 的类型是 PIMAGE_SECTION_HEADER。当您在 C 中将整数值添加到指针时,该值将首先乘以所指向对象的大小(即IMAGE_SECTION_HEADER)。这就是指针算法的工作原理!

您不应假设链接器放置不同部分的顺序。最好遍历所有节标题,例如将部分的名称与.text 匹配。

另外,我不建议使用sizeof(IMAGE_NT_HEADERS) 来跳过可选标题。这是因为IMAGE_OPTIONAL_HEADER 结构(包含在IMAGE_NT_HEADERS 中)以IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; 结尾,您实际上并不能保证PE 映像中存在所有数据目录。更好的方法是读取可选标题,并使用NumberOfRvaAndSizes 字段来确定您应该跳过多少个数据目录来查找节标题表。

最后,我建议您使用结构的IMAGE_XYZ32IMAGE_XYZ64 版本,而不仅仅是IMAGE_XYZ,具体取决于您是要解析PE32(32 位)还是PE32+(64 位) )。否则,您将默认使用系统默认的架构大小。

【讨论】:

  • 哇,我完全失明了...感谢您提供更多信息!
  • 我现在使用 winnt.h 中的 IMAGE_FIRST_SECTION(pNTHeader); 进入第一部分,这样安全吗?
  • @Benjoyo:是的,那也可以!它使用文件头的SizeOfOptionalHeader字段,该字段还包括所有数据目录。
【解决方案2】:

给你:

// Get DOS and PE Header
PIMAGE_DOS_HEADER hdos = (PIMAGE_DOS_HEADER)pe_file.data();
PIMAGE_NT_HEADERS hpe = (PIMAGE_NT_HEADERS)((DWORD)hdos + hdos->e_lfanew);

// Get header of first section
DWORD section_offset = (DWORD)hdos + hdos->e_lfanew + sizeof(IMAGE_NT_HEADERS);
PIMAGE_SECTION_HEADER text_section = (PIMAGE_SECTION_HEADER)(section_offset);

【讨论】:

    猜你喜欢
    • 2012-12-16
    • 1970-01-01
    • 2012-12-19
    • 1970-01-01
    • 1970-01-01
    • 2014-09-25
    • 1970-01-01
    • 2017-08-06
    • 2015-06-26
    相关资源
    最近更新 更多