-
Contributor
[Classic] LuaC offsets (33920)
Just some luac stuff i found whilst working on a project figured I'd share.
Code:
namespace LuaOffsets
{
//base
inline uintptr_t base = reinterpret_cast<uintptr_t>(GetModuleHandle(nullptr));
//lua
inline uintptr_t lua_newstate = base + 0x1649CF0;
inline uintptr_t lua_close = base + 0x1649C70;
inline uintptr_t lua_checkstack = base + 0x1643E60;
inline uintptr_t lua_xmove = base + 0x1646040;
inline uintptr_t lua_setlevel = base + 0x1645A40;
inline uintptr_t lua_atpanic = base + 0x1643DF0;
inline uintptr_t lua_newthread = base + 0x1644C30;
inline uintptr_t lua_gettop = base + 0x16447E0;
inline uintptr_t lua_settop = base + 0x1645B60;
inline uintptr_t lua_remove = base + 0x1645690;
inline uintptr_t lua_insert = base + 0x1644960;
inline uintptr_t lua_replace = base + 0x1645770;
inline uintptr_t lua_pushvalue = base + 0x1645200;
inline uintptr_t lua_type = base + 0x1645FF0;
inline uintptr_t lua_typename = base + 0x1646020;
inline uintptr_t lua_iscfunction = base + 0x1644AC0;
inline uintptr_t lua_isnumber = base + 0x1644AF0;
inline uintptr_t lua_isstring = base + 0x1644B20;
inline uintptr_t lua_isuserdata = base + 0x1644B60;
inline uintptr_t lua_rawequal = base + 0x1645300;
inline uintptr_t lua_equal = base + 0x0; //not found
inline uintptr_t lua_lessthan = base + 0x1644B90;
inline uintptr_t lua_tonumber = base + 0x1645EE0;
inline uintptr_t lua_tointeger = base + 0x1645DC0;
inline uintptr_t lua_toboolean = base + 0x1645D60;
inline uintptr_t lua_tolstring = base + 0x1645E40;
inline uintptr_t lua_objlen = base + 0x1644D40;
inline uintptr_t lua_tocfunction = base + 0x0; //not found
inline uintptr_t lua_touserdata = base + 0x1645FB0;
inline uintptr_t lua_tothread = base + 0x1645F90;
inline uintptr_t lua_topointer = base + 0x1645F20;
inline uintptr_t lua_pushnil = base + 0x16450E0;
inline uintptr_t lua_pushnumber = base + 0x1645100;
inline uintptr_t lua_pushinteger = base + 0x1645010;
inline uintptr_t lua_pushlstring = base + 0x1645060;
inline uintptr_t lua_pushvfstring = base + 0x16452B0;
inline uintptr_t lua_pushfstring = base + 0x1644FC0;
inline uintptr_t lua_pushcclosure = base + 0x1644E80;
inline uintptr_t lua_pushboolean = base + 0x1644E50;
inline uintptr_t lua_pushlightuserdata = base + 0x1645040;
inline uintptr_t lua_pushthread = base + 0x16451D0;
inline uintptr_t lua_gettable = base + 0x16447B0;
inline uintptr_t lua_getfield = base + 0x16446C0;
inline uintptr_t lua_rawget = base + 0x1645350;
inline uintptr_t lua_rawgeti = base + 0x1645400;
inline uintptr_t lua_createtable = base + 0x16440B0;
inline uintptr_t lua_getmetatable = base + 0x1644740;
inline uintptr_t lua_getfenv = base + 0x16444D0;
inline uintptr_t lua_settable = base + 0x1645B10;
inline uintptr_t lua_setfield = base + 0x16459C0;
inline uintptr_t lua_rawset = base + 0x16454B0;
inline uintptr_t lua_rawseti = base + 0x16455A0;
inline uintptr_t lua_setmetatable = base + 0x1645A50;
inline uintptr_t lua_setfenv = base + 0x16458E0;
inline uintptr_t lua_call = base + 0x1643E10;
inline uintptr_t lua_pcall = base + 0x1644DC0;
inline uintptr_t lua_cpcall = base + 0x0; //not found
inline uintptr_t lua_load = base + 0x1644BE0;
inline uintptr_t lua_dump = base + 0x0; //not found
inline uintptr_t lua_status = base + 0x1645D50;
inline uintptr_t lua_gc = base + 0x16441E0;
inline uintptr_t lua_error = base + 0x16441D0;
inline uintptr_t lua_next = base + 0x1644D00;
inline uintptr_t lua_concat = base + 0x1643F30;
inline uintptr_t lua_getallocf = base + 0x0; //not found
inline uintptr_t lua_setallocf = base + 0x0; //not found
inline uintptr_t lua_newuserdata = base + 0x1644C80;
inline uintptr_t lua_getupvalue = base + 0x0; //not found
inline uintptr_t lua_setupvalue = base + 0x0; //not found
inline uintptr_t lua_yield = base + 0x1650600;
inline uintptr_t lua_resume = base + 0x16504B0;
inline uintptr_t lua_getstack = base + 0x1648D10;
inline uintptr_t lua_getinfo = base + 0x1648AE0;
inline uintptr_t lua_getlocal = base + 0x1648CA0;
inline uintptr_t lua_setlocal = base + 0x0; //not found
inline uintptr_t lua_sethook = base + 0x0; //not found
inline uintptr_t lua_gethook = base + 0x0; //not found
inline uintptr_t lua_gethookmask = base + 0x0; //not found
inline uintptr_t lua_gethookcount = base + 0x0; //not found
//luaL
inline uintptr_t luaL_openlib = base + 0x1647440;
inline uintptr_t luaL_register = base + 0x16479B0;
inline uintptr_t luaL_getmetafield = base + 0x1646C00;
inline uintptr_t luaL_callmeta = base + 0x16465D0;
inline uintptr_t luaL_typerror = base + 0x1647B00;
inline uintptr_t luaL_argerror = base + 0x16464C0;
inline uintptr_t luaL_where = base + 0x1647D00;
inline uintptr_t luaL_error = base + 0x1646A20;
inline uintptr_t luaL_checkoption = base + 0x1646810;
inline uintptr_t luaL_ref = base + 0x16477A0;
inline uintptr_t luaL_unref = base + 0x1647B60;
inline uintptr_t luaL_loadfile = base + 0x0; //not found
inline uintptr_t luaL_loadbuffer = base + 0x16470D0;
inline uintptr_t luaL_newstate = base + 0x0; //not found
inline uintptr_t luaL_gsub = base + 0x0; //not found
inline uintptr_t luaL_findtable = base + 0x1646AD0;
inline uintptr_t luaL_buffinit = base + 0x16465B0;
inline uintptr_t luaL_prepbuffer = base + 0x16476F0;
inline uintptr_t luaL_addlstring = base + 0x1646340;
inline uintptr_t luaL_addvalue = base + 0x1646400;
inline uintptr_t luaL_pushresult = base + 0x1647740;
}
Last edited by Icesythe7; 04-10-2020 at 07:48 PM.
-
Post Thanks / Like - 5 Thanks
-
Contributor
Oh also heres a wrapper to make it easier to call the lua functions
Code:
template<typename RetVal_t>
RetVal_t DefaultValue() { return {}; }
template<>
inline void DefaultValue<void>() {}
template<typename T, typename... Args_t>
T LuaCall(uintptr_t luaFunc, Args_t... args)
{
if (luaFunc > LuaOffsets::base)
{
using LuaFunc_t = T(__fastcall*)(Args_t...);
return reinterpret_cast<LuaFunc_t>(luaFunc)(std::forward<Args_t>(args)...);
}
return DefaultValue<T>();
}
usage is like so
Code:
inline const char* lua_tolstring(lua_State* L, int idx, size_t* len)
{
return LuaCall<const char*>(LuaOffsets::lua_tolstring, L, idx, len);
}
then you could call lua functions like so given you are in the games thread
Code:
const auto l = *reinterpret_cast<lua_State**>(base + 0x22BD2A8); //lua_State
lua_getglobal(l, "UnitHealth");
lua_pushstring(l, "player");
lua_call(l, 1, 1);
std::cout << lua_tonumber(l, -1) << std::endl;
lua_pop(l, -1);
Last edited by Icesythe7; 04-11-2020 at 06:08 AM.
-
Post Thanks / Like - 4 Thanks
-
Member
Does this method call Lua need to be in the main thread?
-
Contributor
Originally Posted by
sanyle
Does this method call Lua need to be in the main thread?
It can be wherever you want it but you should call it from the games thread.
-
Member
hi guys, after call luaL_register to register my own function(such as "MyLuaFunc") to lua,i put the command in chat window: /run MyLuaFunc()
then the question occured: invalid function point....
after search, i found wow will check function ptr ,if ptr is not in his .text , the game crashed...
then i want to search a game function ,and change the code make jmp to my function...
then i found wow module addr with 0x1Fa0000 size are map with PAGE_EXECUTE_READ ,i can't even change 1 bit ,and i can't change flProtect with virtualprotect...
then i have no idea how to solve the problem.
plz Give me directions or advise, thanks!!!
(sorry for my poor english!)
-
Contributor
Originally Posted by
lsx11111
hi guys, after call luaL_register to register my own function(such as "MyLuaFunc") to lua,i put the command in chat window: /run MyLuaFunc()
then the question occured: invalid function point....
after search, i found wow will check function ptr ,if ptr is not in his .text , the game crashed...
then i want to search a game function ,and change the code make jmp to my function...
then i found wow module addr with 0x1Fa0000 size are map with PAGE_EXECUTE_READ ,i can't even change 1 bit ,and i can't change flProtect with virtualprotect...
then i have no idea how to solve the problem.
plz Give me directions or advise, thanks!!!
(sorry for my poor english!)
There is a few different ways but if you are just wanting a quick test for yourself you can modify the invalid function pointer check address in .data to be the address of your custom function + 1byte, just dont change it to max int64 (ie dont change it to 0xFFFFFFFFFFF) As stated there are better safer ways but again as a quick test this will work.
That address by the way is (base + 0x22E2610)
-
Post Thanks / Like - 1 Thanks
lsx11111 (1 members gave Thanks to Icesythe7 for this useful post)
-
Member
i found this address! the func ptr must be in range of (base + 0x22E2608,base + 0x22E2610) ,but i don't know is this security.
-
Contributor
Originally Posted by
lsx11111
i found this address! the func ptr must be in range of (base + 0x22E2608,base + 0x22E2610) ,but i don't know is this security.
Yes so expand the value of base + 0x22E2610 to be greater than the address of the function you register
-
Post Thanks / Like - 1 Thanks
lsx11111 (1 members gave Thanks to Icesythe7 for this useful post)
-
Member
Yep! it works! thank you very much!
-
Thank you.
This should be perfect to get started up again. I'm always coming back to this project, but now it seems I can almost wrap my head around it instead of just doing a recipe of instructions then tinkering.
Last edited by GlittPrizes; 04-28-2020 at 12:42 PM.