IsSpellUsable (Lua) menu

Shout-Out

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 15 of 21
  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)

    IsSpellUsable (Lua)

    Since I'm not able to get the LUA return values (missing reversing / coding) skillz, I'm trying to call the function and get the return values from there.


    IsSpellUsable (ASM)
    Code:
    .text:00700760 sub_700760      proc near               ; DATA XREF: .data:00A41C8Co
    .text:00700760
    .text:00700760 var_2C0         = qword ptr -2C0h
    .text:00700760 var_2AC         = dword ptr -2ACh
    .text:00700760 var_C           = dword ptr -0Ch
    .text:00700760 var_8           = dword ptr -8
    .text:00700760 var_4           = dword ptr -4
    .text:00700760 arg_0           = dword ptr  8
    .text:00700760
    .text:00700760                 push    ebp
    .text:00700761                 mov     ebp, esp
    .text:00700763                 sub     esp, 2ACh
    .text:00700769                 push    ebx
    .text:0070076A                 push    esi
    .text:0070076B                 mov     esi, [ebp+arg_0]
    .text:0070076E                 push    edi
    .text:0070076F                 push    1
    .text:00700771                 push    0
    .text:00700773                 lea     edi, [ebp+var_8]
    .text:00700776                 lea     ebx, [ebp+var_4]
    .text:00700779                 mov     [ebp+var_4], 0
    .text:00700780                 call    sub_6FF810
    .text:00700785                 add     esp, 8
    .text:00700788                 test    eax, eax
    .text:0070078A                 jnz     short loc_700793
    .text:0070078C                 pop     edi
    .text:0070078D                 pop     esi
    .text:0070078E                 pop     ebx
    .text:0070078F                 mov     esp, ebp
    .text:00700791                 pop     ebp
    .text:00700792                 retn
    My C# code (with fasm managed)

    Code:
                    //Refresh curMgr code
                    UpdateManager();
    
                    Asm.AddLine("mov eax, " + spellId);
                    Asm.AddLine("push eax");                
                    Asm.AddLine("call " + 0x00700760);
                   
                    m_Process.Asm.AddLine("retn");
                    SuspendThread();               
                    uint result = Asm.InjectAndExecute(cave);
    Sadly after executing this code my WoW immediately crashes.


    Wow crash log:
    pastebin - collaborative debugging tool

    Any idea on this?

    IsSpellUsable (Lua)
  2. #2
    Bobbysing's Avatar Member
    Reputation
    192
    Join Date
    Jan 2009
    Posts
    36
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You need to clean up the stack after the call, the function is __cdecl.

  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, works wonders.
    No more crashing, but the return value seems to be wrong.

    It always returns 0.

    Am I putting the argument wrong on the stack?
    Or isn't it possible to retrieve the values in this way?

  4. #4
    goderion's Avatar Active Member
    Reputation
    25
    Join Date
    Oct 2008
    Posts
    54
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Im confused. I thought this is a lua-function like:
    Lua: Functions and Types: lua_CFunction

    lua_State *L;
    L = GetLuaState();
    lua_pushinteger(L, SpellId);
    IsUsableSpell(L);
    Result = lua_tointeger(1);

    To get the lua_State, wow is using, use this function:
    0x004997B0 (Lua_GetState)
    or this address:
    0x010735F4 (Address_LuaState)

    Maybe this helps, but be carefull, thats only an assumption of mine.

  5. #5
    peterwurst's Avatar Member
    Reputation
    11
    Join Date
    Jul 2006
    Posts
    31
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could use SKU's Lua tostring, but since the invalid pointer check is monitored since 3.1.2 I don't know how to bypass that.

  6. #6
    Robske's Avatar Contributor
    Reputation
    305
    Join Date
    May 2007
    Posts
    1,062
    Thanks G/R
    3/4
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by peterwurst View Post
    You could use SKU's Lua tostring, but since the invalid pointer check is monitored since 3.1.2 I don't know how to bypass that.
    Dereference it or patch the check itself. (And do this on a trail first to be sure )
    "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - Martin Golding
    "I cried a little earlier when I had to poop" - Sku

  7. #7
    Gorzul's Avatar Member
    Reputation
    8
    Join Date
    May 2009
    Posts
    19
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Try to get the result with GetLocalizedText (credits bobbysing )
    Game Deception - Forums - View Single Post - Question: Getting the value of a custom lua variable.

    Pseudocode:
    Code:
    DoLuaString("Result1 = IsSpellUsable("blabla")");
    result = GetLocalizedText("Result1");
    Offsets (3.1.2.9901)
    FrameScript_Execute_char: 0x0049AB60
    GetLocalizedText: 0x005A8500

  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)
    Thanks for that code snippet, helped me alot to understand the things a bit more.

    Sadly, I'm programming in C#, so I can't use a pointer to the function, to get the values.


    So I guess a simple call to the function, pushing the arguments on the stack, should do the same thing.

    What I tried to do this in C# is the following:

    Code:
    DoString("Result1 = GetRealZoneText();");
    uint cave = AllocateMemory(0x400);
    Write(cave + 0x200, "Result1");
    
    UpdateManager();
    Asm.AddLine("push " + (cave + 0x200));
    Asm.AddLine("push -1");
    Asm.AddLine("call " + 0x005A8500);
    AddLine("call __cdecl");
    AddLine("retn");
    SuspendThread();
    uint result = Asm.InjectAndExecute(cave);
    ResumeThread();
    Now I thought I could read the string located at "result", but result always seems to be zero.

    Any suggestions on this?
    Am I in the right direction?

  9. #9
    Gorzul's Avatar Member
    Reputation
    8
    Join Date
    May 2009
    Posts
    19
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Am I in the right direction?
    Yes

    Here is a code snippet from my own project:
    Code:
    public static String GetLocalizedText(string variable)
    {
        uint codecave = blackMagic.AllocateMemory(0x200);
    
        blackMagic.WriteASCIIString(codecave + 0x100, variable);
    
        blackMagic.Asm.Clear();
    
        AsmUpdateCurrentManager();
    
        blackMagic.Asm.AddLine("mov ecx, {0}", localPlayer.BaseAddress);
        blackMagic.Asm.AddLine("push {0}", -1);
        blackMagic.Asm.AddLine("push {0}", codecave + 0x100);
        blackMagic.Asm.AddLine("call {0}", 0x005A8500);
        blackMagic.Asm.AddLine("retn");
          
        SuspendWoW();
    
        uint result = blackMagic.Asm.InjectAndExecute(codecave);
    
        String sResult = "null";
        if (result != 0)
        {
            sResult = blackMagic.ReadASCIIString(result);
        }
    
        blackMagic.FreeMemory(codecave);
    
        ResumeWoW();
    
        return sResult;
    }
    Move the pointer of the player object into ecx and check the order of the arguments.
    Last edited by Gorzul; 05-25-2009 at 05:41 PM.

  10. #10
    luciferc's Avatar Contributor
    Reputation
    90
    Join Date
    Jul 2008
    Posts
    373
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Very nice.

    Still wondering i can never get my LuaDoString to be stable (no crashes) w/ Blackmagic anyone else able to?

    Code:
    for (int i = 0; i < 10000; i++)
                {
                    Asm_Code.Lua_Execute(string.Format("DEFAULT_CHAT_FRAME:AddMessage(\"Test " + i + "\");", DateTime.Now));
                }
    Little thing i whipped up to test it. I cant get it past 5k Usually.

  11. #11
    HapaHaoleVA's Avatar Member
    Reputation
    4
    Join Date
    Apr 2009
    Posts
    10
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Not a master here, but are you suspending/resuming WoW's main thread in your Lua_Execute code?

    Also, there's a flag at LuaThreadLock that you can use to sync against -

    while (m_WoW.Read<int>(ptrLuaThreadLock) != 0)
    Thread.Sleep(0);

    SThread.SuspendThread(m_WoW.MainThread);

    I'd share the offset, but unfortunately I haven't had a chance to update my code yet and LuaThreadLock's pattern is small.

    Edit:
    LuaThreadLock: 0x00499720
    Last edited by HapaHaoleVA; 05-26-2009 at 03:14 AM.

  12. #12
    luciferc's Avatar Contributor
    Reputation
    90
    Join Date
    Jul 2008
    Posts
    373
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ya i was. So loop while A Sleep While != 0 ?

  13. #13
    goderion's Avatar Active Member
    Reputation
    25
    Join Date
    Oct 2008
    Posts
    54
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The following is only an assumption!

    I guess its not possible to make code stable, who is running in the middle of an other process. I mean this suspend thread, execute own code and resume thread. You never know, what the other code is currently doing, like the wow main thread. I dont know what this LuaThreadLock means, guess it is set, if Lua currently execute a script. Even with LuaThreadLock, you are unable to get it stable, couse you dont know what all other parts of wow currently doing, like loading objects and unloading objects. Its quite easy to think of examples, who it will still crash, even considering LuaThreadLock.

    The best way would to find an address in wow, who tell you the current state of the wow main thread. Maybe there is a way to analyse, if Direct3DDevice is currently between BeginScene and EndScene, then it should be stable to do whatever you want to do.

    pseudo code for the own loop: (written in 1 minute, take care! ^^)
    Code:
    HANDLE hWoWProcessHandle; // get it before!
    HANDLE hWoWMainThreadHandle; // get it before!
    LPVOID Address_D3DDeviceState = 0x00000000; // FAKE
    const DWORD D3DIsRendering = 0x00000000; // FAKE
    
    
    DWORD GetDirect3DDeviceState(void)
    {
    	DWORD Direct3DDeviceState;
    	DWORD NumberOfBytesRead;
    
    	ReadProcessMemory(hWoWProcessHandle, Address_D3DDeviceState, &Direct3DDeviceState, 4, &NumberOfBytesRead);
    
    	return Direct3DDeviceState;
    }
    
    BOOL SuspendWoWMainThread(void)
    {
    	// true should be replaced by some other logic! maybe a timeout?
    	while(true)
    	{
    		if( GetDirect3DDeviceState() == D3DIsRendering )
    		{
    			SuspendThread(hWoWMainThreadHandle);
    
    			// check if he is still rendering
    			if( GetDirect3DDeviceState() == D3DIsRendering )
    			{
    				return TRUE;
    			}
    
    			ResumeThread(hWoWMainThreadHandle);
    		}
    
    		Sleep(1);
    	}
    
    	return FALSE;
    }
    
    BOOL ResumeWoWMainThread(void)
    {
    	ResumeThread(hWoWMainThreadHandle);
    
    	return TRUE;
    }
    
    int DoStuff(void)
    {
    	// here you can do all you want to do!
    
    	return 0;
    }
    
    int Execute(void)
    {
    	SuspendWoWMainThread();
    
    	DoStuff();
    
    	ResumeWoWMainThread();
    }
    
    int MainLoop(void)
    {
    	// true should be replaced by some other logic!
    	while(true)
    	{
    		Execute();
    
    		Sleep(1);
    	}
    
    	return 0;
    }

  14. #14
    Shynd's Avatar Contributor
    Reputation
    97
    Join Date
    May 2008
    Posts
    393
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    A while back, before I injected DLLs and did most of my hacks in-process, I used a method very much like goderion's suggestion with another game.

    Make a simple codecave detour on dx->EndScene that checks if a variable you define is 1 and, if so, set that variable to 2 and consta-loop on Sleep(0) while checking that variable's value for zero (return to normal execution). It'd look something like this:
    Code:
    EndScene: ;your detour on EndScene
        jmp MyCodeCave
        
    EndSceneContinue:
    
    ;--------------------------------
    ; codecave
    ;--------------------------------
    MyCodeCave:
        cmp [MyEventState], 0
        jz Continue
    
        mov [MyEventState], 2
        pushad
    TopOfWhile:
        push 1
        call <kernel32.Sleep>
        cmp [MyEventState], 0
        jnz TopOfWhile
        popad
    
    Continue:
        ;restore dx->EndScene opcodes
        jmp EndSceneContinue
    As you can see, the game will go about its business as normal until your external program writes to the address of MyEventState and changes its value to 1 (or anything non-zero and not 2). When the game enters into EndScene and notices that MyEventState is no longer zero, it changes its value to 2 and then loops until your external program changes its value back to zero. That means, you have but to change its value to 1, loop on a read memory until its value is 2, do all your funky shit, and then change its value back to zero at the end. The game's main thread has not executed anything but kernel.Sleep during this time so you know you're not going to access objects and get any kind of threading exception.

    Anyway, it's MUCH better to do something like this in-process, and the performance on this kind of thing isn't the best, but it does work. I've used this method to intercept and read / change packets in games, monitor events, execute code while the game's thread is occupied, etc. Not optimal, but functional.

  15. #15
    HapaHaoleVA's Avatar Member
    Reputation
    4
    Join Date
    Apr 2009
    Posts
    10
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Gorzul View Post
    Yes

    Here is a code snippet from my own project:
    Code:
    public static String GetLocalizedText(string variable)
    {
        uint codecave = blackMagic.AllocateMemory(0x200);
    
        blackMagic.WriteASCIIString(codecave + 0x100, variable);
    
        blackMagic.Asm.Clear();
    
        AsmUpdateCurrentManager();
    
        blackMagic.Asm.AddLine("mov ecx, {0}", localPlayer.BaseAddress);
        blackMagic.Asm.AddLine("push {0}", -1);
        blackMagic.Asm.AddLine("push {0}", codecave + 0x100);
        blackMagic.Asm.AddLine("call {0}", 0x005A8500);
        blackMagic.Asm.AddLine("retn");
          
        SuspendWoW();
    
        uint result = blackMagic.Asm.InjectAndExecute(codecave);
    
        String sResult = "null";
        if (result != 0)
        {
            sResult = blackMagic.ReadASCIIString(result);
        }
    
        blackMagic.FreeMemory(codecave);
    
        ResumeWoW();
    
        return sResult;
    }
    Move the pointer of the player object into ecx and check the order of the arguments.
    Here's a nub question - why does this code immediately close wow - not a crash, just closes it.

    internal static uint GetPlayerBaseAddress(MemoryManager mem)
    {
    uint ptrPlayerBase = OffsetManager.GetAddress("Global", "PlayerBase");

    return mem.Read<uint>(mem.Read<uint>(mem.Read<uint>(ptrPlayerBase) + 0x34) + 0x24);
    }

    public string GetLocalizedText(string variable)
    {
    string result = null;

    Synchronize();

    using (CodeCave cave = m_mem.CreateCodeCave())
    {
    cave.WriteString(cave.AllocationAddress + 0x1024, variable, true);

    cave.AsmClear();
    AsmUpdateCurrentManager(cave);

    cave.AsmAddLine("mov ecx, {0}", GetPlayerBaseAddress(m_mem));
    cave.AsmAddLine("push -1");
    cave.AsmAddLine("push {0}", cave.AllocationAddress + 0x1024);
    cave.AsmAddLine("call {0}", OffsetManager.GetAddress("LUA Functions", "LuaGetLocalizedText"));
    cave.AsmAddLine("add esp, 0xC");
    cave.AsmAddLine("retn");

    uint ptrResult = cave.AsmInjectAndExecute();

    if (ptrResult != 0)
    {
    result = m_mem.ReadString(ptrResult, true);
    }
    }

    ResumeMainThread();

    return result;
    }
    Last edited by HapaHaoleVA; 05-26-2009 at 07:51 PM.

Page 1 of 2 12 LastLast

Similar Threads

  1. [Guide] Lua Scripting Guide is here [Updating]
    By Illidan1 in forum WoW EMU Guides & Tutorials
    Replies: 93
    Last Post: 11-04-2008, 06:56 PM
  2. New LUA Scripts
    By 777devil777 in forum World of Warcraft Emulator Servers
    Replies: 8
    Last Post: 11-26-2007, 05:58 PM
  3. Lua Ascent Script Documentation
    By latruwski in forum World of Warcraft Emulator Servers
    Replies: 0
    Last Post: 11-26-2007, 12:42 PM
  4. LUA Refrences
    By 777devil777 in forum World of Warcraft Emulator Servers
    Replies: 1
    Last Post: 11-22-2007, 08:09 PM
All times are GMT -5. The time now is 11:50 PM. 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