0

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)
    
5
  • 2
    What is your question, exactly? Oct 31, 2021 at 16:50
  • The question is of whether my interpretation of the original structure looks feasible and whether I ought to consider the order of the functions when re-creating the constructor? I.e. my first function is Constructor itself. Should it be there or the first position in the class should be occupied by vtable for example?
    – Irbis77
    Oct 31, 2021 at 17:07
  • Also, considering that the call to the constructor falls over, something in this representation is not right...
    – Irbis77
    Oct 31, 2021 at 17:16
  • 1
    This constructor (and constructors in general) does not tell you anything about the class member functions. It tells you about the class data items. If there were virtual functions, you would see the VTable being installed, from which you could learn about the virtual functions, but there are none in this case. So neither you, nor anybody else, can learn anything about the class member functions from this example, least of all the order in which they were defined in the original source code (though that knowledge is immaterial and won't help you with any reverse engineering-related endeavors). Oct 31, 2021 at 18:23
  • So, how do I go about creating a constructor for the reversed class. Above you can see the definition of that class (structure) Game, which I have created. Now I need a constructor for it. How to create one? GameConstructor is obviously the existing constructor, but I need one for my structure...?
    – Irbis77
    Nov 1, 2021 at 19:16

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.