appsion 发表于 2020-11-2 09:25

PE 文件解析4-数据目录[导入表]

本帖最后由 appsion 于 2020-11-2 11:03 编辑

PE 文件解析4-数据目录[导入表]
新手学习PE文件解析记录,持续更新. 部分参考来源于网络, 无法逐一标注, 如果侵权,请及时联系. 如有错误请指正,误喷.


上文链接: https://www.52pojie.cn/thread-1294832-1-1.html






IAT
      Import Address Table, 导入地址表
INT
      Import Name Table, 导入名称表

结构体: IMAGE_IMPORT_DESCRIPTOR
说明: 导入表信息
头文件: winnt.h
帮助文档: 仅存在于头文件, 没有帮助文档
参考链接: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format



typedef struct _IMAGE_IMPORT_DESCRIPTOR
{
    union {
      DWORD   Characteristics;            // 0 for terminating null import descriptor
      DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
    } DUMMYUNIONNAME;
    DWORD   TimeDateStamp;                  // 0 if not bound,
                                          // -1 if bound, and real date\time stamp
                                          //   in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                          // O.W. date/time stamp of DLL bound to (Old BIND)

    DWORD   ForwarderChain;               // -1 if no forwarders
    DWORD   Name;
    DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;


参数说明: 仅供参考, 详细说明请参考原文.
      DUMMYUNIONNAME.Characteristics
                导入表描述
      DUMMYUNIONNAME.OriginalFirstThunk
                INT的RVA
      TimeDateStamp
                时间日期戳.
      ForwarderChain
                被转向API的索引.
      Name
                导入DLL库文件名的RVA
      FirstThunk
                IAT的RVA, IMAGE_THUNK_DATA 结构.


结构体: IMAGE_THUNK_DATA
说明: 导入外部库文件的函数表信息
头文件: winnt.h
帮助文档: 仅存在于头文件, 没有帮助文档
参考链接: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format



typedef struct _IMAGE_THUNK_DATA32 {
    union {
      DWORD ForwarderString;      // PBYTE
      DWORD Function;             // PDWORD
      DWORD Ordinal;
      DWORD AddressOfData;      // PIMAGE_IMPORT_BY_NAME
    } u1;
} IMAGE_THUNK_DATA32;
typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;

参数说明: 仅供参考, 详细说明请参考原文.
      u1.ForwarderString
                转发字符串
      u1.Function
                导入函数的地址的RVA
      u1.Ordinal
                导入函数的序号
      u1.AddressOfData
                导入函数名称的RVA, IMAGE_IMPORT_BY_NAME 结构.


结构体: IMAGE_IMPORT_BY_NAME
说明: 导入外部库文件的函数序号和名称
头文件: winnt.h
帮助文档: 仅存在于头文件, 没有帮助文档
参考链接: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format



typedef struct _IMAGE_IMPORT_BY_NAME
{
    WORD    Hint;
    CHAR   Name;
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

参数说明: 仅供参考, 详细说明请参考原文.
      Hint
                函数的序号
      Name
                导入函数名


4.1 获取导入表信息

// 参数说明
//    DataBuff: 文件指针
//    ImportRVA: 导入表的RVA

IMAGE_IMPORT_DESCRIPTOR *Import = GetImport(DataBuff, ImportRVA);
while (true)
{
      if (Import->OriginalFirstThunk == 0 && Import->FirstThunk == 0)
      {
                break;
      }

      // 导入表名称
      DWORD DllName_RVA = Import->Name;
      DWORD DllName_FOA = RVAToRaw(SectionHead, SectionCount, DllName_RVA);
      char * DllName = DataBuff + DllName_FOA;

      // INT的RVA
      DWORD INT_RVA = Import->OriginalFirstThunk;

      // IAT的RVA
      DWORD IAT_RVA = Import->FirstThunk;

      Import++;
}




4.2 获取函数信息

// 注:
//1. 判断导入方式
//                        序号方式导入, IMAGE_THUNK_DATA 值的最高位为1, 低31位值为函数序号.
//                        字符串方式导入, IMAGE_THUNK_DATA 的值.

void ImportFunctionInfo(char *DataBuff, DWORD INT_Thunk_RVA, DWORD IAT_Thunk_RVA)
{
      while (true)
      {
                DWORD INT_Thunk_FOA = RVAToRaw(SectionHead, SectionCount, INT_Thunk_RVA);

                IMAGE_THUNK_DATA *THUNK = (IMAGE_THUNK_DATA *)(DataBuff + INT_Thunk_FOA);

                if (THUNK->u1.Ordinal == 0)
                {
                        break;
                }

                // 判断导入方式
                if (THUNK->u1.Ordinal & IMAGE_ORDINAL_FLAG)
                {
                        // 导入序号
                        // THUNK->u1.Ordinal - IMAGE_ORDINAL_FLAG;

                        // INT的RVA
                        // INT_Thunk_RVA

                        // IAT的RVA
                        // IAT_Thunk_RVA

                }
                else
                {
                        // 获取函数名
                        DWORD ByName_RVA = THUNK->u1.AddressOfData;
                        DWORD ByName_FOA = RVAToRaw(SectionHead, SectionCount, ByName_RVA);
                        IMAGE_IMPORT_BY_NAME *ByName = (IMAGE_IMPORT_BY_NAME*)(DataBuff + ByName_FOA);

                        // 导入序号
                        // ByName->Hint

                        // INT的RVA
                        // INT_Thunk_RVA

                        // IAT的RVA
                        // IAT_Thunk_RVA
                }

                INT_Thunk_RVA += sizeof(DWORD);
                IAT_Thunk_RVA += sizeof(DWORD);
      }
}

csc18338004232 发表于 2020-11-2 12:37

我最近也在学

wjt_1221 发表于 2020-11-2 12:57

这个厉害了,要好好学习一下

SilverBulletY 发表于 2020-11-2 13:03


这个厉害了

terry8288 发表于 2020-11-2 13:57

学习学习

cdr741227 发表于 2020-11-2 18:22

学习学习

whngomj 发表于 2020-11-4 08:12


学习学习

醉酒戏红颜 发表于 2020-11-12 09:56

学习了,支持技术大佬

alxstar 发表于 2020-11-17 10:15

谢谢分享!

wolfdada 发表于 2021-2-2 09:16

谢谢大侠分享,受教
页: [1]
查看完整版本: PE 文件解析4-数据目录[导入表]