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;
}

 

转载于:https://www.cnblogs.com/resibe-3/p/11016645.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值