| | WoW Memory Editing WoW Memory Editing for learning purposes only.
This section is more advanced than others on MMOwned Read the section specific rules, infractions will be given out if u break them!That is including the expectations! - If you don't meet them then don't post |  | | 
07-03-2009
| | Master Sergeant | | | Join Date: Jul 2008
Posts: 102
Reputation: 22 Level up: 46%, 274 Points needed | | | | DoString silently failing Hi all,
So I'm having trouble calling WoW's lua_DoString function from my injected code. Everything seems to work; the function even gets called without any errors, and, as far as I can tell, doesn't differ from a natural call triggered by a /run or /script.
IDA spits out this function signature, which I have defined in my code as: Code: int _cdecl GameFunction_Lua_DoString(int* pLua, char* strToDo1, char* strToDo2);
To provide some more (hopefully helpful) information,
-I have the function's 3.1.3 address set to 0x49AAB0;
-I am retrieving the pointer to LUA? at the 3.1.3 address 0xA3D93C; (pLua)
-I am calling the function thusly: Code: GameFunction_Lua_DoString(pLua, strDoString, strDoString);
-I have checked that strDoString and pLua are returning the correct values, etc.
Anyone have any clue as to what I need to do? Do I need to unprotect something or remove some checks? Any tips are much appreciated! I'm going to try and run the code through olly and see what's going on in the meantime. | Donate to remove ads, get your "DONATOR title, and get access to the MMOwned community's elite Shoutbawx. 
07-03-2009
| | Knight-Lieutenant | | | Join Date: Jan 2008
Posts: 267
Reputation: 17 Level up: 16%, 589 Points needed |  | | Um.. I think the state is last param instead of first if it is the right function.
Edit: It is the correct address. Code: typedef void ( __cdecl * tLua_DoString )( char * pszString, char * pszString2, void * pState );
tLua_DoString Lua_DoString = reinterpret_cast<tLua_DoString>( 0x0049AAB0 );
Lua_DoString("message(\"Hello World!\")","message(\"Hello World!\")", NULL) // You don't have to have pState for DoString, you can pass NULL.
Edit2: Make sure your pState is correct, because I am getting mine differently.
Last edited by ramey; 07-03-2009 at 12:04 PM.
| 
07-03-2009
| | Master Sergeant | | | Join Date: Jul 2008
Posts: 102
Reputation: 22 Level up: 46%, 274 Points needed | | | | Whoops@ the wrong argument order..
hmm, it seemed like my pState was somehow incorrect. passing in null fixed it. Just wondering, would WoW ever pass in a null "pState"?
Thanks a lot anyway. +rep | 
07-03-2009
| | Knight-Lieutenant | | | Join Date: Jan 2008
Posts: 267
Reputation: 17 Level up: 16%, 589 Points needed |  | | | No, I don't think WoW would pass in a NULL state. I haven't look at how WoW calls DoString though.
Thanks for the rep. | 
07-03-2009
| | Master Sergeant | | | Join Date: Jul 2008
Posts: 102
Reputation: 22 Level up: 46%, 274 Points needed | | | | hmm.. TODO: never pass in a null to DoString...
Oh well, that's a problem for another day | 
07-03-2009
| | Knight-Lieutenant | | | Join Date: Jan 2008
Posts: 267
Reputation: 17 Level up: 16%, 589 Points needed |  | | Quote:
Originally Posted by vulcanaoc hmm.. TODO: never pass in a null to DoString...
Oh well, that's a problem for another day | Just find where WoW gets the state from. | 
07-03-2009
|  | MMOwned WebDev Legendary User | | | Join Date: Jan 2008
Posts: 1,891
Nominated 5 Times in 1 Post Reputation: 1029 Points: 21,931, Level: 20 | Level up: 71%, 469 Points needed |     | | Just pass 0 as the state. You don't need it. Code: /// <summary>
/// Calls WoW's internal FrameScript_Execute (Lua_DoString)
/// </summary>
/// <param name="lua">The actual Lua code to execute.</param>
/// <param name="fileName">A file name to use in case of an error. (Will be shown as: x error (fileName) ln y)</param>
/// <param name="pState">Pass 0. This isn't really used as FrameScript_Execute is just a wrapper around the actual lua_dostring
/// You do NOT need to pass the actual Lua state. You can retrieve that from the function callbacks!</param>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void LuaDoString(string lua, string fileName, uint pState);
Fairly simple to understand isn't it?
Also, make sure you're calling DoString FROM THE MAIN THREAD! It will silently fail on some functions if not called from the main thread. | 
07-03-2009
| | Master Sergeant | | | Join Date: Jul 2008
Posts: 102
Reputation: 22 Level up: 46%, 274 Points needed | | | Of course I called it from the main thread, I forgot to add that to the OP. It's working now, though
Last edited by vulcanaoc; 07-03-2009 at 02:11 PM.
Reason: awkward wording..
| 
07-03-2009
|  | Knight | | | Join Date: Apr 2009
Posts: 189
Reputation: 6 Level up: 84%, 81 Points needed |  | | Obviously a stupid question but as there are no stupid questions I just ask :>
What do you mean "call it from the main thread"... ?
I think I do it correctly but here is what I do and I have a problem with failing functions:
I made a Byte-String containing Asm Code for my routine to load the dll. I create a remote thread to load my .dll into WoW and start the "unofficial main-function" (a normal exported function I use to manage actions) of my dll. In that function I execute DoString().
Anything wrong about it? | 
07-03-2009
| | Master Sergeant | | | Join Date: Jul 2008
Posts: 102
Reputation: 22 Level up: 46%, 274 Points needed | | | Quote:
Originally Posted by flo8464 Obviously a stupid question but as there are no stupid questions I just ask :>
What do you mean "call it from the main thread"... ?
I think I do it correctly but here is what I do and I have a problem with failing functions:
I made a Byte-String containing Asm Code for my routine to load the dll. I create a remote thread to load my .dll into WoW and start the "unofficial main-function" (a normal exported function I use to manage actions) of my dll. In that function I execute DoString().
Anything wrong about it?  | If I understand you correctly, you're just calling WoW's functions from your own thread. This is a no-no.
You're probably going to want to hook a function that is in WoW's main thread, such as (I believe- this isn't what I hook) D3DDevice::EndScene. After you've hooked a function in the main thread, you can just call your functions and they should work. | 
07-03-2009
| | Knight-Lieutenant | | | Join Date: Jan 2008
Posts: 267
Reputation: 17 Level up: 16%, 589 Points needed |  | | Quote:
Originally Posted by vulcanaoc If I understand you correctly, you're just calling WoW's functions from your own thread. This is a no-no.
You're probably going to want to hook a function that is in WoW's main thread, such as (I believe- this isn't what I hook) D3DDevice::EndScene. After you've hooked a function in the main thread, you can just call your functions and they should work. | Sounds about right. EndScene() is called every frame in WoW. Hook it, and execute your code in there. EndScene() is in the main thread.
You aren't calling your Dostring in main thread, rather in some dll thread.
Last edited by ramey; 07-03-2009 at 03:57 PM.
| 
07-03-2009
|  | MMOwned WebDev Legendary User | | | Join Date: Jan 2008
Posts: 1,891
Nominated 5 Times in 1 Post Reputation: 1029 Points: 21,931, Level: 20 | Level up: 71%, 469 Points needed |     | | Quote:
Originally Posted by flo8464 Obviously a stupid question but as there are no stupid questions I just ask :> | Even so, it was a stupid question. | 
07-03-2009
| | Master Sergeant | | | Join Date: Jul 2008
Posts: 102
Reputation: 22 Level up: 46%, 274 Points needed | | | | Come on, it wasn't that stu- Oh, I see what you did there... :P | 
07-04-2009
|  | Kynox's sister's pimp Legendary User | | | Join Date: Apr 2006 Location: ntdll.dll
Posts: 4,092
Nominated 63 Times in 4 Posts  TOTM/W Award(s): 1 Reputation: 1057 Points: 54,398, Level: 34 | Level up: 84%, 602 Points needed |     | | | Fyi the final argument of DoString is the hardware event code I think. It's not a pointer, it's an integer.
The prototype is (or very close to it):
void FrameScript__Execute(const char* pBuffer, const char* pFile, unsigned int HWEvent);
So you might call it with:
Framescript__Execute("MoveForwardStart()", "FakeFileName.lua", 0); | 
07-04-2009
|  | ^Nothing is as it seems. Legendary User  | | | Join Date: Nov 2006 Location: Germany (DE)
Posts: 2,343
Nominated 15 Times in 3 Posts Reputation: 665 Points: 13,898, Level: 15 | Level up: 22%, 1,102 Points needed |     | | | Being the hardware event, this is also the reason, why certain functions wont be called (restricted) if you passed something.
The filename does not need to be a *.lua one but can be used for you to help you debugging in lua. You could pass the name of the function you're executing your script. The filename will be printed on lua errors seen in those message boxes with red font ingame. |  | |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | All times are GMT -4. The time now is 07:42 PM. |