DllImport的反汇编趣事

 

看了这篇文章之后,你将发现,你在使用dll的时候,即使用错了dllimport或者dllexport,也不是什么严重的问题,编译器可能会帮你把错误纠正过来。到底怎么回事,你看看就会明白了。
由于使用失误,我在一个工程里面引用了dll中的一个函数,在申明的时候把dllimport误写成dllexport,并一直用了很久,因为使用正常,所以竟从来也没有发现此错误。我对它何以一直能够正常使用感到很不解。
我的申明是这样写的:
extern "C" __declspec(dll ex port ) BOOL myfunc1 ();
而正确的写法应该是:
extern "C" __declspec(dllimport) BOOL myfunc1 ();
 
为了分析,我把这个exe文件放到IDA工具里面进行反汇编分析。有下面的发现:
在调用 myfunc1 接口函数的地方,汇编代码是这样写的:
call     _ myfunc1
C编译器在编译时将引入函数 myfunc1的名字Resolve为带下划线的_ myfunc1 。作为一个引入函数,仅仅加桑下划线完成Resolve直觉上感觉是不够的,于是再把鼠标放到_myfunc1上,右键单击选择‘Jump to operand’。我又看到了下面的代码片段:
_myfunc1 proc near            
    jmp     ds:__imp__myfunc1
_ myfunc1 endp
这段汇编代码是_myfunc1的函数定义,可见所谓_myfunc1其实是一个桩函数(stub function),它将再调用了真正的引入函数__imp__myfunc1。函数名__imp__myfunc1正是对外部引入函数myfunc1真正的的Resolve名称,前缀__imp是import的简写。接着再看看__imp__myfunc1的内容,仍然右键选择‘Jump to operand’,我看到的是:
idata:00407028 ;
.idata:00407028 ; Imports from myDll
.idata:0040702C                  extrn __imp__myfunc1:dword
它的意思是说,从myDll中引入接口函数__imp__myfunc1。后面的dword,说明函数指针是4字节大小。

现在可以总结一下了:因为我把dllimport误写成了dllexport,编译器在进行编译的时候当然发现了这个错误,采取了补救措施,不仅真正引入了myDll中的myfunc1函数,而且创建了一个桩函数_myfunc1来调用此引入函数,从而在进行myfunc1调用的地方都一律变成了_myfunc1(call _ myfunc1)调用了。
为了进一步地弄清问题,我修改错误后重新编译,再把新的exe进行IDA反汇编,看到_myfunc1已经不存在了,函数中调用myfunc1的地方被直截编译成:call     __imp__myfunc1。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值