zoukankan      html  css  js  c++  java
  • WIN32 PE Bound Import 绑定导入表

    一丶简介

      根据前几讲,我们已经熟悉了导入表结构.但是如果大家尝试过打印导入表的结构. INT IAT的时候. 会出现问题.

    PE在加载前 INT IAT表都指向一个名称表. 这样说是没错的. 但是如果你打印过导入表.会发现一个问题. 有的EXE程序.在打印IAT表的时候.发现里面是地址.

    原因:

      我们的PE程序在加载的时候.我们知道. PE中导入表的子表. IAT表.会填写函数地址. 但是这就造成了一个问题.PE程序启动慢.每次启动都要给IAT表填写函数地址.

      我们可不可以在文件中就给填写好. 这样是可以的.

    优点:

      PE程序启动变快.

    缺点:

      如果DLL的ImageBase变了.那么就需要进行重定位.因为在文件中你填写的地址是固定的地址.

    导入表结构:

    复制代码
    typedef struct _IMAGE_IMPORT_DESCRIPTOR {
        union {
            DWORD   Characteristics;            // 0 for terminating null import descriptor
            DWORD   OriginalFirstThunk;         // INT 表
        } DUMMYUNIONNAME;
        DWORD   TimeDateStamp;                  // 时间戳.
                                                // -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;                //指向DLL名字的 RVA
        DWORD   FirstThunk;                     // IAT 表
    } IMAGE_IMPORT_DESCRIPTOR;
    typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
    复制代码

    但是我们怎么知道.在文件中IAT表是否填写地址.还是不填写地址. 重要的地方 就是 TimeDateStamp (时间戳)成员, 如果为0 则是这个DLL没有绑定. 如果为 -1 则是这个DLL进行了绑定.

    那么什么是绑定.

      绑定的意思就是IAT的函数地址 是否是文件一开始就写入. 如果是绑定就是一开始就填写的.否则反之.

     

    二丶绑定导入表

      怎么判断导入表中的 IAT表函数地址是否绑定. 根据 TimeDataStamp进行判断. 0未绑定, -1 绑定. 而真正的绑定时间存放在绑定导入表中.

    数据目录的第12项

      绑定导入表结构

    typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR {
        DWORD   TimeDateStamp;                //真正的时间戳,
        WORD    OffsetModuleName;              //DLL的名字. PE的文件名
        WORD    NumberOfModuleForwarderRefs;        //依赖的另外的DLL有几个
    // Array of zero or more IMAGE_BOUND_FORWARDER_REF follows
    } IMAGE_BOUND_IMPORT_DESCRIPTOR,  *PIMAGE_BOUND_IMPORT_DESCRIPTOR;

    我们的一个DLL可能依赖其他的DLL. 所以导入表的最后一个成员是依赖的DLL有几个.如果有两个.那么紧跟着下面就是依赖的DLL的绑定导入表结构.

    依赖DLL的结构

    typedef struct _IMAGE_BOUND_FORWARDER_REF {
        DWORD   TimeDateStamp;
        WORD    OffsetModuleName;
        WORD    Reserved;
    } IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF;

    跟绑定导入表是一样的. REF 引用的意思.就是说.我的绑定导入表中依赖的DLL有两个.那么绑定导入表下面.还有两个就是 xxx_REF结构(跟绑定导入表一样)

    注意REF结构中第三个成员.,他是用来占位置的.保留的.

     

    OffsetModuleName 成员.这个成员不是RVA 也不是FOA 而是第一个绑定导入表地址
    这个成员的值.才是一个指针. 这个指针才是真正的文件名所在的位置.不管你打印到第几个 永远都是 第一个绑定导入表的值 + OffsetModuleName的值
  • 相关阅读:
    测光
    闪光灯
    快门
    光圈
    白加黑减
    曝光补偿
    取景雷区
    着眼点
    Web中的无状态含义
    图计算模型[转]
  • 原文地址:https://www.cnblogs.com/ganxiang/p/13203758.html
Copyright © 2011-2022 走看看