[3.3.5] CGGameObject_C__OnRightClick menu

User Tag List

Results 1 to 8 of 8
  1. #1
    tellien's Avatar Member
    Reputation
    7
    Join Date
    Jan 2018
    Posts
    2
    Thanks G/R
    3/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [3.3.5] CGGameObject_C__OnRightClick

    Greets, I'm trying to inject call of object interaction function in 3.3.5 using Cheat Engine.
    I found this topic CLICK saying that this is non-arg function, but I have to pass pointer to object struct in ECX register.

    I'm trying to interact with mailbox in this. I toggled breakpoint and copied the object (mailbox) base address (it's ok, my c++ object scanner shows same address).
    Using Cheat Engine auto-assemble I created injection and run it. It didn't result crash.

    Cheat engine injection code v.1
    PHP Code:
    [enable]
    alloc(mycode,4096)
    CREATETHREAD(mycode);
    label(mustend)
    registersymbol(mustend)

    mycode:
    mov ecx,1a5f6cb4
    call 00711140
    ret

    mustend
    :
    dd 0

    [disable]
    mustend:
    dd 1 
    Cheat engine injection code v.2
    PHP Code:
    [enable]
    alloc(mycode,4096)
    CREATETHREAD(mycode);
    label(mustend)
    registersymbol(mustend)

    mycode:
    mov ecx,1a5f6cb4
    mov ebx
    ,ca0002f4
    call 00711140
    ret

    mustend
    :
    dd 0

    [disable]
    mustend:
    dd 1 
    So the problem seems to be in (2) call edx (on screenshot). That function puts in eax 1 if evverything's alright and 0 etherwise. However anything that I tried to inject will bring 0 after that call (2).
    In this topic CLICK there's info that my v.1 should work just fine. But it's not.

    Screenshot with everything I mentioned.
    [3.3.5] CGGameObject_C__OnRightClick-untitled-gif
    prnt.sc

    I hope I was informative enough, ty.
    Last edited by tellien; 01-28-2018 at 11:51 AM. Reason: stretching screenshot

    [3.3.5] CGGameObject_C__OnRightClick
  2. Thanks tutrakan (1 members gave Thanks to tellien for this useful post)
  3. #2
    MrNoble's Avatar ezclap CoreCoins Purchaser
    Reputation
    535
    Join Date
    Sep 2015
    Posts
    359
    Thanks G/R
    170/218
    Trade Feedback
    2 (100%)
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)
    How about using InteractObjectByGUID and just get the GUID of the mailbox?
    or atleast thats how i do my object interaction in 7.x.x
    Any fool can write code that a computer can understand. good programmers write code that humans can understand.

  4. #3
    tutrakan's Avatar Contributor
    Reputation
    134
    Join Date
    Feb 2013
    Posts
    175
    Thanks G/R
    124/52
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think it should be fun if you explain us more about the way you use CE to inject code. For example, how do you pass your code to CE, what [enable]/[disable] tags do and what mustend labels is for. I suppose, not all of us are CE experts, so more info about using this amazing tool might be useful.

    And about calling CGGameObject_C::OnRightClick(), you have 1st: find the GO instance address and 2nd: call the rightclick function from the end scene passing the address in ecx.
    So:
    Code:
    mov ecx, address_of_the_gameobject
    call 0x00711140
    is the way to do that (again from the endscene).

    Here the function looks like in IDA:
    Code:
    void __thiscall CGGameObject_C::OnRightClick(CGGameObject_C* this)
    {
        int go; // edi
        __int64 playerguid; // rax
        CGPlayer_C *playerptr; // esi
        bool autoloot; // eax
    
        go = this;
        if ( (*(this->m_baseObj->vfptr + 6))() )                   // CGGameObject_C_TypeBase::CanUseNow()
        {
            CGGameUI::CloseLoot(1, 0, 0);
            playerguid = ClntObjMgrGetActivePlayerGuid();
            playerptr = ClntObjMgrObjectPtr(playerguid, TYPEMASK_PLAYER, "d:\\buildserver\\wow\\1\\work\\wow-code\\branches\\wow-patch-3_3_5_a-bnet\\wow\\source\\object\\objectclient\\Player_C.h", 0xA0);
            if ( playerptr )
            {
                autoloot = CGGameUI::IsAutoLooting();
                CGPlayer_C::SetAutoLoot(playerptr, autoloot);
            }
            CGGameObject_C::Use(go);
        }
    }
    Last edited by tutrakan; 01-28-2018 at 04:30 PM.

  5. #4
    tellien's Avatar Member
    Reputation
    7
    Join Date
    Jan 2018
    Posts
    2
    Thanks G/R
    3/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by ferib View Post
    How about using InteractObjectByGUID and just get the GUID of the mailbox?
    or atleast thats how i do my object interaction in 7.x.x
    3.3.5 doesn't have that feature AFAIK


    Originally Posted by tutrakan View Post
    so more info about using this amazing tool might be useful
    I just completed the official CE tutorial, there was a topic about auto-assemble
    I found the pattern on some website, I don't know exactly how it works (I mean I know assembly, I have no idea what mustend: label is for), I put my asm code in mycode: label. After I click EXECUTE CE allocates memory, copies assembly and runs thread. Basically I can run thread from any point. I found this method much more easier than recompiling c-code every time I need to change something especially while exploring memory. Screenshot with this info PRNT.SC.


    Originally Posted by tutrakan View Post
    And about calling CGGameObject_C::OnRightClick(), you have 1st: find the GO instance address and 2nd: call the rightclick function from the end scene passing the address in ecx.
    So:
    Code:
    mov ecx, address_of_the_gameobject
    call 0x00711140
    is the way to do that (again from the endscene).
    That's exactly what I did, check the screenshot from OP CLICK. In the lower left corner you can see asm code I inject. Injection works just fine, but function does nothing.

    Code:
    1A5F6CB4
    This is the address of the object, I took it from hooked ingame mailbox interaction (You can see it in top right corner under (1) in ECX).


    I did some research, I tried step-by step registers comparsion in original call and from injected function. It seems that disrepancy starts in
    Originally Posted by tutrakan View Post
    Code:
     if ( (*(this->m_baseObj->vfptr + 6))() )                   // CGGameObject_C_TypeBase::CanUseNow()
    Here's comparsion between these two calls, this function is deep inside quouted call. CLICK
    Problem is in this line, that's where ecx from original call get 00E638D8 and in injected 10B4F2A0.

  6. #5
    vegoo's Avatar Contributor
    CoreCoins Purchaser Authenticator enabled
    Reputation
    275
    Join Date
    Dec 2011
    Posts
    707
    Thanks G/R
    10/27
    Trade Feedback
    110 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What I think is that to run code instantly Cheat Engine needs to CreateRemoteThread in allocated address and this mov instruction is moving some thread specific information into ecx, thats why value is different. Just a guess :P
    WoW TGC Loot & WoW Items
    Selling EU & US WoW Gold
    Buying EU & US WoW Gold

  7. #6
    tutrakan's Avatar Contributor
    Reputation
    134
    Join Date
    Feb 2013
    Posts
    175
    Thanks G/R
    124/52
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    All good, but as i said (twice already ), the function must be called from the end scene. If you start it from an external thread, the localplayer will be null, so the function will return prematurely.

    However, i played a bit with CE "Auto Assemble" - in the template tab there are few injection types and i learned something new about CE . Thanks for that.

    I chose "Code Injection" as template and while i wanted to hook the end scene i went to address 006A3450
    Code:
    int __thiscall CGxDeviceD3d::ScenePresent(int this)
    (note that the CGxDeviceD3d::ISceneEnd() in 3.3.5 + is no more called on every frame, but is inlined in the CGxDeviceD3d::ScenePresent()).

    At that point CE generated automatically for me this (it created for me a hook of the 006A3450 - CGxDeviceD3d::ScenePresent):
    Code:
    alloc(newmem,2048)
    label(returnhere)
    label(originalcode)
    label(exit)
    
    newmem: //this is allocated memory, you have read,write,execute access
    //place your code here
    
    originalcode:
    push ebp
    mov ebp,esp
    sub esp,2C
    
    exit:
    jmp returnhere
    
    "Wow.exe"+2A3450:
    jmp newmem
    nop
    returnhere:
    Finally, all that remained was to find the go address, add the go_onrightclick function call and make sure it's executed just once:
    Code:
    alloc(newmem,2048)
    label(returnhere)
    label(originalcode)
    label(isalreadyinteracted)
    label(exit)
    
    newmem:
    mov eax, [isalreadyinteracted]
    cmp eax, 1
    je originalcode
    
    push ecx
    mov ecx, go_address
    call 00711140
    pop ecx
    mov [isalreadyinteracted], 1
    
    originalcode:
    push ebp
    mov ebp,esp
    sub esp,2C
    
    exit:
    jmp returnhere
    
    isalreadyinteracted:
    dd 0
    
    "Wow.exe"+2A3450:
    jmp newmem
    nop
    returnhere:
    P.S You can contact me on skype if you have questions.
    Last edited by tutrakan; 02-16-2018 at 01:59 PM.

  8. Thanks tellien (1 members gave Thanks to tutrakan for this useful post)
  9. #7
    counted's Avatar Contributor Authenticator enabled
    Reputation
    203
    Join Date
    Mar 2008
    Posts
    183
    Thanks G/R
    11/108
    Trade Feedback
    0 (0%)
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    The easy way to accomplish this is to find the mouseoverguid memory location and write the guid of the mail box to that variable and then just send the keystroke for interact with mouse over.

    The next easiest way is to call the interact virtual method for the mail box. You can find the offset for the interact virtual method in the Script_InteractUnit subroutine.

    You can also just dump the virtual method table and check each subroutine in ida and you will eventually find the one that is the interact subroutine.
    Last edited by counted; 02-01-2018 at 07:55 AM.

  10. Thanks tellien (1 members gave Thanks to counted for this useful post)
  11. #8
    tutrakan's Avatar Contributor
    Reputation
    134
    Join Date
    Feb 2013
    Posts
    175
    Thanks G/R
    124/52
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by counted View Post
    ...
    The next easiest way is to call the interact virtual method for the mail box. You can find the offset for the interact virtual method in the Script_InteractUnit subroutine.

    You can also just dump the virtual method table and check each subroutine in ida and you will eventually find the one that is the interact subroutine.
    Duh!
    WowAddin/CGObject_C.h at master * tomrus88/WowAddin * GitHub
    Or, vftable + 0xb0
    Which for game object = 0x00711140, item = 0x00708200, corpse = 0x00706010 and for unit = 0x00731260.
    And that call can still return prematurely if not called from the main game thread (as in his case with CE external thread).
    Last edited by tutrakan; 02-01-2018 at 11:19 PM.

  12. Thanks lsjaf3297 (1 members gave Thanks to tutrakan for this useful post)
All times are GMT -5. The time now is 03:24 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search