PE import/export address table

Posted resibe-3

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PE import/export address table相关的知识,希望对你有一定的参考价值。

 

#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
// http://hatriot.github.io/blog/2017/09/19/abusing-delay-load-dll/
// https://blog.csdn.net/adam001521/article/details/84658708

/* index values of DataDirectory
#define IMAGE_DIRECTORY_ENTRY_EXPORT          0   // Export Directory
#define IMAGE_DIRECTORY_ENTRY_IMPORT          1   // Import Directory
#define IMAGE_DIRECTORY_ENTRY_BASERELOC       5   // Base Relocation Table
#define IMAGE_DIRECTORY_ENTRY_IAT            12   // Import Address Table
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13   // Delay Load Import Descriptors
*/


/*
 * get DOS header (base) --> location of NT header
 * get NT header  
 *                   _IMAGE_FILE_HEADER  
 *                 IMAGE_OPTIONAL_HEADER : DataDirectory array
 *               
 * DataDirectory  RVA SIZE 
 * 
 */

/* export table
struct _IMAGE_EXPORT_DIRECTORY 
DWORD   Characteristics;
DWORD   TimeDateStamp;
WORD    MajorVersion;
WORD    MinorVersion;
DWORD   Name;                   // dll name
DWORD   Base;                   // ordinal base, link a func: @(base + unbased ordinal)
DWORD   NumberOfFunctions;
DWORD   NumberOfNames;            // 
DWORD   AddressOfFunctions;     // function address array
DWORD   AddressOfNames;         // name array, with the same order of ordinals, but not functions
DWORD   AddressOfNameOrdinals;  // unbased ordinals, the index in functions
 
*/



/* import address table is not in Directory
struct _IMAGE_IMPORT_DESCRIPTOR 
union 
    DWORD   Characteristics;            // 0 for terminating null import descriptor
    DWORD   OriginalFirstThunk;         // by name or ordinal
 DUMMYUNIONNAME;
DWORD   TimeDateStamp; 
DWORD   ForwarderChain;
DWORD   Name;                            // dll name
DWORD   FirstThunk;                     // pointer to a pos in IAT, its value firstThunk->u1.function is the address
 IMAGE_IMPORT_DESCRIPTOR;

struct _IMAGE_THUNK_DATA32 
    union 
    DWORD ForwarderString;    
    DWORD Function;             // func address (firstthunk, its one address in IAT) 
    DWORD Ordinal;                // by ordinal
    DWORD AddressOfData;        // PIMAGE_IMPORT_BY_NAME
     u1;


*/


/* delay table
struct _IMAGE_DELAYLOAD_DESCRIPTOR 
union 
    DWORD AllAttributes;
    struct 
        DWORD RvaBased : 1;             // Delay load version 2
        DWORD ReservedAttributes : 31;
        ;
     Attributes;

DWORD DllNameRVA;                       // RVA to the name of the target library (NULL-terminate ASCII string)
DWORD ModuleHandleRVA;                  // RVA to the HMODULE caching location (PHMODULE)
DWORD ImportAddressTableRVA;            // RVA to the start of the IAT (PIMAGE_THUNK_DATA)
DWORD ImportNameTableRVA;               // RVA to the start of the name table (PIMAGE_THUNK_DATA::AddressOfData)
DWORD BoundImportAddressTableRVA;       // RVA to an optional bound IAT
DWORD UnloadInformationTableRVA;        // RVA to an optional unload info table
DWORD TimeDateStamp;                    // 0 if not bound,
 
*/

void GetTables(char *pDllName)

    PIMAGE_EXPORT_DIRECTORY pExportTable;
    PIMAGE_IMPORT_DESCRIPTOR pIMportTable;
    PIMAGE_DELAYLOAD_DESCRIPTOR pDelayTable;

    HMODULE hModule;
    PDWORD Address, Name;
    PWORD Ordinal;
    PIMAGE_DOS_HEADER pImgDos;
    PIMAGE_NT_HEADERS pImgNt;
    //Sleep(20 * 1000);
    hModule = LoadLibraryEx(pDllName, NULL, 0);
    pImgDos = (PIMAGE_DOS_HEADER)(hModule);
    pImgNt  = (PIMAGE_NT_HEADERS)((LPBYTE)pImgDos + pImgDos->e_lfanew);

    // the first section
    // PIMAGE_SECTION_HEADER       pSech = IMAGE_FIRST_SECTION(pImgNt);

    // import table
    pExportTable = (PIMAGE_EXPORT_DIRECTORY)((LPBYTE)hModule + pImgNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
    Address      = (PDWORD)((LPBYTE)hModule + pExportTable->AddressOfFunctions);
    Name         = (PDWORD)((LPBYTE)hModule + pExportTable->AddressOfNames);
    Ordinal      = (PWORD)((LPBYTE)hModule + pExportTable->AddressOfNameOrdinals);

    printf("there are %d functions in the export table, %d are exported by name\n", pExportTable->NumberOfFunctions, pExportTable->NumberOfNames);
    for (int i = 0; i<pExportTable->NumberOfNames; i++)
    
        printf("find function %s at %p  ordinal: %d \n", (char*)hModule + Name[i], (LPBYTE)hModule + Address[Ordinal[i]], Ordinal[i] + pExportTable->Base);
    

    // export table
    printf("-----------------------------------------------------------------------------------\n");
    pIMportTable = (PIMAGE_IMPORT_DESCRIPTOR)((LPBYTE)hModule + pImgNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
    while (pIMportTable->Name != NULL)
    
        printf("Import DLL: %s\n", (LPBYTE)hModule + pIMportTable->Name);
        PIMAGE_THUNK_DATA pInfoEntry = (PIMAGE_THUNK_DATA)((LPBYTE)hModule + pIMportTable->OriginalFirstThunk);
        PIMAGE_THUNK_DATA pAddressEntry = (PIMAGE_THUNK_DATA)((LPBYTE)hModule + pIMportTable->FirstThunk);
        while (pInfoEntry->u1.AddressOfData != NULL)
        
            if (pInfoEntry->u1.Ordinal & IMAGE_ORDINAL_FLAG)
            
                printf("\tfunc ordinal: %d addr: %p\n", IMAGE_ORDINAL(pInfoEntry->u1.Ordinal), pAddressEntry->u1.Function);
            
            else
            
                IMAGE_IMPORT_BY_NAME* pImport = PIMAGE_IMPORT_BY_NAME((LPBYTE)hModule + pInfoEntry->u1.AddressOfData);
                printf("\tfunc name: %s addr: %p entry addr %p\n", pImport->Name, pAddressEntry->u1.Function, pAddressEntry);
            
            pInfoEntry++;
            pAddressEntry++;
        
        pIMportTable++;
    

    // delay table
    printf("-----------------------------------------------------------------------------------\n");
    pDelayTable = (PIMAGE_DELAYLOAD_DESCRIPTOR)((LPBYTE)pImgDos +
        pImgNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress);
    for (IMAGE_DELAYLOAD_DESCRIPTOR* entry = pDelayTable; entry->ImportAddressTableRVA != NULL; entry++) 
        char *pDllName = (char*)((LPBYTE)hModule + entry->DllNameRVA);
        PIMAGE_THUNK_DATA pInfoEntry = (PIMAGE_THUNK_DATA)((LPBYTE)hModule + entry->ImportNameTableRVA);
        PIMAGE_THUNK_DATA pAddressEntry = (PIMAGE_THUNK_DATA)((LPBYTE)hModule + entry->ImportAddressTableRVA);
        printf("delay import module: %s\n", pDllName);
        while (pInfoEntry->u1.AddressOfData != NULL)
        
            if (pInfoEntry->u1.Ordinal & IMAGE_ORDINAL_FLAG)
            
                printf("\tfunc ordinal: %d addr: %p\n", IMAGE_ORDINAL(pInfoEntry->u1.Ordinal), pAddressEntry->u1.Function);
            
            else
            
                IMAGE_IMPORT_BY_NAME* pImport = PIMAGE_IMPORT_BY_NAME((LPBYTE)hModule + pInfoEntry->u1.AddressOfData);
                printf("\tfunc name: %s addr: %p\n", pImport->Name, pAddressEntry->u1.Function);
            
            pInfoEntry++;
            pAddressEntry++;
        
    



int main(int argc, char **argv)

    GetTables(argv[1]);
    return 0;

 

以上是关于PE import/export address table的主要内容,如果未能解决你的问题,请参考以下文章

关于VUE中 import export 和 export default 的注意问题

浅谈 import / export

oracle优化EXPORT和IMPORT

ES6 导入导出 import export export default

JavaScript import/export

save & load & export & import