Question

I have written a routine to dump the symbols and sections from a DLL loaded with LoadLibrary but not sure how to decode MinGW DLLs that have section names that are longer than IMAGE_SIZEOF_SHORT_NAME

For example, a MinGW DLL outputs the follwing sections if I print them as strings:

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

The other sections as objdump.exe gets them:

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

Which are all longer than IMAGE_SIZEOF_SHORT_NAME. MSDN explains that:

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.

So I have the following code:

  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? --
  }

Reading the COFF spec I see that the string table is after the symbol entries so it should be

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];

But I get something that is definitely not the string table. I can see the string table in my hex editor. Where is the string table in a portable executable?

Was it helpful?

Solution

When an executable file is mapped into memory it is not loaded as one contiguous lump. Sections are scattered about as described in the section headers.

Symbols are not necessarily mapped into memory at all.

PointerToSymbolTable is (I think) a file offset, not a memory offset (and, as described above, they are not the same thing).

EXEs and DLLs shouldn't have COFF symbols at all, though this file plainly does.

The answers to most such questions can be found in PEDUMP.

OTHER TIPS

I know that I'm late here but it seems that the question wasn't fully answered. I came here looking for the same answer myself before finding the solution.

Where is the string table in a portable executable?

The string table follows immediately after the symbol table. The number of symbols is in the file header information along with the symbol table start address, with each symbol being 18 bytes. A nice easy calculation to get to the string table.

The first 4 bytes are the size of the string table itself ( hence the /4 for the first entry ). Each string follows on from the previous one. Each string is null terminated. Not that this matters as the offsets are in the section name itself so you can look straight at the them.

String tables are not available in Executables (DLL) there are only available in OBJ files. This is why you cannot enumerate these when analysing a PE file. Sections names of PE files are NEVER longer than 8 characters.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top