如何阅读这个反编译语句?

How to read this decompiled statement?

当我反编译一个函数时,我得到了以下代码

((void(__thiscall**)(int))(*v4 + 4))(v4);

*v4 在这个上下文中是一个虚拟的 table。实在拆不开(谁先解决,具体意思)。

恳请您帮助我逐步解决此问题,以便我了解其工作原理。

((void(__thiscall**)(int))(*v4 + 4))(v4);
                            ^^ pointer
                           ^^^ dereference it
                           ^^^^^^^ add 4
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cast to void (__thiscall**)(int)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Call with v4 as the parameter

void (__thiscall**)(int)是一个指向函数的指针,它有一个int参数。

据推测:

  • v4是一个对象的地址。
  • *v4 从对象中读取 vtable 指针。
  • *v4 + 4就是我们要调用的函数指针所在的虚表中的槽位。它是指向该函数指针的指针。
  • 第一个参数是this

请注意,我们调用的是指向函数指针的指针。函数指针在 C(++) 中自动取消引用,但我不知道这也适用于指向函数指针的指针。显然,确实如此。

(
    (   // these parens around the type declaration are a cast
        void (__thiscall**)(int) // this type declaration:
                                 // a pointer to pointer to function taking int parameter
    )
    (*v4 + 4) // this is a pointer expression
              // this pointer is being cast to a function
) // this is a function pointer
( // these paren's invoke the function
    v4     // this is the parameter being passed to the function 
);

唯一奇怪的是,作为参数传递的 v4 不是转换所说的 int — 它是一个指针。

看起来v4是一个对象,vtable是对象的第一个成员,所以*v4指的是vtable。 *v4+4 指的是第 5 个 vtable 条目。

此语句使用了一些来自 Microsoft 的奇怪的调用约定规范,但它基本上只是一个强制转换,然后是一个调用。

(void(**)(int))这个类型是一个指针,指向一个以int为参数的函数的指针,返回void。

__thiscall 是 Microsoft 编译器仅支持的调用约定说明符,如您所见 here

(*v4 + 4)这部分只是解引用v4,然后加上4,所以我猜*v4是一个指针,v4的类型类似于void **

总结一下,这条语句取消引用 v4,将这个值加 4,将这个新指针转换为指向函数指针的指针,然后通过传递 v4 来调用它。

正如其他人所指出的,v4 作为 int 传递很奇怪。然而,由于架构似乎是 x86,这应该不会破坏任何东西,因为 int 和指针应该具有相同的 32 位大小。