I have the following constructor decompiled by Ghidra, i.e. Game. I know some of the functions, which are part of that constructor. And thus I have created my interpretation of that structure. But I don't know in what exact order those functions were there originally.
So, is my interpretation correct or / and there should be a different approach to disassembling structures like this?
Decompiled Game constructor / class:
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;
}
My version, game.h:
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;
DWORD_PTR* guiObjPtr = 0;
DWORD_PTR* unknownPtrA = 0;
DWORD_PTR* unknownPtrB = 0;
DWORD_PTR* unknownPtrC = 0;
DWORD_PTR* unknownPtrD = 0;
DWORD_PTR* unknownPtrE = 0;
DWORD_PTR* unknownPtrF = 0;
};
The game.cpp looks like this:
#include "game.h"
namespace gladius {
static std::array<Game, 1> functions = { {
// Steam
Game{
(Game::GameConstructor)(AddressHelper::getInstance().GetBaseAddress() + 0x331b0 / (2 * sizeof(DWORD))),
// (Game::GameMain)0x140039ea0,
(Game::GameMain)(AddressHelper::getInstance().GetBaseAddress() + 0x39EA0 / (2 * sizeof(DWORD))),
//(Game::Initialize)0x140033e20,
(Game::Initialize)(AddressHelper::getInstance().GetBaseAddress() + 0x33E20 / (2 * sizeof(DWORD))),
//(Game::Quit)0x14003a0e0
(Game::Quit)(AddressHelper::getInstance().GetBaseAddress() + 0x3A0E0 / (2 * sizeof(DWORD)))
}
} };
Game& get()
{
return functions[0];
}
}
As per discussion in comments, how to change the above game.h and game.cpp files to make a proper constructor for my Game structure?
The way I do it now is:
gladius::Game gameObj;
gladius::Game::Game(gameObj);
And the element of that object can be accessed this way: gameObj.guiObjPtr
But apparently gladius::Game* thisptr1 = &gameObj;
is not equivalent to gladius::Game* thisptr, which is passed to the hooked function.
I.e. thisptr
is initialised properly with all of the addresses and thisptr1 is not accepted by the member functions.
And that is strange considering that the way the hooked function is called is simply this:
Game local_68 [96];
gladius::Game::Game(local_68);
iVar1 = gladius::Game::main(local_68,param_1,param_2,param_3);
Where local_68
is essentially the new gameObj
. It is passed to main as a pointer somehow and that part I don't understand.
And the way how the hooked function signature looks like this:
__int64 __fastcall gamemainHooked(gladius::Game* thisptr, int param_1, char** param_2, char** param_3)