延迟载入

延迟载入一个DLL是一种混合方式,通过LoadLibrary和GetProcAddress,然后我们可以在程序里直接调用它。
延迟加载表本质上跟绑定导入表的目的是一样的,都是为了加快程序加载文件的速度,只不过方法不一样,绑定导入表是事先预测DLL的加载位置,从而减少指令的执行。
延迟加载是指在调用某个DLL时才去加载,目的是为了避免在程序启动之初就加载了不必要的DLL而浪费了时间。

延迟载入并不是操作系统的特征!!!,所以在WinNT.h中无法找到对它的描述。这项特性是通过向链接器运行库加入额外的代码来实现的。
在目录表中可以寻找到。
在这里插入图片描述这是一个指向ImgDelayDescr数组的一个结构,其中每一个延迟载入的DLL都对应于一个ImgDelayDescr的结构。ImgDelayDescr的格式上与IAT和INT是相同的,唯一区别是ImgDelayDescr是由运行库代码不是操作系统写入和读取的。。当第一次从一个延迟载入的DLL中调用一个API函数时,运行库会先调用LoadLibrary,再调用GetProcAddress,得到的地址被保存在延迟载入的IAT中。这样的话,以后每次调用这个API都会来这个地方。

typedef struct ImgDelayDescr {  
    DWORD        grAttrs;       //结构的属性,目前唯一的属性是dlattrRVA,表明这个结构中的字段应是RVA,而不是虚拟地址。这个值被设置为1,结构成员代表的是RVA值。如果这个位关掉,则RVA代表的是虚拟地址
    RVA          rvaDLLName;	//这个DLL名字的RVA
    RVA          rvaHmod;       //指向该DLL被载入内存时,其模块句柄的值,实际上就是DLL在内存中的位置
    RVA          rvaIAT;       	//IAT的RVA,与常规IAT的格式相同
    RVA          rvaINT;      	//INT的RVA,与常规的INT格式相同
    RVA          rvaBoundIAT;  	//绑定导入的IAT的RVA,尽管并不是实际绑定的,但是特征可能会在未来版本出现。
    RVA          rvaUnloadIAT; 	//总是设为0
    DWORD        dwTimeStamp;   //时间戳
    } ImgDelayDescr, * PImgDelayDescr;  

下面实战下,从数据目录表里得到了延迟载入的RVA,跳到那里。
在里插入图片描述
在这里插入图片描述

我们在这里只看关键的部分,grAttr被设置为0,说明后面的RVA声明的成员的值是虚拟地址。rvaDllName的值是0x401050,根据它的加载基址,我们可以算出它在内存中的RVA是0x1050,换算成文件偏移就是0x250。正是user32.dll
在这里插入图片描述
其在内存中的HMODULE是0x40141c,IAT是0x401038,换算成文件偏移是0x238, INT是0x4013d0,换算成文件偏移是0x5d0,我们用winhex看下。
在这里插入图片描述
第一个是0x4013EA,第二个是0x4013DC,换算成文件偏移也就是0x5ea,0x5dc,在winhex中查找
在这里插入图片描述
其中第一项是hint,第二项是ascii字符串。IAT我们就不看了。

再看下第二项的ImgDelaydesc
在这里插入图片描述
grAttr旗标仍然是0,所以后面跟着的仍然是虚拟地址,第二项延迟加载的DLL的VA是0x401060,换算成RVA也就是0x260,跳到那里看下。
在这里插入图片描述

这次加载的是advapi32.dll。后面的就不分析了。

重点记住延迟载入不是操作系统的特征,而是运行库代码所实现的!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值