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},
};