Auto Link into WoW functions menu

User Tag List

Results 1 to 2 of 2
  1. #1
    apollo0510's Avatar Active Member
    Reputation
    18
    Join Date
    Aug 2008
    Posts
    53
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Auto Link into WoW functions

    After some less useful postings of mine, I would like to share something more useful now.

    This is about locating C-Functions in the WoW binary.

    First, we define a little helping structure:

    Code:
    struct CODE_SEARCH
    {
    	const char* pName;
    	void**      ppFunction;
    	const char* pCodeSearch;
    	const char* pCodeIgnore;
    
    	BOOL IsValid() 
    	{
    		return (pCodeSearch && pCodeSearch[0]) && (pCodeIgnore && pCodeIgnore[0]);
    	}
    
    	BOOL IsTerminator()
    	{
    		return (this==NULL) || (ppFunction==NULL);
    	}
    };
    and then we define the code searching function:

    Code:
    #define MAX_CODE_LEN 256
    
    BOOL SearchCode(CODE_SEARCH* pSearch,const char* logfilename)
    {
    	SYSTEM_INFO system_info;
    	GetSystemInfo(&system_info);
    	BYTE *pMaxAddress=(BYTE*)system_info.lpMaximumApplicationAddress;
    
    	int anz_functions=0;
    	{ // clear all function pointers in pSearch
    		CODE_SEARCH* pS=pSearch;
    		while(!pS->IsTerminator())
    		{
    			*pS->ppFunction=NULL;
    			if(pS->IsValid()) anz_functions++;
    			pS++;
    		}
    	}
    
    	union
    	{
    		BYTE* pCurrent;
    		DWORD current_dw;
    	};
    	pCurrent=(BYTE*)system_info.lpMinimumApplicationAddress;
    
    	int anz_found=0;
    	int last_page=-1;
    
    	FILE* pFile=fopen(logfilename,"w");
    	fprintf(pFile," // Starting LUA search for %d functions at [%p - %p]\n",anz_functions,pCurrent,pMaxAddress);
    	fprintf(pFile,"#include <idc.idc>\nstatic main()\n{\n");
    
    	while((!pSearch->IsTerminator()) && (pCurrent<pMaxAddress))
    	{
    		if(pSearch->IsValid())
    		{
    			int code_len=0;
    			BYTE code_search[MAX_CODE_LEN];
    			BYTE code_ignore[MAX_CODE_LEN];
    
    			const char* pCodeSearch=pSearch->pCodeSearch;
    			const char* pCodeIgnore=pSearch->pCodeIgnore;
    
    			for(code_len=0;code_len<MAX_CODE_LEN;code_len++)
    			{
    				if(!pCodeIgnore[code_len]) break;
    				code_ignore[code_len]= pCodeIgnore[code_len]=='?' ? 0 : 0xff;
    				code_search[code_len]= pCodeSearch[code_len]&code_ignore[code_len];
    			}
    
    			if(!code_len)
    			{
    				fprintf(pFile,"// No Code for %s\n",pSearch->pName);
    			}
    			else
    			{
    				fprintf(pFile,"// Searching for %s codelength=%d : ",pSearch->pName,code_len);
    				for(int i=0;i<code_len;i++)
    				{
    					if(code_ignore[i]) fprintf(pFile,"%02X ",code_search[i]);
    					else               fprintf(pFile,"?? ");
    				}
    				fprintf(pFile,"\n");
    
    				BOOL found=FALSE;
    				do
    				{
    					int page=current_dw/system_info.dwPageSize;
    					if(page!=last_page)
    					{
    						last_page=page;
    						MEMORY_BASIC_INFORMATION mem_info;
    						VirtualQuery(pCurrent,&mem_info,sizeof(MEMORY_BASIC_INFORMATION));
    						while( (mem_info.State!=MEM_COMMIT)||(mem_info.Protect!=PAGE_EXECUTE_READ) )
    						{   // try next page
    							current_dw+=system_info.dwPageSize;
    							current_dw&=~(system_info.dwPageSize-1);
    							if(pCurrent>=pMaxAddress) break;
    							VirtualQuery(pCurrent,&mem_info,sizeof(MEMORY_BASIC_INFORMATION));
    						}
    					}
    
    					if(pCurrent>=pMaxAddress) break;
    
    					int compare;
    					for(compare=0;compare<code_len;compare++)
    					{
    						if((pCurrent[compare]&code_ignore[compare])!=code_search[compare]) 
    						{
    							break;
    						}
    					}
    
    					if(compare==code_len)
    					{
    						fprintf(pFile,"   MakeName(0x%p,\"%s\");\n",pCurrent,pSearch->pName);
    						*pSearch->ppFunction=(void*)pCurrent;
    						pCurrent+=code_len;
    						anz_found++;
    						found=TRUE;
    					}
    					else
    					{
    						pCurrent++;
    					}
    					// align the pointer
    					current_dw+=0xf;
    					current_dw&=~0xf;
    				}while(!found);
    			}
    		}
    		pSearch++;
    	}
    	fprintf(pFile,"}\n");
    	fprintf(pFile,"\n// Ended LUA search , found %d\n",anz_found);
    	if(anz_found==anz_functions) fprintf(pFile,"// Found all functions\n");
    	else                         fprintf(pFile,"// Missing functions\n");
    	fclose(pFile);
    	return (anz_found==anz_functions);
    }
    Now, we would like to locate all lua stack manipulation functions , so we write:

    Code:
    /*
    ** basic stack manipulation
    */
    int			(*lua_gettop)	 (lua_State *L)			=NULL;
    void		(*lua_settop)	 (lua_State *L, int idx)=NULL; 
    void		(*lua_remove)	 (lua_State *L, int idx)=NULL;
    void		(*lua_insert)	 (lua_State *L, int idx)=NULL;
    void		(*lua_replace)	 (lua_State *L, int idx)=NULL; // search for "no calling environment"
    void		(*lua_pushvalue) (lua_State *L, int idx)=NULL;
    /*
    ** access functions (stack -> C)
    */
    int			  (*lua_type)			(lua_State *L, int idx)					=NULL;
    const char *  (*lua_typename)		(lua_State *L, int t)					=NULL;
    int			  (*lua_iscfunction)	(lua_State *L, int idx)					=NULL;
    int			  (*lua_isnumber)		(lua_State *L, int idx)					=NULL;
    int			  (*lua_isstring)		(lua_State *L, int idx)					=NULL;
    int			  (*lua_isuserdata)		(lua_State *L, int idx)					=NULL; // not implemented
    int			  (*lua_rawequal)		(lua_State *L, int index1, int index2)	=NULL;
    int			  (*lua_equal)			(lua_State *L, int index1, int index2)	=NULL;
    int			  (*lua_lessthan)		(lua_State *L, int index1, int index2)	=NULL; // not implemented
    lua_Number	  (*lua_tonumber)		(lua_State *L, int idx)					=NULL;
    lua_Integer   (*lua_tointeger)		(lua_State *L, int idx)					=NULL;
    int			  (*lua_toboolean)		(lua_State *L, int idx)					=NULL; 
    const char *  (*lua_tolstring)		(lua_State *L, int idx, size_t *len)	=NULL;
    size_t		  (*lua_objlen)			(lua_State *L, int idx)					=NULL;
    lua_CFunction (*lua_tocfunction)	(lua_State *L, int idx)					=NULL;
    void *		  (*lua_touserdata)		(lua_State *L, int idx)					=NULL; // not implemented
    lua_State *	  (*lua_tothread)		(lua_State *L, int idx)					=NULL;
    const void *  (*lua_topointer)		(lua_State *L, int idx)					=NULL;
    /*
    ** push functions (C -> stack)
    */
    void		(*lua_pushnil)			(lua_State *L)								=NULL;
    void		(*lua_pushnumber)		(lua_State *L, lua_Number n)				=NULL;
    void		(*lua_pushinteger)		(lua_State *L, lua_Integer n)				=NULL;
    void		(*lua_pushlstring)		(lua_State *L, const char *s, size_t len)	=NULL;
    void		(*lua_pushstring)		(lua_State *L, const char *s)				=NULL;
    const char *(*lua_pushvfstring)	    (lua_State *L, const char *fmt,va_list argp)=NULL;
    const char *(*lua_pushfstring)		(lua_State *L, const char *fmt, ...)		=NULL;
    void		(*lua_pushcclosure)	    (lua_State *L, lua_CFunction fn, int n)		=NULL;
    void		(*lua_pushboolean)		(lua_State *L, int b)						=NULL;
    void		(*lua_pushlightuserdata)(lua_State *L, void *p)					    =NULL; // not implemented
    int			(*lua_pushthread)		(lua_State *L)								=NULL;
    
    
    void (*FocusUnit)(OBJECT_GUID* pGuid)=NULL;
    void (*SelectTarget)(OBJECT_GUID Guid)=NULL;
    
    CODE_SEARCH lua_search[]=
    {
    	// basic stack manipulation
    	{ "lua_gettop"			,(void**)&lua_gettop		,"\x55\x8B\xEC\x8B\x4D\x08\x8B\x41\x0C\x2B\x41\x10\xC1\xF8\x04\x5D\xC3","xxxxxxxxxxxxxxxxx"	},
    	{ "lua_settop"			,(void**)&lua_settop		,"\x55\x8B\xEC\x8B\x4D\x0C\x85\xC9\x8B\x45\x08\x7C\x41\xC1\xE1\x04\x8B\xD1\x8B\x48\x10\x03\xCA\x39\x48\x0C","xxxxxxxxxxxxxxxxxxxxxxxxxx"	},
    	{ "lua_remove"			,(void**)&lua_remove		,"\x55\x8B\xEC\x8B\x45\x0C\x56\x8B\x75\x08\x8B\xCE\xE8\x5F\xFD\xFF\xFF\x83\xC0\x10\x3B\x46\x0C\x73\x50","xxxxxxxxxxxxx????xxxxxxxx"	},
    	{ "lua_insert"			,(void**)&lua_insert		,"\x55\x8B\xEC\x8B\x45\x0C\x57\x8B\x7D\x08\x8B\xCF\xE8\xEF\xFC\xFF\xFF\x8B\x4F\x0C\x3B\xC8\x76\x52","xxxxxxxxxxxxx????xxxxxxx"	},
    	{ "lua_replace"			,(void**)&lua_replace		,"\x55\x8B\xEC\x56\x8B\x75\x08\x57\x8B\x7D\x0C\x81\xFF\xEF\xD8\xFF\xFF\x75\x16\x8B\x46\x18\x3B\x46\x2C","xxxxxxxxxxxxxxxxxxxxxxxxx"	},
    	{ "lua_pushvalue"		,(void**)&lua_pushvalue	    ,"\x55\x8B\xEC\x8B\x45\x0C\x56\x8B\x75\x08\x8B\xCE\xE8\x5F\xFB\xFF\xFF\x8B\x10\x8B\x4E\x0C\x89\x11","xxxxxxxxxxxxx????xxxxxxx"	},
    	// access functions (stack -> C)
    	{ "lua_type"			,(void**)&lua_type			,"\x55\x8B\xEC\x8B\x45\x0C\x8B\x4D\x08\xE8\x02\xFB\xFF\xFF\x3D\x28\xBF\x9F\x00\x75\x05\x83\xC8\xFF\x5D\xC3\x8B\x40\x08\x5D\xC3","xxxxxxxxxx????x????xxxxxxxxxxxx"	},
    	{ "lua_typename"		,(void**)&lua_typename		,"\x55\x8B\xEC\x8B\x45\x0C\x83\xF8\xFF\x75\x07\xB8\x18\xBF\x9F\x00\x5D\xC3\x8B\x04\x85\x00\xCD\x9F\x00","xxxxxxxxxxxx????xxxxx????"	},	
    	{ "lua_iscfunction"		,(void**)&lua_iscfunction	,"\x55\x8B\xEC\x8B\x45\x0C\x8B\x4D\x08\xE8\xC2\xFA\xFF\xFF\x83\x78\x08\x06\x75\x0F\x8B\x00\x80\x78\x0A\x00","xxxxxxxxxx????xxxxxxxxxxxx"	},
    	{ "lua_isnumber"		,(void**)&lua_isnumber		,"\x55\x8B\xEC\x8B\x45\x0C\x8B\x4D\x08\x83\xEC\x10\xE8\x8F\xFA\xFF\xFF\x83\x78\x08\x03\x74\x15\x8D\x4D\xF0","xxxxxxxxxxxxx????xxxxxxxxx"	},	
    	{ "lua_isstring"		,(void**)&lua_isstring		,"\x55\x8B\xEC\x8B\x45\x0C\x8B\x4D\x08\xE8\x52\xFA\xFF\xFF\x3D\x28\xBF\x9F\x00\x74\x0D\x8B\x40\x08","xxxxxxxxxx????x????xxxxx"	},
    	{ "lua_isuserdata"		,(void**)&lua_isuserdata	,NULL,NULL	},	
    	{ "lua_rawequal"		,(void**)&lua_rawequal		,"\x55\x8B\xEC\x8B\x45\x0C\x56\x57\x8B\x7D\x08\x8B\xCF\xE8\x1E\xFA\xFF\xFF\x8B\xF0\x8B\x45\x10\x8B\xCF","xxxxxxxxxxxxxx????xxxxxxx"	},
    	{ "lua_equal"			,(void**)&lua_equal			,"\x55\x8B\xEC\x8B\x45\x0C\x56\x8B\x75\x08\x57\x8B\xCE\xE8\xCE\xF9\xFF\xFF\x8B\xF8\x8B\x45\x10\x8B\xCE","xxxxxxxxxxxxxx????xxxxxxx"	},	
    	{ "lua_lessthan"		,(void**)&lua_lessthan		,NULL,NULL	},
    	{ "lua_tonumber"		,(void**)&lua_tonumber		,"\x55\x8B\xEC\x8B\x45\x0C\x8B\x4D\x08\x83\xEC\x10\xE8\x7F\xF9\xFF\xFF\x83\x78\x08\x03\x74\x17\x8D\x4D\xF0","xxxxxxxxxxxxx????xxxxxxxxx"	},	
    	{ "lua_tointeger"		,(void**)&lua_tointeger		,"\x55\x8B\xEC\x8B\x45\x0C\x8B\x4D\x08\x83\xEC\x1C\xE8\x3F\xF9\xFF\xFF\x83\x78\x08\x03\x74\x15\x8D\x4D\xE4","xxxxxxxxxxxxx????xxxxxxxxx"	},
    	{ "lua_toboolean"		,(void**)&lua_toboolean		,"\x55\x8B\xEC\x8B\x45\x0C\x8B\x4D\x08\xE8\x02\xF9\xFF\xFF\x8B\x48\x08\x85\xC9\x74\x11\x83\xF9\x01","xxxxxxxxxx????xxxxxxxxxx"	},	
    	{ "lua_tolstring"		,(void**)&lua_tolstring		,"\x55\x8B\xEC\x56\x8B\x75\x08\x57\x8B\x7D\x0C\x8B\xC7\x8B\xCE\xE8\xCC\xF8\xFF\xFF\x83\x78\x08\x04","xxxxxxxxxxxxxxxx????xxxx"	},
    	{ "lua_objlen"			,(void**)&lua_objlen		,"\x55\x8B\xEC\x8B\x45\x0C\x56\x57\x8B\x7D\x08\x8B\xCF\xE8\x5E\xF8\xFF\xFF\x8B\xF0\x8B\x46\x08\x83\xC0\xFD","xxxxxxxxxxxxxx????xxxxxxxx"	},	
    	{ "lua_tocfunction"		,(void**)&lua_tocfunction	,"\x55\x8B\xEC\x8B\x45\x0C\x8B\x4D\x08\xE8\xF2\xF7\xFF\xFF\x8B\x48\x08\x83\xE9\x02\x74\x10\x83\xE9\x05","xxxxxxxxxx????xxxxxxxxxxx"	},
    	{ "lua_touserdata"		,(void**)&lua_touserdata	,NULL,NULL	},	
    	{ "lua_tothread"		,(void**)&lua_tothread		,"\x55\x8B\xEC\x8B\x45\x0C\x8B\x4D\x08\xE8\xC2\xF7\xFF\xFF\x83\x78\x08\x08\x74\x04\x33\xC0\x5D\xC3","xxxxxxxxxx????xxxxxxxxxx"	},
    	{ "lua_topointer"		,(void**)&lua_topointer		,"\x55\x8B\xEC\x56\x8B\x75\x0C\x57\x8B\x7D\x08\x8B\xC6\x8B\xCF\xE8\x9C\xF7\xFF\xFF\x8B\x48\x08\x83\xC1\xFE\x83\xF9\x06\x77\x2C\xFF\x24\x8D\xD4\x62\x91\x00\x8B\x00\x5F\x5E\x5D\xC3\x8B\xC6\x8B\xCF\xE8\x7B\xF7\xFF\xFF\x8B\x48\x08\x83\xE9\x02\x74\xE9\x83\xE9\x05\x75\x09\x8B\x00\x5F\x83\xC0\x18\x5E\x5D\xC3\x5F\x33\xC0\x5E\x5D\xC3","xxxxxxxxxxxxxxxx????xxxxxxxxxxxxxx????xxxxxxxxxxx????xxxxxxxxxxxxxxxxxxxxxxxxxxxx"	},	
    	// push functions (C -> stack)
    	{ "lua_pushnil"			,(void**)&lua_pushnil		,"\x55\x8B\xEC\x8B\x45\x08\x8B\x48\x0C\x8B\x15\x20\x7C\x35\x01\x89\x51\x0C\xC7\x41\x08\x00\x00\x00\x00","xxxxxxxxxxx????xxxxxxxxxx"	},	
    	{ "lua_pushnumber"		,(void**)&lua_pushnumber	,"\x55\x8B\xEC\x8B\x4D\x08\xDD\x45\x0C\x8B\x41\x0C\x8B\x15\x20\x7C\x35\x01\xDD\x18\x89\x50\x0C\xC7\x40\x08\x03\x00\x00\x00","xxxxxxxxxxxxxx????xxxxxxxxxxxx"	},	
    	{ "lua_pushinteger"		,(void**)&lua_pushinteger	,"\x55\x8B\xEC\x8B\x4D\x08\xDB\x45\x0C\x8B\x41\x0C\x8B\x15\x20\x7C\x35\x01\xDD\x18\x89\x50\x0C\xC7\x40\x08\x03\x00\x00\x00","xxxxxxxxxxxxxx????xxxxxxxxxxxx"	},	
    	{ "lua_pushlstring"		,(void**)&lua_pushlstring	,"\x55\x8B\xEC\x56\x8B\x75\x08\x8B\x46\x14\x8B\x48\x44\x3B\x48\x40\x57\x72\x09\x56\xE8\xD7\x90\x00\x00","xxxxxxxxxxxxxxxxxxxxx????"	},	
    	{ "lua_pushstring"		,(void**)&lua_pushstring	,"\x55\x8B\xEC\x8B\x55\x0C\x85\xD2\x75\x1C\x8B\x45\x08\x8B\x48\x0C\x8B\x15\x20\x7C\x35\x01\x89\x51\x0C","xxxxxxxxxxxxxxxxxx????xxx"	},	
    	{ "lua_pushvfstring"	,(void**)&lua_pushvfstring	,"\x55\x8B\xEC\x56\x8B\x75\x08\x8B\x46\x14\x8B\x48\x44\x3B\x48\x40\x72\x09\x56\xE8\x38\x90\x00\x00","xxxxxxxxxxxxxxxxxxxx????"	},	
    	{ "lua_pushfstring"		,(void**)&lua_pushfstring	,"\x55\x8B\xEC\x56\x8B\x75\x08\x8B\x46\x14\x8B\x48\x44\x3B\x48\x40\x72\x09\x56\xE8\x08\x90\x00\x00","xxxxxxxxxxxxxxxxxxxx????"	},	
    	{ "lua_pushcclosure"	,(void**)&lua_pushcclosure	,"\x55\x8B\xEC\x53\x56\x8B\x75\x08\x8B\x46\x14\x8B\x48\x44\x3B\x48\x40\x57\x72\x09\x56\xE8\xD6\x8F\x00\x00","xxxxxxxxxxxxxxxxxxxxxx????"	},	
    	{ "lua_pushboolean"		,(void**)&lua_pushboolean	,"\x55\x8B\xEC\x8B\x15\x20\x7C\x35\x01\x8B\x4D\x08\x8B\x41\x0C\x89\x50\x0C\x33\xD2\x39\x55\x0C\xC7\x40\x08\x01\x00\x00\x00","xxxxx????xxxxxxxxxxxxxxxxxxxxx"	},	
    	{ "lua_pushlightuserdata",(void**)&lua_pushlightuserdata	,NULL,NULL	},	
    	{ "lua_pushthread"		,(void**)&lua_pushthread	,"\x55\x8B\xEC\x8B\x15\x20\x7C\x35\x01\x8B\x4D\x08\x8B\x41\x0C\x89\x50\x0C\x8B\x55\x0C\x89\x10\xC7\x40\x08\x02\x00\x00\x00","xxxxx????xxxxxxxxxxxxxxxxxxxxx"	},	
    	// terminator
    	{ NULL,NULL,NULL,NULL},
    
    };

    .. and finally, upon DLL injection, we call

    Code:
    	if(!SearchCode(lua_search,"Logs/lua_search.idc"))
    	{
    		::ExitProcess(0); // exit the hard way
    	}
    Now, as a nice side effect, the searchinog function creates an idc file, that you can directly feed into IDA to add your symbols.

    Credits to the maker of the pattern plugin for IDA. I use that to generate my patterns and I paste them into the above code.


    Greetings
    Apollo


    Edit: Don't worry if lua_State is undefined. Declare it as a void thing or a dummy structure and off you go.
    Last edited by apollo0510; 05-04-2009 at 10:57 AM.

    Auto Link into WoW functions
  2. #2
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nice framework!

Similar Threads

  1. [Bot] Injection code into wow. Do you have to call functions from the main thread?
    By Miivers in forum World of Warcraft Bots and Programs
    Replies: 2
    Last Post: 01-13-2014, 02:56 PM
  2. [Guide] Importing Warcraft 3 Models Into WoW *Not for Beginners*
    By Derision in forum WoW ME Tools & Guides
    Replies: 7
    Last Post: 02-07-2008, 11:05 PM
  3. [GUIDE]Stuff your own music into WoW. [Pictures]
    By Macroman in forum WoW ME Tools & Guides
    Replies: 22
    Last Post: 10-23-2007, 06:34 AM
  4. Using proxy/etc. ? to log into wow
    By minim in forum World of Warcraft General
    Replies: 0
    Last Post: 10-15-2007, 01:36 PM
  5. Paul Stanley download link and WoW Item Creator :)
    By stradivuckos in forum Community Chat
    Replies: 9
    Last Post: 09-23-2007, 03:38 AM
All times are GMT -5. The time now is 01:58 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