如何阅读这个反编译语句?
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 位大小。
当我反编译一个函数时,我得到了以下代码
((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 位大小。