0

I have bits of code which decompiles a small part of the existing program. I have added it to the proxy dll. The code to the existing functions is hooked through Detour and looks like below (gui.h and gui.cpp)

But now how do I call my own implementation of the gamemain function? Can someone may be point me to an existing post(s) where calling proxy dll replaced functions is described in detail.

Or / And if you don't mind spending time looking at the code below, I would appreciate the tips on how to make it work in the similar structure to the one I am using or may be there is another solution I should be considering.

Note, I do know the address for the gamemain function in the original exe.

gui.h

#pragma once
#include "world.h"

namespace gladius {

    namespace gui {
    
        
        //struct gladius::world::World* __fastcall getworld();
        struct GUI {
            //gladius::world::World* __fastcall gladius::gui::GUI::getWorld(gladius::gui::GUI* thisptr);
            using GetWorld = gladius::world::World* (__fastcall*) (GUI* thisptr);
            GetWorld getWorld;
        };


        GUI& get();
    } //namespace gui
}

gui.cpp

#include "world.h"
#include "gui.h"
#include <array>


namespace gladius {

    namespace gui {

        static std::array<GUI, 1> functions = { {

                // Steam
                    GUI{
                            (GUI::GetWorld)0x140b81074,
                         },
                } };


        GUI& get()
        {
            return functions[0];
        }
    }
}

This works. But now I want to change another function and replace it with my implementation. I.e. the function looks like this:

game.h

#pragma once

#include "world.h"
#include "game.h"
#include "gui.h"

namespace gladius {
    
    
    struct Game {
        //virtual int __thiscall main(gladius::Game* thisptr, int param_1, char** param_2, char** param_3);
        int __thiscall gladius::Game::gamemain(gladius::Game* thisptr, int param_1, char** param_2, char** param_3)
        {

            gladius::gui::GUI guiInst;
            gladius::world::World worldInst;

            gladius::Game::initialize(this, param_1, param_2, param_3);
            // proxy::gui::GUI::run(*(GUI**)(this + 0x28));
            //worldInst = gladius::gui::GUI::getWorld(*(gladius::gui::GUI**)(this + 0x88));

            gladius::world::World::CreateWorld(*(gladius::world::World**)(*(long long *)(this + 0x5e8) + 0x50));
            gladius::Game::quit(this);
            return 0;
        }
        void __fastcall gladius::Game::initialize(gladius::Game* thisptr, int a2, char** a3, char** a4);
        void __fastcall gladius::Game::quit(gladius::Game* thisptr);
    };


}
3
  • what is the issue you are facing with getting it to execute your own gamemain? if you have hooked the original function. the flow would then be original gamemain -> your gamemain -> whereever you want it to go next , so your gamemain function should be called in that way.
    – Niraeth
    Sep 15 at 3:39
  • also, for your second question, if I get what you are asking, then I think you will want to look at vtable hooking. instead of detouring each function one-by-one, you could alternatively replace the vtable pointer, or the entire vtable with your own. this way your just changing the pointed address, and you don't need to hook a function.
    – Niraeth
    Sep 15 at 3:40
  • Well, the problem with the hook was the exact syntax as it is first time I am doing this. I've figured it out now. Will add to the answer. The problem with vtable pointing is that ideally I would like an example of how it is done. I can figure it out I guess, but it would be more straight forward to see of how it is done in clear example...
    – Irbis77
    Sep 15 at 8:35
0

In regards to the discussion above in the Comments section. As I've mentioned, I have figured out the hooking part, even though it is not fully working yet with the main application.

Here is the solution:

game.cpp

#include "game.h"
#include <array>


namespace gladius {

        static std::array<Game, 1> functions = { {

                // Steam
                    Game{
                            (Game::GameMain)0x140039ea0,
                            (Game::Initialize)0x140033e20,
                            (Game::Quit)0x14003a0e0
                         },

                } };


        Game& get()
        {
            return functions[0];
        }
}

hooks.cpp

#include "hooks.h"
#include "game.h"

namespace hooks {

    Hooks getHooks()
    {
        Hooks hooks{
            HookInfo{(void**)&gladius::get().gamemain, gamemainHooked}, 
        };
        return hooks;
    }

    Hooks getVftableHooks()
    {
        Hooks hooks;
        return hooks;
    }

    int __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::world::World::CreateWorld(*(gladius::world::World**)(*(long long*)(thisptr + 0x5e8) + 0x50));
        gladius::get().quit(thisptr);

        return gladius::get().gamemain(thisptr, param_1, param_2, param_3);
    }

hooks.h

#pragma once

#ifndef HOOKS_H
#define HOOKS_H

#include <string>
#include <utility>
#include <vector>
#include "game.h"


namespace hooks {

    using HookInfo = std::pair<void**, void*>;
    using Hooks = std::vector<HookInfo>;

    /** Returns array of hooks to setup. */
    Hooks getHooks();
    Hooks getVftableHooks();

    int __fastcall gamemainHooked(gladius::Game* thisptr, int param_1, char** param_2, char** param_3);

} // namespace hooks

#endif // HOOKS_H

The problem I found with this kind of work, there is a very scarce set of information and examples on the topic.

I will probably endeavour on writing wiki page with the examples and explanations on how it is done, once I am convinced that this is working.

Because for me personally it would be so much easier if there are simple and comprehensive examples on how it can be done.

The same goes to vtable pointers. I mean, may be it is just me, but is there some source, where I can check different a simple examples of how exactly it is done for the complex programs, not for "Hello World!" apps? Because the later ones tend to reverse the entire code and what I need is a mixture of the reversed and original code working together...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.