首页
社区
课程
招聘
[原创]PE知识汇总
2020-9-22 00:21 4549

[原创]PE知识汇总

2020-9-22 00:21
4549

[原创]PE知识汇总(二)

前文:

PE格式汇总(一)

4、输入表(导入表)

  • 可执行文件使用来自其他DLL的代码或数据的操作称为输入。
  • 输入函数:又称为导入函数,输入函数就是被程序调用但其执行代码不在程序中的函数,这些函数的代码位于相关的DLL中。
  • 输入表的结构(IMAGE_IMPORT_DESCRIPTOR)

    在PE文件头的可选映像头(IMAGE_OPTIONAL_HEADER)中,数据目录表的第二个成员(Import table)指向输入表。输入表以一个IMAGE_IMPORT_DESCRIPTOR(IID)数组开始。每一个PE文件隐式连接的DLL都有一个IID。IID数组以最后一个全是0的IID结构作为结束。

1
2
3
4
5
6
7
8
9
10
struct _IMAGE_IMPORT_DESCRIPTOR {
    union {
        DWORD Characteristics;
        DWORD OriginalFirstThunk;   
    };
    DWORD TimeDateStamp;
    DWORD ForwarderChain;
    DWORD Name;           
    DWORD FirstThunk;       
} IMAGE_IMPORT_DESCRIPTOR;
  • OriginalFirstThunk:包含输入名称表(INT)的RVA。
  • Name:指向DLL的名称。
  • FirstThunk:包含指向输入地址表(IAT)的RVA
  • FirstThunk 和OriginalFirstThunk 相似,它们都指向IMAGE_THUNK_DATA结构数组。这个数组一般称之为输入名称表(Import Name Table->INT)和输入地址表(Import Address Table->IAT).

    4.1、IMAGE_THUNK_DATA结构和IMAGE_IMPORT_BY_NAME结构

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    struct _IMAGE_THUNK_DATA32{
      union {
         DWORD ForwarderString;
         DWORD Function; //被输入的函数的内存地址
         DWORD Ordinal; //高位为1则被输入的API的序数值
         DWORD AddressOfData;//高位为0则指向IMAGE_IMPORT_BY_NAME 结构体二
      }u1;
    }IMAGE_THUNK_DATA32;
    //IMAGE_THUNK_DATA64与IMAGE_THUNK_DATA32的区别,仅仅是把DWORD换成了64位整数。
    //////////////////////////////////////////////////////////
    struct _IMAGE_IMPORT_BY_NAME {
      WORD    Hint;//指出函数在所在的dll的输出表中的序号       
      BYTE    Name[1];//指出要输入的函数的函数名
    } IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

    奇奇怪怪的两张图
    img
    图1
    img
    图2
    这里的两张图都是展示IID的指向方式的,上面的那张图是静态文件下的PE,是由两个并行的指针指向导入函数(IMAGE_IMPORT_BY_NAME)。下面那张是执行状态下被重写后的指向方式,FirstThunk指向函数地址,通过排序和函数对应。

  • 实例:
    未加载下的情况
  1. Import Table
    图片描述
  2. 计算输入表所在区块
    图片描述
  3. 使用16进制编辑器打开PE文件,并且跳转到170C处
    图片描述
    图片描述
  4. 这里就拿第一个DLL举例子
    F4 25 00 00 ——>OriginalFirstThunk
    00 00 00 00 ——>TimeDateStamp
    00 00 00 00 ——>ForwarderChain
    8A 26 00 00 ——>Name
    34 20 00 00 ——>FirstThunk
  5. 通过上述图中的计算方式,得出offset:
    OriginalFirstThunk:25F4 => 17F4
    Name:268A => 188A
    FirstThunk:2034 => 1234
  6. 在16进制编辑器内查看
    OriginalFirstThunk->INT (当双字的高位为0时,表示以字符串类型的函数名方式输入)
    图片描述
    Name:
    图片描述
    FirstThunk:

    OFT -> OriginalFirstThunk

    图片描述

上述都是在静态模式(PE文件未被加载)的情况下分析的,满足图1情况。

加载后的情况
  1. dump 加载后的PE文件
    图片描述

    工具:PETools

  2. 查看Import Table
    图片描述

  3. 16进制编辑器打开PE文件

    注:因为这里PE文件已经是完成映射后的,所以不再需要对RVA进行转换FileOffset的操作
    图片描述
    同样,还是以第一个为例子
    F4 25 00 00 ——>OriginalFirstThunk
    00 00 00 00 ——>TimeDateStamp
    00 00 00 00 ——>ForwarderChain
    8A 26 00 00 ——>Name
    34 20 00 00 ——>FirstThunk
    这里前面的3个和之前的一样,直接看FirstThunk

  4. OD附加,找到FirstThunk(ImageBase+0x2034)
    图片描述
    可以看到,这里MessageBoxA的地址在这里所显示,这里就是IAT

未完待续....


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2020-9-22 09:14 被tutuj编辑 ,原因: 写错
收藏
点赞3
打赏
分享
最新回复 (2)
雪    币: 7121
活跃值: (125793)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
HlccFu 2020-9-22 09:04
2
0
感谢楼主分享
谢谢了
雪    币: 999
活跃值: (1518)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
WMBa0 2023-1-27 13:46
3
0
谢谢!
游客
登录 | 注册 方可回帖
返回