GamerGuy 3 Report post Posted February 6, 2023 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 Quote Share this post Link to post Share on other sites
V3ct0r 2,117 Report post Posted February 6, 2023 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 } Quote Some useful links / Полезные ссылки Tips for making a topic in 'Questions & Help' / Рекомендации по созданию тем в разделе "Помощь" Server Advertising Section Rules / Правила раздела "Реклама серверов" Available e-mail domains for registration / Допустимые e-mail домены для регистрации User groups / Группы пользователей User ranks / Звания пользователей "Broken" pictures on the forum / "Битые" изображения на форуме Beware of scammers! / Осторожно, мошенники! My developments / Мои разработки Mods for client and server / Моды для клиента и сервера PKOdev.NET website for Tales of Pirates Server / PKOdev.NET веб-обвязка для сервера Пиратии I do not provide any help in private messages and outside the forum. Use 'Questions & Help' section please. Thank you for understanding! Я не оказываю какую-либо помощь в личных сообщениях и вне форума. Пожалуйста, используйте раздел "Пиратия: Помощь". Благодарю за понимание! Share this post Link to post Share on other sites
GamerGuy 3 Report post Posted February 6, 2023 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) Quote Share this post Link to post Share on other sites
GamerGuy 3 Report post Posted February 6, 2023 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 1 Quote Share this post Link to post Share on other sites
V3ct0r 2,117 Report post Posted February 6, 2023 @GamerGuy, Exactly! Quote Some useful links / Полезные ссылки Tips for making a topic in 'Questions & Help' / Рекомендации по созданию тем в разделе "Помощь" Server Advertising Section Rules / Правила раздела "Реклама серверов" Available e-mail domains for registration / Допустимые e-mail домены для регистрации User groups / Группы пользователей User ranks / Звания пользователей "Broken" pictures on the forum / "Битые" изображения на форуме Beware of scammers! / Осторожно, мошенники! My developments / Мои разработки Mods for client and server / Моды для клиента и сервера PKOdev.NET website for Tales of Pirates Server / PKOdev.NET веб-обвязка для сервера Пиратии I do not provide any help in private messages and outside the forum. Use 'Questions & Help' section please. Thank you for understanding! Я не оказываю какую-либо помощь в личных сообщениях и вне форума. Пожалуйста, используйте раздел "Пиратия: Помощь". Благодарю за понимание! Share this post Link to post Share on other sites