Jump to content
GamerGuy

Modloader GUI classes/structs missing

Recommended Posts

I found @V3ct0r's pkodev modloader quite a while back and had no idea what I was doing at the time but after some playing around and creating a few "test" mods, I absolutely think this is the best thing to happen to precompiled ToP binaries in forever, however I started a new project fixing and adding new forms ingame when I hit a roadblock.

While most of the classes used in ToP are easily found with Ida I could not find CTextButton and a few others at all only the address for their procedures, I would think the class would've been recoverable as a struct that I could recreate and have functions get called when it's clicked et cetera.

 

Would I just need to recreate the class from source?(but then with vtables?) I'm a bit lost at the moment and any help is appreciated!

///
	gui::CForm* frmTest = gui::CUIInterface::Instance().FindForm("frmTest");
    if (frmTest != nullptr) {
        CTextButton* btnTest = frmTest->Find<CTextButton>("btnTest");
        if (btnTest != nullptr) {
          btnTest.evtMouseClick = ClickTestButton;
        }
    }
///

void ClickTestButton(CGuiData* sender,int x, int y, MouseClickState key){
//Do whatever
}



I suppose this question is more pointed to @V3ct0r but I'm happy for a response from anyone with the knowledge

Share this post


Link to post
Share on other sites

Hello @GamerGuy,

 

You should write address of ClickTestButton() function into btnTest + 0x94 address.

 

For example:

class CTextButton {
public:
	typedef void(__cdecl* OnMouseClickHandler__Ptr)(CTextButton*, int, int, unsigned int);
	
	CTextButton() = delete;
	~CTextButton() = default;
	inline void OnMouseClick(OnMouseClickHandler__Ptr handler) { m_evtMouseClick = handler; }
private:
	char m_nop[0x94];
	OnMouseClickHandler__Ptr m_evtMouseClick;
};

and:

CTextButton* btnTest = frmTest->Find<CTextButton>("btnTest");
if (btnTest != nullptr) {
	btnTest->OnMouseClick(&ClickTestButton);
}

 

or another way:

void ClickTestButton(void* sender, int x, int y, unsigned int key);


void* btnTest = frmTest->Find<void>("btnTest");
if (btnTest != nullptr) {
	*reinterpret_cast<unsigned int*>(reinterpret_cast<unsigned int>(btnTest) + 0x94) = reinterpret_cast<unsigned int>(&ClickTestButton);
}


void ClickTestButton(void* sender, int x, int y, unsigned int key) {
    //Do whatever
}

 


Share this post


Link to post
Share on other sites
2 hours ago, V3ct0r said:

Hello @GamerGuy,

 

You should write address of ClickTestButton() function into btnTest + 0x94 address.

 

For example:


class CTextButton {
public:
	typedef void(__cdecl* OnMouseClickHandler__Ptr)(CTextButton*, int, int, unsigned int);
	
	CTextButton() = delete;
	~CTextButton() = default;
	inline void OnMouseClick(OnMouseClickHandler__Ptr handler) { m_evtMouseClick = handler; }
private:
	char m_nop[0x94];
	OnMouseClickHandler__Ptr m_evtMouseClick;
};

and:


CTextButton* btnTest = frmTest->Find<CTextButton>("btnTest");
if (btnTest != nullptr) {
	btnTest->OnMouseClick(&ClickTestButton);
}

 

or another way:


void ClickTestButton(void* sender, int x, int y, unsigned int key);


void* btnTest = frmTest->Find<void>("btnTest");
if (btnTest != nullptr) {
	*reinterpret_cast<unsigned int*>(reinterpret_cast<unsigned int>(btnTest) + 0x94) = reinterpret_cast<unsigned int>(&ClickTestButton);
}


void ClickTestButton(void* sender, int x, int y, unsigned int key) {
    //Do whatever
}

 

Thanks alot for the fast reply! 

May I ask how you came upon this address?
I've been using ida for looking for the addresses but I can't seem to find it

(I am mostly a noob with reverse engineering tho)

Share this post


Link to post
Share on other sites

Aha! I think I might have found out myself!

So I started looking for a place that sets the function to call inside the binary and came across this

loc_46FAB2:
mov     dword ptr [eax+94h], offset loc_46F770 //eax must be the offset for the CTextButton object and thus eax + 0x94 must be the offset for function
mov     this, [esi+4]
mov     eax, [this]
push    offset aBtnlefthair ; "btnLeftHair"
call    dword ptr [eax+48h]
test    eax, eax
jnz     short loc_46FB01

I'm thinking this is right but otherwise feel free to correct me

  • Thanks 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...