GetLocalizedText and C++ menu

Shout-Out

User Tag List

Page 1 of 3 123 LastLast
Results 1 to 15 of 32
  1. #1
    jockel's Avatar Member
    Reputation
    4
    Join Date
    Mar 2009
    Posts
    54
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    GetLocalizedText and C++

    Heya guys,

    I'm currently doing some playing around with my C++ library.

    I'm using a function pointer to execute Lua_DoString when Wow's EndScene is called.

    Now I want to get the return values via the GetLocalizedText function.

    Here is what I use for the typdef function pointer:
    Code:
    typedef unsigned int (__cdecl * tLuaGetText)(int unkn1, char * luaVar);
    tLuaGetText getText = (tLuaGetText)0x005A8500;
    Now I'm going to execute this piece of code:

    doString("test = GetRealZoneText();");
    unsigned int a = getText(-1, "test");

    The DoString is correctly executed (tried it with CastSpellByName), but the getText part crashs my Wow.

    Any ideas on this guys?

    Thanks

    GetLocalizedText and C++
  2. #2
    SKU's Avatar Contributor
    Reputation
    306
    Join Date
    May 2007
    Posts
    565
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    0055E046                |.  6A FF             PUSH -1                                                          ; /Arg2 = FFFFFFFF
    0055E048                |.  8D55 E0           LEA EDX,[LOCAL.8]                                                ; |
    0055E04B                |.  52                PUSH EDX                                                         ; |Arg1 = 7C91E514
    0055E04C                |.  8BCE              MOV ECX,ESI                                                      ; |
    0055E04E                |.  E8 ADA40400       CALL Wow.005A8500                                                ; \Wow.005A8500

    Code:
    005A8500                /$  55                PUSH EBP
    005A8501                |.  8BEC              MOV EBP,ESP
    005A8503                |.  53                PUSH EBX
    005A8504                |.  56                PUSH ESI
    005A8505                |.  8BF1              MOV ESI,ECX
    005A8507                |.  8B46 08           MOV EAX,DWORD PTR DS:[ESI+8]
    005A850A                |.  8B58 04           MOV EBX,DWORD PTR DS:[EAX+4]
    005A850D                |.  57                PUSH EDI                                                         ;  ntdll.7C920228
    005A850E                |.  8B38              MOV EDI,DWORD PTR DS:[EAX]
    005A8510                |.  E8 CB3F2100       CALL Wow.007BC4E0
    005A8515                |.  3BF8              CMP EDI,EAX
    005A8517                |.  75 10             JNZ SHORT Wow.005A8529
    005A8519                |.  3BDA              CMP EBX,EDX                                                      ;  ntdll.KiFastSystemCallRet
    005A851B                |.  75 0C             JNZ SHORT Wow.005A8529
    005A851D                |.  8B86 D00F0000     MOV EAX,DWORD PTR DS:[ESI+FD0]
    005A8523                |.  0FB640 1C         MOVZX EAX,BYTE PTR DS:[EAX+1C]
    005A8527                |.  EB 0A             JMP SHORT Wow.005A8533
    005A8529                |>  8B8E D0000000     MOV ECX,DWORD PTR DS:[ESI+D0]
    005A852F                |.  0FB641 42         MOVZX EAX,BYTE PTR DS:[ECX+42]
    005A8533                |>  5F                POP EDI                                                          ;  kernel32.7C817077
    005A8534                |.  5E                POP ESI                                                          ;  kernel32.7C817077
    005A8535                |.  83E8 01           SUB EAX,1
    005A8538                |.  5B                POP EBX                                                          ;  kernel32.7C817077
    005A8539                |.  B8 02000000       MOV EAX,2
    005A853E                |.  75 05             JNZ SHORT Wow.005A8545
    005A8540                |.  B8 03000000       MOV EAX,3
    005A8545                |>  8B55 0C           MOV EDX,[ARG.2]
    005A8548                |.  50                PUSH EAX                                                         ; /Arg3 = 00000000
    005A8549                |.  8B45 08           MOV EAX,[ARG.1]                                                  ; |Wow.<ModuleEntryPoint>
    005A854C                |.  52                PUSH EDX                                                         ; |Arg2 = 7C91E514
    005A854D                |.  50                PUSH EAX                                                         ; |Arg1 = 00000000
    005A854E                |.  E8 1D2CEFFF       CALL Wow.0049B170                                                ; \Wow.0049B170
    005A8553                |.  83C4 0C           ADD ESP,0C
    005A8556                |.  5D                POP EBP                                                          ;  kernel32.7C817077
    005A8557                \.  C2 0800           RETN 8
    Looks like a __thiscall (definitively not a __cdecl), and you're pushing the arguments in the wrong order.

  3. #3
    jockel's Avatar Member
    Reputation
    4
    Join Date
    Mar 2009
    Posts
    54
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the fast response,

    Using __thiscall won't crash my Wow anymore,
    so the right order of the arguments should be:

    Code:
    typedef unsigned int (__thiscall * tLuaGetText)( char * luaVar, int unkn1);
    tLuaGetText getText = (tLuaGetText)0x005A8500;

    Code:
    0055E04C                |.  8BCE              MOV ECX,ESI
    This means that the playerbase is moved into ecx right?

    Doesn't the function call automatically do this for me, or do I have to manually manage this with inline asm.

  4. #4
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    "Doesn't the function call automatically do this for me, or do I have to manually manage this with inline asm."
    Think about that for a few minutes, then kick yourself for asking such a stupid question.

    Also, that typedef you pasted above shouldn't even work. I'm almost certain that's not valid C++. You can't declare a function explicitly as __thiscall using the '__thiscall' keyword, you have to declare the function as a member of a class and let it use __thiscall implicitly.

    This is legal and should work though I think:
    typedef void (SomeClass::* tFoo)();

  5. #5
    wraithZX's Avatar Active Member
    Reputation
    43
    Join Date
    May 2007
    Posts
    122
    Thanks G/R
    0/1
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    __thiscall just tells the compiler that the first argument is the this argument.
    (Actually it fudges the first argument to be placed in ecx - the same place that 'this' normally would be.)

    So:

    Code:
    typedef int (__thiscall *pFunc)(void *p, int arg);
    is valid for
    Code:
    struct P
    {
       int Func(int arg);
    };
    i.e.
    Code:
    pFunc Func = P::Func; // yeah yeah I know, not valid, work with me here
    P p;
    Func(p, 5);
    p.Func(5);

  6. #6
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by wraithZX View Post
    __thiscall just tells the compiler that the first argument is the this argument.
    (Actually it fudges the first argument to be placed in ecx - the same place that 'this' normally would be.)

    So:

    Code:
    typedef int (__thiscall *pFunc)(void *p, int arg);
    is valid for
    Code:
    struct P
    {
       int Func(int arg);
    };
    i.e.
    Code:
    pFunc Func = P::Func; // yeah yeah I know, not valid, work with me here
    P p;
    Func(p, 5);
    p.Func(5);
    What you've done there is totally different to what I meant was invalid, but it seems I was mistaken. This does actually compile:
    typedef void (__thiscall* tFoobar)(UINT This);
    tFoobar oFoobar = reinterpret_cast<tFoobar>(0xDEADBEEF);
    oFoobar(1);

    EDIT:
    Though, you'd want to be careful. Compilers implement the C++ member function calling convention differently, so whilst that may work with MSVC, if you compile it with GCC it may fail. You're probably better off manually moving 'this' into ECX.

    EDIT2:
    Pretty sure most major compilers have it. But its also worth noting __thiscall is a nonstandard language extension.
    Last edited by Cypher; 06-02-2009 at 12:21 AM.

  7. #7
    wraithZX's Avatar Active Member
    Reputation
    43
    Join Date
    May 2007
    Posts
    122
    Thanks G/R
    0/1
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yep. Assuming your 'this' pointer sits at 0x00000001

  8. #8
    jockel's Avatar Member
    Reputation
    4
    Join Date
    Mar 2009
    Posts
    54
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hum, thanks for the answers guys, I did some testing around for the last hours, but I'm not able to get it working.

    According to cyphers last post I tried:
    typedef int (__thiscall* tLuaGetText)(char * a, int b);
    tLuaGetText getText = reinterpret_cast<tLuaGetText>(0x005A8500);
    Which crashes my Wow with a read error at the GetText offset.


    So I tried what Cypher was first posting with the implizit declaration of the function:

    struct sLuaHelper {
    int __thiscall tLuaGetText(char * luaVar, int unkn1);
    };

    typedef int (sLuaHelper:: * tLuaGetText)(char * a, int b);

    tLuaGetText getText = (tLuaGetText)0x005A8500;
    The compiler gives me in the red markes line an error that he can't convert "tLuaGetText " to int.
    I can't get the function build together correctly, can you give me a hint on this?

  9. #9
    SKU's Avatar Contributor
    Reputation
    306
    Join Date
    May 2007
    Posts
    565
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Cypher: Close your eyes now.

    Code:
    #include <Windows.h>
    #include <string>
    #include <boost/format.hpp>
    
    // GetText
    typedef char* (__thiscall * tGetText)(void* pThis, char* sText, DWORD_PTR unk1);
    tGetText oGetText = reinterpret_cast<tGetText>(0x005A8500);
    
    // DoString
    typedef void (__cdecl * tDoString)(const char* sCommand1,const char* sCommand2, void* pState /*  = null */);
    tDoString oDoString = reinterpret_cast<tDoString>(0x0049AB60);
    
    // startup routine
    void start()
    {
    	// fugly. 0 pointer checks anyone? Get the local player..
    	DWORD_PTR dwLocalPlayer = *reinterpret_cast<DWORD_PTR*>(*reinterpret_cast<DWORD_PTR*>(*reinterpret_cast<DWORD_PTR*>(0x10BD5F4) + 0x34) + 0x24);
    	// call dostring with random crap
    	oDoString("sText = GetMinimapZoneText();", "sText = GetMinimapZoneText();", NULL);
    	// get text
    	std::string sResult(oGetText(reinterpret_cast<void*>(dwLocalPlayer), "sText", -1));
    	// show the result
    	MessageBoxA(NULL, sResult.c_str(), "ZOMG", MB_OK);
    }
    
    // dll entry point
    BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
    {
    	if (dwReason == DLL_PROCESS_ATTACH)
    		CreateThread(0, 0, (LPTHREAD_START_ROUTINE)start, 0, 0, 0);
    
    	return TRUE;
    }

  10. #10
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Don't do this:
    CreateThread(0, 0, (LPTHREAD_START_ROUTINE)start, 0, 0, 0);

    It's evil and will potentially crash randomly on x64. Plus, it ****s with anything that relies on TLS.

    First off, don't use CreateThread, use beginthreadex. Second, match the ThreadProc prototype correctly and pass in the pointer like this:
    Foo(&Start);

  11. #11
    SKU's Avatar Contributor
    Reputation
    306
    Join Date
    May 2007
    Posts
    565
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Will do in the future, thanks.

  12. #12
    jockel's Avatar Member
    Reputation
    4
    Join Date
    Mar 2009
    Posts
    54
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the bunch of information.

    So since GetLocalizedText needs the playerbase as an argument, I assume that this function doesn't work before we are ingame, is this right?

  13. #13
    namreeb's Avatar Legendary

    Reputation
    668
    Join Date
    Sep 2008
    Posts
    1,029
    Thanks G/R
    8/222
    Trade Feedback
    0 (0%)
    Mentioned
    9 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Cypher View Post

    Don't do this:
    CreateThread(0, 0, (LPTHREAD_START_ROUTINE)start, 0, 0, 0);

    It's evil and will potentially crash randomly on x64. Plus, it ****s with anything that relies on TLS.

    First off, don't use CreateThread, use beginthreadex. Second, match the ThreadProc prototype correctly and pass in the pointer like this:
    Foo(&Start);
    Meaning compiled as x64 or just running on an x64 system?

  14. #14
    lanman92's Avatar Active Member
    Reputation
    50
    Join Date
    Mar 2007
    Posts
    1,033
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Just running on an x64 will have the possibility to crash. I know from experience... Sigh. It's not hard, just change your proto.

  15. #15
    flo8464's Avatar Active Member
    Reputation
    30
    Join Date
    Apr 2009
    Posts
    434
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry for digging out this old thread.

    I tried to use dostring/gettext but had problems doing it.

    C&Ped SKUs code and got a valid result.

    I was confused and tried "sText = GetMinimapZoneText();" with my code and it worked.

    So my code has to be valid, there is a problem with the lua-code I supply to my function.

    "count = GetItemCount(6256);"
    Why does this always return 0?
    If I type it ingame as "/script ..." it returns the correct value, 1.

    Or should I call GetItemCount() directly ? I hope not, using 2 functions for everything sounds much more comfortable.

Page 1 of 3 123 LastLast

Similar Threads

  1. Above and beyond Orgrimmar
    By Matt in forum World of Warcraft Exploits
    Replies: 3
    Last Post: 12-30-2006, 08:37 PM
  2. Recipes.. and their locations
    By Matt in forum World of Warcraft Guides
    Replies: 4
    Last Post: 12-03-2006, 08:21 AM
  3. Farming Bijous and Coins in ZG
    By Matt in forum World of Warcraft Guides
    Replies: 1
    Last Post: 11-02-2006, 06:48 PM
  4. 8 World of Warcraft Guide Packs (Gold, Profs and Skills)
    By Matt in forum World of Warcraft Guides
    Replies: 17
    Last Post: 09-23-2006, 10:53 AM
  5. WoWGlider and GALB Botting Locations
    By Matt in forum World of Warcraft Bots and Programs
    Replies: 14
    Last Post: 04-11-2006, 08:01 PM
All times are GMT -5. The time now is 01:20 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