C++虚函数:虚指针、虚表、虚函数入口地址
2015-04-17 20:39
351 查看
测试程序:
//test.c
#include"stdio.h" #include"string.h" class GSVirtual { public: void gsv(char *src) { char buf[200]; strcpy(buf,src); vir2(); } virtual void vir1() { printf("vir1"); } virtual void vir2() { printf("vir2"); } }; int main(int argc,char *argv[]) { GSVirtual test; test.gsv(argv[1]); return 0; }在linux下编译:
$g++ -o vtabletest ./vtabletest.c
在ida下查看vtabletest的反汇编,找到关键函数点 gsv(char *src):
该函数中调用了虚函数vir2(),虽然gsv显示只有一个参数,但是实际上默认还有另一个参数:虚指针,查看调用gsv时,参数入栈可发现,有两个参数入栈:
然后,我们回到gsv函数中,其中首先分配了当前栈帧空间:
.text:08048538 55 push ebp
.text:08048539 89 E5 mov ebp, esp
.text:0804853B 81 EC F8 00 00 00 sub esp, 0F8h
然后,将第一个参数复制到当前栈帧中:注意这个参数就是虚指针的地址(一般在上一个函数的栈帧中)
.text:08048541 8B 45 08 mov eax, [ebp+arg_0] //arg0=8
.text:08048544 89 85 24 FF FF FF mov [ebp+var_DC], eax //var_DC=-0XDC
后面,函数会分配函数的局部变量的栈帧中的位置,然后执行strcpy(buf,src)
然后调用虚函数vir2(),我们主要来分析这一段代码:
.text:08048576 8B 85 24 FF FF FF mov eax, [ebp+var_DC] //将虚指针地址赋值给eax
.text:0804857C 8B 00 mov eax, [eax] //提取虚指针内存地址中的虚表入口地址,一般在.rodata中
.text:0804857E 83 C0 04 add eax, 4 //由于调用的是vir2(),因此,该虚函数地址在虚表中的位置偏移4*1 bytes
.text:08048581 8B 10 mov edx, [eax] //提取vir2()虚函数的入口地址
.text:08048583 8B 85 24 FF FF FF mov eax, [ebp+var_DC]
.text:08048589 89 04 24 mov [esp], eax //虚指针继续入栈,可视为为下一个函数调用的参数
.text:0804858C FF D2 call edx //调用vir2()
在linux中,用gdb调试:
在0x8048576处下断点后,查看相关内存信息:
可对照ida下的汇编代码看,ebp+8和ebp-0xdc 存储的都是虚指针地址0xbffff2dc 在上一个函数的栈帧中
虚指针指向地址0x80486c8,即虚表地址
虚表中按顺序存储了每个虚函数的入口地址。
0x80485a2 和0x80485b6分别就是虚函数vir1()和vir2()的地址:
最后,测试程序存在缓冲区溢出漏洞,在gs保护下,则可通过覆盖虚表指针来劫持控制流。
相关文章推荐
- C++ 虚函数实现:虚函数表 虚表指针
- C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址
- C++ 虚函数 获取C++虚表地址和虚函数地址
- [C++] 虚指针,虚表,虚函数地址打印
- C++ 多重继承 计算虚表指针及虚函数地址
- c++多态性之虚函数与虚表指针
- C/C++ 函数名 指针,地址 全析
- C++中虚函数、虚表、虚指针实例讲解
- 浅谈C++虚表指针及虚函数表
- x86代码移植到x64下,如何访问虚表和虚函数指针,使用地址调用虚函数
- C++中动多态实现之虚函数与虚表指针
- 获取C++虚表地址和虚函数地址
- C++封装、继承、多态(虚函数、虚指针、虚表)
- (Boolan) C++ 类型大小和内存分布(虚函数指针、虚表、内存对齐问题)
- 虚函数的入口地址和普通函数有什么不同
- c++ 函数入口地址问题
- C/C++ 函数指针、虚函数、纯虚函数
- 虚函数地址C++虚函数的一点分析与思考
- C++ 从函数返回指针(函数外返回局部静态变量的地址)
- Q13.3 关于虚表指针、虚函数表、虚函数表中虚函数地址