将尝试改写实际问题,因此希望它更具描述性并且更清楚我所追求的内容:
所以,有一个函数 main,我已经成功地钩住了。挂钩版本如下所示:
__int64 __fastcall gamemainHooked(gladius::Game* thisptr, int param_1, char** param_2, char** param_3)
{
gladius::get().initialize(thisptr, param_1, param_2, param_3);
gladius::gui::get().guiRun(*(GUI**)(thisptr + 0x28));
gladius::get().quit(thisptr);
return gladius::get().gamemain(thisptr, param_1, param_2, param_3);
}
现在,看到有一个 Game* thisptr,它被传递给该函数。
当函数运行时,它会填充 Game* thisptr 实例
thisptr->GameConstructor (0x0x00000271704c6ec0)
thisptr->gamemain (0x00000271788a94f0)
thisptr->initialize(0x000002716d523b90)
thisptr->quit(0x000002716fdebdd0)
原始 main 函数和钩子函数有一个名为 guiRun 的函数,它采用thisptr + 0x28偏移量,从下面的代码中可以看出它是构造函数(游戏)的第 5 个元素。
Game * __thiscall gladius::Game::Game(Game *this)
{
*(undefined8 *)this = 0;
*(undefined8 *)(this + 8) = 0;
*(undefined8 *)(this + 0x10) = 0;
*(undefined8 *)(this + 0x18) = 0;
*(undefined8 *)(this + 0x20) = 0;
*(undefined8 *)(this + 0x28) = 0;
*(undefined8 *)(this + 0x30) = 0;
*(undefined8 *)(this + 0x38) = 0;
*(undefined8 *)(this + 0x40) = 0;
*(undefined8 *)(this + 0x48) = 0;
*(undefined8 *)(this + 0x50) = 0;
return this;
}
现在,扭转这种情况的最佳方法是什么,以便我可以处理 Game 实例的第 5 个元素?代码应该是什么样子,以便使用thisptr+0x28调用 guiRun成功。
我应该用里面的所有指针完全反转构造函数然后指向它吗?
关键是调用guiRun (thisptr + 0x28)不起作用,因为thisptr + 0x28没有指向 Game* 实例的第 5 个元素......
当前反转的 Game 结构如下所示:
namespace gladius {
struct Game {
//virtual int __thiscall main(gladius::Game* thisptr, int param_1, char** param_2, char** param_3);
using GameConstructor = Game * (__fastcall*) (Game* thisptr);
GameConstructor gameConstructor;
using GameMain = __int64(__fastcall*) (gladius::Game* thisptr, int param_1, char** param_2, char** param_3);
GameMain gamemain;
using Initialize = void(__fastcall*) (gladius::Game* thisptr, int a2, char** a3, char** a4);
Initialize initialize;
using Quit = void(__fastcall*) (gladius::Game* thisptr);
Quit quit;
};
Game& get();
} /
PS 似乎 guiRun 想要接受 * thisptr而不是thisptr。但这意味着必须更改函数的原始签名。不确定这是否会导致挂钩无法正常工作。