Home > C++, Open Source, Programming, ROSE Online, Reverse Engineering > TGameCtrl_r.lib, doing the impossible :D

TGameCtrl_r.lib, doing the impossible :D

June 11th, 2009

After my lovely TriggerVFS.lib I decided to move onto something a bit more complex, making a lib for TGameCtrl_r.dll, which is probably over 9000% more complex as it uses full classes, multiple inheritance and virtual functions. Making a lib for that would be madness surely!

Yes it is madness, but I actually got it to work. I still can’t believe it even works to be honest as it is completely reliant on Visual C++ compiling my lib (with all its inheritance and virtual functions) to be identical to the ROSE dll. Which is ridiculous, yet worked.

Most likely you will not understand how ridiculous it is that this works unless you have a good knowledge of C++ and how those aforementioned features compile into assembly.

What does this mean then? This means it is piss easy to create a custom dialog for ROSE Online, simple link to my library and include required header files such as #include ‘TDialog.H’ or ‘WinCtrl.h’ or w/e you want :) .

Custom dialogs are now as easy as this:

class TestDialog : public CTDialog {
public:
	TestDialog(){}
	virtual ~TestDialog(){}
};

void AddTestDialog(){
	TestDialog* testDlg = new TestDialog();
	testDlg->Create("dlgAchievements");
	AddDialog(1339, testDlg, testDlg->GetControlID());
	testDlg->Show();
}

How simple eh? It is as if we actually have the real code to TGameCtrl, this is how it would be used in ROSE, with the simple inheritance, all the virtual functions working properly and everything :D .

Pretty awesome :) .

It is not yet ready for release as I have many more classes to reverse from TGameCtrl_r.dll, below is a list of what I have done so far after many hours of reverse engineering. It may look light a random assortment of classes but it is basically every class which CTDialog depends on, other than the scroll bar related ones, I began implementing them now so I can implement the ZListBox class so I can fully recreate my achievements dialog with my new code.


Directory of C:\Programming\Libraries\TGameCtrl\TGameCtrl

221 ActionListenerList.h
161 IActionListener.h
115 IScrollModel.cpp
495 IScrollModel.h
79 ITControl.cpp
340 ITControl.h
134 ITDraw.h
319 SinglelineString.h
886 TButton.cpp
1,300 TButton.h
677 TCaption.cpp
886 TCaption.h
171 TCommand.h
217 TCommandQ.h
2,281 TDialog.cpp
2,582 TDialog.h
345 TGameCtrl.h
5,878 TGameCtrl.vcproj
593 TImage.cpp
923 TImage.h
131 TObject.cpp
256 TObject.h
1,012 TScrollBar.cpp
1,289 TScrollBar.h
190 TScrollBarType.h
704 TScrollBox.cpp
974 TScrollBox.h
251 TStatusBar.cpp
411 TStatusBar.h
2,156 WinCtrl.cpp
2,892 WinCtrl.h
33 File(s) 28,869 bytes

Sorry if you guys are not as excited as I am but I thought this was totally awesome, it might not seem as awesome if you do not know how C++ works and how it compiles into ASM.

Expect a release soon.

admin C++, Open Source, Programming, ROSE Online, Reverse Engineering

  1. June 11th, 2009 at 12:51 | #1

    HELLS YEAH!!!!
    >.<
    Lol I can’t wait to read this code and/or Tutorial. :D

  2. June 11th, 2009 at 12:51 | #2

    Thanks, this shit is insane though, so much better than anyway done before xD

  3. bret pit
    June 11th, 2009 at 18:43 | #3

    <3 c++ libs :P

  4. Bapao
    June 12th, 2009 at 16:58 | #4

    The stuff is so cool. I attempted to do this way back but my reversing was too sucky, and Brett just laughed at me for even attempting to do something like this. Maybe he told you about the idea?

  5. Bapao
    June 12th, 2009 at 17:02 | #5

    Sorry for the double post, but did you use the 2003 compiler for function decorations or wasn’t that necessary?

  6. June 12th, 2009 at 17:47 | #6

    Nope I am using VS2008, the decoration is a c++ standard, not compiler specific. Brett didn’t tell me about the idea.

  7. Bapao
    June 12th, 2009 at 19:01 | #7

    Ok clear, I was having trouble with those tough, but must’ve been something else then.

  8. Rescudo
    June 13th, 2009 at 16:08 | #8

    Holy crap, that is really awesome man. I can’t believe it actually works :P
    Major props for taking the time to reverse engineer TGameCtrl_r for the rest of us to enjoy. :)

  9. csharp
    July 16th, 2009 at 21:30 | #9

    what’s that AddDialog function? I don’t see it anywhere in the lib 0.0

  10. July 18th, 2009 at 11:46 | #10

    AddDialog is not in the lib as it is for TRose not TGameCtrl!

    If you want your dialog to be added at start of game we need to apply a hook

    static const char* TROSE_MakeCustDlgRet = (char*)0×00490065;
    static const char* TROSE_MakeCustDlgCall = (char*)0×00500B32;
    static void _declspec(naked) ASMMakeDialogForward(){
    _asm {
    PUSH ECX
    PUSH EDX
    CALL EAX
    POP EDX
    POP ECX
    PUSH 0×130
    MOV ESI, ECX
    CALL TROSE_MakeCustDlgCall
    JMP TROSE_MakeCustDlgRet
    }
    }

    static void HookMakeDialog(PF_VOIDVOID targetFunc){
    ApplyJmpForwardHook(reinterpret_cast(0×00490059), &ASMMakeDialogForward, reinterpret_cast(targetFunc), 2);
    }

    Now to add dialog you need this (it is the same class used for adding text messages in game!):
    class cTR_GuiClass {
    public:
    };

    static inline cTR_GuiClass* TR_GuiClass(){
    return reinterpret_cast(0×697AD0);
    }

    typedef void (__thiscall cTR_GuiClass::*PTR_AddDialog)(int id, class CTDialog* dialog, int unk1_1);
    const int addr_TR_AddDialog = 0×48F9D0;
    static const PTR_AddDialog TR_AddDialog = *((PTR_AddDialog*)&addr_TR_AddDialog);
    #define AddDialog (TR_GuiClass()->*TR_AddDialog)

    Now to put this all together:
    HookMakeDialog(&MakeCustomDialog);

    void __stdcall MakeCustomDialog(){
    TestDialog* testDlg = new TestDialog();
    testDlg->Create(”dlgAchievements”);
    AddDialog(1339, testDlg, testDlg->GetControlID());
    testDlg->Show();
    }

    Something like that!

  11. CSharp
    July 18th, 2009 at 11:50 | #11

    Thanks :D Ill try it out.

  12. July 18th, 2009 at 23:37 | #12

    Oops forgot this:
    typedef void (__cdecl *PF_CDVOIDVOID)(void);
    typedef void (__stdcall *PF_VOIDVOID)(void);

    void ApplyJmpForwardHook(byte* code, PF_CDVOIDVOID location, byte* forwardFunc, int nops = 0){
    DWORD oldProtect;
    VirtualProtect(code, 10 + nops, PAGE_EXECUTE_READWRITE, &oldProtect);
    code[0] = 0xB8;
    *reinterpret_cast(code+1) = (int)forwardFunc;
    code[5] = 0xE9;
    *reinterpret_cast
    (code+6) = (int)location – ((int)code + 10);
    if(nops > 0) memset(code + 10, 0×90, nops);
    VirtualProtect(code, 10 + nops, oldProtect, &oldProtect);
    }

  13. David
    August 20th, 2009 at 23:25 | #13

    holy shiat, nice reversing :o

  1. No trackbacks yet.