PE文件格式详解(4)

1.RVA to RAW
    PE文件加载到内存时,每个节区都要准确完成内存地址与文件偏移的映射。这种映射便称为RVA to RAW,实现这个过程需要经过以下的步骤。
         1.查找RVA所在节区。
         2.使用公式计算出文件偏移。
         根据IMAGE_SECTION_HEADER结构体,换算公式如下。
         RAW - PoniterToRawData = RVA - VirtualAddress
                                               RAW  = RVA - VirtualAddress + PointerToRawData
  2.IAT(Import Address Table,导入地址表)
    IAT保存的内容与Windows操作系统的核心进、内存、DLL结构等有关。(即掌握了IAT便掌握了Windows操作系统的根基)。

      1.DLL(Dynamic Linked Library)
        加载DLL的方式有两种:一种是“显式链接”(Explicit Linking),程序使用DLL时加载,使用完毕后释放内存。另一种是“隐式链接”(Implicit Linking),程序开始时遍一同加载DLL,程序终止时,再释放占用的内存。IAT提供的机制便与隐式链接有关。
    DLL重定位,DLL文件的ImageBase一般为10000000.比如某个程序使用a.dll和b.dll,OE装载器先把a.dll装载到内存的10000000(ImageBase)处,然后尝试把b.dll也装载到该处。但是由于该地址处已经装载了a.dll,所以PE装载器需要查找其他空白的内存空间(ex:3E000000),然后将b.dll装载进去。这就是DLL文件的重定位。
    2.IMAGE_IMPOT_DESCRIPTOR
        IMAGE_IMPORT_DESCRIPTOR结构体中记录着PE文件要导入哪些库文件。 IMAGE_OPTIONAL_HEADER32.DataDirectory[1].VirtualAddress 的值即是IMAGE_IMPORT_DESCRIPTOR结构体数组的起始地址(RVA值)。(第一个4字节为虚拟地址,第二个4字节为Size成员。)
           注:Import:导入,向库提供服务(函数)。
                  Export:导出,从库向其他PE文件提供服务(函数)。
 
代码 IMAGE_IMPORT_DESCRIPTOR

typedef struct _IMAGE_IMPORT_DESCRIPTOR{
    union{
         DWORD     Characteristics;
         DWORD     OriginalFirstThunk;          //INT(Import Name Table) address (RVA)
    };
    DWORD     TimeDatastamp;
    DWORD     ForwarderChain;
    DWORD     Name;                                        // library name string address (RVA)
    DWORD     FirstThunk;                               // IAT( Import Address Table) address (RVA)
     } IMAGE_IMPORT_DESCRIPTOR;

typedef struct _IMAGE_IMPORT_BY_NAME{
    WORD     Hint;                                              // ordinal
    BYTE         Name[1];                                      // function name string
      } IMAGE_IMPORT_BY_NAME , *PIMAGE_IMPORT_BY_NAME;

    执行一个普通程序时往往需要导入多个库,导入多少库就存在多少个IMAGE_IMPORT_DESCRIPTOR结构体,这些结构体形成了数组,且结构体数组最后以NULL结构体结束。
  IMAGE_IMPORT_DESCRIPTOR的重要成员如下
                                  项目                                   含义
              OriginalFirstThunk          INT的地址(RVA)
                        Name                            库名称字符串的地址 (RVA)
              FirstThunk                            IAT的地址 (RVA)
注:INT与IAT是长整型(4个字节数据类型)数组,以NULL结束(未另外明确指出大小)。
        INT中各元素的值为IMAGE_IMPORT_BY_NAME结构体指针(有时IAT也有相同的值)。
         INT与IAT的大小应相同。
3.EAT
    Windows操作系统中,“库”是为了方便其他程序调用而集中包含相关函数的文件(DLL/SYS)。Win32 API是最具代表性的库,其中的kernel32.dll文件称为最核心的库文件。
    EAT是一种核心机制,它使不同的应用程序可以条用库文件中提供的函数(即只有通过EAT才能准确求得从相应库中导出函数的起始地址)。PE文件内部有且仅有一个用来说明库EAT的IMAGE_EXPORT_DIRECTORY结构体,并且保存着导出信息。  
    注: IAT的结构体以数组的形式存在,且拥有多个成员。即说明PE文件可以同时导入多个库。
    可以在PE文件的PE头中查找到IMAGE_EXPORT_DIRECTORY结构体的闻之。 IMAGE_OPTIONAL_HEADER32.DataDirectory[0].VirtualAddress 值即为结构身体数组的其实地址(RVA值)。 (第一个4字节为虚拟地址,第二个4字节为Size成员。)
    
    代码    IMAGE_EXPORT_DIRECTORY结构体
    typedef struct _IMAGE_EXPORT_DIRECTORY {
         DWORD     Characteristics;
         DWORD     TimeDateStamp;               //creation time date stamp
         WORD        MajorVersion;
         WORD        MinorVersion;
         DWORD    Name;                                   //address of library file neme
         DWORD    Base;                                      //ordinal base
         DWORD    NumberOfFunctions;       //number of functions
         DWORD    NumberOfNames;          //number of names
         DWORD    AddressOfFunctions;     //address of function start address array
         DWORD    AddressOfName;             //address of function name string array
          DWORD    AddressOfNameOrdinals;    //address of ordinal array
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

其中结构体中的重要成员如下
                   项目                                                  含义          
NumberOfFunctions                    实际Export函数的个数
NumberOfNames                          Export函数中具名的函数个数
AddressOfFunctions                    Export函数地址数组(数组元素个数= NumberOfFunctions
AddressOfNames                          函数名称地址数组( 数组元素个数= NumberOfNames
AddressOfNameOrdinals          Ordinal地址数组 (数组元素个数= NumberOfNames)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值