I am a man full of contradictions, I am using Unix and, yet, I want to analyze a Microsoft Windows DLL.

Usually, when looking for symbols in a dynamic or static library in the ELF World, one can either use nm or readelf or even objdump. Here is an example with objdump:

$ objdump -tT /usr/lib/libcdt.so

/usr/lib/libcdt.so:     file format elf64-x86-64

no symbols

0000000000000cc8 l    d  .init  0000000000000000              .init
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 free
0000000000000000  w   D  *UND*  0000000000000000              _ITM_deregisterTMCloneTable
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 memcmp
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 strcmp
0000000000000000  w   D  *UND*  0000000000000000              __gmon_start__
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 malloc
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.2.5 realloc
0000000000000000  w   D  *UND*  0000000000000000              _Jv_RegisterClasses
0000000000000000  w   D  *UND*  0000000000000000              _ITM_registerTMCloneTable
0000000000000000  w   DF *UND*  0000000000000000  GLIBC_2.2.5 __cxa_finalize
0000000000000ec0 g    DF .text  0000000000000097  Base        dtclose
0000000000204af8 g    DO .data  0000000000000008  Base        Dtorder
0000000000204af0 g    DO .data  0000000000000008  Base        Dttree
... cut ...

So, we have all exported function name from reading this dynamic library. But, lets try it with a DLL:

$ objdump -tT SE_U20i.dll 

SE_U20i.dll:     file format pei-i386

objdump: SE_U20i.dll: not a dynamic object
no symbols

no symbols

As you see, objdump fail to extract the exported symbols from the DLL (and so do nm). But, if I can see a few thing more if I do:

$ objdump -p SE_U20i.dll

SE_U20i.dll:     file format pei-i386

Characteristics 0xa18e
    line numbers stripped
    symbols stripped
    little endian
    32 bit words
    big endian

... clip ...

There is an export table in .edata at 0x658000

The Export Tables (interpreted .edata section contents)

Export Flags                    0
Time/Date stamp                 0
Major/Minor                     0/0
Name                            0025803c SE_U20i.dll
Ordinal Base                    1
Number in:
    Export Address Table            00000002
    [Name Pointer/Ordinal] Table    00000002
Table Addresses
    Export Address Table            00258028
    Name Pointer Table              00258030
    Ordinal Table                   00258038

Export Address Table -- Ordinal Base 1
    [   0] +base[   1] 23467c Export RVA
    [   1] +base[   2] 233254 Export RVA

[Ordinal/Name Pointer] Table
    [   0] DoResurrection
    [   1] Initialize

... clip ...

So, the export table seems to be what we are looking for (not sure about it). But it is drown among a lot of other information (the option -p display really a LOT of lines).

So, first, is the export table what I am looking for to know what are the functions and variables that exported by the DLL ?

Second, why did objdump present differently the exported symbols in the case of ELF and PE ? (I guess there is some technical differences between exported symbols in ELF and PE and that confusing both would be extremely misleading, but I would like to know in what they differ).


1 Answer 1


The surprising part for me is objdump can recognize anything in a PE file. According to Wikipedia,

.. PE is a modified version of the Unix COFF file format. PE/COFF is an alternative term in Windows development.

so apparently there is just enough overlap in the headers to make it work (at least partially). The basic design of one is clearly based on the other, but after that they evolved separately. Finding the exact differences at this point in time might well be a pure academical exercise.

Yes: in a DLL, the export directory is what you are looking for. Here is a screen grab from Dependency Walker inspecting comctl32.dll (using VirtualBox 'cause I'm on a Mac):

Dependency Walker showing Exports

The field "E^" lists the exported function names and other interesting details.

If you are in to Python: pefile has been mentioned as a library that can access PE parts, but then again PE has been so long around there is no end to good descriptions of all the gory low level details of all its headers and structures. Last time I felt inspecting some Windows program, I used these descriptions to write a full set of PE import/export C routines from scratch (.. again, I should add -- this way I can have return it the exact data I want in exactly the required format).

IDA Pro seems to be the utility of choice for most disassembling jobs, and last time I used that it did a good job of loading both Import and Export directories, although it didn't provide a concise list of all functions.

  • Actually, I do not have the "usual" binutils package. I rebuild it with all the targets. That may explain why objdump can recognize a few things in PE files. But, the support for PE is really minimalistic. Anyway, thanks a lot for your answer. It gave me a lot of starting points to work with !
    – perror
    Nov 29, 2013 at 16:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.