首页
社区
课程
招聘
[原创]菜鸟也学输入表
发表于: 2012-2-13 15:44 4294

[原创]菜鸟也学输入表

2012-2-13 15:44
4294

关于导入表:

      可执行文件使用来自于其他dll的代码或数据时,称为输入。当PE文件装入时,

Windows加载器的工作之一就是定位所有被输入的函数和数据,并且让正在被装入的

PE文件可以使用那些地址。这个过程是通过PE文件的输入表(Import Tab 也称之为

导入表)完成的,输入表中保存的是函数名和其驻留的dll名等,动态连接所需输信息,

输入表在软件外壳技术上的地位十分重要,因此在研究外壳的技术时一定要掌握这部分

知识。

学习输入表要先从整个PE文件说起,
-------------*-------------------------------------------------*
                 | DOS Header(IMAGE_DOS_HEADER) | -->64 Byte
DOS头部  --------------------------------------------------
                 | DOS Stub                                            | -->112 Byte
-------------*-------------------------------------------------*
                 | "PE"00 (Signature)                              | -->4 Byte
                  -------------------------------------------------
                 | IMAGE_FILE_HEADER                        | -->20 Byte
PE文件头 --------------------------------------------------
                 | IMAGE_OPTIONAL_HEADER32          | -->96 Byte
                 ---------------------------------------------------
                 | 数据目录表                                           | -->128 Byte
-------------*--------------------------------------------------*
                 | IMAGE_SECTION_HEADER                 | -->40 Byte
                 ---------------------------------------------------
   块表       | IMAGE_SECTION_HEADER                 | -->40 Byte
                  --------------------------------------------------
                 | IMAGE_SECTION_HEADER                 | -->40 Byte  
-------------*--------------------------------------------------*
                 |.text                                                       | -->512 Byte
                 ---------------------------------------------------
    块          |.rdata                                                   | -->512 Byte
                 ---------------------------------------------------
                 |.data                                                     | -->512 Byte
-------------*-------------------------------------------------*
                 | COFF行号                                            | -->NULL
                 ---------------------------------------------------
调试信息 | COFF符号表                                         | -->NULL
                 ---------------------------------------------------
                 | Code View 调试信息                             | -->NULL
-------------*--------------------------------------------------*
--------->>>摘自互联网(方舟子把我们搞的人心惶惶的,我等菜鸟写点东西都心惊胆战)

上面就是一个简单的PE结构图(附件里我会附带一个比较详细的PE结构图供菜菜们娱乐),
我们来找出和输入表有关的区段和数据结构以及他们在PE文件中的位置。

1.IMAGE_NT_HEADER->IMAGE_OPTIONAL_HEADER32->第104个字节(也就是数据目录表的IMAGE_DIRECTORY_ENTRY_IMPORT) :struct _IMAGE_DATA_DIRECTORY{DWORD VirtualAdress;    DWORD  Size;};
该结构第一个成员是指向.idata区段首地址。

2.节表    .idata
typedef struct _IMAGE_SECTION_HEADER {
       BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
    union {
           DWORD PhysicalAddress;
           DWORD VirtualSize;
    }     Misc;
     DWORD VirtualAddress;
     DWORD SizeOfRawData;
     DWORD PointerToRawData;
     DWORD PointerToRelocations;
     DWORD PointerToLinenumbers;
     WORD NumberOfRelocations;
     WORD NumberOfLinenumbers;
     DWORD Characteristics;
};
第五个成员表示该区段在文件中的起始地址。

3.   .idata区段中
参考附件中的图片。

   typedef struct _IMAGE_IMPORT_DESCRIPTOR {
    union {
        DWORD   Characteristics;            // 0 for terminating null import descriptor
        DWORD   OriginalFirstThunk;         // RVA to original unbound IAT    (PIMAGE_THUNK_DATA)
    };
    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;
//传说中的IID结构。
这个结构很重要,我们一个一个成员来分析

1)指向输入名称表(简称INT)的RVA,INT是一个IMAGE_THUNK_DATA结构数组,数组中的每一个IMAGE_THUNK_DATA结构指向IMAGE_IMPORT_BY_NAME结构,数组最后一个内容是内容为0的IMAGE_THUNK_DATA。

typedef struct _IMAGE_IMPORT_BY_NAME {
                      WORD    Hint;
                     BYTE    Name[1];
          } IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

成员1:
          WORD    Hint;指示本函数在其所驻留dll的输入表中的序号。该域被PE装载器
用来在DLL的输出表里快速查询函数。该值不是必须的,一些链接器将此值设为0.

成员2:
         BYTE    Name[1];含有输入函数的函数名,函数名是一个ASCII码字符串

2)32位时间标志。

3)这个是第一个被转向的API的索引,一般为0。

4)DLL的名字的指针,是一个以00结尾的ASCII字符的RVA地址,例如”kernel32.dll”

5)包含指向输入地址表(IAT)的RVA。IAT是一个IMAGE_THUNK_DATA数组。

成员1同成员5非常相似,他们指向两个本质上相同的数组IMAGE_THUNK_DATA。

以上便是PE中和输入表相关的数据结构








[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 6
支持
分享
最新回复 (7)
雪    币: 47
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
应该是可选头文件的第105个字节开始是输入表段的起始地址,虽然写得很菜,也不能祸害别人是吧,
2012-2-13 15:56
0
雪    币: 163
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
附件在哪??没找到
另:谁有邀请码给他一个
2012-2-13 17:12
0
雪    币: 47
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
附件啦啦啦
上传的附件:
2012-2-13 17:50
0
雪    币: 1644
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
鼓励下。。。
2012-2-15 16:08
0
雪    币: 29
活跃值: (60)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
感叹破解真的好难
2012-2-15 16:32
0
雪    币: 33
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
写得不错......
2013-10-25 11:02
0
雪    币: 36
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
看这代码有点复杂,
2013-10-25 11:54
0
游客
登录 | 注册 方可回帖
返回
//