win32中 怎么样通过函数名 正确获取函数的地址

C++语言 码拜 8年前 (2016-09-23) 1746次浏览
C++中函数名表示函数的地址,但是直接输出函数名得到的值貌似不是函数的地址。
win32中 怎么样通过函数名 正确获取函数的地址
上边这张图是win32程序简单的调用一个函数,并且输出该函数名的值
win32中 怎么样通过函数名 正确获取函数的地址
上图是在反汇编中看到的call 后边函数名的括号中所带的值,与程序的输出一致,
win32中 怎么样通过函数名 正确获取函数的地址
win32中 怎么样通过函数名 正确获取函数的地址
但是从上边两张汇编的截图中,貌似函数的地址是另一个值?
求指导?
解决方案

10

c++函数名,就是函数地址啊。
你用不着关心那个jmp指令,无条件跳转而已。
你看看那个jmp指令上下,不是各种函数的实现地址吗。
这就是VC封装的函数地址表么。
其他的编译器不一定这样实现。

10

40

这个是编译器在 Debug 版中优化编译的一种手法. 可以通过 disable incremental linking 选项来去掉,但是会增加链接时间.
假设一个程序有连续两个foo和bar (所谓连续,就是他们编译连接之后函数体连续存放), foo入口位置在0x0400,长度为0x200个字节,那么bar入口就应该在0x0600 = 0x0400+0x0200。程序员在开发的时候总是频繁的修改code然后build,假设程序员在foo里面增加了一些内容,现在foo函数体占0x300个字节了,bar的入口也就只好往后移0x100变成了0x0700,这样就有一个问题,假如foo在程序中被调用了n次,那么linker不得不修改这n个函数调用点,虽然linker不嫌累,但是link时间长了,程序员会觉得不爽。所以MSVC在Debug版的build,不会让各个函数体之间这么紧凑,每个函数体后都有padding(全是汇编代码int 3,作用是引发中断,这样原因是古怪原因运行到不该运行的padding部分,会发生异常),有了这些padding,就可以一定程度上缓解上面提到的问题,不过当函数增加内容太多超过padding,还是有问题,怎么办呢?MSVC在Debug build中用上了Incremental Link Table, ILT其实就是一串jmp语句,每个jmp语句对应一个函数,jmp的目的地就是函数的入口点,和没有ILT的区别是,现在对函数的调用不是直接call到函数入口点了,而是call到ILT中对应的位置,而这个位置上什么也不做,直接jmp到函数中去。这样的好处是,当一个函数入口地址改变时,只要修改ILT中对应值就搞定了,用不着修改每一个调用位置,用一个冗余的ITL把时间复杂度从O(n)将为O(1),值得,当然Debug版的二进制文件会稍大稍慢,Release版不会用上ILT。

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明win32中 怎么样通过函数名 正确获取函数的地址
喜欢 (0)
[1034331897@qq.com]
分享 (0)