3

我编写了一个例程来从加载的 DLL 中转储符号和部分,LoadLibrary但不知道如何解码部分名称长于IMAGE_SIZEOF_SHORT_NAME

例如,如果我将以下部分打印为字符串,则 MinGW DLL 会输出以下部分:

[".text", ".data", ".rdata", ".pdata", ".xdata", ".bss", ".edata", ".idata",
 ".CRT", ".tls", ".reloc", "/4", "/19", "/31", "/45", "/57", "/70", "/81",
 "/92"]

其他部分objdump.exe得到它们:

.debug_aranges
.debug_info
.debug_abbrev
.debug_line
.debug_frame
.debug_str
.debug_loc
.debug_ranges

都长于IMAGE_SIZEOF_SHORT_NAME. MSDN解释说:

For longer names, this member contains a forward slash (/) followed by an ASCII representation of a decimal number that is an offset into the string table.

所以我有以下代码:

  Char buffer[IMAGE_SIZEOF_SHORT_NAME + 1];
  std::strncpy(buffer, reinterpret_cast<const Char * const>(section_header_ptr[i].Name), IMAGE_SIZEOF_SHORT_NAME);
  buffer[IMAGE_SIZEOF_SHORT_NAME] = '\0';
  const Char * name = buffer;
  if (name[0] == '/') {
    const Long rva = std::strtol(name + 1, NULL, 10);
    if ((LONG_MAX == rva) || (LONG_MIN == rva) || ((0 == rva) && (name[0] != '0'))) {
      static const Char * const failure = "failed to convert offset";
      name = failure;
    }
    // -- How do I get the string table here? and use the offset? --
  }

阅读 COFF 规范,我看到字符串表在符号条目之后,所以它应该是

HMODULE handle = LoadLibrary("some_mingw_library.dll");
PIMAGE_DOS_HEADER idh = (PIMAGE_DOS_HEADER)(handle);
PIMAGE_NT_HEADERS inh = (PIMAGE_NT_HEADERS)(((const uint8_t*)(idh)) + idh->e_lfanew)
PIMAGE_FILE_HEADER ifh = &inh->FileHeader;
PIMAGE_SYMBOL is = (PIMAGE_SYMBOL)(((const uint8_t*)(idh)) + ifh->PointerToSymbolTable)
const char * const string_table = &is[ifh->NumberOfSymbols];

但我得到的东西绝对不是字符串表。我可以在我的十六进制编辑器中看到字符串表。可移植可执行文件中的字符串表在哪里?

4

3 回答 3

3

当一个可执行文件被映射到内存中时,它不会作为一个连续的块加载。部分分散,如部分标题中所述。

符号根本不需要映射到内存中。

PointerToSymbolTable是(我认为)文件偏移量,而不是内存偏移量(并且,如上所述,它们不是一回事)。

EXE 和 DLL 根本不应该有 COFF 符号,尽管这个文件显然有。

大多数此类问题的答案都可以在PEDUMP中找到。

于 2013-10-02T18:51:56.637 回答
1

我知道我在这里迟到了,但似乎这个问题没有得到完全回答。在找到解决方案之前,我自己来这里寻找相同的答案。

可移植可执行文件中的字符串表在哪里?

字符串表紧跟在符号表之后。符号数与符号表起始地址一起在文件头信息中,每个符号为 18 个字节。一个很好的简单计算来获取字符串表。

前 4 个字节是字符串表本身的大小(因此 /4 表示第一个条目)。每个字符串都从前一个字符串开始。每个字符串都以空值结尾。这并不重要,因为偏移量在部分名称本身中,因此您可以直接查看它们。

于 2018-10-14T07:48:42.450 回答
-1

字符串表在可执行文件 (DLL) 中不可用,仅在 OBJ 文件中可用。这就是为什么在分析 PE 文件时无法枚举这些的原因。PE 文件的部分名称永远不会超过 8 个字符。

于 2013-10-02T18:43:44.137 回答