I'd like to share my experiments about calling lua functions and getting their results in outer program.
Most lua functions we can see in IDA, only have one argument, which is always called "lua state". Then how such fuctions get their true aruguments and how they return their results(maybe several returned values)?
these are lua stack addresses and functions to get arguments and set values:
//lua state address
ptrLua_L = $012E87EC;
//get arguments from lua stack
ptrLua_ToString = $007AD920;
ptrLua_ToNumber = $007AD870;
//push results to lua stack
ptrLua_PushString = $007ADB90;
ptrLua_PushNumber = $007ADAE0;
ptrLua_PushNil = $007ADAC0;
//this address shows which addon is call lua function, the value is addon's name(string)
ptrAddon = $012EA330;
now, I give an example for calling the lua function : GetPlayerMapPosition(unit)
this func needs a string arg and returns two number values,like this:
x,y = GetPlayerMapPosition("player")
ptrGetPlayerMapPosition = $004BBD70
type
TLua_ToString = function(Lua_L,index,Zero:LongWord):PChar;cdecl;
TLua_ToNumber = function(Lua_L,index : LongWord):double;cdecl;
TLua_PushString = function(Lua_L:Longword;value:PChar):Integer;cdecl;
TLua_PushNumber = function(Lua_L:LongWord;valueouble):Integer;cdecl;
TLua_PushNil = function(Lua_L:LongWord):Integer;cdecl;
var
Lua_ToString : TLua_ToString = Pointer(ptrLua_ToString);
Lua_ToNumber : TLua_ToNumber = Pointer(ptrLua_ToNumber);
Lua_PushString : TLua_PushString = Pointer(ptrLua_PushString);
Lua_PushNumber : TLua_PushNumber = Pointer(ptrLua_PushNumber);
Lua_PushNil : TLua_PushNil = Pointer(ptrLua_PushNil);
then,it's easy to call a lua function
procedure MyGetPlayerMapPosition(var x,y : double)
var
unit : PChar;
Lua_L : DWord;
begin
//prepare parameters
unit := 'player';
Lua_L := GetDWordValue(ptrLua_L);
//push argument to lua stack
Lua_PushString(Lua_L,unit);
//cal lua function
asm
mov ebx,ptrGetPlayerMapPosition
call ebx
end;
//get returned values from lua stack
x := Lua_ToNumber(Lua_L,1);
y := Lua_ToNumber(Lua_L,2);
end;
If the lua function we are calling is protected, we should clear addon value.
example code is :
...
mov [ptrAddon],0
mov ebx,ptrGetPlayerMapPosition
call ebx
...
That's all.