C++ 如何浏览vtable的方法?

C++ 如何浏览vtable的方法?,c++,visual-studio,C++,Visual Studio,我有一个大学作业,要求我访问一个班级的vtable。我需要在这里编写一个名为pb的函数,它将指向对象的指针作为参数和整数,然后只打印类的方法的输出。我已经设法访问了第一个函数,但我不知道如何访问第二个函数。以下是我目前掌握的代码: typedef int(*firstFun)(); typedef int(*secondFun)(int); class B { public: virtual int __cdecl first() = 0; virtual int __cdec

我有一个大学作业,要求我访问一个班级的vtable。我需要在这里编写一个名为pb的函数,它将指向对象的指针作为参数和整数,然后只打印类的方法的输出。我已经设法访问了第一个函数,但我不知道如何访问第二个函数。以下是我目前掌握的代码:

typedef int(*firstFun)();
typedef int(*secondFun)(int);

class B {
public:
    virtual int __cdecl first() = 0;
    virtual int __cdecl second(int) = 0;
};

class D : public B {
public:
    virtual int __cdecl first() { return 42; }
    virtual int __cdecl second(int x) {
        return first() + x; }
};

void pb(B* object, int x) {
    unsigned int adressVTable = *(unsigned int*)object;
    unsigned int adressVTable2; //yet unknown
    firstFun bFirst = (firstFun)(*(unsigned int*)(adressVTable));
    secondFun bSecond = (secondFun)(*(unsigned int*)(int)(adressVTable2));
    int f=bFirst();
    int s=bSecond(x);
    printf("First: %d, second: %d", f, s);
}

总之,如何让bSecond为secondint工作,就像bFirst为first工作一样?

vTable只是一个函数指针数组,所以只是一个指针数组。如果目标进程是x86,那么只需将0x4添加到第一个指针的地址,就可以在vtable中获得第二个指针。如果目标进程是x64,则添加0x8,因为这是该体系结构上指针的大小

其次,您将这些定义为cdecl函数,它不会按照您的计划工作。虚拟函数/成员函数是_thiscall,它要求在ECX中传递this指针。因此,您需要正确地键入定义函数指针,并将thisptr作为第一个参数传递

测试工作:

typedef int_uthiscall*firstFunvoid*thisptr; typedef int_uthiscall*secondFunvoid*thisptr,int; B类 { 公众: 虚拟int first=0; 虚拟整数secondint=0; }; D类:公共B类 { 公众: 虚拟整数第一个{return 42;} 虚拟整数秒整数x { 先返回+x; } }; 无效pbB*对象,int x { unsigned int addressable=*unsigned int*对象; 无符号整数地址表2=地址表+0x4; firstFun bFirst=firstFun*无符号整数*可寻址; secondFun BSSecond=secondFun*无符号整数*地址表2; int f=bFirstobject; int s=bSecondobject,x; 打印头:%d,第二个:%d,f,s; } int main { D obj; pb&obj,5; getchar; 返回0; }
提示?:提示:在成员函数中,您可以使用this关键字。我试过了,但没有成功。我在L1Z5_ooup.exe中得到一个异常:在0x00000000抛出异常:0xC0000005:当我添加0x8时,访问冲突执行位置0x00000000。当我添加0x4时,我得到了一个读访问冲突。@F.Kukec这是因为它们不是cdecl函数,它们是uuu thiscall函数,您必须将它们定义为u thiscall,并将thisptr作为第一个参数传递。我喜欢将vtable视为一个结构,而不是数组。您从未遍历vtable。