C++ 中的逆向工程虚拟函数代码
我刚刚在VS2010上编译了以下内容(优化关闭)。
class Shape {
public:
int x,y;
Shape() {
x=10;
y=20;
}
virtual void function1() {
cout<<"function1";
}
virtual void function2() {
cout<<"function2";
}
};
int main() {
Shape *s = new Shape();
s->function1();
s->function2();
return 0;
}
反汇编没有显示与虚拟函数相对应的代码块或对其的任何调用,因此我假设这是由于使用 vftable 查找虚拟函数的方式造成的。我使用的是 IDA Pro,因此它可能无法解决此类问题。如果我错了,请纠正我。
对此我也有一些疑问。
- 有什么方法可以在反汇编过程中像查看其他函数一样查看虚拟函数吗?我可以使用任何脚本(IDAPython)/方法吗?
- 有什么方法可以列出可执行文件中的所有虚拟函数吗?
- 建议阅读?
I just compiled the following on VS2010(with optimization turned off).
class Shape {
public:
int x,y;
Shape() {
x=10;
y=20;
}
virtual void function1() {
cout<<"function1";
}
virtual void function2() {
cout<<"function2";
}
};
int main() {
Shape *s = new Shape();
s->function1();
s->function2();
return 0;
}
The disassembly does not show the code blocks corresponding to the virtual functions or any calls to it, so Im assuming that it is because of the way virtual functions are looked up using the vftable. I'm using IDA Pro so it is probably not able to resolve such issues. Please correct me if I'm wrong.
I also have a few doubts in this regard.
- Is there any way I can view the virtual functions just as the other functions during disassembly? Any script(IDAPython)/method that I could use?
- Is there any way I can list all virtual functions in an executable?
- Suggested Reading?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
仅当对象的动态类型与其静态类型(指向派生类的基类指针)不同时,才会涉及虚拟调度。既然你甚至没有继承,也没有调用站点的确切类型,为什么要在 vtable 中进行查找呢?
Virtual dispatch is only involved when the dynamic type of an object is different from its static type (pointer-to-Base pointing to a derived class). Since you don't even have inheritance, and an exact type at the call site, why should it do the lookup in the vtable?
由于您已经在类定义中定义了虚拟函数,因此我认为编译器可能会内联您的函数,因为它知道调用站点的确切类型。尝试将函数体移出类体。那么它们肯定会出现在反汇编中。我怀疑他们现在可能被链接器彻底剥夺了。
Since you've defined your virtual functions inside the class definition, I think your functions might be being inlined by the compiler, as it knows the exact type at the call site. Try moving the function bodies out of the class body. They should definitely show up in disassembly then. I suspect they might be deadstripped by the linker at the moment.
正如其他人所指出的:您没有任何继承,因此编译器通过消除虚拟分派来变得聪明。
建议阅读:Stroustrup 的《C++ 的设计与演化》。它不会解决您的所有问题,但会为您提供一个框架来帮助您回答这些问题或更有效地研究他们的答案。
As others have noted: you don't have any inheritance, so the compiler is being smart by eliminating virtual dispatch.
Suggested reading: Stroustrup's The Design and Evolution of C++. It won't address all your questions, but give you a framework to help answer them or research their answer more effectively.
我没有你的编译器,这高度依赖于编译器和选项。使用 g++ 4.5,使用默认选项(并在修复代码中的一些问题之后),我已将代码编译成程序集(
g++ -S -o test.asm test.cpp
),并且它确实显示通过虚拟调度机制的函数和调用(在 main 中,调用构造函数后,它提取 vptr,对其进行偏移并通过寄存器中的值进行调用)。至于其他人所说的编译器可以完全省略虚拟调度或内联函数,那是真的。此版本的 g++ 不会针对该特定代码段执行此操作,而是通过删除指针(使用具有静态存储持续时间的
Shape
)I don't have your compiler, and this is highly dependent on the compiler and options. With g++ 4.5, with the default options (and after fixing a few issues in the code) I have compiled into assembly (
g++ -S -o test.asm test.cpp
) the code and it does show the functions and the calls through the virtual dispatch mechanism (inmain
after calling the constructor it extracts the vptr, offsets it and calls through the value in the register).As to what others have been saying that the compiler can elide the virtual dispatch completely or inline the function, that is true. This version of g++ doesn't do it for that particular piece of code, but by removing the pointer (using a
Shape
with static storage duration)