"using VirtualFn1_t = void(__thiscall*)(void* thisptr);" 在 C++ 中是什么意思?
What does "using VirtualFn1_t = void(__thiscall*)(void* thisptr);" means in c++?
我在阅读源代码时试图理解挂钩对于虚函数方法 table 从维基百科挂钩我遇到了这条线。
using VirtualFn1_t = void(__thiscall*)(void* thisptr);
我不知道它是什么意思。是否将 void 指针转换为调用约定并将其重新转换为 void 指针并将其用作 VirtualFn1_t 别名。我也想了解 void (__thiscall*)(void* thisptr)
和 (__thiscall*)(void* thisptr)
是什么意思。
这是来自维基百科的完整资源。
#include <iostream>
#include "windows.h"
using namespace std;
class VirtualClass
{
public:
int number;
virtual void VirtualFn1() //This is the virtual function that will be hooked.
{
cout << "VirtualFn1 called " << number++ << "\n\n";
}
};
using VirtualFn1_t = void(__thiscall*)(void* thisptr);
VirtualFn1_t orig_VirtualFn1;
void __fastcall hkVirtualFn1(void* thisptr, int edx) //This is our hook function which we will cause the program to call instead of the original VirtualFn1 function after hooking is done.
{
cout << "Hook function called" << "\n";
orig_VirtualFn1(thisptr); //Call the original function.
}
int main()
{
VirtualClass* myClass = new VirtualClass(); //Create a pointer to a dynamically allocated instance of VirtualClass.
void** vTablePtr = *reinterpret_cast<void***>(myClass); //Find the address that points to the base of VirtualClass' VMT (which then points to VirtualFn1) and store it in vTablePtr.
DWORD oldProtection;
VirtualProtect(vTablePtr, 4, PAGE_EXECUTE_READWRITE, &oldProtection); //Removes page protection at the start of the VMT so we can overwrite its first pointer.
orig_VirtualFn1 = reinterpret_cast<VirtualFn1_t>(*vTablePtr); //Stores the pointer to VirtualFn1 from the VMT in a global variable so that it can be accessed again later after its entry in the VMT has been
//overwritten with our hook function.
*vTablePtr = &hkVirtualFn1; //Overwrite the pointer to VirtualFn1 within the virtual table to a pointer to our hook function (hkVirtualFn1).
VirtualProtect(vTablePtr, 4, oldProtection, 0); //Restore old page protection.
myClass->VirtualFn1(); //Call the virtual function from our class instance. Because it is now hooked, this will actually call our hook function (hkVirtualFn1).
myClass->VirtualFn1();
myClass->VirtualFn1();
delete myClass;
return 0;
}
VirtualFn1_t
被定义为以下类型的别名:指向采用 void*
参数、返回 void
并使用 __thiscall
调用约定的函数的指针。
自 C++11 起,using
是创建类型别名的新方法。它与 typedef
.
相似(但更灵活)
本题中的using
语句:
using VirtualFn1_t = void(__thiscall*)(void* thisptr);
等同于 typedef
:
typedef void (__thiscall *VirtualFn1_t)(void* thisptr);
这两个语句都将 VirtualFn1_t
定义为一种新类型,它是一个 指针 指向一个函数:
- 接受一个
void*
作为输入参数
- 使用
__thiscall
调用约定
- returns一个
void
.
orig_VirtualFn1
被声明为 VirtualFn1_t
类型的变量(因此 orig_VirtualFn1
是一个指针),并指向原始 VirtualClass::VirtualFn1()
的内存地址方法在运行时,在 VirtualClass
class 的 vtable(虚方法 table)被修改之前,使 VirtualFn1()
的插槽指向 hkVirtualFn1()
钩子函数代替。
我在阅读源代码时试图理解挂钩对于虚函数方法 table 从维基百科挂钩我遇到了这条线。
using VirtualFn1_t = void(__thiscall*)(void* thisptr);
我不知道它是什么意思。是否将 void 指针转换为调用约定并将其重新转换为 void 指针并将其用作 VirtualFn1_t 别名。我也想了解 void (__thiscall*)(void* thisptr)
和 (__thiscall*)(void* thisptr)
是什么意思。
这是来自维基百科的完整资源。
#include <iostream>
#include "windows.h"
using namespace std;
class VirtualClass
{
public:
int number;
virtual void VirtualFn1() //This is the virtual function that will be hooked.
{
cout << "VirtualFn1 called " << number++ << "\n\n";
}
};
using VirtualFn1_t = void(__thiscall*)(void* thisptr);
VirtualFn1_t orig_VirtualFn1;
void __fastcall hkVirtualFn1(void* thisptr, int edx) //This is our hook function which we will cause the program to call instead of the original VirtualFn1 function after hooking is done.
{
cout << "Hook function called" << "\n";
orig_VirtualFn1(thisptr); //Call the original function.
}
int main()
{
VirtualClass* myClass = new VirtualClass(); //Create a pointer to a dynamically allocated instance of VirtualClass.
void** vTablePtr = *reinterpret_cast<void***>(myClass); //Find the address that points to the base of VirtualClass' VMT (which then points to VirtualFn1) and store it in vTablePtr.
DWORD oldProtection;
VirtualProtect(vTablePtr, 4, PAGE_EXECUTE_READWRITE, &oldProtection); //Removes page protection at the start of the VMT so we can overwrite its first pointer.
orig_VirtualFn1 = reinterpret_cast<VirtualFn1_t>(*vTablePtr); //Stores the pointer to VirtualFn1 from the VMT in a global variable so that it can be accessed again later after its entry in the VMT has been
//overwritten with our hook function.
*vTablePtr = &hkVirtualFn1; //Overwrite the pointer to VirtualFn1 within the virtual table to a pointer to our hook function (hkVirtualFn1).
VirtualProtect(vTablePtr, 4, oldProtection, 0); //Restore old page protection.
myClass->VirtualFn1(); //Call the virtual function from our class instance. Because it is now hooked, this will actually call our hook function (hkVirtualFn1).
myClass->VirtualFn1();
myClass->VirtualFn1();
delete myClass;
return 0;
}
VirtualFn1_t
被定义为以下类型的别名:指向采用 void*
参数、返回 void
并使用 __thiscall
调用约定的函数的指针。
自 C++11 起,using
是创建类型别名的新方法。它与 typedef
.
本题中的using
语句:
using VirtualFn1_t = void(__thiscall*)(void* thisptr);
等同于 typedef
:
typedef void (__thiscall *VirtualFn1_t)(void* thisptr);
这两个语句都将 VirtualFn1_t
定义为一种新类型,它是一个 指针 指向一个函数:
- 接受一个
void*
作为输入参数 - 使用
__thiscall
调用约定 - returns一个
void
.
orig_VirtualFn1
被声明为 VirtualFn1_t
类型的变量(因此 orig_VirtualFn1
是一个指针),并指向原始 VirtualClass::VirtualFn1()
的内存地址方法在运行时,在 VirtualClass
class 的 vtable(虚方法 table)被修改之前,使 VirtualFn1()
的插槽指向 hkVirtualFn1()
钩子函数代替。