Search code examples
c++cwinapivisual-c++portable-executable

C/C++ assign pointer address of DWORD array


I am programming a C/C++ PE Parsing library where I use DLL or exe to extract info about directories and headers. My prblem is when I extract the export address and get the address of functions, I don't know how to use that address to point it to the array with the number of export functions exported

DWORD ExportRVA = PEHeader->optional.data_directory[0].virtual_address;
image_export_directory* Exports = (image_export_directory*)(RVAToOffset(ExportRVA)+BaseAddress);

ExportTable.nNames = Exports->number_of_names;
ExportTable.nFunctions = Exports->number_of_functions;
ExportTable.pFunctions = Exports->address_of_functions;
ExportTable.nNames = Exports->address_of_names;
ExportTable.pNamesOrdinals = Exports->address_of_name_ordinals;

Do I have to assign a pointer to array like

DWORD * AddrFunctions;

changing the pointer address?


Solution

  • The address_of_functions and address_of_names fields are RVAs to arrays of RVAs to the actual function entry points and names, respectively, whereas the address_of_name_ordinals field is an RVA to an array of WORD values, eg:

    #define RVAToPtr(RVA) ( ((LPBYTE)BaseAddress) + ((DWORD)(RVA)) )
    
    image_export_directory* Exports = (image_export_directory*) RVAToPtr(PEHeader->optional.data_directory[0].virtual_address); 
    
    ExportTable.nFunctions = Exports->number_of_functions; 
    ExportTable.nNames = Exports->number_of_names; 
    ExportTable.pFunctions = (PDWORD) RVAToPtr(Exports->address_of_functions); 
    ExportTable.pNames = (PDWORD) RVAToPtr(Exports->address_of_names); 
    ExportTable.pNamesOrdinals = (PWORD) RVAToPtr(Exports->address_of_name_ordinals); 
    
    for (DWORD i = 0; i < ExportTable.nFunctions; ++i)
    {
        void *FuncPtr = (void*) RVAToPtr(ExportTable.pFunctions[i]);
        char* FuncName = (char*) RVAToPtr(ExportTable.pNames[i]);
        WORD FuncOrdinal = ExportTable.Base + ExportTable.pNamesOrdinals[i]; 
        ...
    }
    

    Refer to MSDN for more details.