• IAT表


    0X0

    0 DLL介绍

    DLL翻译器为动态链接库,原来不存在DLL的概念只有,库的概念,编译器会把从库中获取的二进制代码插入到应用程序中。在现在windows操作系统使用了数量庞大的库函数(进程,内存,窗口,消息)采用这种包含库的方式,会造成内存严重的浪费。因此,windows OS 设计者根据需要引入了DLL这一概念

    (1) 不要把库包含到程序中,单独组成DLL文件,需要时调用即可
    (2) 内存映射技术使加载后的DLL代码,资源在多个进程中实现共享
    (3) 更新库时只要替换相关的DLL文件即可

    0X01 IMAGE_IMPORT_DESCRIPTOR

    IMAGE_IMPORT_DESCRIPTOR 结构体记录着PE文件要导入哪些库文件
    IMAGE_IMPORT_DESCRIPTOR 结构体如下

    typedef struct _IMAGE_IMPORT_DESCRIPTOR {
        union {
            DWORD   Characteristics;            // 0 for terminating null import descriptor
            DWORD   OriginalFirstThunk;         // RVA to original unbound INT (PIMAGE_THUNK_DATA) 存着INT表地址
        } DUMMYUNIONNAME;
        DWORD   TimeDateStamp;                  // 0 if not bound,
                                                // -1 if bound, and real date	ime 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) 存着IAT表地址
    } IMAGE_IMPORT_DESCRIPTOR;
    typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
    

    执行一个普通程序往往需要导入多个库,导入多个库就存在多少IMAGE_IMPORT_DESCRIPTOR结构体,这些结构体形成了数组,且结构体数组最后以NULL结构体结束。

    项目 含义
    OriginalFirstThunk INT的地址(RVA)
    Name 库的名字
    FirstThunk IAT的地址(RVA)

    IAT 和 INT 存着很多IMAGE_THUNK_DATA,IMAGE_THUNK_DATA结构体汇总只有一个联合体,一般用四字节的AddressOfData来获取

    typedef struct _IMAGE_THUNK_DATA32 {
        union {
            DWORD ForwarderString;      // PBYTE 
            DWORD Function;             // PDWORD
            DWORD Ordinal;
            DWORD AddressOfData;        //RVA 指向_IMAGE_IMPORT_BY_NAME 
        } u1;
    } IMAGE_THUNK_DATA32;
    typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;
    
    typedef struct _IMAGE_IMPORT_BY_NAME {
        WORD    Hint;       //可能为0,编译器决定,如果不为0,是函数在导出表中的索引
        BYTE    Name[1];    //函数名称,以0结尾,由于不知道到底多长,所以干脆只给出第一个字符,找到0结束
    } IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
    
    

    INT 导入姓名表 IAT为导入地址表,程序在初始化时需要把获取库中的函数地址存入IAT表中进行IAT的初始化,在开始时INT和IAT指的是同一个结构体IMAGE_IMPORT_BY_NAME(我在XP环境中测试的时候记事本程序时在文件中,INT表存的是IMAGE_IMPORT_BY_NAME 结构体,IAT表存的是写死的函数地址)

    描述IMAGE_IMPORT_DESCRIPTOR 的示意图

    下面了解一下PE装载器把导入函数输入至IAT的顺序

    1. 读取IID的Name成员,获取库名称字符串("kernel32.dll")
    1. 装载相应库 ->LoadLibrary("kernel32.dll")
    2. 读取IID的OriginalFirstThunk成员,获取INT地址
    3. 逐一读取INT中数组的值,该值是IMAGE_IMPORT_BY_NAME的地址,然后获取IMAGE_IMPORT_BY_NAME结构体中的Hint 或者Name项 使用GetProcAddress()获取相应的起始地址
    4. 读取IID的FirstThunk(IAT)成员,获取IAT地址
    5. 将上面获取的函数地址输入相应的IAT数组值
    6. 重复4-6这几个步骤直到INT结束

    0X02 在xp系统下用notepad.exe进行演示

    0x021 从PE可选头查找导出表的位置

    IMAGE_IMPORT_DESCROPTOR 结构的起始地址存在于 可选头的DataDirectory 数组第二个位置IMAGE_OPTIONAL_HEADER32.DataDirectory[1].VirtualAddress的值

    1. 首先通过PEwiew查看 notepad.exe的PE可选头 看出 IMPORT表 RVA 7604 => RAW 6A04
    1. 我们查到了导入表的首地址我们用HXd查看一下

    我们可以看到数组的最后是以NULL结尾的

    1. 我先列一下第一个导入表对应的各个地址,全是F的话就是还未装载,在进入内存是将会装载
    地址(RVA) 含义 地址(RAW)
    7990 OriginalFirstThunk 6D90‬
    FFFFFFFF TimeDateStamp 0
    FFFFFFFF ForwarderChain 0
    7AAC Name 6EAC‬
    12C4 FirstThunk 06C4
    1. 先看一下这个库的名字 是 comdlg32.dll
    1. 查看导入姓名表 中的 IMAGE_THUNK_DATA32 结构

    RVA 7A7A => RAW 6E7A 为 IMAGE_IMPORT_BY_NAME 结构体的首地址

    1. 查看IMAGE_IMPORT_BY_NAME 结构体

    可以看出000F为函数的编号 ,后面则是导入的函数名字 PageSetupDlgW

    1. 查看IAT表中的 IMAGE_THUNK_DATA32 结构

      IAT表中的IMAGE_THUNK_DATA32 结构存的就不是姓名表的地址了,而是一个写死了的,该函数的内存地址,为了兼容其他系统,程序在执行时会通过IAT和库的导出表来动态获取该函数的地址。并把地址存入IAT表的对应位置,然后进行下一个函数名称查找,直到把所有函数查找完。
    1. 我们通过OllyIce查看在内存中IAT表的样子

    看着该函数地址与在hxd文件一样,那是因为在xp系统下,换个系统这两个值就可能会不一致。

  • 相关阅读:
    将光标定位于输入框最右侧的实现方式
    Canvas学习笔记
    CSS3 颜色模式
    CSS ^ $选择器
    jQuery.Validator Sample
    让网页的title动起来
    转:线程间操作无效: 从不是创建控件“”的线程访问它~~~的解决方法~
    winform 表单正则表达式验证 示例(ValidationRule)
    详解用Navicat工具将Excel中的数据导入Mysql中
    PHP面试题之实现输出100以内的质数
  • 原文地址:https://www.cnblogs.com/mhpcuit/p/13049764.html
Copyright © 2020-2023  润新知