gpt4 book ai didi

c++ - 完全覆盖VMT(虚拟方法表)

转载 作者:搜寻专家 更新时间:2023-10-31 01:00:01 25 4
gpt4 key购买 nike

我通过取消引用在 vmt 上调用虚拟方法,直到我获得指向该方法的指针。

这一切都很好,但是我如何才能完全更改指向对象上 VM 表的指针?

示例:

PP A; // points to its default VM table

PP B; // points to a completely different VM table

A->MethodOne() // calls as mentioned above

B->MethodOne() // calls a completely different method since we override its pointer to the VM table to an alternate table with different method pointers

我将如何完成这个?

我的代码:

#include <Windows.h>
#include <iostream>

class PP
{
public:
PP() { }
~PP() { }

virtual void MethodOne() { std::cout << "1" << std::endl; }
virtual void MethodTwo() { std::cout << "2" << std::endl; }
};

typedef void (*MyFunc)(void);

int main()
{
PP* A = new PP();

//(*(void(**)(void))(*(DWORD*)A + (4*1)))();

( *(MyFunc*) ( *(DWORD*)A + (4*0) ) )(); // call index 0 (4bytes*0)
A->MethodOne();
A->MethodTwo();
system("PAUSE");
delete A;
return 0;
}

最佳答案

由于派生另一个类的常用方法对您不起作用,因此我可以想到三种解决方案。

  1. 改变虚表指针。这是不可移植的,并且有很多方法会出错。假设 vtable 位于类的开头(它用于 WinAPI 中的简单类),您可以将该指针替换为指向您自己的表的指针。

    *(void **)A = newVtable;

用适当的指向成员函数的指针定义了 newVtable。您必须格外小心才能进行设置。它还可能搞乱删除和异常处理。

  1. 创建您自己的虚拟表。定义一个具有所需的指向方法函数的指针的类,然后在您的类中定义一个指向其中之一的指针。然后您可以根据需要更改指向表的指针。虽然您可以定义其他成员函数来隐藏难看的代码,但这样调用会有点冗长。

    class vtable;

    class PP {
    public:
    PP();
    ~PP() { }

    void MethodOne() { std::cout << "1" << std::endl; }
    void MethodTwo() { std::cout << "2" << std::endl; }

    const vtable *pVtable;
    };

    class vtable {
    public:
    void (PP::*MethodOne)();
    };

    vtable One = {&PP::MethodOne};
    vtable Two = {&PP::MethodTwo};

    PP::PP(): pVtable(&One) { }

    void main() {
    PP* A = new PP();


    A->pVtable = &One;

    // call with
    (A->*(A->pVtable->MethodOne))(); // calls MethodOne

    A->pVtable = &Two;
    (A->*(A->pVtable->MethodOne))(); // calls MethodTwo
    }

(使用 VS2015 社区编译和测试)。这将是便携和安全的。

  1. 在类中定义方法指针,并单独更新它们。

关于c++ - 完全覆盖VMT(虚拟方法表),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32084324/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com