再谈VTable

    最近十分颓废,为了改变这种状态,建议自己再一次去看基础。

    还是多态中late_binding技术。大家都知道,编译器对virtual function的处理方式是通过vtable完成的。但我今天突然想知道 是否每个对象都要维护一张单独的vtable 还是共享使用同一个vtable呢?为次 写了一些测试代码:

#include "stdafx.h"
#include <iostream>
using namespace std;

class Base
{
public:
	Base(){m_base = 10;};
	~Base(){};

	virtual void test(){ cout << " this is Base::test() " << endl; };
	virtual void test_1(){ cout << " this is Base::test_1() " << endl; };
private:
	int m_base;
};


class A : public Base
{
public:
	A(){ m_A = 20;};
	~A(){};
public:
	virtual void test(){ cout << " this is A::test() " << endl; };
	virtual void test_1(){ cout << " this is A::test_1() " << endl; };
private:
	int m_A;
};

class B : public A
{
public:
	B(){ m_B = 30; };
	~B(){};
public:
	virtual void test(){ cout << " this is B::test() " << endl; };
	virtual void test_1(){ cout << " this is B::test_1() " << endl; };;
private:
	int m_B;
};



int _tmain(int argc, _TCHAR* argv[])
{
	Base *pBase = new A();
	Base *pBase0 = new B();
	Base *pBase1 = new B();


	pBase->test();
	pBase0->test();
	pBase1->test();


	return 0;
}
    大家想必都已经知道了 对于含有virtual function的类  其对象的地址开始就是指向vtable的vptr 上例中的pBase pBase0 pBase1开始都是vptr的值。跟踪调试 在memory中(我的是32位机器) pBase开始四个字节的值: pBase地址:0x003D9F58  该地址处开始的四个字节:04 78 41 00(这四个字节就是vtable的地址)      pBase0=0x003d9fa0 该地址开始处的四个字节:20 78 41 00  pBase1=0x003d64f0 该地址开始处的四个字节:20 78 41 00

   可以发现什么?pBase0与pBase1 共享同一个vtable 因为二者是属于同一个类的两个对象 而pBase自己使用另外一个vtable 

   说明:每一个抽象类的派生都会维护自己的一个vtable(当然了) 这样的话 若类层次特别深 则其内存开销会非常大。


<think>好的,用户的问题是关于pwn中vtable利用技术,特别是在C++或二进制漏洞利用中的方法。我需要先回忆一下vtable的基本概念以及它在漏洞利用中的常见攻击方式。 首先,vtable是C++中虚函数表,每个包含虚函数的类都会有这样一个表,其中存储了指向各个虚函数的指针。当对象被创建时,会有一个指向该vtable的指针(vptr)存放在对象的内存布局中。攻击者如果能够篡改这个vptr,就可能控制程序执行流程,比如跳转到恶意代码。 接下来,常见的利用方法包括覆盖vptr指向攻击者控制的地址,从而执行任意代码。或者利用内存泄漏获取vtable地址,绕过ASLR。此外,虚函数调用时的索引越界也可能被利用,比如修改索引使其指向非预期的函数。 需要注意,不同编译器(如GCC和MSVC)在vtable布局上可能有差异,这会影响利用方式。缓解措施方面,地址空间布局随机化(ASLR)、控制流完整性(CFI)等技术会增加利用难度。 用户可能需要具体的例子,比如如何通过堆溢出修改vptr,或者如何构造fake vtable。此外,引用中的信息提到文件操作的函数指针,可能和IO相关的vtable利用有关,比如篡改FILE结构体中的函数指针,这属于更广泛的vtable利用范畴。 在回答时,应该分点说明技术原理、步骤、示例代码(如果有的话),以及相关的缓解措施。同时,确保使用正确的中文术语,并引用提供的参考资料中的例子,比如引用[1]中的函数指针结构,可以联系到IO vtable的利用。</think>### Pwn中vtable利用技术分析 #### 一、技术原理 虚函数表(vtable)是C++实现多态的核心数据结构,每个包含虚函数的类在内存中拥有对应的虚函数表。对象实例通过虚表指针(vptr)访问虚函数表。攻击者可通过以下漏洞进行利用: 1. **内存破坏漏洞**:堆溢出、UAF(Use-After-Free)等漏洞可篡改vptr 2. **类型混淆漏洞**:错误的对象类型转换导致虚函数调用异常 3. **虚函数表伪造**:构造虚假vtable控制程序流 #### 二、利用方法详解 1. **vptr覆盖攻击**(以堆溢出为例) - 步骤: (1) 通过堆溢出覆盖对象的vptr (2) 构造虚假vtable指向攻击者控制的内存 (3) 触发虚函数调用实现控制流劫持 - 示例内存布局: ``` | 对象数据区 | vptr(被覆盖) | 堆元数据 | ``` 2. **IO_FILE结构体利用** 标准I/O库的FILE结构体包含函数指针表(类似vtable),如引用[1]所示的: ```c struct _IO_jump_t { _IO_read_t __read; // 如: ssize_t (*)(FILE *, void *, ssize_t) _IO_write_t __write; // ...其他函数指针 }; ``` 通过伪造FILE结构体可劫持`fread`/`fwrite`等操作,常用于FSOP(File Stream Oriented Programming)攻击。 3. **类型混淆攻击** ```c++ class Base { virtual void func(); }; class Derived : public Base { int data; }; // 若将Derived对象强制转换为Base类后删除 Base* obj = new Derived; delete obj; // 可能产生未定义行为的内存布局 ``` #### 三、缓解措施 1. **地址随机化**:ASLR使vtable地址难以预测 2. **虚表保护**:编译器选项(如GCC的`-fvtable-verify`) 3. **内存保护**:DEP/NX防止执行堆栈中的代码 4. **控制流完整性**:CFI验证函数调用目标
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值