关于导入表

写一篇关于导入表的文章。

逆向脱壳,找到入口点之后,dump。一般都会遇到要修复导入表的问题,因而了解导入表就有必要。

首先说一下什么是导入表,百度百科给出的解释是


Import Address Table 由于导入函数就是被程序调用但其执行代码又不在程序中的函数,这些函数的代码位于一个或者多个DLL 中.当PE 文件被装入内存的时候,Windows 装载器才将DLL 装入,并将调用导入函数的指令和函数实际所处的地址联系起来(动态连接),这操作就需要导入表完成.其中导入地址表就指示函数实际地址。


换言之,就是windows给我们调用其dll的一个实现方法。

对于每一个引入的可执行文件,就比如dll,有一个导入表,在winnt.h中可以查看到它的形式为


typedef struct _IMAGE_IMPORT_DESCRIPTOR {
    union {
        DWORD   Characteristics;          
        DWORD   OriginalFirstThunk;      
    };
    DWORD   TimeDateStamp;             
    DWORD   ForwarderChain;             
    DWORD   Name;                         
    DWORD   FirstThunk;                   
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;

可以看到结构体中有五个DWORD,其中我们重点看的是union中的一个DWORD,还有FirstThunk,从名字来看OriginalFirstThunk和FirstThunk应该有某种联系。

实际上他们两个都是指针,其中存放的是两个RVA地址。

通过字段找到导入表,第一眼看到的就是结构体了,OriginalFirstThunk应该就是第一个数据,可是我们知道在c语言中引用结构体的方法是(p).x        之所以强调这一步是因为,结构体并非是按地址直接存放,这个.操作符就是带我们走向x的实际地址,所以我们的OriginalFirstThunk应该是第一个Dword所指的地址,这个地址怎么求呢,实际上很简单,因为不可能把p和x放的太远,你甚至可以直接往下翻找,但我们说更正确的办法那就是Dword所指的虚拟地址转成物理地址,我们可以用dword中存放的虚拟地址减去这个section的虚拟地址,得到的偏移量再加上Dword的物理地址(因为OriginalFirstThunk就是第一个,所以Dword的物理地址就是section的物理地址)。好的,假设我们现在已经到达OriginalFirstThunk的实际空间,前面说过他是一个指针,所以应该存放着一个RVA地址,关于这个RVA地址的物理地址转换方法同上,往下走,我们跟着这个指针到了其所指的地址,其中的数据是一个双字节的hint和函数名字,然后是下一个双字节hint和函数名字……

除了通过OriginalFirstThunk可以找到,也可以用Name找到,方法就简单很多了,直接通过结构体中Name所占Dword作为指针,就可以跳到函数所在地址。

再说FirstThunk,他实际上是一个指向数组的指针,这个数组的类型名字有点长,叫做IMAGE_THUNK_DATA,实际上OriginalFirstThunk也是指向这个数组,具体来看看IMAGE_THUNK_DATA长什么样子

typedef struct _IMAGE_THUNK_DATA32 {
    union {
        PBYTE  ForwarderString;
        PDWORD Function;
        DWORD Ordinal;
        PIMAGE_IMPORT_BY_NAME  AddressOfData;//这个东西也可以用来指向函数
    } u1;
} IMAGE_THUNK_DATA32;
typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;

看起来是一个四选一的东东,每个这种东东都能拿来指向函数,其中第四个是一个结构体


typedef struct _IMAGE_IMPORT_BY_NAME {
    WORD    Hint; ///该函数的导出序数
    BYTE    Name[1]; ///该函数的名字
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;


看到这里我们就能明白,我们从OriginalFirstThunk中走过去的那些Hint和函数名字是为什么了吧。

没错就是 _IMAGE_IMPORT_BY_NAME ,其他三个东东我们这里不细讲,因为一般看到的就是这种形式(第三个ordinal也有使用)


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值