Skip to main content

Windows PE NumberofNames, AddressOfNames,AddressOfFunctions & AddressOfNameOrdinals (windbg)

·4 mins

A quick step by step tutorial to resolve function address through important fields in IMAGE EXPORT DIRECTORY. The following attributes of the structure are very important the NumberofNames, AddressOfNames, NumberOfFuntions, AddressOfFunctions, AddressOfNameOrdinals.

By finding the symbol position in AddressOfNames we can find the index number of FunctionsAddress in AddressOfNameOrdinals and this structure is a 2 bytes. With the 2 bytes index number we can then find the function address RVA in AddressOfFunction.

I will walk through with the windbg, but before we need to find the value of e_elfanew (0x3c) and offset to IMAGE OPTIONAL HEADERS (0x18) and Export Directory Table. You can check the previous post Windows PE File structure (windbg) and Export Directory Table

Unnfortunately the windbg does not come with symbols for IMAGE EXPORT DIRECTORY, but we can see the structure as showing below:

References: doxygen reactos & Dr. Fu’s Security Blog

IMAGE EXPORT DIRECTORY STRUCTURE #

typedef struct _IMAGE_EXPORT_DIRECTORY {
  DWORD Characteristics; //offset 0x0
  DWORD TimeDateStamp; //offset 0x4
  WORD MajorVersion;  //offset 0x8
  WORD MinorVersion; //offset 0xa
  DWORD Name; //offset 0xc
  DWORD Base; //offset 0x10
  DWORD NumberOfFunctions;  //offset 0x14
  DWORD NumberOfNames;  //offset 0x18
  DWORD AddressOfFunctions; //offset 0x1c
  DWORD AddressOfNames; //offset 0x20
  DWORD AddressOfNameOrdinals; //offset 0x24
 }

FYI, you can find Export Directory Table with command below: !dh kernelbase -f then get the VMA with ? kernelbase+1EAAA0.

FIND EXPORT DIRECTORY TABLE #

0:003> !dh kernelbase -f

File Type: DLL
FILE HEADER VALUES
     14C machine (i386)
       6 number of sections
...snipped...
            Guard
  1EAAA0 [    EF52] address [size] of Export Directory
  1FEB2C [      64] address [size] of Import Directory
  205000 [     548] address [size] of Resource Directory
       0 [       0] address [size] of Exception Directory
  231600 [    75E0] address [size] of Security Directory
...snipped...

We will use kernelbase module as an example, after finding the Export Directory VMA.
We can dump all the attributes values of Export Directory Table structure as showing below:

EXPORT DIRECTORY TABLE Structure #

0:003> dd  (KERNELBASE+1EAAA0)
7566aaa0  00000000 2c1f03ea 00000000 001ef578
7566aab0  00000001 00000778 00000778 001eaac8
7566aac0  001ec8a8 001ee688 001c4b60 00130260

NUMBEROFNAMES #

0:003> dd  (KERNELBASE+1EAAA0)+0x18 l1
7559aab8  00000778

ADDRESSOFNAMES (Array) RVA #

Here we can dump the AddressOfNames array at offset 0x20.

0:003> dd  (KERNELBASE+1EAAA0)+0x20 l1
7566aac0  001ec8a8

ADDRESSOFFUNCTIONS (Array) RVA #

Here we can dump the AddressOfFunctions array at offset 0x1c.

0:003> dd  (KERNELBASE+1EAAA0)+0x1c l1
7566aabc  001eaac8

ADDRESSOFNAMEORDINALS (Array) RVA #

0:003> dd  (KERNELBASE+1EAAA0)+0x24 l1
7566aac4  001ee688

Steps to find address of function #

Finding the symbol position in NamesOfFunction #

Lets say we are interested to find the function address for AccessCheckByType which is located as third position with RVA value in the NamesOfFunction array: 001ef64b which the symbol is translated to “AccessCheckByType”. Remember that the NamesOfFunction RVA is 001ec8a8 found earlier.

0:003> dd  (KERNELBASE+001ec8a8)
7566c8a8  001ef625 001ef631 001ef64b 001ef65d
7566c8b8  001ef67d 001ef699 001ef6cb 001ef6f5
7566c8c8  001ef72e 001ef761 001ef772 001ef781
7566c8d8  001ef795 001ef7ab 001ef7c5 001ef7d8
7566c8e8  001ef7ed 001ef806 001ef80d 001ef81f
7566c8f8  001ef833 001ef84b 001ef85c 001ef86d
7566c908  001ef890 001ef8a0 001ef8b3 001ef8c3
7566c918  001ef8da 001ef8e7 001ef8ff 001ef91a
0:003> da kernelbase+001ef64b
7566f64b  "AccessCheckByType"

Find the index number in AddressOfNameOrdinals #

To find that we know the RVA for AddressOfNameOrdinals is 001ee688 found earlier, with kernelbase base address we know the VMA and dump the values.

Something to notice is that this structure is 2 bytes and not 4 bytes, the first position value is 0007, the second value is 0006 and so on due to how CPU architecture presents data to memory (little endian) the highest order is presented in memory, network we know uses big endian.

As seen above the symbol “AccessCheckByType” is the third position in NamesOfFunction, we need to find the third position value in AddressofNameOrdinals. The index value is 0009, now we can go to next step to find that in AddressOfFunctions

0:003> dd kernelbase+001ee688
7566e688  00070006 00090008 000b000a 000d000c
7566e698  000f000e 00110010 00130012 00150014
7566e6a8  00170016 00190018 001b001a 001d001c
7566e6b8  001f001e 00210020 00230022 00250024
7566e6c8  00270026 00290028 002b002a 002d002c
7566e6d8  002f002e 00310030 00330032 00350034
7566e6e8  00370036 00390038 003b003a 003d003c
7566e6f8  003f003e 00410040 00430042 00450044

Looking for desired function RVA in AddressOfFunctions #

The RVA for AddressofFunctions discovered earlier is 001eaac8, we can dump the RVA of the functions. The index position we are interested is 0x9 (discovered earlier). Here is the RVA (0x00148b50) of function address for AccessCheckByType symbol.

0:003> dd kernelbase+001eaac8
7566aac8  001c4b60 00130260 00100ff0 001ef5dd
7566aad8  001601b0 0014c6f0 0010f650 0014f380
7566aae8  00148b50 001d8cf0 001d8da0 001d8e10
7566aaf8  001d8ed0 001ef70d 001ef743 0015ffb0
7566ab08  0014eba0 0014ff70 001566b0 001d8f90
7566ab18  00161920 001d8fe0 001d9030 00150c10
7566ab28  001d9080 001d90c0 001d9110 001d55a0
7566ab38  001d56d0 00174eb0 001678a0 001c60c0

Resolving RVA of AccessCheckByType #

We can see that we successfully resolved the function address for AccessCheckByType symbol in kernelbase module. Just combining the RVA of AccessCheckByType with Base Address of KernelBase. The u command resolves the address displaying the symbol along with the assembly instructions.

0:003> u kernelbase+0x00148b50
KERNELBASE!AccessCheckByType:
755c8b50 8bff            mov     edi,edi
755c8b52 55              push    ebp
755c8b53 8bec            mov     ebp,esp
755c8b55 51              push    ecx
755c8b56 8d45fc          lea     eax,[ebp-4]
755c8b59 50              push    eax
755c8b5a ff752c          push    dword ptr [ebp+2Ch]
755c8b5d ff7528          push    dword ptr [ebp+28h]