Search code examples
fileexportsymbolsportable-executable

How to get name/export index of a symbol at a specific address (GetProcAddress inverse)


Suppose I have a DLL that exports some functions and I know an address within that DLL. If that address refers to an location within such a function, then, assuming the export table is sorted by function entry, the following would find the index of this function in the export table:

IMAGE_DOS_HEADER* dosHeader;
dosHeader = (IMAGE_DOS_HEADER*)m_handle;
unsigned int count;

if(dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
{return __MODULE_ADDRESS_NOT_FOUND;}

IMAGE_NT_HEADERS* ntHeaders = (IMAGE_NT_HEADERS*)(((BYTE*)dosHeader) + dosHeader->e_lfanew);

if(ntHeaders->Signature != 0x00004550)
    {return __MODULE_ADDRESS_NOT_FOUND;}

IMAGE_OPTIONAL_HEADER* optionalHeader = &ntHeaders->OptionalHeader;
if(optionalHeader->NumberOfRvaAndSizes<IMAGE_DIRECTORY_ENTRY_EXPORT)
    {return __MODULE_ADDRESS_NOT_FOUND;}

if(optionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size==0)
    {return __MODULE_ADDRESS_NOT_FOUND;}

IMAGE_DATA_DIRECTORY* dataDirectory = &optionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
IMAGE_EXPORT_DIRECTORY* Exp;
Exp = (IMAGE_EXPORT_DIRECTORY*)((DWORD)dosHeader + dataDirectory->VirtualAddress);

ULONG* addressoffunctions=(ULONG*)((BYTE*) m_handle + Exp->AddressOfFunctions);

if(Exp->NumberOfNames==1)
{
    if(addressoffunctions[0] + (BYTE*)m_handle < address)
        {return 0;}
    return __MODULE_ADDRESS_NOT_FOUND;
    }

for(count = 1; count < Exp->NumberOfNames; count++)
    {
    if(addressoffunctions[count-1] + (BYTE*)m_handle >= address
    && addressoffunctions[count] + (BYTE*)m_handle < address)
        {return count-1;}
    }

, but how do I assert that the address really refers to an location within an exported function.


Solution

  • In common case, you can't. You should disassemble whole function instructions graph to get addresses of all its instructions.

    In some trivial cases, you can search for ret instruction, but it's not reliable.

    If you can perform static analysis, you can use IDA to get function boundaries.