cheat-engine/Cheat Engine/LuaHandler.pas
2023-11-22 16:59:38 +01:00

17390 lines
411 KiB
ObjectPascal
Executable file

unit LuaHandler;
{todo: Split up into smaller units. 9255 lines is becomming too big}
{todo2: dll injecting lua into a target process}
{Note:
Assume all strings passed between lua are in UTF8 format
}
{$mode delphi}
interface
uses
{$ifdef darwin}
mactypes, macport, LCLIntf, LCLType, macCreateRemoteThread, dynlibs,
{$endif}
{$ifdef windows}
jwawindows, windows, ShellApi,
{$endif}
vmxfunctions, Classes, dialogs, SysUtils, lua, lualib,
lauxlib, syncobjs, syncobjs2, CEFuncProc, NewKernelHandler, Graphics,
controls, LuaCaller, forms, ExtCtrls, StdCtrls, comctrls, ceguicomponents,
genericHotkey, luafile, xmplayer_server, ExtraTrainerComponents, customtimer,
menus, XMLRead, XMLWrite, DOM, Clipbrd, typinfo, PEInfoFunctions,
LCLProc, strutils, registry, md5, commonTypeDefs, LResources, Translations,
variants, LazUTF8, zstream, MemoryQuery, LCLVersion
{$ifdef darwin}
,macportdefines
{$endif},
{$ifdef laztrunk}
LazFileUtils,
{$endif}
betterControls;
const MAXTABLERECURSIONLOOKUP=2;
var
_LuaVM: Plua_State; //Global lua state (generally not used by anything except creating threads)
_LuaCS: Tcriticalsection; //critical section for the _LuaVM state
threadvar
Thread_LuaVM: PLua_State;
Thread_LuaRef: integer;
function lua_strtofloat(s: string): double;
function lua_strtoint(s: string): integer;
procedure lua_register(L: Plua_State; const n: PChar; f: lua_CFunction);
function lua_pcall(L: Plua_State; nargs, nresults, errf: Integer): Integer; cdecl;
function lua_dostring(L: Plua_State; const str: PChar): Integer;
function luaL_ref(L: Plua_State; t: Integer): Integer; cdecl;
procedure luaL_unref(L: Plua_State; t, ref: Integer); cdecl;
procedure Lua_RegisterObject(name: string; o: TObject);
function CheckIfConditionIsMetContext(threadid: dword; context: pointer; script: string): boolean;
procedure LUA_DoScript(s: string);
function LUA_functioncall(routinetocall: string; parameters: array of const): integer;
procedure LUA_memrec_callback(memrec: pointer; routine: string);
procedure LUA_SetCurrentContextState(tid: dword; context: pointer; extraregs: boolean=false);
procedure LUa_GetNewContextState(context: pointer; extraregs: boolean=false);
function LUA_onBreakpoint(threadid: dword; context: PContext; functionAlreadyPushed: boolean=false): boolean;
procedure LUA_onNotify(functionid: integer; sender: tobject);
function Lua_ToString(L: Plua_State; i: Integer): string;
function lua_ToCEUserData(L: PLua_state; i: integer): pointer;
function lua_tovariant(L: PLua_state; i: integer): variant;
procedure lua_pushvariant(L: PLua_state; v: variant);
procedure lua_pushrect(L: PLua_state; r: TRect);
procedure lua_pushpoint(L: PLua_state; r: TPoint);
function lua_toRect(L: PLua_State; index: integer): TRect;
function lua_toPoint(L: PLua_State; index: integer): TPoint;
function lua_toaddress(L: PLua_state; i: integer; self: boolean=false): ptruint;
procedure lua_pushcontext(L: PLua_state; context: PContext);
procedure InitializeLuaScripts(noautorun: boolean=false);
procedure InitializeLua;
procedure InitLimitedLuastate(L: Plua_State);
function LuaValueToDescription(L: PLua_state; i: integer; recursivetablecount: integer=0): string;
function GetLuaState: PLUA_State; inline;
function LuaVM: PLUA_State; inline;
function lua_oldprintoutput:TStrings;
procedure lua_setPrintOutput(output: TStrings);
function lua_synchronize(L: Plua_State): integer; cdecl;
resourcestring
rsPluginAddress = 'Plugin Address';
rsThisTypeIsNotSupportedHere='This type is not supported here';
rsIncorrectNumberOfParameters='Incorrect number of parameters';
implementation
uses autoassembler, MainUnit, MainUnit2, LuaClass, frmluaengineunit, plugin, pluginexports,
formsettingsunit, MemoryRecordUnit, debuggertypedefinitions, symbolhandler,
symbolhandlerstructs, types,
frmautoinjectunit, simpleaobscanner, addresslist, memscan, foundlisthelper,
cesupport, DBK32functions, sharedMemory, disassemblerComments, disassembler,
LuaCanvas, LuaPen, LuaFont, LuaBrush, LuaPicture, LuaMenu, LuaDebug, LuaThread,
LuaGraphic, LuaProgressBar, LuaOldD3DHook, LuaWinControl, LuaMemoryRecord,
LuaForm, MemoryBrowserFormUnit, disassemblerviewunit, hexviewunit,
CustomTypeHandler, LuaStructure, LuaRegion, LuaXMPlayer, LuaMemscan, LuaFoundlist,
LuaRadioGroup, LuaRasterImage, LuaCheatComponent, LuaAddresslist, byteinterpreter,
OpenSave, CEDebugger, DebugHelper, StructuresFrm2, Assemblerunit, LuaObject,
LuaComponent, LuaControl, LuaStrings, LuaStringlist, LuaCustomControl,
LuaGraphicControl, LuaPanel, LuaImage, LuaButton, LuaCheckbox, LuaGroupbox,
LuaListbox, LuaCombobox, LuaTrackbar, LuaListcolumn, LuaEdit, LuaMemo, LuaCollection,
LuaListColumns, LuaListItem, LuaListItems, LuaTimer, LuaListview, LuaGenericHotkey,
LuaTableFile, LuaMemoryRecordHotkey, LuaMemoryView, LuaD3DHook, LuaDisassembler,
LuaDissectCode, LuaByteTable, LuaBinary, lua_server, HotkeyHandler, LuaPipeClient,
LuaPipeServer, LuaTreeview, LuaTreeNodes, LuaTreeNode, LuaCalendar, LuaSymbolListHandler,
LuaCommonDialog, LuaFindDialog, LuaSettings, LuaPageControl, LuaStructureFrm,
LuaInternet, SymbolListHandler, ProcessHandlerUnit, processlist,
DebuggerInterface, WindowsDebugger, VEHDebugger, KernelDebuggerInterface,
DebuggerInterfaceAPIWrapper, Globals, math, speedhack2, CETranslator, binutils,
xinput, winsapi, frmExeTrainerGeneratorUnit, CustomBase85, FileUtil, networkConfig,
LuaCustomType, Filehandler, LuaSQL, frmSelectionlistunit, cpuidUnit, LuaRemoteThread,
LuaManualModuleLoader, pointervaluelist, frmEditHistoryUnit, LuaCheckListBox,
LuaDiagram, frmUltimap2Unit, frmcodefilterunit, BreakpointTypeDef, LuaSyntax,
LazLogger, LuaSynedit, LuaRIPRelativeScanner, LuaCustomImageList ,ColorBox,
rttihelper, LuaDotNetPipe, LuaRemoteExecutor, windows7taskbar, debugeventhandler,
tcclib, dotnethost, CSharpCompiler, LuaCECustomButton, feces, process,
networkInterface, networkInterfaceApi, LuaVirtualStringTree, userbytedisassembler,
parsers, LuaNetworkInterface, symbolsync, GDBServerDebuggerInterface, contexthandler;
{$warn 5044 off}
resourcestring
rsLUA_DoScriptWasNotCalledRomTheMainThread = 'LUA_DoScript was not called '
+'from the main thread';
rsUndefinedLuaError = 'Undefined lua error';
rsCheatengineIsBeingAFag = 'Cheatengine is being a fag';
rsInvalidFloat = 'Invalid floating point string:%s';
rsInvalidInt = 'Invalid integer:%s';
rsError = 'Error:';
rsConditionalBreakpointError = 'Conditional breakpoint error';
rsNonMainthreadLuaError = 'Lua error in a secondary thread';
rsMainLuaError = 'main.lua error:';
rsMainLuaError2 = 'main.lua error';
rsError2 = ' error:';
rsError3 = ' error';
rsLUAPanic = 'LUA panic!';
rsDebugsetBreakpointNeedsAtLeastAnAddress = 'debug_setBreakpoint needs at least an address';
rsCreateMemScanNeedsAProgressbarOrNil = 'createMemScan needs a progressbar or nil. ';
rsIsNotAProgressbar = ' is not a progressbar';
rsDeallocateSharedMemoryIsNotImplemented = 'deallocateSharedMemory is not implemented (It''s not even in the list of available functions)';
rsGetProcessListTheProvidedListObjectIsNotValid = 'getProcessList: the provided List object is not valid';
rsGetThreadlistTheProvidedListObjectIsNotValid = 'getThreadlist: the provided List object is not valid';
rsPlaySoundTheParameterMustBeATableFileOrAMemoryStream = 'playSound: The parameter must be a table file or a memory stream. Nothing else';
rsNumberRequired = 'Number required';
rsScriptCorruptedVar = '%s has corrupted the global %s variable. Many scripts will fail to load now';
var
printoutput: TStrings;
waitforsymbols: boolean=true;
autorunpath: string;
function lua_oldprintoutput:TStrings;
begin
result:=printoutput;
end;
procedure lua_setPrintOutput(output: TStrings);
begin
printoutput:=output;
end;
function GetLuaState: PLUA_State; inline;
begin
if Thread_LuaVM=nil then
begin
if (_luacs<>nil) and (_luavm<>nil) then
begin
_luacs.Enter;
try
if _luavm<>nil then
begin
Thread_LuaVM:=lua_newthread(_luavm);
Thread_LuaRef:=luaL_ref(_luavm, LUA_REGISTRYINDEX);
end;
finally
_luacs.leave;
end;
end;
end;
result:=Thread_LuaVM;
end;
function LuaVM: PLUA_State; inline;
begin
result:=GetLuaState;
end;
procedure lua_register(L: Plua_State; const n: PChar; f: lua_CFunction);
//overriding the original lua_register to add both a lower and uppercase start
var s: string;
begin
if luasyntaxStringHashList<>nil then
luasyntaxStringHashList.Add(n);
lua.lua_register(L, n, f);
s:=n;
s[1]:=chr(ord(s[1]) xor $20); //switch from uppercase to lowercase and lowercase to uppercase
lua.lua_register(L, pchar(s), f);
if luasyntaxStringHashList<>nil then
luasyntaxStringHashList.Add(s);
end;
var luarefcs: TCriticalSection;
function luaL_ref(L: Plua_State; t: Integer): Integer; cdecl;
begin
luarefcs.Enter;
result:=lauxlib.luaL_ref(l, t);
luarefcs.leave;
end;
procedure luaL_unref(L: Plua_State; t, ref: Integer); cdecl;
begin
luarefcs.enter;
lauxlib.luaL_unref(l, t, ref);
luarefcs.leave;
end;
threadvar insideErrorHandler: boolean;
function lua_defaulterrorhandler(L: Plua_State):integer; cdecl;
var
e: string;
traceresult: string;
begin
result:=0;
insideErrorHandler:=true;
try
lua_getglobal(L,'onLuaError');
if lua_isfunction(L,-1) then
begin
lua_pushvalue(L,1);
lua_pcall(L,1,1,0);
exit(1);
end;
//still here so no onLuaError
lua_pop(L,1);
//lual_traceback is also an option
lua_getglobal(L,'debug');
if not lua_istable(L,-1) then
begin
lua_pop(L,1);
exit(1);
end;
lua_pushstring(L,'traceback');
lua_gettable(L,-2);
if not lua_isfunction(L,-1) then
begin
lua_pop(L,2);
exit(1);
end;
e:=LuaValueToDescription(L,1);
lua_pushstring(L,e);
lua_pushinteger(L,2);
lua_pcall(L,2,1,0);
traceresult:=Lua_ToString(L,-1);
lua_pop(L,1);
lua_pushstring(L,traceresult);
result:=1;
finally
insideErrorHandler:=false;
end;
end;
function lua_pcall(L: Plua_State; nargs, nresults, errf: Integer): Integer; cdecl;
var
error: string;
usesluaengineform: boolean;
addedexceptionhandler: boolean;
begin
try
if lua_isfunction(L, (-nargs)-1)=false then
begin
lua_pop(L,nargs+1);
outputdebugstring(pchar('lua_pcall with invalid parameter'));
//MessageBoxA(0, pchar('lua_pcall with invalid parameter'), pchar('Lua: Not a function'), MB_OK);
exit(LUA_ERRRUN);
end;
if (errf=0) and (not insideErrorHandler) then
begin
//add the default error handler
errf:=lua_gettop(L)-nargs;
lua_pushcfunction(L, @lua_defaulterrorhandler);
lua_insert(L,errf);
addedexceptionhandler:=true;
end
else
addedexceptionhandler:=false;
result:=lua.lua_pcall(L, nargs, nresults, errf);
if addedexceptionhandler then
begin
lua_remove(L,errf);
errf:=0;
end;
except
on e: exception do
begin
lua_pop(L, lua_gettop(L));
result:=LUA_ERRRUN;
if addedexceptionhandler then
errf:=0;
lua_pushstring(l, e.Message);
if (GetCurrentThreadId=MainThreadID) and mainform.miEnableLCLDebug.checked then
begin
DebugLn('Lua Exception: '+e.Message);
lazlogger.DumpExceptionBackTrace;
end;
end;
end;
if (result=LUA_ERRRUN) and (errf=0) then //an error occured and no error handler was specified
begin
if GetCurrentThreadId=MainThreadID then
begin
//lua_Debug
error:=Lua_ToString(l, -1);
if (error<>'') then
begin
usesluaengineform:=false;
if printoutput=nil then
begin
if frmLuaEngine=nil then
frmLuaEngine:=TfrmLuaEngine.Create(application);
printoutput:=frmLuaEngine.mOutput.Lines;
usesluaengineform:=true;
end;
if printoutput=nil then //e.g closing CE
begin
OutputDebugString('printoutput=nil');
exit;
end;
printoutput.AddText(rsError+error);
if (frmLuaEngine<>nil) and usesluaengineform and (frmLuaEngine.cbShowOnPrint.checked) then
frmLuaEngine.show;
if usesluaengineform then
printoutput:=nil;
lua_pop(L, lua_gettop(L));
end;
end
else
begin
//MessageBoxA(0, pchar(Lua_ToString(l, -1)), pchar(rsNonMainthreadLuaError), MB_OK);
end;
end;
end;
function lua_dostring(L: Plua_State; const str: PChar): Integer;
begin
Result := luaL_loadstring(L, str);
if Result = 0 then
Result := lua_pcall(L, 0, LUA_MULTRET, 0);
end;
function lua_isstring(L: PLua_state; i: integer): boolean;
begin
result := lua_type(L,i)=LUA_TSTRING;
end;
function Lua_ToString(L: Plua_State; i: Integer): string;
var r: pchar;
begin
if lua_islightuserdata(L, i) then
Result := inttohex(ptruint(lua_touserdata(L, i)),1)
else
begin
r := lua.lua_tostring(l,i);
if r<>nil then
result:=r
else
result:='';
end;
//unclear should there be a result:=Utf8ToAnsi(s); ?
end;
function lua_toRect(L: PLua_State; index: integer): TRect;
var i: integer;
begin
ZeroMemory(@result,sizeof(trect));
i:=lua_absindex(L,index);
if lua_istable(L, i) then
begin
lua_pushstring(L,'Left');
lua_gettable(L, i);
result.Left:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'Top');
lua_gettable(L, i);
result.Top:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'Right');
lua_gettable(L, i);
result.Right:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'Bottom');
lua_gettable(L, i);
result.Bottom:=lua_tointeger(L,-1);
lua_pop(L,1);
end;
end;
procedure lua_pushrect(L: PLua_state; r: TRect);
begin
lua_createtable(L, 0,4);
lua_pushstring(L, 'Left');
lua_pushinteger(L, r.left);
lua_settable(L, -3);
lua_pushstring(L, 'Top');
lua_pushinteger(L, r.top);
lua_settable(L, -3);
lua_pushstring(L, 'Right');
lua_pushinteger(L, r.right);
lua_settable(L, -3);
lua_pushstring(L, 'Bottom');
lua_pushinteger(L, r.bottom);
lua_settable(L, -3);
end;
function lua_toPoint(L: PLua_State; index: integer): TPoint;
var i: integer;
begin
result.x:=0;
result.y:=0;
i:=lua_absindex(L,index);
if lua_istable(L, i) then
begin
lua_pushstring(L,'x');
lua_gettable(L,i);
if lua_isnil(L,-1) then
begin
lua_pop(L,1);
lua_pushinteger(L,1);
lua_gettable(L,i);
end;
result.x:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'y');
lua_gettable(L,i);
if lua_isnil(L,-1) then
begin
lua_pop(L,1);
lua_pushinteger(L,1);
lua_gettable(L,i);
end;
result.y:=lua_tointeger(L,-1);
lua_pop(L,1);
end;
end;
procedure lua_pushpoint(L: PLua_state; r: TPoint);
begin
lua_createtable(L, 0,2);
lua_pushstring(L,'x');
lua_pushinteger(L,r.x);
lua_settable(L, -3);
lua_pushstring(L,'y');
lua_pushinteger(L,r.y);
lua_settable(L, -3);
end;
procedure lua_pushvariant(L: PLua_state; v: variant);
begin
case (tvardata(v).vtype and vartypemask) of
varempty: lua_pushnil(L);
varnull: lua_pushnil(L);
varsmallint, varinteger, vardecimal, varshortint, varbyte, varword, varlongword, varint64, varqword: lua_pushinteger(L, v);
varsingle, vardouble: lua_pushnumber(L, v);
varboolean: lua_pushboolean(L, v);
varstring, varustring: lua_pushstring(L, v);
else
lua_pushstring(L, v);
end;
end;
function lua_tovariant(L: PLua_state; i: integer): variant;
begin
case lua_type(L, i) of
LUA_TNONE : result:=nil;
LUA_TNIL : result:=nil;
LUA_TBOOLEAN : result:=lua_toboolean(L, i);
LUA_TNUMBER : result:=lua_tonumber(L, i);
LUA_TSTRING : result:=Lua_ToString(L, i);
else
raise exception.create(rsThisTypeIsNotSupportedHere);
end;
end;
function lua_ToCEUserData(L: PLua_state; i: integer): pointer;
//Cheat Engine implements two types of userdata. the legacy LightUserData used in 6.2- and the Heavy UserData in 6.3+
//Heavy UserData is a pointer with a pointer to the real object, while lightuserdata is just a pointer to the object
begin
result:=lua_touserdata(L,i);
if (result<>nil) and (lua_isheavyuserdata(L, i)) then //once the conversion is done this if check if it's userdata can go as it will always be userdata
result:=ppointer(result)^;
end;
function lua_toaddress(L: PLua_state; i: integer; self: boolean=false): ptruint; inline;
begin
if lua_type(L,i)=LUA_TSTRING then
begin
if self then
result:=selfsymhandler.getAddressFromNameL(lua_tostring(L,i),waitforsymbols)
else
result:=symhandler.getAddressFromNameL(lua_tostring(L,i),waitforsymbols)
end
else
result:=lua_tointeger(L,i);
end;
function LuaValueToDescription(L: PLua_state; i: integer; recursivetablecount: integer=0): string;
var index, count: integer;
fieldname: string;
valuedesc: string;
o: tobject;
tablepad: string;
stackstart: integer;
begin
result:='';
if not lua_isnil(L, i) then
begin
if lua_isheavyuserdata(L, i) then
begin
stackstart:=lua_gettop(L);
o:=lua_ToCEUserData(L, i);
try
if o is TObject then
begin
result:='Object of type '+o.ClassName;
if o is TControl then
result:=result+' (Name='+tcontrol(o).Name+')'
end;
except
end;
index:=lua_gettop(l);
lua_settop(l, stackstart);
end
else
if lua_isuserdata(L, i) then
result:='Pointer: '+inttohex(ptruint(lua_topointer(L,i)),8)
else
if lua_iscfunction(L, i) then
result:='native function'
else
if lua_isfunction(L, i) then
result:='function'
else
if lua_istable(L, i) then
begin
result:='table';
if recursivetablecount<MAXTABLERECURSIONLOOKUP then
begin
tablepad:=DupeString(' ',recursivetablecount);
stackstart:=lua_gettop(l);
result:=result+#13#10+tablepad+'['+#13#10;;
count:=10;
lua_pushvalue(L, i);
index:=lua_gettop(L);
lua_pushnil(L); //first key (nil)
while lua_next(L, index)<>0 do
begin
count:=count-1;
if count<0 then
begin
result:=result+tablepad+'...'+#13#10;;
break;
end;
if lua_type(L,-2)=LUA_TSTRING then
fieldname:=Lua_ToString(L, -2)
else if lua_type(L,-2)=LUA_TLIGHTUSERDATA then
fieldname:='pointert: '+inttohex(lua_tointeger(L,-2),8)
else
fieldname:=inttostr(lua_tointeger(L, -2));
valuedesc:=LuaValueToDescription(L, -1, recursivetablecount+1);
result:=result+tablepad+' '+fieldname+' = '+valuedesc+#13#10;
lua_pop(L, 1); //pop the value, keep the key
end;
// lua_pop(L,1); //pop the pushvalue from before
lua_settop(l, stackstart);
result:=result+tablepad+']';
end;
end
else
if lua_isboolean(L, i) then
result:=BoolToStr(lua_toboolean(L,i),'true','false')
else
result:=Lua_ToString(L, i);
end
else
result:='nil';
end;
procedure LoadLuaScriptsFromPath(path: string; var mainformwasset: boolean; var addresslistwasset: boolean);
var
DirInfo: TSearchRec;
i,r: integer;
pc: pchar;
begin
ZeroMemory(@DirInfo,sizeof(TSearchRec));
r := FindFirst(path+'*.lua', FaAnyfile, DirInfo);
while (r = 0) do
begin
if (DirInfo.Attr and FaVolumeId <> FaVolumeID) then
begin
if ((DirInfo.Attr and FaDirectory) <> FaDirectory) then
begin
i:=lua_dofile(luavm, pchar( UTF8ToWinCP(autorunpath+DirInfo.name)));
if i<>0 then //error
begin
i:=lua_gettop(luavm);
if i>0 then
begin
pc:=lua_tolstring(luavm, -1,nil);
if pc<>nil then
showmessage(DirInfo.name+rsError2+pc)
else
showmessage(DirInfo.name+rsError3);
end
else showmessage(DirInfo.name+rsError3);
end;
//reset stack
lua_pop(LuaVM, lua_gettop(luavm));
if mainformwasset then
begin
lua_getglobal(LuaVM,'MainForm');
if lua_isnil(LuaVM,-1) then
begin
MessageDlg(format(rsScriptCorruptedVar, [autorunpath+DirInfo.name, 'MainForm']), mtError,[mbOK],0);
mainformwasset:=false;
end;
lua_pop(LuaVM,1);
end;
if addresslistwasset then
begin
lua_getglobal(LuaVM,'AddressList');
if lua_isnil(LuaVM,-1) then
begin
MessageDlg(format(rsScriptCorruptedVar, [autorunpath+DirInfo.name, 'AddressList']), mtError,[mbOK],0);
addresslistwasset:=false;
end;
lua_pop(LuaVM,1);
end;
end;
end;
r := FindNext(DirInfo);
end;
FindClose(DirInfo);
end;
procedure InitializeLuaScripts(noautorun: boolean=false);
var f: string;
i,r: integer;
pc: pchar;
mainformwasset: boolean=true;
addresslistwasset: boolean=false;
begin
lua_getglobal(LuaVM,'MainForm');
if lua_isnil(LuaVM,-1) then
begin
MessageDlg('MainForm is undefined. Invalid CE Build', mtError, [mbok],0);
mainformwasset:=false;
end;
lua_pop(LuaVM,1);
lua_getglobal(LuaVM,'AddressList');
if lua_isnil(LuaVM,-1) then
begin
MessageDlg('AddressList is undefined. Invalid CE Build', mtError, [mbok],0);
addresslistwasset:=false;
end;
lua_pop(LuaVM,1);
f:='main.lua';
{$ifdef darwin}
f:=extractfiledir(extractfiledir(Application.ExeName))+'/Lua/main.lua';
{$endif}
if not FileExists(f) then //perhaps in the cedir
begin
f:=CheatEngineDir+'main.lua';
if not FileExists(f) then
begin
//try the defines only then
f:='defines.lua';
if not FileExists(f) then
begin
f:=CheatEngineDir+'defines.lua';
if not FileExists(f) then
exit;
end;
end;
end;
//file exists
try
if lua_dofile(luavm, pchar(f))<>0 then
begin
i:=lua_gettop(luavm);
if i>0 then
begin
pc:=lua_tolstring(luavm, -1,nil);
if pc<>nil then
showmessage(rsMainLuaError+pc)
else
showmessage(rsMainLuaError2);
end
else showmessage(rsMainLuaError2);
end;
finally
lua_pop(LuaVM, lua_gettop(luavm)); //reset stack
end;
//autorun folder
if noautorun=false then
begin
loadLuaScriptsFromPath(autorunpath, mainformwasset, addresslistwasset);
LoadLuaScriptsFromPath(autorunpath+'custom'+PathDelim, mainformwasset, addresslistwasset);
end;
if translationfilepath<>'' then
begin
if FileExists(translationfilepath+'init.lua') then
begin
lua_dofile(luavm, pchar(translationfilepath+'init.lua'));
lua_pop(LuaVM, lua_gettop(luavm));
if mainformwasset then
begin
lua_getglobal(LuaVM,'MainForm');
if lua_isnil(LuaVM,-1) then
begin
MessageDlg(format(rsScriptCorruptedVar, [translationfilepath+'init.lua', 'MainForm']), mtError,[mbOK],0);
mainformwasset:=false;
end;
lua_pop(LuaVM,1);
end;
if addresslistwasset then
begin
lua_getglobal(LuaVM,'AddressList');
if lua_isnil(LuaVM,-1) then
begin
MessageDlg(format(rsScriptCorruptedVar, [translationfilepath+'init.lua', 'AddressList']), mtError,[mbOK],0);
addresslistwasset:=false;
end;
lua_pop(LuaVM,1);
end;
end;
end;
lua_settop(LuaVM,0);
end;
function lua_strtofloat(s: string): double;
var stackpos: integer;
s2: integer;
begin
try
stackpos:=lua_gettop(luavm);
if lua_dostring(luavm, pchar('return '+s) )=0 then
begin
s2:=lua_gettop(luavm);
if (s2-stackpos)>0 then
result:=lua_tonumber(luavm, stackpos-s2)
else
raise exception.create(Format(rsInvalidFloat, [s]));
end
else
raise exception.create(Format(rsInvalidFloat, [s]));
finally
lua_settop(luavm, stackpos);
end;
end;
function lua_strtoint(s: string): integer;
var stackpos: integer;
s2: integer;
begin
try
stackpos:=lua_gettop(luavm);
if lua_dostring(luavm, pchar('return '+s) )=0 then
begin
s2:=lua_gettop(luavm);
if (s2-stackpos)>0 then
begin
if lua_isnil(luavm,-1)=false then
result:=lua_tointeger(luavm, stackpos-s2)
else
raise exception.create(rsInvalidInt);
end
else
raise exception.create(Format(rsInvalidInt, [s]));
end
else
raise exception.create(Format(rsInvalidInt, [s]));
finally
lua_settop(luavm, stackpos);
end;
end;
procedure Lua_RegisterObject(name: string; o: TObject);
var s: integer;
begin
s:=lua_gettop(LuaVM);
luaclass_newClass(LuaVM, o);
lua_setglobal(LuaVM, pchar(name));
lua_settop(LuaVM, s);
end;
function LUA_onBreakpoint(threadid: dword; context: PContext; functionAlreadyPushed: boolean=false): boolean;
var p: integer;
begin
result:=false;
if context=nil then exit;
try
try
LUA_SetCurrentContextState(threadid, context);
if not functionAlreadyPushed then
begin
lua_pop(LuaVM, lua_gettop(luavm)); //clear it just to be sure
lua_getglobal(luavm, pchar('debugger_onBreakpoint'));
p:=lua_gettop(luavm);
if p=0 then exit;
end;
if lua_isfunction(luavm, -1) then //extra check
begin
if lua_pcall(LuaVM, 0, 1, 0)=0 then
begin
p:=lua_gettop(luavm);
if (p=1) then //only 1 parameter returned
result:=lua_tointeger(luavm, -1)<>0; //return the result is not 0
lua_pop(LuaVM, lua_gettop(luavm)); //clear stack
//set new state if changes where made
LUA_GetNewContextState(context);
end;
end;
except
end;
finally
lua_pop(LuaVM, lua_gettop(luavm));
end;
end;
procedure lua_pushcontext(L: PLua_state; context: PContext);
var
t: integer;
i: integer;
begin
lua_newtable(L);
t:=lua_gettop(L);
lua_pushstring(L, 'ContextFlags');
lua_pushinteger(L,context^.ContextFlags);
lua_settable(L,t);
lua_pushstring(L, 'CS');
lua_pushinteger(L,context^.SegCs);
lua_settable(L,t);
lua_pushstring(L, 'DS');
lua_pushinteger(L,context^.SegDs);
lua_settable(L,t);
lua_pushstring(L, 'ES');
lua_pushinteger(L,context^.SegEs);
lua_settable(L,t);
lua_pushstring(L, 'FS');
lua_pushinteger(L,context^.SegFs);
lua_settable(L,t);
lua_pushstring(L, 'GS');
lua_pushinteger(L,context^.SegGs);
lua_settable(L,t);
lua_pushstring(L, 'SS');
lua_pushinteger(L,context^.SegSs);
lua_settable(L,t);
lua_pushstring(L, 'EFlags');
lua_pushinteger(L,context^.EFlags);
lua_settable(L,t);
{$ifdef cpu64}
lua_pushstring(L, 'RAX');
lua_pushinteger(L,context^.Rax);
lua_settable(L,t);
lua_pushstring(L, 'RBX');
lua_pushinteger(L,context^.Rbx);
lua_settable(L,t);
lua_pushstring(L, 'RCX');
lua_pushinteger(L,context^.Rcx);
lua_settable(L,t);
lua_pushstring(L, 'RDX');
lua_pushinteger(L,context^.Rdx);
lua_settable(L,t);
lua_pushstring(L, 'RSI');
lua_pushinteger(L,context^.Rsi);
lua_settable(L,t);
lua_pushstring(L, 'RDI');
lua_pushinteger(L,context^.Rdi);
lua_settable(L,t);
lua_pushstring(L, 'RBP');
lua_pushinteger(L,context^.Rbp);
lua_settable(L,t);
lua_pushstring(L, 'RSP');
lua_pushinteger(L,context^.Rsp);
lua_settable(L,t);
lua_pushstring(L, 'RIP');
lua_pushinteger(L,context^.Rip);
lua_settable(L,t);
lua_pushstring(L, 'R8');
lua_pushinteger(L,context^.R8);
lua_settable(L,t);
lua_pushstring(L, 'R9');
lua_pushinteger(L,context^.R9);
lua_settable(L,t);
lua_pushstring(L, 'R10');
lua_pushinteger(L,context^.R10);
lua_settable(L,t);
lua_pushstring(L, 'R11');
lua_pushinteger(L,context^.R11);
lua_settable(L,t);
lua_pushstring(L, 'R12');
lua_pushinteger(L,context^.R12);
lua_settable(L,t);
lua_pushstring(L, 'R13');
lua_pushinteger(L,context^.R13);
lua_settable(L,t);
lua_pushstring(L, 'R14');
lua_pushinteger(L,context^.R14);
lua_settable(L,t);
lua_pushstring(L, 'R15');
lua_pushinteger(L,context^.R15);
lua_settable(L,t);
{$endif}
if processhandler.is64Bit=false then
begin
lua_pushstring(L, 'EAX');
lua_pushinteger(L,context^.{$ifdef cpu64}Rax{$else}eax{$endif} and $ffffffff);
lua_settable(L,t);
lua_pushstring(L, 'EBX');
lua_pushinteger(L,context^.{$ifdef cpu64}Rbx{$else}ebx{$endif} and $ffffffff);
lua_settable(L,t);
lua_pushstring(L, 'ECX');
lua_pushinteger(L,context^.{$ifdef cpu64}Rcx{$else}ecx{$endif} and $ffffffff);
lua_settable(L,t);
lua_pushstring(L, 'EDX');
lua_pushinteger(L,context^.{$ifdef cpu64}Rdx{$else}edx{$endif} and $ffffffff);
lua_settable(L,t);
lua_pushstring(L, 'ESI');
lua_pushinteger(L,context^.{$ifdef cpu64}Rsi{$else}esi{$endif} and $ffffffff);
lua_settable(L,t);
lua_pushstring(L, 'EDI');
lua_pushinteger(L,context^.{$ifdef cpu64}Rdi{$else}edi{$endif} and $ffffffff);
lua_settable(L,t);
lua_pushstring(L, 'EBP');
lua_pushinteger(L,context^.{$ifdef cpu64}Rbp{$else}ebp{$endif} and $ffffffff);
lua_settable(L,t);
lua_pushstring(L, 'ESP');
lua_pushinteger(L,context^.{$ifdef cpu64}Rsp{$else}esp{$endif} and $ffffffff);
lua_settable(L,t);
lua_pushstring(L, 'EIP');
lua_pushinteger(L,context^.{$ifdef cpu64}Rip{$else}eip{$endif} and $ffffffff);
lua_settable(L,t);
end;
lua_pushstring(L, 'DR0');
lua_pushinteger(L,context^.DR0);
lua_settable(L,t);
lua_pushstring(L, 'DR1');
lua_pushinteger(L,context^.DR1);
lua_settable(L,t);
lua_pushstring(L, 'DR2');
lua_pushinteger(L,context^.DR2);
lua_settable(L,t);
lua_pushstring(L, 'DR3');
lua_pushinteger(L,context^.DR3);
lua_settable(L,t);
lua_pushstring(L, 'DR6');
lua_pushinteger(L,context^.DR6);
lua_settable(L,t);
lua_pushstring(L, 'DR7');
lua_pushinteger(L,context^.DR7);
lua_settable(L,t);
for i:=0 to 7 do
begin
lua_pushstring(L,'FP'+inttostr(i));
{$ifdef cpu32}
CreateByteTableFromPointer(L, @context^.FloatSave.RegisterArea[10*i], 10);
{$else}
CreateByteTableFromPointer(L, @context^.FltSave.FloatRegisters[i], 10);
{$endif}
lua_settable(L,t);
end;
//xmm regs
for i:=0 to 15 do
begin
if (i>=8) and (not processhandler.is64Bit) then break;
lua_pushstring(L,'XMM'+inttostr(i));
{$ifdef cpu32}
CreateByteTableFromPointer(luavm, @context^.ext.XMMRegisters[i], 16);
{$else}
CreateByteTableFromPointer(luavm, @context^.FltSave.XmmRegisters[i], 16);
{$endif}
lua_settable(L,t);
end;
end;
procedure LUA_SetCurrentContextState(tid: dword; context: pointer; extraregs: boolean=false);
var i: integer;
ch: TContextInfo;
gpr: PContextElementRegisterList;
fpu,fpu2: PContextElementRegisterList;
begin
lua_pushinteger(luavm, tid);
lua_setglobal(luavm, 'THREADID');
ch:=getBestContextHandler;
gpr:=ch.getGeneralPurposeRegisters;
for i:=0 to length(gpr^)-1 do
begin
lua_pushinteger(luavm, gpr^[i].getValue(context));
lua_setglobal(luavm, pchar(uppercase(gpr^[i].name)));
end;
if (processhandler.SystemArchitecture=archX86) and (ch.getGeneralPurposeFlags<>nil) then
begin
lua_pushinteger(luavm, pdword(ch.getGeneralPurposeFlags^[0].getPointer(context))^);
lua_setglobal(luavm, 'EFLAGS');
end;
if extraregs then //default off as it's a bit slow
begin
fpu2:=ch.getAlternateFloatingPointRegisters;
if fpu2<>nil then
begin
for i:=0 to length(fpu2^)-1 do
begin
CreateByteTableFromPointer(luavm, fpu2^[i].getPointer(context), fpu2^[i].size);
lua_setglobal(luavm, pchar(fpu2^[i].name));
end;
end;
//xmm regs
fpu:=ch.getFloatingPointRegisters;
for i:=0 to length(fpu^)-1 do
begin
CreateByteTableFromPointer(luavm, fpu^[i].getPointer(context), fpu^[i].size);
lua_setglobal(luavm, pchar(fpu^[i].name));
end;
end;
end;
procedure LUA_GetNewContextState(context: pointer; extraregs: boolean=false);
var
i: integer;
t: integer;
ch: TContextInfo;
gpr: PContextElementRegisterList;
fpu,fpu2: PContextElementRegisterList;
begin
ch:=getBestContextHandler;
if (processhandler.SystemArchitecture=archX86) and (ch.getGeneralPurposeFlags<>nil) then
begin
lua_getglobal(luavm, 'EFLAGS');
pdword(ch.getGeneralPurposeFlags^[0].getPointer(context))^:=lua_tointeger(luavm, -1);
lua_pop(luavm,1);
end;
gpr:=ch.getGeneralPurposeRegisters;
for i:=0 to length(gpr^)-1 do
begin
lua_getglobal(luavm, pchar(uppercase(gpr^[i].name)));
gpr^[i].setValue(context, lua_tointeger(luavm, -1));
end;
if extraregs then
begin
fpu2:=ch.getAlternateFloatingPointRegisters;
for i:=0 to length(fpu2^)-1 do
begin
lua_getglobal(luavm, pchar(uppercase(fpu2^[i].name)));
if not lua_isnil(luavm, -1) then
begin
t:=lua_gettop(LuaVM);
readBytesFromTable(luavm, t, fpu2^[i].getPointer(context), fpu2^[i].size);
end;
lua_pop(luavm,1);
end;
fpu:=ch.getFloatingPointRegisters;
for i:=0 to length(fpu^)-1 do
begin
lua_getglobal(luavm, pchar(uppercase(fpu^[i].name)));
if not lua_isnil(luavm, -1) then
begin
t:=lua_gettop(LuaVM);
readBytesFromTable(luavm, t, fpu^[i].getPointer(context), fpu^[i].size);
end;
lua_pop(luavm,1);
end;
end;
end;
procedure LUA_DoScript(s: string);
var i: integer;
pc: pchar;
stack: integer;
begin
//if GetCurrentThreadId<>MainThreadID then raise exception.create(rsLUA_DoScriptWasNotCalledRomTheMainThread);
stack:=lua_gettop(luavm);
try
i:=lua_dostring(luavm, pchar(s));
if i<>0 then
begin
pc:=lua.lua_tostring(luavm, -1);
if pc<>nil then
raise Exception.Create(pc)
else
raise exception.create(rsUndefinedLuaError);
end;
finally
lua_settop(luavm, stack);
end;
end;
procedure LUA_onNotify(functionid: integer; sender: tobject);
begin
try
lua_rawgeti(Luavm, LUA_REGISTRYINDEX, functionid);
lua_pushlightuserdata(Luavm, sender);
lua_pcall(Luavm, 1, 0, 0);
finally
lua_pop(luavm, lua_gettop(luavm)); //clear the stack
end;
end;
procedure LUA_memrec_callback(memrec: pointer; routine: string);
var m: TMemoryrecord;
p: integer;
begin
try
m:=memrec;
lua_getglobal(luavm, pchar(routine));
p:=lua_gettop(luavm);
if p<>0 then
begin
if lua_isfunction(luavm, -1) then
begin
lua_pushlightuserdata(luavm, memrec);
lua_pcall(luavm, 1, 0, 0);
end;
end;
finally
lua_pop(luavm,lua_gettop(luavm));
end;
end;
procedure lua_setbasictableentry(L: Plua_State; tableindex: integer; entryname: string; data: Variant);
var x: integer;
begin
lua_pushstring(L, entryname);
x:=vartype(data) and vartypemask;
case x of
varsmallint, varinteger, varint64, varqword, varlongword, varword, varbyte, varshortint: lua_pushinteger(L, data);
varsingle, vardouble: lua_pushnumber(L, data);
varboolean: lua_pushboolean(L, data);
varstring,varustring,varolestr: lua_pushstring(L, data);
end;
lua_settable(L, tableindex);
end;
function LUA_functioncall(routinetocall: string; parameters: array of const): integer;
var i,e: integer;
c: string;
p: integer;
oldstack: integer;
l: Plua_State;
begin
l:=luavm;
result:=-1;
oldstack:=lua_gettop(l);
try
lua_getglobal(l, pchar(routinetocall));
p:=lua_gettop(l);
if p<>oldstack then
begin
if lua_isfunction(l, -1) then
begin
//routine exists, fill in the parameters
for i:=0 to length(parameters)-1 do
begin
case parameters[i].VType of
system.vtInteger : lua_pushinteger(L, parameters[i].VInteger);
system.vtBoolean: lua_pushboolean(L, parameters[i].VBoolean);
system.vtChar:
begin
c:=parameters[i].VChar;
lua_pushstring(L, c);
end;
system.vtExtended: lua_pushnumber(L, parameters[i].VExtended^);
system.vtString: lua_pushstring(L, pchar(parameters[i].VString));
system.vtPointer: lua_pushlightuserdata(L, parameters[i].VPointer);
system.vtPChar: lua_pushstring(L, parameters[i].VPChar);
system.vtObject: luaclass_newClass(L, parameters[i].VObject); //lua_pushlightuserdata(L, pointer(parameters[i].VObject));
system.vtClass: lua_pushlightuserdata(L, pointer(parameters[i].VClass));
system.vtWideChar, vtPWideChar, vtVariant, vtInterface,
vtWideString: lua_pushstring(L, rsCheatengineIsBeingAFag);
system.vtAnsiString: lua_pushstring(L, pchar(parameters[i].VAnsiString));
system.vtCurrency: lua_pushnumber(L, parameters[i].VCurrency^);
system.vtInt64:
begin
if (parameters[i].VInt64^<=$ffffffff) then
lua_pushinteger(L, parameters[i].VInt64^)
else
lua_pushlightuserdata(L, pointer(parameters[i].VInt64^));
end;
system.vtQWord:
begin
if (parameters[i].VQWord^<=$ffffffff) then
lua_pushinteger(L, parameters[i].VQWord^)
else
lua_pushlightuserdata(L, pointer(parameters[i].VQWord^));
end;
end;
end;
lua_pcall(L, length(parameters), 1, 0);
i:=lua_gettop(L);
if i>0 then //it has a parameter
result:=lua_tointeger(L, -1);
end;
end;
finally
lua_settop(L, oldstack);
end;
end;
{
procedure LUA_callback(routine: string; parameters: tvararray);
var m: TMemoryrecord;
p: integer;
begin
LuaCS.Enter;
try
m:=memrec;
lua_getfield(luavm, LUA_GLOBALSINDEX, pchar(routine));
p:=lua_gettop(luavm);
if p<>0 then
begin
if lua_isfunction(luavm, -1) then
begin
lua_pushlightuserdata(luavm, memrec);
lua_pcall(luavm, 1, 0, 0);
end;
end;
finally
lua_pop(luavm,lua_gettop(luavm));
luacs.Leave;
end;
end; }
function CheckIfConditionIsMetContext(threadid: dword; context: pointer; script: string): boolean;
{
precondition: script returns a value (so already has the 'return ' part appended for single line scripts)
}
var
i: integer;
s: string;
begin
result:=false;
try
LUA_SetCurrentContextState(threadid, context);
if lua_dostring(luavm, pchar(script))=0 then
begin
i:=lua_gettop(LuaVM);
if i=1 then //valid return
result:=lua_toboolean(LuaVM, -1);
end
else
begin
s:=Lua_ToString(LuaVM,-1);
outputdebugstring('CheckIfConditionIsMetContext error:' +s);
end;
finally
lua_pop(LuaVM, lua_gettop(luavm));
end;
end;
function LuaPanic(L: Plua_State): Integer; cdecl;
begin
result:=0;
lua_pop(L, lua_gettop(L));
raise exception.create(rsLUAPanic);
end;
function lua_sleep(L: PLua_State): integer; cdecl;
var
parameters: integer;
begin
parameters:=lua_gettop(L);
result:=0;
if parameters=1 then
sleep(lua_tointeger(L, -1));
lua_pop(L, parameters);
end;
function print2(param: pointer): pointer;
var
usesluaengineform: boolean;
l: tstringlist;
i: integer;
begin
if application.Terminated then exit;
usesluaengineform:=false;
if printoutput=nil then
begin
if frmLuaEngine=nil then
frmLuaEngine:=TfrmLuaEngine.Create(MemoryBrowser);
printoutput:=frmLuaEngine.mOutput.Lines;
usesluaengineform:=true;
end;
l:=tstringlist.create;
l.text:=pchar(param);
for i:=0 to l.Count-1 do
printoutput.add(l[i]);
l.free;
if (frmLuaEngine<>nil) and usesluaengineform and (frmLuaEngine.cbShowOnPrint.checked) then
frmLuaEngine.show;
if usesluaengineform then
printoutput:=nil;
result:=nil;
end;
function print(L: PLua_State): integer; cdecl;
var
parameters: integer;
s: string;
str: string;
i: integer;
begin
if MainThreadID<>GetCurrentThreadId then
begin
//print is threadsafe because it always syncs
lua_pushcfunction(L,@print);
lua_insert(L,1);
exit(lua_synchronize(L));
end;
parameters:=lua_gettop(L);
if parameters=0 then exit(0);
str:='';
for i:=-parameters to -1 do
begin
if lua_isuserdata(L,i) then
s:=inttohex(ptruint(lua_ToCEUserData(L, i)),8)
else
s:=lua_tostring(L, i);
str:=str+s+' ';
end;
if str<>'' then
begin
print2(@str[1]);
//pluginsync(print2, @str[1]);
end;
lua_pop(L, parameters);
lua_pushstring(L, str);
result:=1;
end;
function inputQuery_lua(L: PLua_State): integer; cdecl;
var
caption, prompt, value: string;
parameters: integer;
begin
result:=0;
parameters:=lua_gettop(l);
if parameters=3 then
begin
caption:=Lua_ToString(L, 1);
prompt:=Lua_ToString(L, 2);
value:=Lua_ToString(L, 3);
if InputQuery(caption, prompt, value) then
begin
result:=1;
lua_pushstring(L, value);
end;
end;
end;
function showMessage_lua(L: PLua_State): integer; cdecl;
var
parameters: integer;
s: string;
begin
parameters:=lua_gettop(L);
if parameters=0 then exit(0);
if lua_islightuserdata(l,-1) then
s:=inttohex(ptruint(lua_touserdata(L, -1)),8)
else
s:=lua_tostring(L, -1);
ShowMessage(s);
// ce_showmessage(pchar(s));
lua_pop(L, parameters);
result:=0;
end;
function readSmallIntegerEx(L: PLua_State; processhandle: thandle): integer; cdecl;
var
parameters: integer;
address: ptruint;
signed: boolean;
v: smallInt;
r: PtrUInt;
begin
result:=0;
try
parameters:=lua_gettop(L);
if parameters>=1 then
begin
//ShowMessage(inttostr(lua_type(L, 1)));
address:=lua_toaddress(L,1, processhandle=GetCurrentProcess);
if parameters>=2 then
signed:=lua_toboolean(L,2)
else
signed:=false;
lua_pop(L, parameters);
v:=0;
if ReadProcessMemory(processhandle, pointer(address), @v, sizeof(v), r) then
begin
if signed then
lua_pushinteger(L, v)
else
lua_pushinteger(L, word(v));
result:=1;
end;
end;
except
result:=0;
lua_pop(L, lua_gettop(L));
end;
end;
function readSmallIntegerLocal(L: PLua_State): integer; cdecl;
begin
result:=readSmallIntegerEx(L, GetCurrentProcess);
end;
function readSmallInteger(L: PLua_State): integer; cdecl;
begin
result:=readSmallIntegerEx(L, ProcessHandle);
end;
function readShortIntegerEx(L: PLua_State; processhandle: thandle): integer; cdecl;
var
parameters: integer;
address: ptruint;
signed: boolean;
v: ShortInt;
r: PtrUInt;
begin
result:=0;
try
parameters:=lua_gettop(L);
if parameters>=1 then
begin
address:=lua_toaddress(L,1, processhandle=GetCurrentProcess);
if parameters>=2 then
signed:=lua_toboolean(L,2)
else
signed:=false;
lua_pop(L, parameters);
v:=0;
if ReadProcessMemory(processhandle, pointer(address), @v, sizeof(v), r) then
begin
if signed then
lua_pushinteger(L, v)
else
lua_pushinteger(L, byte(v));
result:=1;
end;
end;
except
result:=0;
lua_pop(L, lua_gettop(L));
end;
end;
function readShortIntegerLocal(L: PLua_State): integer; cdecl;
begin
result:=readShortIntegerEx(L, GetCurrentProcess);
end;
function readShortInteger(L: PLua_State): integer; cdecl;
begin
result:=readShortIntegerEx(L, ProcessHandle);
end;
function readIntegerEx(L: PLua_State; processhandle: thandle): integer; cdecl;
var
parameters: integer;
address: ptruint;
signed: boolean;
v: integer;
r: PtrUInt;
begin
result:=0;
try
parameters:=lua_gettop(L);
if parameters>=1 then
begin
//ShowMessage(inttostr(lua_type(L, 1)));
address:=lua_toaddress(L,1, processhandle=GetCurrentProcess);
if parameters>=2 then
signed:=lua_toboolean(L,2)
else
signed:=false;
lua_pop(L, parameters);
v:=0;
if ReadProcessMemory(processhandle, pointer(address), @v, sizeof(v), r) then
begin
if signed then
lua_pushinteger(L, v)
else
lua_pushinteger(L, dword(v));
result:=1;
end;
end;
except
result:=0;
lua_pop(L, lua_gettop(L));
end;
end;
function readIntegerLocal(L: PLua_State): integer; cdecl;
begin
result:=readIntegerEx(L, GetCurrentProcess);
end;
function readInteger(L: PLua_State): integer; cdecl;
begin
result:=readIntegerEx(L, ProcessHandle);
end;
function readQwordEx(L: PLua_State; processhandle: thandle): integer; cdecl;
var
parameters: Qword;
address: ptruint;
v: Qword;
r: PtrUInt;
begin
result:=0;
try
parameters:=lua_gettop(L);
if parameters=1 then
begin
//ShowMessage(inttostr(lua_type(L, -1)));
address:=lua_toaddress(L,-1,processhandle=GetCurrentProcess);
lua_pop(L, parameters);
v:=0;
if ReadProcessMemory(processhandle, pointer(address), @v, sizeof(v), r) then
begin
lua_pushinteger(L, v);
result:=1;
end;
end;
except
result:=0;
lua_pop(L, lua_gettop(L));
end;
end;
function readQwordLocal(L: PLua_State): integer; cdecl;
begin
result:=readQwordEx(L, GetCurrentProcess);
end;
function readQword(L: PLua_State): integer; cdecl;
begin
result:=readQwordEx(L, ProcessHandle);
end;
function readPointerLocal(L: PLua_State): integer; cdecl;
begin
{$ifdef cpu64}
result:=readQwordLocal(L);
{$else}
result:=readIntegerLocal(L);
{$endif}
end;
function readPointer(L: PLua_State): integer; cdecl;
begin
if processhandler.is64Bit then
result:=readQword(L)
else
result:=readInteger(L);
end;
function readFloatEx(L: PLua_State; ProcessHandle: THandle): integer; cdecl;
var
parameters: integer;
address: ptruint;
v: single;
r: PtrUInt;
begin
result:=0;
try
parameters:=lua_gettop(L);
if parameters=1 then
begin
address:=lua_toaddress(L,-1,processhandle=GetCurrentProcess);
lua_pop(L, parameters);
v:=0;
if ReadProcessMemory(processhandle, pointer(address), @v, sizeof(v), r) then
begin
lua_pushnumber(L, v);
result:=1;
end;
end;
except
result:=0;
lua_pop(L, lua_gettop(L));
end;
end;
function readFloatLocal(L: PLua_State): integer; cdecl;
begin
result:=readFloatEx(L, GetCurrentProcess);
end;
function readFloat(L: PLua_State): integer; cdecl;
begin
result:=readFloatEx(L, ProcessHandle);
end;
function readDoubleEx(L: PLua_State; ProcessHandle: THandle): integer; cdecl;
var
parameters: integer;
address: ptruint;
v: double;
r: PtrUInt;
begin
result:=0;
try
parameters:=lua_gettop(L);
if parameters=1 then
begin
address:=lua_toaddress(L,-1,processhandle=GetCurrentProcess);
lua_pop(L, parameters);
v:=0;
if ReadProcessMemory(processhandle, pointer(address), @v, sizeof(v), r) then
begin
lua_pushnumber(L, v);
result:=1;
end;
end;
except
result:=0;
lua_pop(L, lua_gettop(L));
end;
end;
function readDoubleLocal(L: PLua_State): integer; cdecl;
begin
result:=readDoubleEx(L, GetCurrentProcess);
end;
function readDouble(L: PLua_State): integer; cdecl;
begin
result:=readDoubleEx(L, processhandle);
end;
function readStringEx(L: PLua_State; ProcessHandle: THandle): integer; cdecl;
var
parameters: integer;
address: ptruint;
v: pchar;
w: pwidechar absolute v;
s: string;
r: PtrUInt;
maxsize: integer;
usewidechar: boolean;
begin
result:=0;
try
parameters:=lua_gettop(L);
if parameters>=1 then
begin
address:=lua_toaddress(L,1,processhandle=GetCurrentProcess);
if parameters>=2 then
maxsize:=lua_tointeger(L,2)
else
maxsize:=50;
if parameters>=3 then
begin
usewidechar:=lua_toboolean(L,3);
maxsize:=maxsize+1;
end
else
usewidechar:=false;
lua_pop(L, parameters);
getmem(v,maxsize+1);
try
r:=0;
ReadProcessMemory(processhandle, pointer(address), v, maxsize, r);
if (r>0) and (r<=maxsize) then
begin
v[maxsize]:=#0;
if (r+1)<=maxsize then
v[r+1]:=#0;
if usewidechar then
begin
v[maxsize-1]:=#0;
if (r+2)<=maxsize then
v[r+2]:=#0;
s:=w;
end
else
s:=v;
lua_pushstring(L, s);
result:=1;
end;
finally
freememandnil(v);
end;
end;
except
result:=0;
lua_pop(L, lua_gettop(L));
end;
end;
function readStringLocal(L: PLua_State): integer; cdecl;
begin
result:=readStringEx(L, GetCurrentProcess);
end;
function readString(L: PLua_State): integer; cdecl;
begin
result:=readStringEx(L, processhandle);
end;
function writeShortIntegerEx(L: PLua_State; processhandle: THandle): integer; cdecl;
var
parameters: integer;
address: ptruint;
v: shortint;
r: PtrUInt;
begin
result:=0;
try
parameters:=lua_gettop(L);
if parameters=2 then
begin
address:=lua_toaddress(L,1,processhandle=GetCurrentProcess);
v:=lua_tointeger(L, 2);
lua_pop(L, parameters);
lua_pushboolean(L, WriteProcessMemory(processhandle, pointer(address), @v, sizeof(v), r));
result:=1;
end;
except
result:=0;
lua_pop(L, lua_gettop(L));
end;
end;
function writeShortIntegerLocal(L: PLua_State): integer; cdecl;
begin
result:=writeShortIntegerEx(L, GetCurrentProcess);
end;
function writeShortInteger(L: PLua_State): integer; cdecl;
begin
result:=writeShortIntegerEx(L, processhandle);
end;
function writeSmallIntegerEx(L: PLua_State; processhandle: THandle): integer; cdecl;
var
parameters: integer;
address: ptruint;
v: smallInt;
r: PtrUInt;
begin
result:=0;
try
parameters:=lua_gettop(L);
if parameters=2 then
begin
address:=lua_toaddress(L,1,processhandle=GetCurrentProcess);
v:=lua_tointeger(L, 2);
lua_pop(L, parameters);
lua_pushboolean(L, WriteProcessMemory(processhandle, pointer(address), @v, sizeof(v), r));
result:=1;
end;
except
result:=0;
lua_pop(L, lua_gettop(L));
end;
end;
function writeSmallIntegerLocal(L: PLua_State): integer; cdecl;
begin
result:=writeSmallIntegerEx(L, GetCurrentProcess);
end;
function writeSmallInteger(L: PLua_State): integer; cdecl;
begin
result:=writeSmallIntegerEx(L, processhandle);
end;
function writeIntegerEx(L: PLua_State; processhandle: THandle): integer; cdecl;
var
parameters: integer;
address: ptruint;
v: integer;
r: PtrUInt;
begin
result:=0;
try
parameters:=lua_gettop(L);
if parameters=2 then
begin
address:=lua_toaddress(L,1,processhandle=GetCurrentProcess);
v:=lua_tointeger(L, 2);
lua_pop(L, parameters);
lua_pushboolean(L, WriteProcessMemory(processhandle, pointer(address), @v, sizeof(v), r));
result:=1;
end;
except
result:=0;
lua_pop(L, lua_gettop(L));
end;
end;
function writeIntegerLocal(L: PLua_State): integer; cdecl;
begin
result:=writeIntegerEx(L, GetCurrentProcess);
end;
function writeInteger(L: PLua_State): integer; cdecl;
begin
result:=writeIntegerEx(L, processhandle);
end;
function writeQwordEx(L: PLua_State; processhandle: THandle): integer; cdecl;
var
parameters: Qword;
address: ptruint;
v: Qword;
r: PtrUInt;
begin
result:=0;
try
parameters:=lua_gettop(L);
if parameters=2 then
begin
address:=lua_toaddress(L,1,processhandle=GetCurrentProcess);
v:=lua_tointeger(L, 2);
lua_pop(L, parameters);
lua_pushboolean(L, WriteProcessMemory(processhandle, pointer(address), @v, sizeof(v), r));
result:=1;
end;
except
result:=0;
lua_pop(L, lua_gettop(L));
end;
end;
function writeQwordLocal(L: PLua_State): integer; cdecl;
begin
result:=writeQwordEx(L, GetCurrentProcess);
end;
function writeQword(L: PLua_State): integer; cdecl;
begin
result:=writeQwordEx(L, processhandle);
end;
function writePointerLocal(L: PLua_State): integer; cdecl;
begin
{$ifdef cpu64}
result:=writeQwordLocal(L);
{$else}
result:=writeIntegerLocal(L);
{$endif}
end;
function writePointer(L: PLua_State): integer; cdecl;
begin
if processhandler.is64bit then
result:=writeQword(L)
else
result:=writeInteger(L);
end;
function writeFloatEx(L: PLua_State; processhandle: THandle): integer; cdecl;
var
parameters: integer;
address: ptruint;
v: single;
r: PtrUInt;
begin
result:=0;
try
parameters:=lua_gettop(L);
if parameters>=2 then
begin
address:=lua_toaddress(L,1,processhandle=GetCurrentProcess);
v:=lua_tonumber(L, 2);
lua_pop(L, parameters);
lua_pushboolean(L, WriteProcessMemory(processhandle, pointer(address), @v, sizeof(v), r));
result:=1;
end;
except
result:=0;
lua_pop(L, lua_gettop(L));
end;
end;
function writeFloatLocal(L: PLua_State): integer; cdecl;
begin
result:=writeFloatEx(L, GetCurrentProcess);
end;
function writeFloat(L: PLua_State): integer; cdecl;
begin
result:=writeFloatEx(L, processhandle);
end;
function writeDoubleEx(L: PLua_State; processhandle: THandle): integer; cdecl;
var
parameters: integer;
address: ptruint;
v: double;
r: PtrUInt;
begin
result:=0;
try
parameters:=lua_gettop(L);
if parameters=2 then
begin
address:=lua_toaddress(L,1,processhandle=GetCurrentProcess);
v:=lua_tonumber(L, 2);
lua_pop(L, parameters);
lua_pushboolean(L, WriteProcessMemory(processhandle, pointer(address), @v, sizeof(v), r));
result:=1;
end;
except
result:=0;
lua_pop(L, lua_gettop(L));
end;
end;
function writeDoubleLocal(L: PLua_State): integer; cdecl;
begin
result:=writeDoubleEx(L, GetCurrentProcess);
end;
function writeDouble(L: PLua_State): integer; cdecl;
begin
result:=writeDoubleEx(L, processhandle);
end;
function writeStringEx(L: PLua_State; processhandle: THandle): integer; cdecl;
var
parameters: integer;
address: ptruint;
v: pchar;
usewidechar: boolean;
w: widestring;
r: PtrUInt;
begin
result:=0;
try
parameters:=lua_gettop(L);
if parameters>=2 then
begin
address:=lua_toaddress(L,1,processhandle=GetCurrentProcess);
v:=lua.lua_tostring(L, 2);
if parameters>=3 then
usewidechar:=lua.lua_toboolean(L, 3)
else
usewidechar:=false;
lua_pop(L, parameters);
if usewidechar then
begin
//convert the ansi sring to a widestring
w:=v;
lua_pushboolean(L, WriteProcessMemory(processhandle, pointer(address), @w[1], length(w)*2, r));
end
else
lua_pushboolean(L, WriteProcessMemory(processhandle, pointer(address), v, length(v), r));
result:=1;
end;
except
result:=0;
lua_pop(L, lua_gettop(L));
end;
end;
function writeStringLocal(L: PLua_State): integer; cdecl;
begin
result:=writeStringEx(L, GetCurrentProcess);
end;
function writeString(L: PLua_State): integer; cdecl;
begin
result:=writeStringEx(L, processhandle);
end;
function readBytesEx(processhandle: THandle; L: PLua_State): integer; cdecl;
var parameters: integer;
addresstoread: ptruint;
bytestoread: integer;
i: integer;
bytes: array of byte;
x: PtrUInt;
tableversion: boolean;
begin
tableversion:=false;
result:=0;
parameters:=lua_gettop(L);
if lua_isstring(L, 1) then
begin
if processhandle=GetCurrentProcess then
addresstoread:=selfsymhandler.getAddressFromNameL(lua_tostring(L,1), waitforsymbols)
else
addresstoread:=symhandler.getAddressFromNameL(lua_tostring(L,1), waitforsymbols);
end
else
addresstoread:=lua_tointeger(L,1);
if parameters>1 then
begin
bytestoread:=lua_tointeger(L,2);
if parameters>2 then
tableversion:=lua_toboolean(L, 3);
end
else
bytestoread:=1;
lua_pop(L, parameters);
setlength(bytes,bytestoread);
ZeroMemory(@bytes[0], bytestoread);
x:=0;
ReadProcessMemory(processhandle, pointer(addresstoread), @bytes[0], bytestoread, x);
if (x>0) and (x<=bytestoread) then
begin
if tableversion then
begin
lua_createtable(L, x,0);
for i:=0 to x-1 do
begin
lua_pushinteger(L, i+1);
lua_pushinteger(L, bytes[i]);
lua_settable(L, -3);
end;
result:=1;
end
else
begin
while lua_checkstack(L,x)=false do
x:=x div 2;
for i:=0 to x-1 do
lua_pushinteger(L,bytes[i]);
result:=x;
end;
end;
end;
function writeBytesEx(processhandle: THandle; L: PLua_State): integer;
var
parameters, parameters2: integer;
bytes: array of byte;
i,j: integer;
bytecount: integer;
address: ptruint;
x: PtrUInt;
oldprotect: dword;
b: byte;
vpe: boolean;
begin
parameters:=lua_gettop(L);
if parameters=0 then exit(0);
address:=lua_toaddress(L,1,processhandle=GetCurrentProcess);
bytecount:=0;
if lua_istable(L, 2) then
begin
parameters2:=lua_objlen(L, 2);
setlength(bytes, parameters2);
for i:=1 to parameters2 do
begin
lua_pushinteger(L,i);
lua_gettable(L, 2);
if lua_isnumber(L,-1) then
begin
j:=lua_tointeger(L,-1);
bytes[bytecount]:=j;
inc(bytecount);
end;
lua_pop(L,1);
end;
end
else
begin
setlength(bytes,parameters-1);
bytecount:=0;
for i:=(-parameters)+1 to -1 do
begin
b:=lua_tointeger(L,i);
bytes[bytecount]:=b;
inc(bytecount);
end;
end;
x:=0;
if SystemSupportsWritableExecutableMemory or SkipVirtualProtectEx then
vpe:=(SkipVirtualProtectEx=false) and VirtualProtectEx(processhandle, pointer(address), bytecount, PAGE_EXECUTE_READWRITE, oldprotect)
else
begin
if processid<>GetCurrentProcessId then
ntsuspendProcess(processhandle);
vpe:=(SkipVirtualProtectEx=false) and VirtualProtectEx(processhandle, pointer(address), bytecount, PAGE_READWRITE, oldprotect);
end;
WriteProcessMemory(processhandle, pointer(address), @bytes[0], bytecount, x);
if vpe then VirtualProtectEx(processhandle, pointer(address), bytecount, oldprotect, oldprotect);
if (not (SystemSupportsWritableExecutableMemory or SkipVirtualProtectEx)) and (processid<>GetCurrentProcessId) then
ntresumeProcess(processhandle);
lua_pop(L, parameters);
lua_pushinteger(L, x); //return the number of bytes written
result:=1; //return 1 value
end;
function writeBytes(L: PLua_state): integer; cdecl;
begin
result:=writeBytesEx(processhandle, L);
end;
function readBytes(L: PLua_State): integer; cdecl;
begin
result:=readBytesEx(processhandle, L);
end;
function writeBytesLocal(L: PLua_state): integer; cdecl;
begin
result:=writebytesEx(getcurrentprocess, L);
end;
function readBytesLocal(L: PLua_State): integer; cdecl;
begin
result:=readbytesEx(getcurrentprocess, L);
end;
function lua_createSection(L: PLua_State): integer; cdecl;
{$IFDEF windows}
var
n: NTSTATUS;
s: THandle;
size: LARGE_INTEGER;
{$ENDIF}
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)>=1 then
begin
size.QuadPart:=lua_tointeger(L,1);
s:=0;
n:=ZwCreateSection(@s,SECTION_ALL_ACCESS,nil, @size, PAGE_EXECUTE_READWRITE,SEC_COMMIT,0);
// STATUS_MAPPED_FILE_SIZE_ZERO
if Succeeded(n) then
begin
lua_pushinteger(L,s);
result:=1;
end
else
begin
lua_pushnil(L);
lua_pushinteger(L,n);
result:=2;
end;
end;
{$ENDIF}
end;
function lua_MapViewOfSection(L: PLua_State): integer; cdecl;
{$IFDEF windows}
var
basep: pointer;
sh: thandle;
base: pointer;
offset: LARGE_INTEGER;
n: NTSTATUS;
si: SECTION_INHERIT;
viewsize: LARGE_INTEGER;
{$ENDIF}
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)>=1 then
begin
sh:=lua_tointeger(L,1);
if lua_Gettop(L)>=2 then
begin
if lua_isstring(L, 2) then
base:=pointer(symhandler.getAddressFromNameL(lua_tostring(L,2), waitforsymbols))
else
base:=pointer(lua_tointeger(L,2));
end
else
base:=nil;
basep:=@base;
offset.QuadPart:=0;
viewsize.QuadPart:=0;
n:=ZwMapViewOfSection(sh,processhandle, @base,0,0,nil,@viewsize,2,0,PAGE_EXECUTE_READWRITE);
if succeeded(n) then
begin
lua_pushinteger(L,ptruint(base));
result:=1;
end
else
begin
lua_pushnil(L);
lua_pushinteger(L, n);
result:=2;
end;
end;
{$ENDIF}
end;
function lua_unMapViewOfSection(L: PLua_State): integer; cdecl;
var parameters: integer;
address: ptruint;
begin
{$IFDEF windows}
result:=1;
parameters:=lua_gettop(L);
if parameters=0 then begin lua_pushboolean(L, false); exit; end;
address:=lua_toaddress(L,1);
lua_pop(L, parameters);
lua_pushinteger(L, ZwUnmapViewOfSection(processhandle, pointer(address)));
{$ELSE}
result:=0;
{$ENDIF}
end;
function deAllocEx(processhandle: THandle; L: PLua_State): integer; cdecl;
var parameters: integer;
address: ptruint;
size: integer;
begin
result:=1;
parameters:=lua_gettop(L);
if parameters=0 then begin lua_pushboolean(L, false); exit; end;
address:=lua_toaddress(L,1, processhandle=GetCurrentProcess);
size:=lua_tointeger(L,2);
lua_pop(L, parameters);
lua_pushboolean(L, virtualfreeex(processhandle,pointer(address),0,MEM_RELEASE));
end;
function deAlloc_lua(L: PLua_State): integer; cdecl;
begin
result:=deAllocEx(processhandle, L);
end;
function deAllocLocal_lua(L: PLua_State): integer; cdecl;
begin
result:=deAllocEx(getcurrentprocess, L);
end;
function AutoAssembleCheck_lua(L: PLua_State): integer; cdecl;
var
script: tstringlist;
enable: boolean;
targetself: boolean;
begin
if lua_gettop(L)=0 then
begin
lua_pushboolean(L,false);
lua_pushstring(L,'No parameters given');
exit(2);
end;
script:=tstringlist.create;
try
script.text:=Lua_ToString(L,1);
if lua_gettop(L)>=2 then
enable:=lua_toboolean(L,2)
else
enable:=true;
if lua_gettop(L)>=3 then
targetself:=lua_toboolean(L,3)
else
targetself:=false;
try
lua_pushboolean(L,autoassemble(script,false,enable,true,targetself));
exit(1);
except
on e:exception do
begin
lua_pushboolean(L,false);
lua_pushstring(L,e.message);
exit(2);
end;
end;
finally
script.free;
end;
end;
function autoAssemble_lua(L: PLua_State): integer; cdecl;
var
parameters: integer;
code: TStringlist=nil;
disableinfo: TDisableInfo;
r: boolean;
targetself: boolean;
i: integer;
secondaryResultTable: integer;
tableIndex, tableIndex2: integer;
disableInfoIndex: integer;
enable: boolean;
name: string;
address: ptruint;
begin
result:=1;
enable:=true;
parameters:=lua_gettop(L);
if parameters=0 then
begin
lua_pushboolean(L, false);
exit;
end;
code:=tstringlist.create;
disableinfo:=TDisableInfo.create;
try
code.text:=lua_tostring(L, 1);
if (parameters>1) and lua_isboolean(L,2) then
targetself:=lua_toboolean(L, 2)
else
targetself:=false;
disableInfoIndex:=0;
if (parameters>1) and lua_istable(L,2) then
disableInfoIndex:=2
else
if (parameters>2) and lua_istable(L,3) then
disableInfoIndex:=3;
if disableInfoIndex>0 then
begin
try
if lua_istable(L, disableInfoIndex) then
begin
enable:=false;
lua_pushstring(L,'allocs');
lua_gettable(L,disableInfoIndex);
if lua_isnil(L,-1)=false then
begin
if lua_istable(L,-1)=false then raise exception.create('Corrupt disableInfo section at the allocs side');
//enum all the entries
lua_pushnil(L); //allocs table at -2
while lua_next(L, -2)<>0 do
begin
i:=length(disableinfo.allocs);
setlength(disableinfo.allocs,i+1);
disableinfo.Allocs[i].varname:=Lua_ToString(L,-2);
tableindex:=lua_gettop(L);
lua_pushstring(L,'address');
lua_gettable(L,tableindex);
if lua_isnumber(L,-1)=false then raise exception.create('Corrupt disableInfo section at '+disableinfo.allocs[i].varname+'.address');
disableinfo.allocs[i].address:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'size');
lua_gettable(L,tableindex);
if lua_isnumber(L,-1)=false then raise exception.create('Corrupt disableInfo section at '+disableinfo.Allocs[i].varname+'.size');
disableinfo.Allocs[i].size:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'prefered');
lua_gettable(L,tableindex);
if lua_isnil(L,-1)=false then
begin
if lua_isnumber(L,-1)=false then raise exception.create('Corrupt disableInfo section at '+disableinfo.Allocs[i].varname+'.prefered');
disableinfo.Allocs[i].prefered:=lua_tointeger(L,-1);
end;
lua_pop(L,1);
lua_pop(L,1);
end;
end;
lua_pop(L,1);
lua_pushstring(L,'registeredsymbols');
lua_gettable(L,disableInfoIndex);
if not lua_isnil(L,-1) then
begin
if lua_istable(L,-1)=false then raise exception.create('Corrupt disableInfo section at the registeredsymbols side');
lua_pushnil(L);
while lua_next(L, disableInfoIndex+1)<>0 do
begin
disableinfo.registeredsymbols.Add(Lua_ToString(L,-1));
lua_pop(L,1);
end;
end;
lua_pop(L,1);
lua_pushstring(L,'ccodesymbols');
lua_gettable(L,disableInfoIndex);
if not lua_isnil(L,-1) then
begin
disableinfo.ccodesymbols.free;
disableinfo.ccodesymbols:=lua_ToCEUserData(L,-1);
lua_pop(L,1);
end;
lua_pushstring(L,'exceptionlist');
lua_gettable(L,disableInfoIndex);
if not lua_isnil(L,-1) then
begin
if lua_istable(L,-1)=false then raise exception.create('Corrupt disableInfo section at the exceptionlist side');
setlength(disableinfo.exceptions, lua_objlen(L,-1));
for i:=1 to length(disableinfo.exceptions) do
begin
lua_pushinteger(L,i);
lua_gettable(L,-2);
disableinfo.exceptions[i-1]:=lua_tointeger(L,-1);
lua_pop(L,1);
end;
end;
lua_pop(L,1); //pop exceptionlist
lua_pushstring(L,'symbols');
lua_gettable(l,disableInfoIndex);
if not lua_isnil(L,-1) then
begin
if lua_istable(L,-1)=false then raise exception.create('Corrupt disableInfo section at the symbols side');
lua_pushnil(L);
while lua_next(L, -2)<>0 do
begin
name:=Lua_ToString(L,-2);
address:=lua_tointeger(L,-1);
disableinfo.allsymbols.AddObject(name, tobject(address));
lua_pop(L,1);
end;
end;
lua_pop(L,1);
end
else raise exception.create('Not a valid disableInfo variable');
except
on e:exception do
begin
lua_pushboolean(L,false);
lua_pushstring(L,e.Message);
exit(2);
end;
end;
end;
try
r:=autoassemble(code, false, enable, false, targetself, disableinfo);
except
on e:exception do
begin
lua_pushboolean(L,false);
lua_pushstring(L,e.Message);
exit(2);
end;
end;
lua_pop(L, parameters);
lua_pushboolean(L, r);
if r and enable then
begin
result:=2;
lua_newtable(L);
secondaryResultTable:=lua_gettop(L); //should be 2
lua_pushstring(L,'allocs');
lua_newtable(L);
tableIndex:=lua_gettop(L);
for i:=0 to length(disableinfo.Allocs)-1 do
begin
lua_pushstring(L, disableinfo.Allocs[i].varname);
lua_newtable(L);
tableindex2:=lua_gettop(L);
lua_setbasictableentry(L, tableindex2, 'address',disableinfo.Allocs[i].address);
lua_setbasictableentry(L, tableindex2, 'size',disableinfo.Allocs[i].size);
if disableinfo.Allocs[i].prefered<>0 then
lua_setbasictableentry(L, tableindex2, 'prefered',disableinfo.Allocs[i].prefered);
lua_settable(L, tableindex);
end;
lua_settable(l,secondaryResultTable);
lua_pushstring(L,'registeredsymbols');
lua_newtable(L);
tableIndex:=lua_gettop(L);
for i:=0 to disableinfo.registeredsymbols.Count-1 do
begin
lua_pushinteger(L,i+1);
lua_pushstring(L, disableinfo.registeredsymbols[i]);
lua_settable(L, tableIndex);
end;
lua_settable(L, secondaryResultTable);
//ccode symbollist
if (disableinfo.ccodesymbols.count>0) then
begin
disableinfo.donotfreeccodedata:=true; //will return later
lua_pushstring(L,'ccodesymbols');
luaclass_newClass(L,disableinfo.ccodesymbols);
lua_settable(L, secondaryResultTable);
end;
lua_pushstring(L,'exceptionlist');
lua_newtable(L);
tableIndex:=lua_gettop(L);
for i:=0 to length(disableinfo.exceptions)-1 do
begin
lua_pushinteger(L,i+1);
lua_pushinteger(L, disableinfo.exceptions[i]);
lua_settable(L, tableIndex);
end;
lua_settable(L, secondaryResultTable);
lua_pushstring(L,'symbols');
lua_newtable(L);
tableindex:=lua_gettop(L);
for i:=0 to disableinfo.allsymbols.count-1 do
begin
name:=disableinfo.allsymbols[i];
address:=ptruint(disableinfo.allsymbols.Objects[i]);
lua_pushstring(L,name);
lua_pushinteger(L,address);
lua_settable(L, tableindex);
end;
lua_settable(L, secondaryResultTable);
end;
finally
if code<>nil then
code.free;
if disableinfo<>nil then
disableinfo.free;
end;
end;
function lua_assemble(L: PLua_State): integer; cdecl;
var
address: ptruint;
line: string;
pref: TassemblerPreference;
skiprangecheck: boolean;
r: TAssemblerBytes;
begin
if lua_gettop(L)>=1 then
begin
try
line:=Lua_ToString(L,1);
if lua_gettop(L)>=2 then
address:=lua_toaddress(L,2)
else
address:=0;
if lua_gettop(L)>=3 then
pref:=TassemblerPreference(lua_tointeger(L,3))
else
pref:=apNone;
if lua_gettop(L)>=4 then
skiprangecheck:=lua_toboolean(L,4)
else
skiprangecheck:=false;
if Assemble(line,address,r, pref,skiprangecheck) then
begin
CreateByteTableFromPointer(L,@r[0],length(r));
exit(1);
end
else
begin
lua_pushnil(L);
exit(1);
end;
except
on e: exception do
begin
lua_pushnil(L);
lua_pushstring(L,e.Message);
exit(2);
end;
end;
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'invalid parameters');
exit(2);
end;
end;
function getPixel(L: PLua_State): integer; cdecl;
var t:TCanvas;
parameters: integer;
r: dword;
x,y: integer;
begin
result:=0; //return 0 paramaters
parameters:=lua_gettop(L);
if parameters=2 then
begin
x:=lua_tointeger(L, -2); //x
y:=lua_tointeger(L, -1); //y
lua_pop(L, 2);
try
t:=TCanvas.create;
try
t.Handle:=getdc(0);
r:=t.Pixels[x,y];
lua_pushinteger(L,r); //push the color on the stack
result:=1; //tell lue I put 1 parameter on the stack
ReleaseDC(0,t.handle);
finally
t.free;
end;
except
end;
end else lua_pop(L, parameters);
end;
function getMousePos(L: PLua_State): integer; cdecl;
var t:TCanvas;
parameters: integer;
cp: Tpoint;
begin
result:=0; //return 0 parameters
parameters:=lua_gettop(L);
if parameters=0 then
begin
cp:=mouse.CursorPos;
lua_pushinteger(L, cp.x);
lua_pushinteger(L, cp.y);
result:=2; //return 2 parameters
end else lua_pop(L, parameters);
end;
function setMousePos(L: PLua_State): integer; cdecl;
var t:TCanvas;
parameters: integer;
cp: Tpoint;
begin
result:=0; //return 0 parameters
parameters:=lua_gettop(L);
if parameters=2 then
begin
cp.x:=lua_tointeger(L, -2); //x
cp.y:=lua_tointeger(L, -1); //y
lua_pop(L, 2);
mouse.CursorPos:=cp;
end else lua_pop(L, parameters);
end;
function createTableEntry(L: PLua_State): integer; cdecl;
var parameters: integer;
r: pointer;
begin
lua_pop(L, lua_gettop(L)); //clear the stack
r:=ce_createTableEntry;
luaclass_newClass(L, r);
result:=1;
end;
function getTableEntry(L: PLua_State): integer; cdecl;
var parameters: integer;
description: pchar;
r: pointer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
description:=lua.lua_tostring(L,-1); //description
lua_pop(L, parameters); //clear stack
r:=ce_getTableEntry(description);
if r<>nil then
begin
luaclass_newClass(L, r);
result:=1;
end;
end else lua_pop(L, parameters);
end;
function isKeyPressed(L: PLua_State): integer; cdecl;
var parameters: integer;
keyinput: pchar;
key: integer;
w: word;
r: boolean;
begin
result:=0;
r:=false;
key:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
if lua_isstring(L,-1) then //char given instead of keycode
begin
keyinput:=lua.lua_tostring(L,-1);
if keyinput<>nil then
key:=ord(keyinput[0]);
end
else
if lua_isnumber(L,-1) then //keycode
key:=lua_tointeger(L,-1);
lua_pop(L, parameters); //parameters have been fetched, clear stack
if key<>0 then
begin
{$IFDEF windows}
if key>=VK_PAD_A then
begin
lua_pushboolean(L, HotkeyHandler.IsKeyPressed(key));
exit(1);
end;
{$ENDIF}
w:=GetAsyncKeyState(key);
r:=(w and 1)=1;
if not r then
r:=((w shr 15) and 1)=1;
lua_pushboolean(L, r);
result:=1;
end;
end else lua_pop(L, parameters);
end;
function lua_mouse_event(L: PLua_State): integer; cdecl;
var
flags, x,y,data: dword;
extrainfo: ptruint;
c: integer;
begin
result:=0;
{$IFDEF windows}
c:=lua_gettop(L);
if c=0 then exit(0); //flags is important, the rest can be ignored
flags:=lua_tointeger(L, 1);
x:=lua_tointeger(L, 2);
y:=lua_tointeger(L, 3);
data:=lua_tointeger(L, 4);
extrainfo:=lua_tointeger(L, 5);
mouse_event(flags, x, y, data, extrainfo);
{$ENDIF}
end;
function keyDown(L: PLua_State): integer; cdecl;
var parameters: integer;
keyinput: pchar;
key: integer;
w: word;
r: boolean;
begin
result:=0;
{$IFDEF windows}
r:=false;
key:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
if lua_isstring(L,-1) then //char given isntead of keycode
begin
keyinput:=lua.lua_tostring(L,-1);
if keyinput<>nil then
key:=ord(keyinput[0]);
end
else
if lua_isnumber(L,-1) then //keycode
key:=lua_tointeger(L,-1);
if key<>0 then
keybd_event(key, 0,0,0);
end;
lua_pop(L, parameters);
{$ENDIF}
end;
function keyUp(L: PLua_State): integer; cdecl;
var parameters: integer;
keyinput: pchar;
key: integer;
w: word;
r: boolean;
begin
result:=0;
{$IFDEF windows}
r:=false;
key:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
if lua_isstring(L,-1) then //char given isntead of keycode
begin
keyinput:=lua.lua_tostring(L,-1);
if keyinput<>nil then
key:=ord(keyinput[0]);
end
else
if lua_isnumber(L,-1) then //keycode
key:=lua_tointeger(L,-1);
if key<>0 then
keybd_event(key, 0,KEYEVENTF_KEYUP,0);
end;
lua_pop(L, parameters);
{$ENDIF}
end;
function doKeyPress(L: PLua_State): integer; cdecl;
var parameters: integer;
keyinput: pchar;
key: integer;
w: word;
r: boolean;
begin
result:=0;
{$IFDEF windows}
r:=false;
key:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
if lua_isstring(L,1) then //char given instead of keycode
begin
keyinput:=lua.lua_tostring(L,1);
if keyinput<>nil then
key:=ord(keyinput[0]);
end
else
if lua_isnumber(L,1) then //keycode
key:=lua_tointeger(L,1);
if key<>0 then
begin
keybd_event(key, 0, 0, 0);
windows.sleep(110);
keybd_event(key, 0, KEYEVENTF_KEYUP, 0);
end;
end;
lua_pop(L, parameters);
{$ENDIF}
end;
function getProcessIDFromProcessName(L: PLua_state): integer; cdecl;
var parameters: integer;
pname: pchar;
pid: dword;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
pname:=lua.lua_tostring(L, -1);
lua_pop(L, parameters);
pid:=ce_getProcessIDFromProcessName(pname);
if pid<>0 then
begin
lua_pushinteger(L, pid);
result:=1;
end;
end else lua_pop(L, parameters);
end;
function openProcess(L: PLua_state): integer; cdecl;
var parameters: integer;
pname: pchar;
pid: dword;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
begin
if lua_isstring(L,1) then
begin
pname:=lua.lua_tostring(L,1);
pid:=ce_getProcessIDFromProcessName(pname);
end
else
pid:=lua_tointeger(L,1);
lua_pop(L, parameters);
if pid<>0 then
ce_openProcess(pid);
if (ProcessHandle<>0) and (processid=pid) then
begin
lua_pushboolean(L, true);
result:=1;
end;
end else lua_pop(L, parameters);
end;
function beep(L: PLua_state): integer; cdecl;
begin
lua_pop(L, lua_gettop(L)); //clear the stack
SysUtils.Beep;
result:=0;
end;
function pause(L: PLua_state): integer; cdecl;
begin
lua_pop(L, lua_gettop(L)); //clear the stack
ce_pause;
result:=0;
end;
function unpause(L: PLua_state): integer; cdecl;
begin
lua_pop(L, lua_gettop(L)); //clear the stack
ce_unpause;
result:=0;
end;
function debugProcess(L: PLua_state): integer; cdecl;
var parameters: integer;
debuggerinterface: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
debuggerinterface:=lua_tointeger(L, -1)
else
debuggerinterface:=0;
lua_pop(L, lua_gettop(L)); //clear the stack
ce_debugProcess(debuggerinterface);
end;
function debug_getCurrentDebuggerInterface(L:PLua_State): integer; cdecl;
begin
if debuggerthread<>nil then
begin
{$IFDEF windows}
if (CurrentDebuggerInterface is TWindowsDebuggerInterface) then
lua_pushinteger(L, 1);
if (CurrentDebuggerInterface is TVEHDebugInterface) then
lua_pushinteger(L, 2);
if (CurrentDebuggerInterface is TKernelDebugInterface) then
lua_pushinteger(L, 3);
{$ENDIF}
{$ifdef darwin}
lua_pushinteger(L, 4);
{$endif}
if (CurrentDebuggerInterface is TGDBServerDebuggerInterface) then
lua_pushinteger(L, 5);
result:=1;
end
else
result:=0;
end;
function debug_getBreakpointList(L: Plua_State): integer; cdecl;
var
al: TAddressArray;
t: integer;
i: integer;
begin
result:=0;
if debuggerthread<>nil then
begin
debuggerthread.getBreakpointAddresses(al);
lua_newtable(L);
t:=lua_gettop(L);
for i:=0 to length(al)-1 do
begin
lua_pushinteger(L, i+1);
lua_pushinteger(L, al[i]);
lua_settable(L, t);
end;
result:=1;
end;
end;
function lua_checkSynchronize(L: Plua_State): integer; cdecl;
var timeout: integer=0;
begin
result:=0;
if lua_Gettop(L)>0 then
timeout:=lua_tointeger(L,1);
CheckSynchronize(timeout);
end;
function lua_queue(L: Plua_State): integer; cdecl;
var lc: TLuaCaller;
f: integer;
routine: string;
begin
result:=0;
lc:=nil;
if lua_isfunction(L,1) then
begin
lua_pushvalue(L, 1);
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
end
else
if lua_isstring(L,1) then
begin
routine:=lua_tostring(L,1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
end;
if lc<>nil then
begin
lc.syncvm:=l;
if lua_gettop(L)>=2 then
begin
lc.synchronizeparam:=2;
lc.synchronizeparamcount:=lua_gettop(l)-1;
end
else
lc.synchronizeparam:=0;
// tthread.ForceQueue(TThread.CurrentThread, lc.queue);
tthread.ForceQueue(TThread.CurrentThread, lc.queue);
result:=0;
end;
end;
function lua_getCurrentThreadID(L: Plua_State): integer; cdecl;
begin
lua_pushinteger(L, qword(GetCurrentThreadId));
exit(1);
end;
function lua_synchronize(L: Plua_State): integer; cdecl;
var lc: TLuaCaller;
f: integer;
routine: string;
begin
result:=0;
lc:=nil;
if lua_isfunction(L,1) then
begin
lua_pushvalue(L, 1);
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
end
else
if lua_isstring(L,1) then
begin
routine:=lua_tostring(L,1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
end;
if lc<>nil then
begin
lc.syncvm:=l;
if lua_gettop(L)>=2 then
begin
lc.synchronizeparam:=2;
lc.synchronizeparamcount:=lua_gettop(l)-1;
end
else
lc.synchronizeparam:=0;
tthread.Synchronize(nil, lc.synchronize);
result:=1;
end;
end;
function inMainThread(L: Plua_State): integer; cdecl;
begin
lua_pushboolean(L, MainThreadID=GetCurrentThreadId);
result:=1;
end;
function debug_isDebugging(L: Plua_State): integer; cdecl;
begin
lua_pushboolean(L, debuggerthread<>nil);
result:=1;
end;
function debug_canBreak(L: Plua_State): integer; cdecl;
var list: TAddressArray;
begin
if debuggerthread<>nil then
begin
debuggerthread.getBreakpointAddresses(list);
lua_pushboolean(L, (length(list)>0) or ((debuggerthread.CurrentThread<>nil) and (debuggerthread.CurrentThread.isHandled)) );
end
else
lua_pushboolean(L, false);
result:=1;
end;
function debug_isBroken(L: PLua_state): integer; cdecl;
var r: boolean;
begin
r:=(debuggerthread<>nil) and (debuggerthread.CurrentThread<>nil) and (debuggerthread.CurrentThread.isHandled);
lua_pushboolean(L, r);
result:=1;
end;
function debug_isStepping(L: PLua_state): integer; cdecl;
var r: boolean;
begin
r:=(debuggerthread<>nil) and (debuggerthread.CurrentThread<>nil) and (debuggerthread.CurrentThread.isSingleStepping);
lua_pushboolean(L, r);
result:=1;
end;
function debug_setBreakpointForThread(L: Plua_State): integer; cdecl;
var
threadid: dword;
parameters: integer;
address: ptruint;
size: integer;
trigger: TBreakpointTrigger;
method: TBreakpointMethod;
lc: TLuaCaller;
bpe: TBreakpointEvent;
begin
lc:=nil;
trigger:=bptExecute;
result:=0;
size:=1;
parameters:=lua_gettop(L);
if parameters=0 then
raise exception.create(rsDebugsetBreakpointNeedsAtLeastAnAddress);
threadid:=lua_tointeger(L,1);
address:=lua_toaddress(L,2);
if parameters>=3 then
begin
if lua_isfunction(L,3) then //address, function type
begin
lua_pushvalue(L,3);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=luaL_ref(L,LUA_REGISTRYINDEX);
end
else
begin
if lua_isnumber(L, 3) then
size:=lua_tointeger(L, 3)
else
begin //function name as string
lc:=TLuaCaller.create;
lc.luaroutine:=Lua_ToString(L,3);
end;
end;
end;
method:=preferedBreakpointMethod;
if lc=nil then //address, size OPTIONAL, trigger OPTIONAL, method, functiontocall OPTIONAL
begin
if parameters>=4 then
trigger:=TBreakpointTrigger(lua_tointeger(L,4))
else
trigger:=bptExecute;
if parameters>=5 then
begin
if lua_isnumber(L, 5) then //address, size OPTIONAL, trigger OPTIONAL, method
begin
method:=TBreakpointMethod(lua_tointeger(L,5));
end
else
begin
//addresss, size, trigger, function
if lua_isfunction(L,5) then //address, function type
begin
lua_pushvalue(L,5);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=luaL_ref(L,LUA_REGISTRYINDEX);
end
else
begin
lc:=TLuaCaller.create;
lc.luaroutine:=Lua_ToString(L,5);
end;
end;
end;
if lc=nil then
begin
if parameters>=6 then
begin
if lua_isfunction(L,6) then //address, function type
begin
lua_pushvalue(L,6);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=luaL_ref(L,LUA_REGISTRYINDEX);
end
else
begin
lc:=TLuaCaller.create;
lc.luaroutine:=Lua_ToString(L,6);
end;
end;
end;
end;
try
if lc<>nil then
bpe:=TBreakpointEvent(lc.BreakpointEvent)
else
bpe:=nil;
if startdebuggerifneeded(false) then
begin
case trigger of
bptAccess: debuggerthread.SetOnAccessBreakpoint(address, size, method, threadid, bpe);
bptWrite: debuggerthread.SetOnWriteBreakpoint(address, size, method, threadid, bpe);
bptExecute: debuggerthread.SetOnExecuteBreakpoint(address, method,false, threadid, bpe);
end;
MemoryBrowser.hexview.update;
Memorybrowser.disassemblerview.Update;
end;
except
end;
lua_pop(L, lua_gettop(L)); //clear the stack
end;
function debug_setBreakpoint(L: Plua_State): integer; cdecl;
begin
lua_pushinteger(L,0);
lua_insert(L,1);
result:=debug_setBreakpointForThread(L);
end;
function debug_removeBreakpoint(L: Plua_State): integer; cdecl;
var parameters: integer;
address: ptruint;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
address:=lua_toaddress(L,1);
lua_pushboolean(L, ce_debug_removeBreakpoint(address));
result:=1;
end;
lua_pop(L, lua_gettop(L)); //clear the stack
end;
function debug_breakThread(L: Plua_State): integer; cdecl;
var
threadid: dword;
threadlist: TList;
i: integer;
begin
result:=0;
if lua_gettop(L)>0 then
begin
threadid:=lua_tointeger(L,1);
if not startdebuggerifneeded(false) then exit;
if debuggerthread<>nil then
begin
//find the thread
threadlist:=debuggerthread.lockThreadlist;
try
for i:=0 to threadlist.count-1 do
begin
if TDebugThreadHandler(threadlist[i]).ThreadId=threadid then
begin
TDebugThreadHandler(threadlist[i]).breakThread;
exit(0);
end;
end;
finally
debuggerthread.unlockThreadlist;
end;
end;
end;
end;
function debug_continueFromBreakpoint(L: Plua_State): integer; cdecl;
var parameters: integer;
method: TContinueOption;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
method:=TContinueOption(lua_tointeger(L, -1));
ce_debug_continuefrombreakpoint(method);
end;
lua_pop(L, lua_gettop(L)); //clear the stack
end;
function debug_addThreadToNoBreakList(L: Plua_State): integer; cdecl;
begin
result:=1;
if debuggerthread<>nil then
begin
CurrentDebuggerInterface.AddToNoBreakList(lua_tointeger(L,1));
lua_pushboolean(L, true);
end
else
lua_pushboolean(L, false);
end;
function debug_removeThreadFromNoBreakList(L: Plua_State): integer; cdecl;
begin
result:=1;
if debuggerthread<>nil then
begin
CurrentDebuggerInterface.RemoveFromNoBreakList(lua_tointeger(L,1));
lua_pushboolean(L, true);
end
else
lua_pushboolean(L, false);
end;
var isclosing: boolean;
function closeCE(L: Plua_state): integer; cdecl;
var th: thandle;
b: boolean;
begin
if isclosing=false then
begin
isclosing:=true;
ce_closeCE; //cleanup
{$ifdef windows}
ExitProcess(0);
{$else}
application.Terminate;
{$endif}
end;
result:=0;
end;
function hideAllCEWindows(L: Plua_State): integer; cdecl;
begin
result:=0;
lua_pop(L, lua_gettop(L)); //clear the stack
ce_hideAllCEWindows;
end;
function unhideMainCEwindow(L: Plua_State): integer; cdecl;
begin
result:=0;
lua_pop(L, lua_gettop(L)); //clear the stack
ce_unhideMainCEwindow;
end;
function createLabel(L: Plua_State): integer; cdecl;
var parameters: integer;
f,p: pointer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
f:=lua_toceuserdata(L, -1);
p:=ce_createLabel(f);
lua_pop(L, lua_gettop(L));
luaclass_newClass(L, p);
result:=1;
end else lua_pop(L, lua_gettop(L));
end;
function messageDialog(L: PLua_State): integer; cdecl;
var
parameters: integer;
message: string;
title: string;
dialogtype: TMsgDlgType;
buttontype: integer;
r: integer;
i: integer;
b: TMsgDlgButtons;
dialogtypeindex: integer;
begin
result:=0;
dialogtypeindex:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
begin
title:='';
if parameters>=2 then
begin
if lua_type(L,2)=LUA_TSTRING then
begin
if parameters>=3 then
dialogtypeindex:=3;
title:=Lua_ToString(L,1);
message:=lua_tostring(L,2);
end
else
begin
message:=lua_tostring(L,1);
if parameters>=2 then
dialogtypeindex:=2;
end;
end
else
message:=lua_tostring(L,1);
if dialogtypeindex=0 then
dialogtype:=mtConfirmation
else
dialogtype:=TMsgDlgType(lua_tointeger(L,dialogtypeindex));
b:=[];
if dialogtypeindex>0 then
begin
for i:=dialogtypeindex+1 to parameters do
begin
buttontype:=lua_tointeger(L,i);
case buttontype of
0: b:=b+[mbYes];
1: b:=b+[mbNo];
2: b:=b+[mbOK];
3: b:=b+[mbCancel];
4: b:=b+[mbAbort];
5: b:=b+[mbRetry];
6: b:=b+[mbIgnore];
7: b:=b+[mbAll];
8: b:=b+[mbNoToAll];
9: b:=b+[mbYesToAll];
10: b:=b+[mbHelp];
11: b:=b+[mbClose];
else b:=b+[mbyes];
end;
end;
end;
if b=[] then
b:=[mbOk];
lua_pop(L, parameters);
if title<>'' then
r:=messageDlg(title,message,dialogtype,b,0)
else
r:=messageDlg(message, dialogtype, b,0);
lua_pushinteger(L,r);
result:=1;
end else lua_pop(L, parameters);
end;
function speedhack_getSpeed(L: PLua_State): integer; cdecl;
begin
lua_pushnumber(L, speedhack.getSpeed);
result:=1;
end;
function speedhack_setSpeed(L: PLua_State): integer; cdecl;
var
parameters: integer;
speed: single;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
speed:=lua_tonumber(L,-1);
ce_speedhack_setSpeed(speed);
end;
lua_pop(L, parameters);
end;
function injectDLL(L: PLua_State): integer; cdecl;
var
parameters: integer;
filename: string;
skipsymbolwait: boolean;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
begin
filename:=lua_tostring(L,1);
try
OutputDebugString('Lua: injectLibrary('+filename+')');
if parameters>1 then
skipsymbolwait:=lua_toboolean(L,2)
else
skipsymbolwait:=false;
cefuncproc.injectdll(filename,'');
if skipsymbolwait=false then
begin
symhandler.reinitialize;
symhandler.waitForExports;
end;
except
on e:exception do
begin
lua_pushboolean(L, false);
lua_pushstring(L, e.Message);
exit(2);
end;
end;
//still here
result:=1;
lua_pushboolean(L, true);
end;
end;
function getAutoAttachList(L: Plua_State): integer; cdecl;
var f: pointer;
parameters: integer;
visible: boolean;
begin
result:=1;
lua_pop(L, lua_gettop(L));
f:=ce_getAutoAttachList();
luaclass_newClass(L, f);
result:=1;
end;
function generateAPIHookScript_lua(L: PLua_state): integer; cdecl;
var
parameters: integer;
address: string;
addressTo: string;
addresstogetnewcalladdress: string;
ext: string='';
self: boolean=false;
script: tstringlist;
enable,disable: Tstringlist;
begin
address:='';
addressTo:='';
addresstogetnewcalladdress:='';
result:=0;
parameters:=lua_gettop(L);
if parameters>=2 then
begin
address:=lua_tostring(L, 1);
addressTo:=lua_tostring(L, 2);
if parameters>=3 then
addresstogetnewcalladdress:=lua_tostring(L, 3);
if parameters>=4 then
ext:=lua_tostring(L, 4);
if parameters>=5 then
self:=lua_toboolean(L,5);
lua_pop(L, lua_gettop(L));
script:=tstringlist.create;
enable:=tstringlist.create;
disable:=tstringlist.create;
try
script.add('[enable]');
script.add('');
script.add('[disable]');
script.add('');
generateAPIHookScript(script, address, addressto, addresstogetnewcalladdress,ext,self);
getEnableOrDisableScript(script, enable, true);
getEnableOrDisableScript(script, disable, false);
lua_pushstring(L, pchar(enable.text));
lua_pushstring(L, pchar(disable.text));
result:=2;
finally
script.free;
enable.free;
disable.free;
end;
end;
end;
function createProcess(L: PLua_state): integer; cdecl;
var parameters: integer;
path,params: string;
debug: boolean;
breakonentrypoint: boolean;
begin
result:=0;
parameters:=lua_gettop(L);
path:='';
params:='';
debug:=false;
breakonentrypoint:=false;
if parameters>0 then
path:=lua_tostring(L, 1);
if parameters>1 then
params:=lua_tostring(L, 2);
if parameters>2 then
debug:=lua_toboolean(L, 3);
if parameters>3 then
breakonentrypoint:=lua_toboolean(L, 4);
if path<>'' then
ce_createProcess(pchar(path), pchar(params), debug, breakonentrypoint);
lua_pop(L, lua_gettop(L));
end;
function AOBScanModuleUnique(L: PLua_state): integer; cdecl;
var
module: string;
scanstring: string;
protectionflags: string;
alignmentparam: string;
alignmenttype: TFastScanMethod;
list: tstringlist;
r: ptruint;
parameters: integer;
begin
parameters:=lua_gettop(L);
if parameters>=2 then
begin
module:=Lua_ToString(L,1);
scanstring:=Lua_ToString(L,2);
if parameters>=3 then
protectionflags:=Lua_ToString(L, 3)
else
protectionflags:='*X*W*C';
if parameters>=4 then
alignmenttype:=TFastScanMethod(lua_tointeger(L, 4))
else
alignmenttype:=fsmNotAligned;
if parameters>=5 then
alignmentparam:=Lua_ToString(L, 5)
else
alignmentparam:='1';
if scanstring='' then
begin
lua_pushstring(L,'Invalid parameter. Must be a string');
lua_pushnil(L);
result:=2;
end;
r:=findaobInModule(module, scanstring, protectionflags, alignmenttype,alignmentparam,true);
if r=0 then
lua_pushnil(L)
else
lua_pushinteger(L,r);
result:=1;
end
else
begin
lua_pushstring(L,'Not enough parameters');
lua_pushnil(L);
result:=2;
end;
end;
function AOBScanUnique(L: PLua_state): integer; cdecl;
var
scanstring: string;
protectionflags: string;
alignmentparam: string;
alignmenttype: TFastScanMethod;
list: tstringlist;
r: ptruint;
parameters: integer;
begin
lua_pushstring(L,'');
lua_insert(L,1);
exit(AOBScanModuleUnique(L));
end;
function AOBScan(L: PLua_state): integer; cdecl;
var
parameters: integer;
i,b: integer;
scanstring: string;
protectionflags: string;
alignmentparam: string;
alignmenttype: TFastScanMethod;
list: tstringlist;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=0 then exit;
protectionflags:='';
alignmenttype:=fsmNotAligned;
alignmentparam:='1';
if (parameters>=1) and (lua_isstring(L,1)) then
begin
//it's a scanstring, optional call
scanstring:=Lua_ToString(L, 1);
if parameters>=2 then
protectionflags:=Lua_ToString(L, 2);
if parameters>=3 then
alignmenttype:=TFastScanMethod(lua_tointeger(L, 3));
if parameters>=4 then
alignmentparam:=Lua_ToString(L, 4);
end
else
begin
//buildup the scanstring
scanstring:='';
for i:=-parameters to -1 do
begin
b:=lua_tointeger(L,i);
if (b>255) then scanstring:=scanstring+'* '
else
if b=0 then
begin
if not lua_isnumber(L,i) then
scanstring:=scanstring+'* '
else
scanstring:=scanstring+'00 '
end
else scanstring:=scanstring+inttohex(b,2)+' ';
end;
end;
lua_pop(L, lua_gettop(L));
list:=tstringlist.create;
if getaoblist(scanstring, list, protectionflags, alignmenttype, alignmentparam) then
begin
result:=1;
luaclass_newClass(L, list);
end
else
begin
list.free;
end;
end;
function getOpenedProcessID(L: PLua_state): integer; cdecl;
begin
lua_pushinteger(L, processid);
result:=1;
end;
function getOpenedProcessHandle(L: PLua_state): integer; cdecl;
begin
lua_pushinteger(L, processhandle);
result:=1;
end;
function getSymbolInfo(L: PLua_state): integer; cdecl;
var
parameters: integer;
symbolname: string;
mi: TModuleInfo;
si: TCESymbolInfo;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
symbolname:=Lua_ToString(L, 1);
lua_pop(L, lua_gettop(l));
if symhandler.GetSymbolInfo(symbolname, si) then
begin
pushSymbol(L, @si);
result:=1;
end;
end;
end;
function getModuleSize(L: PLua_state): integer; cdecl;
var
parameters: integer;
modulename: string;
mi: TModuleInfo;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
modulename:=Lua_ToString(L, 1);
lua_pop(L, lua_gettop(l));
if symhandler.getmodulebyname(modulename, mi) then
begin
lua_pushinteger(L, mi.basesize);
result:=1;
end;
end;
end;
function getAddressSafe(L: PLua_state): integer; cdecl;
var parameters: integer;
s: string;
local,shallow,e: boolean;
begin
result:=0;
parameters:=lua_gettop(L);
//outputdebugstring('getAddressSafe. parameters='+parameters.ToString);
if parameters>=1 then
begin
if lua_type(L,1)=LUA_TNUMBER then
begin
lua_pushinteger(L,lua_tointeger(L,1));
exit(1);
end;
s:=Lua_ToString(L, 1);
//outputdebugstring('getAddressSafe('+s+')');
if parameters>=2 then
local:=lua_toboolean(L, 2)
else
local:=false;
if parameters>=3 then
begin
shallow:=lua_toboolean(L, 3);
//if shallow then
// outputdebugstring('getAddressSafe: shallow=true');
end
else
shallow:=false;
lua_pop(L, lua_gettop(l));
try
if not local then
lua_pushinteger(L,symhandler.getAddressFromName(s, waitforsymbols, e, nil, shallow))
else
lua_pushinteger(L,selfsymhandler.getAddressFromName(s, waitforsymbols, e, nil, shallow));
if e then
result:=0
else
result:=1;
except
exit(0);
end;
end;
end;
function getAddress(L: PLua_state): integer; cdecl;
var parameters: integer;
s: string;
local: boolean;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
begin
if lua_type(L,1)=LUA_TNUMBER then
begin
lua_pushinteger(L,lua_tointeger(L,1));
exit(1);
end;
s:=Lua_ToString(L, 1);
if parameters>=2 then
local:=lua_toboolean(L, 2)
else
local:=false;
lua_pop(L, lua_gettop(l));
try
if not local then
lua_pushinteger(L,symhandler.getAddressFromNameL(s, waitforsymbols))
else
lua_pushinteger(L,selfsymhandler.getAddressFromNameL(s, waitforsymbols));
except
on e:exception do
begin
{$ifdef windows}
{$ifdef cpu64}
lua_pushstring(L,e.Message);
lua_error(L);
{$else}
raise;
{$endif}
{$else}
lua_pushnil(L);
lua_pushstring(L, e.message);
exit(2);
{$endif}
end;
end;
result:=1;
end
else
lua_pop(L, lua_gettop(l));
end;
function getNameFromAddress(L: PLua_state): integer; cdecl;
var parameters: integer;
s: string;
address: ptruint;
modulenames: boolean=true;
symbols: boolean=true;
sections: boolean=false;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
begin
address:=lua_toaddress(L,1);
if (parameters>=2) and (not lua_isnil(L,2)) then modulenames:=lua_toboolean(L,2);
if (parameters>=3) and (not lua_isnil(L,3)) then symbols:=lua_toboolean(L,3);
if (parameters>=4) and (not lua_isnil(L,4)) then sections:=lua_toboolean(L,4);
lua_pop(L, lua_gettop(l));
lua_pushstring(L,symhandler.getNameFromAddress(address, symbols, modulenames, sections));
result:=1;
end
else lua_pop(L, lua_gettop(l));
end;
function inModule(L: PLua_state): integer; cdecl;
var parameters: integer;
s: string;
address: ptruint;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
address:=lua_toaddress(L,1);
lua_pop(L, lua_gettop(l));
lua_pushboolean(L,symhandler.inModule(address));
result:=1;
end
else lua_pop(L, lua_gettop(l));
end;
function inSystemModule(L: PLua_state): integer; cdecl;
var parameters: integer;
s: string;
address: ptruint;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
address:=lua_toaddress(L,1);
lua_pop(L, lua_gettop(l));
lua_pushboolean(L,symhandler.inSystemModule(address));
result:=1;
end;
end;
function getCommonModuleList(L: PLua_state): integer; cdecl;
begin
result:=0;
lua_pop(L, lua_gettop(l));
luaclass_newClass(L,symhandler.getCommonModuleList);
result:=1;
end;
function reinitializeDotNetSymbolhandler(L:PLua_state): integer; cdecl;
var modulename: string;
begin
result:=0;
if lua_gettop(L)>=1 then
modulename:=Lua_ToString(L, 1)
else
modulename:='';
symhandler.reinitializeDotNetSymbols(modulename);
end;
function reinitializeSymbolhandler(L: PLua_state): integer; cdecl;
var waittilldone: boolean;
begin
outputdebugstring('lua: reinitializeSymbolhandler');
if lua_gettop(L)>=1 then
waittilldone:=lua_toboolean(L,1)
else
waittilldone:=true;
lua_pop(L, lua_gettop(L));
result:=0;
symhandler.reinitialize(true);
if waitTillDone then
symhandler.waitforsymbolsloaded;
end;
function waitForSections(L: PLua_state): integer; cdecl;
begin
symhandler.waitForSections;
result:=0;
end;
function waitForExports(L: PLua_state): integer; cdecl;
begin
symhandler.waitforExports;
result:=0;
end;
function waitForDotNet(L: PLua_state): integer; cdecl;
begin
symhandler.waitforDotNet;
result:=0;
end;
function waitForPDB(L: PLua_state): integer; cdecl;
begin
symhandler.waitforpdb;
result:=0;
end;
function searchPDBWhileLoading(L: PLua_state): integer; cdecl;
begin
if lua_gettop(L)>=1 then
symhandler.searchPDBWhileLoading(lua_toboolean(L,1));
result:=0;
end;
function reinitializeSelfSymbolhandler(L: PLua_state): integer; cdecl;
var waittilldone: boolean;
begin
if lua_gettop(L)>=1 then
waittilldone:=lua_toboolean(L,1)
else
waittilldone:=true;
lua_pop(L, lua_gettop(L));
result:=0;
selfsymhandler.reinitialize(true);
if waitTillDone then
selfsymhandler.waitforsymbolsloaded;
end;
function enumModules(L:PLua_state): integer; cdecl;
var
i: integer;
ml: tstringlist;
tableindex: integer;
entryindex: integer;
ths: THandle;
me32: TModuleEntry32;
is64bitmodule: boolean;
pid: integer;
st: qword;
tt: qword;
{ ar: lua_debug;
s: pchar;}
begin
{ if MainThreadID=GetCurrentThreadId then
begin
ZeroMemory(@ar,sizeof(ar));
lua_getstack(L, 1,@ar);
lua_getinfo(L,'S',@ar);
showmessage(ar.source);
end;}
result:=0;
if lua_gettop(L)=1 then
pid:=lua_tointeger(L,1)
else
pid:=processid;
tt:=GetTickCount64;
st:=GetTickCount64;
ths:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE or TH32CS_SNAPMODULE32, pid);
// OutputDebugString('CreateToolhelp32Snapshot took '+inttostr(GetTickCount64-st)+' ms.');
if ths<>0 then
begin
lua_newtable(L);
tableindex:=lua_gettop(L);
me32.dwSize:=sizeof(MODULEENTRY32);
i:=1;
st:=GetTickCount64;
if module32first(ths,me32) then
repeat
// OutputDebugString('module32first/next took '+inttostr(GetTickCount64-st)+' ms.');
lua_newtable(L);
entryindex:=lua_gettop(L);
lua_pushstring(L, 'Name');
lua_pushstring(L, extractfilename(me32.szExePath));
lua_settable(L, entryindex);
lua_pushstring(L, 'Address');
lua_pushinteger(L, ptruint(me32.modBaseAddr));
lua_settable(L, entryindex);
is64bitmodule:=processhandler.is64Bit;
{$ifdef windows}
if (processhandler.isNetwork) or (peinfo_is64bitfile(me32.szExePath, is64bitmodule)=false) then
is64bitmodule:=processhandler.is64Bit; //fallback on an assumption
{$endif}
lua_pushstring(L, 'Is64Bit');
lua_pushboolean(L, is64bitmodule);
lua_settable(L, entryindex);
lua_pushstring(L, 'PathToFile');
lua_pushstring(L, me32.szExePath);
lua_settable(L, entryindex);
lua_pushinteger(L, i);
lua_pushvalue(L, entryindex);
lua_settable(L, tableindex);
lua_pop(L, 1); //remove the current entry table
inc(i);
st:=GetTickCount64;
until Module32Next(ths, me32)=false;
lua_pushvalue(L, tableindex); //shouldn't be needed, but let's make sure
result:=1;
closehandle(ths);
end;
//OutputDebugString('enumModules took '+inttostr(GetTickCount64-tt)+' ms.');
end;
function getSettingsForm(L: PLua_state): integer; cdecl;
begin
result:=1;
lua_pop(L, lua_gettop(l));
luaclass_newClass(l, formSettings);
end;
function getMemoryViewForm(L: PLua_state): integer; cdecl;
begin
result:=1;
lua_pop(L, lua_gettop(l));
luaclass_newClass(l, MemoryBrowser);
end;
function getMainForm(L: PLua_state): integer; cdecl;
begin
result:=1;
lua_pop(L, lua_gettop(l));
luaclass_newClass(l, mainform);
end;
function getAddressList(L: PLua_state): integer; cdecl;
begin
result:=1;
lua_pop(L, lua_gettop(l));
luaclass_newClass(l, mainform.addresslist);
end;
function getFreezeTimer(L: PLua_state): integer; cdecl;
begin
result:=1;
lua_pop(L, lua_gettop(l));
luaclass_newClass(l, mainform.FreezeTimer);
end;
function getUpdateTimer(L: PLua_state): integer; cdecl;
begin
result:=1;
lua_pop(L, lua_gettop(l));
luaclass_newClass(l, mainform.UpdateTimer);
end;
function setGlobalKeyPollInterval(L: PLua_state): integer; cdecl;
begin
if lua_gettop(L)=1 then
hotkeyPollInterval:=lua_tointeger(L, -1);
result:=0;
end;
function setGlobalDelayBetweenHotkeyActivation(L: PLua_state): integer; cdecl;
begin
if lua_gettop(L)=1 then
hotkeyIdletime:=lua_tointeger(L, -1);
result:=0;
end;
function inheritsFromObject(L: PLua_state): integer; cdecl;
var x: TObject;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
x:=lua_toceuserdata(L, 1);
lua_pop(L, lua_gettop(l));
if x<>nil then
begin
result:=1;
lua_pushboolean(l, (x is TObject));
end;
end;
end;
function inheritsFromComponent(L: PLua_state): integer; cdecl;
var x: TObject;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
x:=lua_toceuserdata(L, 1);
lua_pop(L, lua_gettop(l));
if x<>nil then
begin
result:=1;
lua_pushboolean(l, (x is TComponent));
end;
end;
end;
function inheritsFromControl(L: PLua_state): integer; cdecl;
var x: TObject;
r: boolean;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
x:=lua_toceuserdata(L, 1);
lua_pop(L, lua_gettop(l));
if x<>nil then
begin
result:=1;
r:=x is TControl;
lua_pushboolean(l, r);
end;
end;
end;
function inheritsFromWinControl(L: PLua_state): integer; cdecl;
var x: TObject;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
x:=lua_toceuserdata(L, 1);
lua_pop(L, lua_gettop(l));
if x<>nil then
begin
result:=1;
lua_pushboolean(l, (x is TWinControl));
end;
end;
end;
function createToggleBox(L: Plua_State): integer; cdecl;
var
ToggleBox: TCEToggleBox;
parameters: integer;
owner: TWincontrol;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
owner:=lua_toceuserdata(L, -parameters)
else
owner:=nil;
lua_pop(L, lua_gettop(L));
ToggleBox:=TCEToggleBox.Create(owner);
if owner<>nil then
ToggleBox.Parent:=owner;
luaclass_newClass(L, ToggleBox);
result:=1;
end;
function opendialog_execute(L: Plua_State): integer; cdecl; //6.2- version only
var
opendialog: TOpenDialog;
begin
opendialog:=luaclass_getClassObject(L);
if opendialog.execute then
lua_pushnil(L)
else
lua_pushstring(L, opendialog.FileName);
result:=1;
end;
function createOpenDialog(L: Plua_State): integer; cdecl;
var
o: TOpenDialog;
begin
result:=0;
if lua_gettop(L)>=1 then
luaclass_newClass(L, TOpenDialog.create(lua_toceuserdata(L, 1)))
else
luaclass_newClass(L, TOpenDialog.create(nil), true);
result:=1;
end;
function createSaveDialog(L: Plua_State): integer; cdecl;
var
o: TSaveDialog;
begin
result:=0;
if lua_gettop(L)>=1 then
luaclass_newClass(L, TSaveDialog.create(lua_toceuserdata(L, 1)))
else
luaclass_newClass(L, TSaveDialog.create(nil));
result:=1;
end;
function CreateSelectDirectoryDialog(L: Plua_State): integer; cdecl;
var
o: TSaveDialog;
begin
result:=0;
if lua_gettop(L)>=1 then
luaclass_newClass(L, TSelectDirectoryDialog.create(lua_toceuserdata(L, 1)))
else
luaclass_newClass(L, TSelectDirectoryDialog.create(nil));
result:=1;
end;
function createMemoryStream(L: Plua_State): integer; cdecl;
begin
luaclass_newClass(L, TMemoryStream.create);
result:=1;
end;
function createFileStream(L: Plua_State): integer; cdecl;
var
filename: string;
mode: word;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
filename:=lua_tostring(L, 1);
if lua_gettop(L)>=2 then
mode:=lua_tointeger(L, 2)
else
begin
//in case the user forgets or doesn't care
if FileExists(filename) then
mode:=fmOpenReadWrite or fmShareDenyNone
else
mode:=fmCreate;
end;
try
luaclass_newClass(L, TFileStream.create(filename, mode));
result:=1;
except
on e:exception do
begin
lua_pushnil(L);
lua_pushstring(L,e.Message);
result:=2;
end;
end;
end;
end;
{
function createStringStream(L: Plua_State): integer; cdecl;
var s: pchar;
//sl: size_t;
ss: TStringStream;
b: TBytes;
stringlength: psize_t;
begin
getmem(stringlength,16);
if lua_gettop(L)>0 then
s:=lua_tolstring(L, 1, stringlength)
else
s:=nil;
setlength(b,0);
ss:=TStringStream.create('',TEncoding.Default,false); //(s);
if (s<>nil) and (stringlength^>0) then
begin
ss.WriteBuffer(s^, stringlength^);
ss.position:=0;
end;
freemem(stringlength);
luaclass_newClass(L, ss);
result:=1;
end;
}
function createStringStream(L: Plua_State): integer; cdecl;
var s: pchar;
sl: size_t=0;
ss: TStringStream;
begin
if lua_gettop(L)>0 then
s:=lua_tolstring(L, 1, @sl)
else
s:=nil;
ss:=TStringStream.create(''{$if FPC_FULLVERSION>=030200},TEncoding.Default,false{$endif});
if (s<>nil) and (sl>0) then
begin
ss.WriteBuffer(s^, sl);
ss.position:=0;
end;
luaclass_newClass(L, ss); //lua_pushinteger(L,ptruint(ss));
result:=1;
end;
function readRegionFromFile(L: Plua_State): integer; cdecl;
var parameters: integer;
filename: string;
address: ptruint;
size: integer;
x: PtrUInt;
buf: pointer;
f: tmemorystream;
begin
result:=0;
x:=0;
f:=nil;
parameters:=lua_gettop(L);
if (parameters=2) then
begin
filename:=Lua_ToString(L, 1);
address:=lua_toaddress(L,2);
lua_pop(L, lua_gettop(L));
f:=tmemorystream.create;
try
f.LoadFromFile(filename);
writeprocessmemory(processhandle, pointer(address), f.memory, f.size, x);
finally
freeandnil(f);
end;
result:=1;
lua_pushinteger(L,x);
end else lua_pop(L, lua_gettop(L));
end;
function writeRegionToFile(L: Plua_State): integer; cdecl;
var parameters: integer;
filename: string;
address: ptruint;
size: integer;
x: PtrUInt;
buf: pointer;
f: tfilestream;
begin
result:=0;
x:=0;
f:=nil;
parameters:=lua_gettop(L);
if (parameters=3) then
begin
filename:=Lua_ToString(L, -3);
address:=lua_toaddress(L,-2);
size:=lua_tointeger(L,-1);
lua_pop(L, lua_gettop(L));
getmem(buf,size);
try
readprocessmemory(processhandle, pointer(address), buf, size, x);
f:=tfilestream.create(filename, fmCreate);
f.WriteBuffer(buf^, x);
finally
if f<>nil then
FreeAndNil(f);
freememandnil(buf);
end;
result:=1;
lua_pushinteger(L,x);
end else lua_pop(L, lua_gettop(L));
end;
function registerSymbol(L: Plua_State): integer; cdecl;
var parameters: integer;
symbolname: string;
address: string;
donotsave: boolean;
begin
result:=1;
parameters:=lua_gettop(L);
if (parameters>=2) then
begin
symbolname:=Lua_ToString(L, 1);
if lua_isstring(L, 2) then
address:=lua_tostring(L,2)
else
address:=IntToHex(lua_tointeger(L,2),1);
donotsave:=(parameters>=3) and (lua_toboolean(L, 3));
try
symhandler.DeleteUserdefinedSymbol(symbolname);
symhandler.AddUserdefinedSymbol(address, symbolname, donotsave);
lua_pushboolean(L,true);
except
on e: exception do
begin
lua_pushboolean(L,false);
lua_pushstring(L,e.message);
result:=2;
end;
end;
end;
end;
function unregisterSymbol(L: Plua_State): integer; cdecl;
var parameters: integer;
symbolname: string;
begin
result:=0;
parameters:=lua_gettop(L);
if (parameters=1) then
begin
symbolname:=Lua_ToString(L, 1);
symhandler.DeleteUserdefinedSymbol(symbolname);
end;
lua_pop(L, lua_gettop(L));
end;
function resetLuaState(L: Plua_State): integer; cdecl;
begin
result:=0;
lua_pop(L, lua_gettop(L));
InitializeLua; //this creates a NEW lua state (cut doesn't destroy the current one)
end;
function reloadSettingsFromRegistry(L: Plua_State): integer; cdecl;
begin
result:=0;
LoadSettingsFromRegistry;
end;
function createMemScan(L: Plua_State): integer; cdecl;
var
progressbar: TCustomProgressbar;
memscan: TMemScan;
parameters: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
progressbar:=lua_toceuserdata(L, -1)
else
progressbar:=nil;
lua_pop(L, lua_gettop(L));
if (progressbar<>nil) and (progressbar is TCustomProgressBar=false) then
raise exception.create(rsCreateMemScanNeedsAProgressbarOrNil+progressbar.ClassName+rsIsNotAProgressbar);
memscan:=TMemscan.create(progressbar);
luaclass_newClass(L, memscan);
result:=1;
end;
function getCurrentMemscan(L: Plua_State): integer; cdecl;
begin
lua_pop(L, lua_gettop(L));
luaclass_newClass(L, mainform.memscan);
result:=1;
end;
function supportCheatEngine(L: Plua_State): integer; cdecl;
var
parameters: integer;
//attachwindow, hasclosebutton, width, height, position ,yoururl OPTIONAL, extraparameters OPTIONAL, percentageshown OPTIONAL
attachwindow: TCustomForm;
hasCloseButton: boolean;
width: integer;
height: integer;
position: integer;
yoururl: string;
extraparameters: string;
percentageshown: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=5 then
begin
attachwindow:=lua_toceuserdata(L, 1);
hasCloseButton:=lua_toboolean(L, 2);
width:=lua_tointeger(L, 3);
height:=lua_tointeger(L, 4);
position:=lua_tointeger(L, 5);
if parameters>=6 then
yoururl:=Lua_ToString(L, 6)
else
yoururl:='';
if parameters>=7 then
extraparameters:=Lua_ToString(L, 7)
else
extraparameters:='';
if parameters>=8 then
percentageshown:=lua_tointeger(L, 8)
else
percentageshown:=0;
lua_pop(L, lua_gettop(L));
if adwindow=nil then
adwindow:=TADWindow.Create2(Application, hasclosebutton);
adwindow.clientWidth:=width;
adwindow.clientheight:=height;
adwindow.show;
adwindow.AttachToForm(attachwindow);
case position of
0: adwindow.setPosition(akTop);
1: adwindow.setPosition(akRight);
2: adwindow.setPosition(akBottom);
3: adwindow.setPosition(akLeft);
end;
adwindow.setUserUrl(yoururl);
adwindow.setUserPercentage(percentageshown);
adwindow.optional:=extraparameters;
adwindow.LoadAdNow;
end else lua_pop(L, lua_gettop(L));
end;
function fuckCheatEngine(L: Plua_State): integer; cdecl;
begin
lua_pop(L, lua_gettop(L));
if adwindow<>nil then
adWindow.visible:=false;
result:=0;
end;
function dbk_initialize(L: Plua_State): integer; cdecl;
var
state,x: BOOL;
reason: string;
begin
result:=0;
{$IFDEF windows}
if isDriverLoaded(nil)=false then
begin
reason:='A lua script wants to load the driver. Reason:';
if lua_gettop(L)>=1 then
reason:=Lua_ToString(L,1)
else
reason:='No reason';
LoadDBK32;
state:=isDriverLoaded(@x);
lua_pushboolean(L, state);
if state then
lua_pushinteger(L, hdevice)
else
lua_pushnil(L);
result:=2;
end
else
begin
lua_pushboolean(L,true);
result:=1;
end;
{$ENDIF}
end;
function dbk_useKernelmodeOpenProcess(L: Plua_State): integer; cdecl;
begin
{$IFDEF windows}
UseDBKOpenProcess;
{$ENDIF}
result:=0;
end;
function dbk_useKernelmodeProcessMemoryAccess(L: Plua_State): integer; cdecl;
begin
{$IFDEF windows}
UseDBKReadWriteMemory;
{$ENDIF}
result:=0;
end;
function dbk_useKernelmodeQueryMemoryRegions(L: Plua_State): integer; cdecl;
begin
{$IFDEF windows}
UseDBKQueryMemoryRegion;
{$ENDIF}
result:=0;
end;
function dbk_usePhysicalMemoryAccess(L: Plua_State): integer; cdecl;
begin
{$IFDEF windows}
if dbvm_version<>0 then
DBKPhysicalMemoryDBVM
else
DBKPhysicalMemory;
MainForm.ProcessLabel.Caption:=strPhysicalMemory;
{$ENDIF}
result:=0;
end;
function dbk_setSaferPhysicalMemoryScanning(L: Plua_State): integer; cdecl;
begin
{$IFDEF windows}
saferQueryPhysicalMemory:=lua_toboolean(L,1);
{$ENDIF}
result:=0;
end;
function lua_dbk_readphysicalmemory(L: PLua_state): integer; cdecl;
var
PhysicalAddress: qword;
buffer:pointer;
size:integer;
i: integer;
br: ptruint;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)<2 then raise exception.create('not all parameters given');
PhysicalAddress:=lua_tointeger(L,1);
size:=lua_tointeger(L,2);
getmem(buffer,size);
br:=0;
ReadPhysicalMemory(qword(-1),pointer(PhysicalAddress), buffer, size, br);
if size=br then
begin
CreateByteTableFromPointer(L, buffer,size);
freemem(buffer);
exit(1);
end
else
begin
freemem(buffer);
exit(0);
end;
{$ENDIF}
end;
function lua_dbk_writephysicalmemory(L: PLua_state): integer; cdecl;
var
PhysicalAddress: qword;
buffer:pointer;
size:integer;
i: integer;
bw: ptruint;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)<2 then raise exception.create('not all parameters given');
PhysicalAddress:=lua_tointeger(L,1);
if lua_istable(L,2)=false then raise exception.create('2nd parameter needs to be a bytetable');
size:=lua_objlen(L, 2);
getmem(buffer,size);
readBytesFromTable(L,2,buffer,size);
bw:=0;
WritePhysicalMemory(qword(-1),pointer(PhysicalAddress), buffer, size, bw);
if size=bw then
lua_pushboolean(L,true)
else
lua_pushboolean(L,false);
freemem(buffer);
exit(1);
{$ENDIF}
end;
function dbk_getPEProcess(L: PLua_State): integer; cdecl;
var
parameters: integer;
pid: dword;
begin
result:=0;
{$IFDEF windows}
parameters:=lua_gettop(L);
if parameters=1 then
begin
pid:=lua_tointeger(L,-1);
lua_pushinteger(L, GetPEProcess(pid));
result:=1;
end else lua_pop(L, parameters);
{$ENDIF}
end;
function dbk_getPEThread(L: PLua_State): integer; cdecl;
var
parameters: integer;
pid: dword;
begin
result:=0;
{$IFDEF windows}
parameters:=lua_gettop(L);
if parameters=1 then
begin
pid:=lua_tointeger(L,-1);
lua_pushinteger(L, GetPEThread(pid));
result:=1;
end else lua_pop(L, parameters);
{$ENDIF}
end;
function dbk_executeKernelMemory(L: PLua_State): integer; cdecl;
var
parameters: integer;
address: ptruint;
parameter: ptruint;
begin
result:=0;
{$IFDEF windows}
parameters:=lua_gettop(L);
if parameters>=1 then
begin
address:=lua_toaddress(L,-parameters);
if parameters>=2 then
begin
if lua_isstring(L, -parameters+1) then
parameter:=symhandler.getAddressFromNameL(Lua_ToString(L,-parameters+1), waitforsymbols)
else
parameter:=lua_tointeger(L, -parameters+1);
end
else
parameter:=0;
lua_pop(L, parameters);
executeKernelCode(address,parameter);
result:=0;
end else lua_pop(L, parameters);
{$ENDIF}
end;
function dbk_writesIgnoreWriteProtection(L: PLua_State): integer; cdecl;
var state: boolean;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)=1 then
begin
state:=lua_toboolean(L, 1);
lua_pushboolean(L, KernelWritesIgnoreWriteProtection(state));
result:=1;
end;
{$ENDIF}
end;
function lua_getPhysicalAddressCR3(L: PLua_State): integer; cdecl;
var
CR3: QWORD;
VirtualAddress: QWORD;
PhysicalAddress: QWORD;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)>=2 then
begin
CR3:=lua_tointeger(L,1);
VirtualAddress:=lua_tointeger(L,2);
if VirtualToPhysicalCR3(CR3, VirtualAddress, PhysicalAddress) then
begin
lua_pushinteger(L, PhysicalAddress);
result:=1;
end;
end;
{$ENDIF}
end;
function lua_readProcessMemoryCR3(L: PLua_State): integer; cdecl;
var
CR3: QWORD;
Address: QWORD;
Size: integer;
x: ptruint;
buf: pointer;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)>=3 then
begin
CR3:=lua_tointeger(L,1);
Address:=lua_tointeger(L,2);
Size:=lua_tointeger(L,3);
getmem(buf, size);
x:=0;
ReadProcessMemoryCR3(cr3, pointer(address), buf, size, x);
if x>0 then
begin
CreateByteTableFromPointer(L, buf, x);
result:=1;
freememandnil(buf);
end;
end;
{$ENDIF}
end;
function lua_writeProcessMemoryCR3(L: PLua_State): integer; cdecl;
var
CR3: QWORD;
Address: QWORD;
size: integer;
buf: pointer;
x: ptruint;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)>=3 then
begin
CR3:=lua_tointeger(L,1);
Address:=lua_tointeger(L,2);
if lua_istable(L,3) then
begin
size:=lua_objlen(L, 3);
getmem(buf,size);
readBytesFromTable(L, 3, buf, size);
x:=0;
WriteProcessMemoryCR3(cr3, pointer(Address), buf, size, x);
freememandnil(buf);
if (x>0) then
begin
lua_pushboolean(L,true);
exit(1);
end;
end;
end;
lua_pushboolean(L, false);
result:=1;
{$ENDIF}
end;
function dbk_getPhysicalAddress(L: PLua_State): integer; cdecl;
var
address: ptruint;
pa: qword;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)=1 then
begin
address:=lua_toaddress(L,1);
if GetPhysicalAddress(processhandle, pointer(address), pa) then
begin
lua_pushinteger(L, pa);
result:=1;
end;
end;
{$ENDIF}
end;
function dbk_getCR0(L: PLua_state): integer; cdecl;
begin
result:=0;
{$IFDEF windows}
lua_pushinteger(L, getcr0);
result:=1;
{$ENDIF}
end;
function dbk_getCR3(L: PLua_state): integer; cdecl;
var cr3: qword;
begin
result:=0;
{$IFDEF windows}
if GetCR3(processhandle, cr3) then
lua_pushinteger(L, cr3)
else
lua_pushnil(L);
result:=1;
{$ENDIF}
end;
function dbk_getCR4(L: PLua_state): integer; cdecl;
begin
result:=0;
{$IFDEF windows}
lua_pushinteger(L, getcr4);
result:=1;
{$ENDIF}
end;
function dbvm_getCR0(L: PLua_state): integer; cdecl;
begin
result:=0;
{$IFDEF windows}
lua_pushinteger(L, dbvm_getRealCR0);
result:=1;
{$ENDIF}
end;
function dbvm_getCR3(L: PLua_state): integer; cdecl;
begin
result:=0;
{$IFDEF windows}
lua_pushinteger(L, dbvm_getRealCR3);
result:=1;
{$ENDIF}
end;
function dbvm_getCR4(L: PLua_state): integer; cdecl;
begin
lua_pushinteger(L, dbvm_getRealCR4);
result:=1;
end;
function lua_dbk_test(L: PLua_state): integer; cdecl;
begin
result:=0;
{$IFDEF windows}
dbk_test;
{$ENDIF}
end;
function lua_dbvm_jtagbp(L: PLua_state): integer; cdecl;
begin
lua_pushboolean(L, dbvm_jtagbp);
result:=1;
end;
function lua_dbvm_readMSR(L: PLua_State): integer; cdecl;
var
parameters: integer;
msr: dword;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
msr:=lua_tointeger(L,1);
lua_pushinteger(L, dbvm_readMSR(msr));
result:=1;
end;
end;
function lua_dbvm_writeMSR(L: PLua_State): integer; cdecl;
var
parameters: integer;
msr: dword;
msrvalue: qword;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=2 then
begin
msr:=lua_tointeger(L,1);
msrvalue:=lua_tointeger(L,2);
dbvm_writeMSR(msr, msrvalue);
end;
lua_pop(L, parameters);
end;
function lua_dbvm_writephysicalmemory(L: PLua_state): integer; cdecl;
var
PhysicalAddress: qword;
buffer:pointer;
size:integer;
i: integer;
begin
if lua_gettop(L)<2 then raise exception.create('not all parameters given');
PhysicalAddress:=lua_tointeger(L,1);
if lua_istable(L,2)=false then raise exception.create('2nd parameter needs to be a bytetable');
size:=lua_objlen(L, 2);
getmem(buffer,size);
readBytesFromTable(L,2,buffer,size);
i:=dbvm_write_physical_memory(PhysicalAddress, buffer, size);
if size=i then
lua_pushboolean(L,true)
else
lua_pushboolean(L,false);
freemem(buffer);
exit(1);
end;
function lua_dbvm_readphysicalmemory(L: PLua_state): integer; cdecl;
var
PhysicalAddress: qword;
buffer:pointer;
size:integer;
i: integer;
begin
if lua_gettop(L)<2 then raise exception.create('not all parameters given');
PhysicalAddress:=lua_tointeger(L,1);
size:=lua_tointeger(L,2);
getmem(buffer,size);
i:=dbvm_read_physical_memory(PhysicalAddress, buffer, size);
if size=i then
begin
CreateByteTableFromPointer(L, buffer,size);
freemem(buffer);
exit(1);
end
else
begin
freemem(buffer);
raise exception.create('not all memory read');
end;
end;
function lua_dbvm_psod(L: PLua_state): integer; cdecl;
begin
dbvm_psod;
result:=1;
lua_pushstring(L,'WTF');
end;
function lua_dbvm_getNMIcount(L: PLua_state): integer; cdecl;
begin
lua_pushinteger(L, dbvm_getNMIcount);
result:=1;
end;
function lua_dbvm_debug_setSpinlockTimeout(L: PLua_state): integer; cdecl;
var timeout: qword;
begin
timeout:=lua_tointeger(L,1);
dbvm_debug_setSpinlockTimeout(timeout);
result:=0;
end;
function lua_dbvm_get_statistics(L: PLua_state): integer; cdecl;
var
stats: TDBVMStatistics;
i: integer;
count: qword;
begin
result:=0;
count:=dbvm_get_statistics(stats);
lua_newtable(L);
//
lua_pushstring(L,'Local');
lua_newtable(L);
for i:=0 to 55 do
begin
lua_pushinteger(L,i);
lua_pushinteger(L,stats.eventCountersCurrentCPU[i]);
lua_settable(L,-3);
end;
lua_settable(L,-3);
lua_pushstring(L,'Global');
lua_newtable(L);
for i:=0 to 55 do
begin
lua_pushinteger(L,i);
lua_pushinteger(L,stats.eventCountersAllCPUS[i]);
lua_settable(L,-3);
end;
lua_settable(L,-3);
lua_pushinteger(L,count);
result:=2;
end;
function lua_dbvm_watch_writes(L: PLua_state): integer; cdecl;
var
physicalAddress: qword=0;
size: integer;
options: DWORD;
MaxEntryCount: integer;
top: integer;
usermodeLoop: qword=0;
kernelmodeLoop: qword=0;
begin
top:=lua_gettop(L);
if top>=1 then
physicalAddress:=lua_tointeger(L,1)
else
begin
lua_pushstring(L, 'dbvm_watch_writes needs a physical address');
lua_error(L);
end;
if top>=2 then
size:=lua_tointeger(L,2)
else
size:=4;
if top>=3 then
options:=lua_tointeger(L,3)
else
options:=0;
if top>=4 then
MaxEntryCount:=lua_tointeger(L,4)
else
MaxEntryCount:=16;
if (options and EPTO_DBVMBP) = EPTO_DBVMBP then
begin
//needs usermode field
if top>=5 then
usermodeloop:=lua_tointeger(L,5)
else
begin
lua_pushnil(L);
lua_pushstring(L,'option DBVMBP needs a usermode loop address');
exit(2);
end;
if top>=6 then
kernelmodeLoop:=lua_tointeger(L,6); //NOT recommended. If CE writes it, CE will freeze.
end;
lua_pushinteger(L, dbvm_watch_writes(physicalAddress, Size, Options, MaxEntryCount,UserModeLoop, kernelmodeloop)); //there is no kernelmode loop, so those will be skipped
result:=1;
end;
function lua_dbvm_watch_reads(L: PLua_state): integer; cdecl;
var
physicalAddress: qword=0;
size: integer;
options: DWORD;
MaxEntryCount: integer;
usermode :qword;
top: integer;
usermodeLoop: qword=0;
kernelmodeLoop: qword=0;
begin
top:=lua_gettop(L);
if top>=1 then
physicalAddress:=lua_tointeger(L,1)
else
begin
lua_pushstring(L, 'dbvm_watch_reads needs a physical address');
lua_error(L);
end;
if top>=2 then
size:=lua_tointeger(L,2)
else
size:=4;
if top>=3 then
options:=lua_tointeger(L,3)
else
options:=0;
if top>=4 then
MaxEntryCount:=lua_tointeger(L,4)
else
MaxEntryCount:=16;
if (options and EPTO_DBVMBP) = EPTO_DBVMBP then
begin
//needs usermode field
if top>=5 then
usermodeloop:=lua_tointeger(L,5)
else
begin
lua_pushnil(L);
lua_pushstring(L,'option DBVMBP needs a usermode loop address');
exit(2);
end;
if top>=6 then
kernelmodeLoop:=lua_tointeger(L,6); //NOT recommended. If CE writes it, CE will freeze.
end;
lua_pushinteger(L, dbvm_watch_reads(physicalAddress, Size, Options, MaxEntryCount, usermodeLoop, kernelmodeloop));
result:=1;
end;
function lua_dbvm_watch_executes(L: PLua_state): integer; cdecl;
var
physicalAddress: qword=0;
size: integer;
options: DWORD;
MaxEntryCount: integer;
top: integer;
usermodeLoop: qword=0;
kernelmodeLoop: qword=0;
begin
top:=lua_gettop(L);
if top>=1 then
physicalAddress:=lua_tointeger(L,1)
else
begin
lua_pushstring(L, 'dbvm_watch_reads needs a physical address');
lua_error(L);
end;
if top>=2 then
size:=lua_tointeger(L,2)
else
size:=4;
if top>=3 then
options:=lua_tointeger(L,3)
else
options:=0;
if top>=4 then
MaxEntryCount:=lua_tointeger(L,4)
else
MaxEntryCount:=16;
if (options and EPTO_DBVMBP) = EPTO_DBVMBP then
begin
//needs usermode field
if top>=5 then
usermodeloop:=lua_tointeger(L,5)
else
begin
lua_pushnil(L);
lua_pushstring(L,'option DBVMBP needs a usermode loop address');
exit(2);
end;
if top>=6 then
kernelmodeLoop:=lua_tointeger(L,6);
end;
lua_pushinteger(L, dbvm_watch_executes(physicalAddress, Size, Options, MaxEntryCount, usermodeloop, kernelmodeloop));
result:=1;
end;
procedure lua_push_watch_basic_fields(L: PLua_state; pbasic: PPageEventBasic; index: integer);
begin
lua_pushstring(L,'VirtualAddress');
lua_pushinteger(L,pbasic^.VirtualAddress);
lua_settable(L,index);
lua_pushstring(L,'PhysicalAddress');
lua_pushinteger(L,pbasic^.PhysicalAddress);
lua_settable(L,index);
lua_pushstring(L,'CR3');
lua_pushinteger(L,pbasic^.CR3);
lua_settable(L,index);
lua_pushstring(L,'FSBASE');
lua_pushinteger(L,pbasic^.FSBASE);
lua_settable(L,index);
lua_pushstring(L,'GSBASE');
lua_pushinteger(L,pbasic^.GSBASE);
lua_settable(L,index);
lua_pushstring(L,'GSBASE_KERNEL');
lua_pushinteger(L,pbasic^.GSBASE_KERNEL);
lua_settable(L,index);
lua_pushstring(L,'FLAGS');
lua_pushinteger(L,pbasic^.FLAGS);
lua_settable(L,index);
lua_pushstring(L,'RAX');
lua_pushinteger(L,pbasic^.RAX);
lua_settable(L,index);
lua_pushstring(L,'RBX');
lua_pushinteger(L,pbasic^.RBX);
lua_settable(L,index);
lua_pushstring(L,'RCX');
lua_pushinteger(L,pbasic^.RCX);
lua_settable(L,index);
lua_pushstring(L,'RDX');
lua_pushinteger(L,pbasic^.RDX);
lua_settable(L,index);
lua_pushstring(L,'RSI');
lua_pushinteger(L,pbasic^.RSI);
lua_settable(L,index);
lua_pushstring(L,'RDI');
lua_pushinteger(L,pbasic^.RDI);
lua_settable(L,index);
lua_pushstring(L,'R8');
lua_pushinteger(L,pbasic^.R8);
lua_settable(L,index);
lua_pushstring(L,'R9');
lua_pushinteger(L,pbasic^.R9);
lua_settable(L,index);
lua_pushstring(L,'R10');
lua_pushinteger(L,pbasic^.R10);
lua_settable(L,index);
lua_pushstring(L,'R11');
lua_pushinteger(L,pbasic^.R11);
lua_settable(L,index);
lua_pushstring(L,'R12');
lua_pushinteger(L,pbasic^.R12);
lua_settable(L,index);
lua_pushstring(L,'R13');
lua_pushinteger(L,pbasic^.R13);
lua_settable(L,index);
lua_pushstring(L,'R14');
lua_pushinteger(L,pbasic^.R14);
lua_settable(L,index);
lua_pushstring(L,'R15');
lua_pushinteger(L,pbasic^.R15);
lua_settable(L,index);
lua_pushstring(L,'RBP');
lua_pushinteger(L,pbasic^.RBP);
lua_settable(L,index);
lua_pushstring(L,'RSP');
lua_pushinteger(L,pbasic^.RSP);
lua_settable(L,index);
lua_pushstring(L,'RIP');
lua_pushinteger(L,pbasic^.RIP);
lua_settable(L,index);
lua_pushstring(L,'DR0');
lua_pushinteger(L,pbasic^.DR0);
lua_settable(L,index);
lua_pushstring(L,'DR1');
lua_pushinteger(L,pbasic^.DR1);
lua_settable(L,index);
lua_pushstring(L,'DR2');
lua_pushinteger(L,pbasic^.DR2);
lua_settable(L,index);
lua_pushstring(L,'DR3');
lua_pushinteger(L,pbasic^.DR3);
lua_settable(L,index);
lua_pushstring(L,'DR6');
lua_pushinteger(L,pbasic^.DR6);
lua_settable(L,index);
lua_pushstring(L,'DR7');
lua_pushinteger(L,pbasic^.DR7);
lua_settable(L,index);
lua_pushstring(L,'CS');
lua_pushinteger(L,pbasic^.CS);
lua_settable(L,index);
lua_pushstring(L,'DS');
lua_pushinteger(L,pbasic^.DS);
lua_settable(L,index);
lua_pushstring(L,'ES');
lua_pushinteger(L,pbasic^.ES);
lua_settable(L,index);
lua_pushstring(L,'SS');
lua_pushinteger(L,pbasic^.SS);
lua_settable(L,index);
lua_pushstring(L,'FS');
lua_pushinteger(L,pbasic^.FS);
lua_settable(L,index);
lua_pushstring(L,'GS');
lua_pushinteger(L,pbasic^.GS);
lua_settable(L,index);
lua_pushstring(L,'Count');
lua_pushinteger(L,pbasic^.Count);
lua_settable(L,index);
end;
procedure lua_push_watch_fxsave_fields(L: PLua_state; fpudata: PFXSAVE64; index: integer);
var index2: integer;
begin
lua_pushstring(L,'FXSAVE64');
lua_createtable(L,0,32);
index2:=lua_gettop(L); //should be index+2
lua_pushstring(L,'FCW');
lua_pushinteger(L,fpudata^.FCW);
lua_settable(L,index2);
lua_pushstring(L,'FSW');
lua_pushinteger(L,fpudata^.FSW);
lua_settable(L,index2);
lua_pushstring(L,'FTW');
lua_pushinteger(L,fpudata^.FTW);
lua_settable(L,index2);
lua_pushstring(L,'FOP');
lua_pushinteger(L,fpudata^.FOP);
lua_settable(L,index2);
lua_pushstring(L,'IP');
lua_pushinteger(L,fpudata^.FPU_IP);
lua_settable(L,index2);
lua_pushstring(L,'DP');
lua_pushinteger(L,fpudata^.FPU_DP);
lua_settable(L,index2);
lua_pushstring(L,'MXCSR');
lua_pushinteger(L,fpudata^.MXCSR);
lua_settable(L,index2);
lua_pushstring(L,'MXCSR_MASK');
lua_pushinteger(L,fpudata^.MXCSR_MASK);
lua_settable(L,index2);
lua_pushstring(L,'FP_MM0');
CreateByteTableFromPointer(L, @fpudata.FP_MM0,16);
lua_settable(L,index2);
lua_pushstring(L,'FP_MM1');
CreateByteTableFromPointer(L, @fpudata.FP_MM1,16);
lua_settable(L,index2);
lua_pushstring(L,'FP_MM2');
CreateByteTableFromPointer(L, @fpudata.FP_MM2,16);
lua_settable(L,index2);
lua_pushstring(L,'FP_MM3');
CreateByteTableFromPointer(L, @fpudata.FP_MM3,16);
lua_settable(L,index2);
lua_pushstring(L,'FP_MM4');
CreateByteTableFromPointer(L, @fpudata.FP_MM4,16);
lua_settable(L,index2);
lua_pushstring(L,'FP_MM5');
CreateByteTableFromPointer(L, @fpudata.FP_MM5,16);
lua_settable(L,index2);
lua_pushstring(L,'FP_MM6');
CreateByteTableFromPointer(L, @fpudata.FP_MM6,16);
lua_settable(L,index2);
lua_pushstring(L,'FP_MM7');
CreateByteTableFromPointer(L, @fpudata.FP_MM7,16);
lua_settable(L,index2);
lua_pushstring(L,'XMM0');
CreateByteTableFromPointer(L, @fpudata.XMM0,16);
lua_settable(L,index2);
lua_pushstring(L,'XMM1');
CreateByteTableFromPointer(L, @fpudata.XMM1,16);
lua_settable(L,index2);
lua_pushstring(L,'XMM2');
CreateByteTableFromPointer(L, @fpudata.XMM2,16);
lua_settable(L,index2);
lua_pushstring(L,'XMM3');
CreateByteTableFromPointer(L, @fpudata.XMM3,16);
lua_settable(L,index2);
lua_pushstring(L,'XMM4');
CreateByteTableFromPointer(L, @fpudata.XMM4,16);
lua_settable(L,index2);
lua_pushstring(L,'XMM5');
CreateByteTableFromPointer(L, @fpudata.XMM5,16);
lua_settable(L,index2);
lua_pushstring(L,'XMM6');
CreateByteTableFromPointer(L, @fpudata.XMM6,16);
lua_settable(L,index2);
lua_pushstring(L,'XMM7');
CreateByteTableFromPointer(L, @fpudata.XMM7,16);
lua_settable(L,index2);
lua_pushstring(L,'XMM8');
CreateByteTableFromPointer(L, @fpudata.XMM8,16);
lua_settable(L,index2);
lua_pushstring(L,'XMM9');
CreateByteTableFromPointer(L, @fpudata.XMM9,16);
lua_settable(L,index2);
lua_pushstring(L,'XMM10');
CreateByteTableFromPointer(L, @fpudata.XMM10,16);
lua_settable(L,index2);
lua_pushstring(L,'XMM11');
CreateByteTableFromPointer(L, @fpudata.XMM11,16);
lua_settable(L,index2);
lua_pushstring(L,'XMM12');
CreateByteTableFromPointer(L, @fpudata.XMM12,16);
lua_settable(L,index2);
lua_pushstring(L,'XMM13');
CreateByteTableFromPointer(L, @fpudata.XMM13,16);
lua_settable(L,index2);
lua_pushstring(L,'XMM14');
CreateByteTableFromPointer(L, @fpudata.XMM14,16);
lua_settable(L,index2);
lua_pushstring(L,'XMM15');
CreateByteTableFromPointer(L, @fpudata.XMM15,16);
lua_settable(L,index2);
lua_settable(L,index);
end;
procedure lua_push_watch_stack(L: PLua_state; stack: pointer; index: integer);
begin
lua_pushstring(L,'Stack');
CreateByteTableFromPointer(L, stack, 4096);
lua_settable(L,index);
end;
function lua_dbvm_watch_retrievelog(L: PLua_state): integer; cdecl;
var
id: integer;
size: integer;
buf: PPageEventListDescriptor;
i: integer;
basic: PPageEventBasicArray;
extended: PPageEventExtendedArray absolute basic;
basics: PPageEventBasicWithStackArray absolute basic;
extendeds: PPageEventExtendedWithStackArray absolute basic;
begin
OutputDebugString('lua_dbvm_watch_retrievelog');
result:=0;
if lua_gettop(L)=0 then exit;
ID:=lua_tointeger(L,1);
OutputDebugString('id='+inttostr(id));
lua_pop(L,lua_gettop(L));
buf:=nil;
size:=0;
i:=dbvm_watch_retrievelog(ID, buf,size);
while i=2 do
begin
//must be 2
OutputDebugString('reallocating buffer for watchlog');
if (buf<>nil) then
begin
freememandnil(buf);
end;
size:=size*2;
getmem(buf, size);
if (buf=nil) then exit;
FillMemory(buf, size,$ce);
i:=dbvm_watch_retrievelog(ID, buf,size);
end;
if i<>0 then
begin
lua_pushnil(L);
case i of
1: lua_pushstring(L,'invalid id');
3: lua_pushstring(L,'inactive id');
4: lua_pushstring(L,'invalid address for buffer');
else lua_pushstring(L,'unknown error '+inttostr(i));
end;
exit(2);
end;
outputdebugstring('Buf allocated at '+inttohex(QWORD(buf),8));
basic:=PPageEventBasicArray(qword(buf)+sizeof(TPageEventListDescriptor));
outputdebugstring('sizeof(TPageEventBasic)='+inttostr(sizeof(TPageEventBasic)));
outputdebugstring('sizeof(TPageEventExtended)='+inttostr(sizeof(TPageEventExtended)));
outputdebugstring('sizeof(TPageEventBasicWithStack)='+inttostr(sizeof(TPageEventBasicWithStack)));
outputdebugstring('sizeof(TPageEventExtendedWithStack)='+inttostr(sizeof(TPageEventExtendedWithStack)));
outputdebugstring('sizeof(TPageEventListDescriptor)='+inttostr(sizeof(TPageEventListDescriptor)));
outputdebugstring(' buf^.ID='+inttostr(buf^.ID));
outputdebugstring(' buf^.maxSize='+inttostr(buf^.maxSize));
outputdebugstring(' buf^.numberOfEntries='+inttostr(buf^.numberOfEntries));
outputdebugstring(' buf^.entryType='+inttostr(buf^.entryType));
lua_createtable(L, buf^.numberOfEntries, 0); //index 1
for i:=0 to buf^.numberOfEntries-1 do
begin
lua_pushinteger(L,i+1); //2
lua_createtable(L, 0, 32); //3
case buf^.entryType of
0:
begin
//basic
lua_push_watch_basic_fields(L, @basic[i], 3);
end;
1:
begin
//extended
lua_push_watch_basic_fields(L, @extended^[i].basic, 3);
lua_push_watch_fxsave_fields(L, @extended^[i].fpudata, 3);
end;
2:
begin
//basics
lua_push_watch_basic_fields(L, @basics^[i].basic, 3);
lua_push_watch_stack(L, @basics^[i].stack[0], 3);
end;
3:
begin
//extendeds
lua_push_watch_basic_fields(L, @extendeds^[i].basic, 3);
lua_push_watch_fxsave_fields(L, @extendeds^[i].fpudata, 3);
lua_push_watch_stack(L, @extendeds^[i].stack[0], 3);
end;
end;
lua_settable(L,1);
end;
if buf<>nil then
freemem(buf);
result:=1;
end;
function lua_dbvm_watch_disable(L: PLua_State): integer; cdecl;
var
id: integer;
begin
if lua_gettop(L)=0 then exit(0);
id:=lua_tointeger(L,1);
dbvm_watch_delete(id);
result:=0;
end;
function lua_dmvm_watch_getstatus(L: PLua_State): integer; cdecl;
var last,best: TEPTWatchLogData;
begin
if dbvm_watch_getstatus(last,best) then
begin
lua_createtable(L,0,2);
lua_pushstring(L,'last');
lua_createtable(L,0,7);
lua_pushstring(L,'physicalAddress');
lua_pushinteger(L,last.physicalAddress);
lua_settable(L,-3);
lua_pushstring(L,'initialID');
lua_pushinteger(L,last.initialID);
lua_settable(L,-3);
lua_pushstring(L,'actualID');
lua_pushinteger(L,last.actualID);
lua_settable(L,-3);
lua_pushstring(L,'rip');
lua_pushinteger(L,last.rip);
lua_settable(L,-3);
lua_pushstring(L,'data');
lua_pushinteger(L,last.data);
lua_settable(L,-3);
lua_pushstring(L,'cacheIssue');
lua_pushinteger(L,last.cacheIssue);
lua_settable(L,-3);
lua_pushstring(L,'skipped');
lua_pushinteger(L,last.skipped);
lua_settable(L,-3);
lua_settable(L,-3);
lua_pushstring(L,'best');
lua_createtable(L,0,7);
lua_pushstring(L,'physicalAddress');
lua_pushinteger(L,best.physicalAddress);
lua_settable(L,-3);
lua_pushstring(L,'initialID');
lua_pushinteger(L,best.initialID);
lua_settable(L,-3);
lua_pushstring(L,'actualID');
lua_pushinteger(L,best.actualID);
lua_settable(L,-3);
lua_pushstring(L,'rip');
lua_pushinteger(L,best.rip);
lua_settable(L,-3);
lua_pushstring(L,'data');
lua_pushinteger(L,best.data);
lua_settable(L,-3);
lua_pushstring(L,'cacheIssue');
lua_pushinteger(L,best.cacheIssue);
lua_settable(L,-3);
lua_pushstring(L,'skipped');
lua_pushinteger(L,best.skipped);
lua_settable(L,-3);
lua_settable(L,-3);
result:=1;
end
else
result:=0;
end;
function lua_dbvm_cloak_activate(L: PLua_State): integer; cdecl;
var PA, VA: QWORD;
mode :integer;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
pa:=lua_tointeger(L,1);
if lua_gettop(L)>=2 then
VA:=lua_tointeger(L,2)
else
VA:=0;
if lua_gettop(L)>=3 then
mode:=lua_tointeger(L,3)
else
mode:=1;
lua_pushinteger(L, dbvm_cloak_activate(PA, VA, mode));
result:=1;
end;
end;
function lua_dbvm_cloak_deactivate(L: PLua_State): integer; cdecl;
var PA: QWORD;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
pa:=lua_tointeger(L,1);
lua_pushboolean(L, dbvm_cloak_deactivate(PA));
result:=1;
end;
end;
function lua_dbvm_cloak_readOriginal(L: PLua_State): integer; cdecl;
var
PA: QWORD;
buf: pointer;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
pa:=lua_tointeger(L,1);
getmem(buf,4096);
dbvm_cloak_readoriginal(PA, buf);
CreateByteTableFromPointer(L, buf, 4096);
FreeMemAndNil(buf);
result:=1;
end;
end;
function lua_dbvm_cloak_writeOriginal(L: PLua_State): integer; cdecl;
var
PA: QWORD;
buf: pointer;
r: integer;
begin
result:=0;
if lua_gettop(L)>=2 then
begin
pa:=lua_tointeger(L,1);
if lua_istable(L,2) then
begin
getmem(buf,4096);
readBytesFromTable(L, 2,buf,4096);
r:=dbvm_cloak_writeoriginal(PA, buf);
lua_pushinteger(L, r);
FreeMemAndNil(buf);
result:=1;
end;
end;
end;
function lua_dbvm_traceonbp(L: PLua_State): integer; cdecl;
(*
dbvm_traceonbp(pa, count, va, {secondaryoptions})
secondaryoptions is a table:
logFPU: boolean
logStack: boolean
...
*)
var
pa,va: qword;
count: integer;
options: dword;
logFPU: boolean;
logStack: boolean;
r: integer;
begin
if lua_gettop(L)>=2 then
begin
pa:=lua_tointeger(L,1);
count:=lua_tointeger(L,2);
if count<=0 then
begin
lua_pushnil(L);
lua_pushstring(L,'count has to be > 0 ');
exit(2);
end;
if lua_gettop(L)>=3 then
va:=lua_toaddress(L,3)
else
va:=0;
logFPU:=false;
logStack:=false;
if lua_gettop(L)>=4 then
begin
if lua_istable(L,4) then
begin
lua_pushstring(L,'logFPU');
lua_gettable(L,4);
if lua_isboolean(L,-1) then
logFPU:=lua_toboolean(L,-1);
lua_pop(L,1);
lua_pushstring(L,'logStack');
lua_gettable(L,4);
if lua_isboolean(L,-1) then
logStack:=lua_toboolean(L,-1);
lua_pop(L,1);
end;
end;
options:=0;
if logfpu then options:=options or 1;
if logstack then options:=options or 2;
r:=dbvm_cloak_traceonbp(pa,count,options,va);
lua_pushinteger(L,r);
result:=1;
end
else
result:=0;
end;
function lua_dbvm_traceonbp_retrievelog(L: PLua_state): integer; cdecl;
var
id: integer;
size: integer;
buf: PTracerListDescriptor;
i: integer;
basic: PPageEventBasicArray;
extended: PPageEventExtendedArray absolute basic;
basics: PPageEventBasicWithStackArray absolute basic;
extendeds: PPageEventExtendedWithStackArray absolute basic;
begin
OutputDebugString('lua_dbvm_traceonbp_retrievelog');
result:=0;
lua_pop(L,lua_gettop(L));
buf:=nil;
size:=0;
i:=dbvm_cloak_traceonbp_readlog(buf,size);
while i=2 do
begin
//must be 2
OutputDebugString(format('reallocating buffer for tracelog (should be at least %d bytes)',[size]));
if (buf<>nil) then
freememandnil(buf);
size:=size*2;
getmem(buf, size);
if (buf=nil) then exit;
FillMemory(buf, size,$ce);
i:=dbvm_cloak_traceonbp_readlog(buf,size);
end;
if i<>0 then
begin
lua_pushnil(L);
case i of
4: lua_pushstring(L,'invalid address for buffer');
6: lua_pushstring(L,'offset too high');
else lua_pushstring(L,'unknown error '+inttostr(i));
end;
exit(2);
end;
outputdebugstring('Buf allocated at '+inttohex(QWORD(buf),8));
basic:=PPageEventBasicArray(qword(buf)+sizeof(TTracerListDescriptor));
outputdebugstring('sizeof(TTracerListDescriptor)='+inttostr(sizeof(TTracerListDescriptor)));
outputdebugstring(' buf^.datatype='+inttostr(buf^.datatype));
outputdebugstring(' buf^.count='+inttostr(buf^.count));
lua_createtable(L, buf^.count, 0); //index 1
for i:=0 to buf^.count-1 do
begin
lua_pushinteger(L,i+1); //2
lua_createtable(L, 0, 32); //3
case buf^.datatype of
0:
begin
//basic
lua_push_watch_basic_fields(L, @basic[i], 3);
end;
1:
begin
//extended
lua_push_watch_basic_fields(L, @extended^[i].basic, 3);
lua_push_watch_fxsave_fields(L, @extended^[i].fpudata, 3);
end;
2:
begin
//basics
lua_push_watch_basic_fields(L, @basics^[i].basic, 3);
lua_push_watch_stack(L, @basics^[i].stack[0], 3);
end;
3:
begin
//extendeds
lua_push_watch_basic_fields(L, @extendeds^[i].basic, 3);
lua_push_watch_fxsave_fields(L, @extendeds^[i].fpudata, 3);
lua_push_watch_stack(L, @extendeds^[i].stack[0], 3);
end;
end;
lua_settable(L,1);
end;
// if (buf<>nil) then
// freemem(buf);
result:=1;
end;
function lua_dbvm_traceonbp_getstatus(L: PLua_State): integer; cdecl;
var
count, maxcount: dword;
r: integer;
begin
r:=dbvm_cloak_traceonbp_getstatus(count, maxcount);
lua_pushinteger(L,r);
lua_pushinteger(L,count);
lua_pushinteger(L,maxcount);
result:=3;
end;
function lua_dbvm_traceonbp_stoptrace(L: PLua_State): integer; cdecl;
var r: integer;
begin
r:=dbvm_cloak_traceonbp_stoptrace();
lua_pushinteger(L,r);
result:=r;
end;
function lua_dbvm_traceonbp_remove(L: PLua_State): integer; cdecl;
var
pa: qword=0;
force: boolean=false;
r: integer;
begin
if lua_gettop(L)>=1 then
pa:=lua_tointeger(L,1);
if lua_gettop(L)>=2 then
force:=lua_toboolean(L,2);
r:=dbvm_cloak_traceonbp_remove(pa, force);
lua_pushinteger(L,r);
result:=1;
end;
function lua_dbvm_changeregonbp(L: PLua_State): integer; cdecl;
var
pa,va: qword;
changeregonbpinfo: TChangeRegOnBPInfo;
r: boolean;
begin
result:=0;
if lua_gettop(L)>=2 then
begin
pa:=lua_tointeger(L,1);
if lua_istable(L,2) then
begin
lua_pushstring(L,'newCF');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.Flags.newCF:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeCF:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newPF');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.Flags.newPF:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changePF:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newAF');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.Flags.newAF:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeAF:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newZF');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.Flags.newZF:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeZF:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newSF');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.Flags.newSF:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeSF:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newOF');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.Flags.newOF:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeOF:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newRAX');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newRAX:=lua_tointeger(L,-1);
changeregonbpinfo.flags.changeRAX:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newRBX');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newRBX:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeRBX:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newRCX');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newRCX:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeRCX:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newRDX');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newRDX:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeRDX:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newRSI');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newRSI:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeRSI:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newRDI');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newRDI:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeRDI:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newRBP');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newRBP:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeRBP:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newRSP');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newRSP:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeRSP:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newRIP');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newRIP:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeRIP:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newR8');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newR8:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeR8:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newR9');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newR9:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeR9:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newR10');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newR10:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeR10:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newR11');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newR11:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeR11:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newR12');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newR12:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeR12:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newR13');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newR13:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeR13:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newR14');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newR14:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeR14:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
lua_pushstring(L,'newR15');
lua_gettable(L,2);
if not lua_isnil(L,-1) then
changeregonbpinfo.newR15:=lua_tointeger(L,-1);
changeregonbpinfo.Flags.changeR15:=ifthen(lua_isnil(L,-1), 0, 1);
lua_pop(L,1);
if lua_gettop(L)>=3 then
VA:=lua_tointeger(L,3)
else
VA:=0;
r:=dbvm_cloak_changeregonbp(PA, changeregonbpinfo, VA)=0;
lua_pushboolean(l,r);
result:=1;
end;
end;
end;
function lua_dbvm_removechangeregonbp(L: PLua_State): integer; cdecl;
var PA: qword;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
PA:=lua_tointeger(L,1);
lua_pushboolean(L, dbvm_cloak_removechangeregonbp(PA)=0);
result:=1;
end;
end;
function lua_dbvm_ept_reset(L: PLua_State): integer; cdecl;
begin
dbvm_ept_reset;
result:=0;
end;
function lua_dbvm_log_cr3_start(L: PLua_State): integer; cdecl;
begin
lua_pushboolean(L, dbvm_log_cr3values_start);
result:=1;
end;
function lua_dbvm_log_cr3_stop(L: PLua_State): integer; cdecl;
var
r: boolean;
log: array [0..511] of QWORD;
i,j: integer;
begin
result:=0;
ZeroMemory(@log[0],4096);
r:=dbvm_log_cr3values_stop(@log[0]);
if r then
begin
lua_newtable(L);
j:=1;
for i:=0 to 511 do
begin
if log[i]<>0 then
begin
lua_pushinteger(L, j);
lua_pushinteger(L,log[i]);
lua_settable(L, -3);
inc(j);
end;
end;
result:=1;
end;
end;
function lua_dbvm_registerPlugin(L: PLua_State): integer; cdecl;
var
pluginAddress: ptruint;
pluginSize: integer;
plugintype: integer;
r: integer;
begin
if lua_gettop(L)>=3 then
begin
pluginAddress:=lua_tointeger(L,1);
pluginSize:=lua_tointeger(L,2);
plugintype:=lua_tointeger(L,2);
r:=dbvm_registerPlugin(pointer(pluginAddress), pluginSize, pluginType);
lua_pushinteger(L,r);
result:=1;
end
else
result:=0;
end;
function lua_dbvm_raisePMI(L: PLua_State): integer; cdecl;
begin
result:=0;
dbvm_raisePMI;
end;
function lua_dbvm_ultimap2_hideRangeUsage(L: PLua_State): integer; cdecl;
begin
result:=0;
dbvm_ultimap2_hideRangeUsage;
end;
function lua_dbvm_ultimap_getDebugInfo(L: PLua_State): integer; cdecl;
var
di: TULTIMAPDEBUGINFO;
r: integer;
begin
r:=dbvm_ultimap_debuginfo(@di);
result:=2;
lua_pushinteger(L,r);
lua_newtable(L);
lua_pushstring(L,'Active');
lua_pushinteger(L,di.Active);
lua_settable(L,2);
lua_pushstring(L,'CR3');
lua_pushinteger(L,di.CR3);
lua_settable(L,2);
lua_pushstring(L,'DEBUGCTL');
lua_pushinteger(L,di.DEBUGCTL);
lua_settable(L,2);
lua_pushstring(L,'DS_AREA');
lua_pushinteger(L,di.DS_AREA);
lua_settable(L,2);
lua_pushstring(L,'OriginalDebugCTL');
lua_pushinteger(L,di.OriginalDebugCTL);
lua_settable(L,2);
lua_pushstring(L,'OriginalDS_AREA');
lua_pushinteger(L,di.OriginalDS_AREA);
lua_settable(L,2);
lua_pushstring(L,'CR3_switchcount');
lua_pushinteger(L,di.CR3_switchcount);
lua_settable(L,2);
lua_pushstring(L,'CR3_switchcount2');
lua_pushinteger(L,di.CR3_switchcount2);
lua_settable(L,2);
lua_pushstring(L,'LastOldCR3');
lua_pushinteger(L,di.LastOldCR3);
lua_settable(L,2);
lua_pushstring(L,'LastNewCR3');
lua_pushinteger(L,di.LastNewCR3);
lua_settable(L,2);
lua_pushstring(L,'cpunr');
lua_pushinteger(L,di.cpunr);
lua_settable(L,2);
result:=2;
end;
function lua_dbvm_setTSCAdjust(L: PLua_State): integer; cdecl;
var
enabled:boolean;
timeout: integer;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
enabled:=lua_toboolean(L,1);
if enabled and (lua_gettop(L)>=2) then
timeout:=lua_tointeger(L,2)
else
timeout:=2000;
dbvm_setTSCAdjust(enabled, timeout);
end;
end;
function lua_dbvm_speedhack_setSpeed(L: PLua_State): integer; cdecl;
var speed: double;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
speed:=lua_tonumber(L,1);
dbvm_speedhack_setSpeed(speed);
end;
end;
function lua_dbvm_enableTSCHook(L: PLua_State): integer; cdecl;
begin
dbvm_enableTSCHook;
result:=0;
end;
function lua_dbvm_disableTSCHook(L: PLua_State): integer; cdecl;
begin
lua_pushboolean(L, dbvm_disableTSCHook);
result:=1;
end;
function lua_dbvm_findCR3(L: PLua_State): integer; cdecl;
begin
lua_pushinteger(L, dbvm_findCR3(processhandle));
result:=1;
end;
function lua_dbvm_hidephysicalmemory(L: PLua_State): integer; cdecl;
begin
result:=0;
dbvm_hidephysicalmemory;
end;
function lua_dbvm_hidephysicalmemoryall(L: PLua_State): integer; cdecl;
begin
result:=0;
dbvm_hidephysicalmemoryall;
end;
function lua_dbvm_bp_getBrokenThreadListSize(L: PLua_State): integer; cdecl;
begin
lua_pushinteger(L,dbvm_bp_getBrokenThreadListSize());
result:=1;
end;
function lua_dbvm_bp_getProcessAndThreadIDFromEvent(L: PLua_State): integer; cdecl;
var
shortstate: TDBVMBPShortState;
cid: TClientID;
begin
result:=0;
if lua_gettop(L)>=1 then //given is a short or full state
begin
if lua_istable(L,1) then
begin
lua_pushstring(L,'GSBASE');
lua_gettable(L,1);
if lua_isnil(L,-1) then
begin
lua_pushnil(L);
lua_pushstring(L,'Missing GSBASE');
exit(2);
end;
shortstate.gsbase:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'GSBASE_KERNEL');
lua_gettable(L,1);
if lua_isnil(L,-1) then
begin
lua_pushnil(L);
lua_pushstring(L,'Missing GSBASE_KERNEL');
exit(2);
end;
shortstate.GSBASE_KERNEL:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'FSBASE');
lua_gettable(L,1);
if lua_isnil(L,-1) then
begin
lua_pushnil(L);
lua_pushstring(L,'Missing FSBASE');
exit(2);
end;
shortstate.FSBASE:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'CR3');
lua_gettable(L,1);
if lua_isnil(L,-1) then
begin
lua_pushnil(L);
lua_pushstring(L,'Missing CR3');
exit(2);
end;
shortstate.cr3:=lua_tointeger(L,-1);
lua_pop(L,1);
cid.UniqueProcess:=0;
cid.UniqueThread:=0;
if getClientIDFromDBVMBPShortState(shortstate, cid) then
begin
lua_pushinteger(L,cid.UniqueProcess);
lua_pushinteger(L,cid.UniqueThread);
exit(2);
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'Failure to get the process and threadid');
exit(2);
end;
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'First parameter needs to be a threadevent table');
exit(2);
end;
end;
end;
function lua_dbvm_bp_getBrokenThreadEventShort(L: PLua_State): integer; cdecl;
var
id: integer;
r: integer;
shortstate: TDBVMBPShortState;
begin
result:=0;
if lua_Gettop(L)>=1 then
begin
id:=lua_tointeger(L,1);
r:=dbvm_bp_getBrokenThreadEventShort(id,shortstate);
if r=0 then
begin
lua_createtable(L,0,7);
lua_pushstring(L,'WatchID');
lua_pushinteger(L,shortstate.watchid);
lua_settable(L,-3);
lua_pushstring(L,'Status');
lua_pushinteger(L,shortstate.status);
lua_settable(L,-3);
lua_pushstring(L,'CS');
lua_pushinteger(L,shortstate.cs);
lua_settable(L,-3);
lua_pushstring(L,'RIP');
lua_pushinteger(L,shortstate.rip);
lua_settable(L,-3);
lua_pushstring(L,'CR3');
lua_pushinteger(L,shortstate.cr3);
lua_settable(L,-3);
lua_pushstring(L,'FSBASE');
lua_pushinteger(L,shortstate.fsbase);
lua_settable(L,-3);
lua_pushstring(L,'GSBASE');
lua_pushinteger(L,shortstate.gsbase);
lua_settable(L,-3);
lua_pushstring(L,'GSBASE_KERNEL');
lua_pushinteger(L,shortstate.gsbase_kernel);
lua_settable(L,-3);
lua_pushstring(L,'Heartbeat');
lua_pushinteger(L,shortstate.heartbeat);
lua_settable(L,-3);
result:=1;
end
else
begin
lua_pushnil(L);
case r of
1: lua_pushstring(L,'invalid id');
2: lua_pushstring(L,'not active');
else
lua_pushstring(L,'unknown');
end;
exit(2);
end;
end;
end;
function lua_dbvm_bp_getBrokenThreadEventFull(L: PLua_State): integer; cdecl;
var
id: integer;
r: integer;
state: TPageEventExtended ;
watchid: integer;
status: integer;
ti: integer;
begin
result:=0;
if lua_Gettop(L)>=1 then
begin
id:=lua_tointeger(L,1);
r:=dbvm_bp_getBrokenThreadEventFull(id,watchid, status, state);
if r=0 then
begin
lua_newtable(L);
ti:=lua_gettop(L);
lua_push_watch_basic_fields(L, @state.basic, ti);
lua_push_watch_fxsave_fields(L, @state.fpudata, ti);
lua_pushstring(L,'Count');
lua_pushnil(L);
lua_settable(L,ti);
lua_pushstring(L,'Heartbeat');
lua_pushinteger(L,state.basic.Count);
lua_settable(L,ti);
lua_pushstring(L,'Status');
lua_pushinteger(L,status);
lua_settable(L,ti);
lua_pushstring(L,'WatchID');
lua_pushinteger(L,watchid);
lua_settable(L,-3);
result:=1;
end
else
begin
lua_pushnil(L);
case r of
1: lua_pushstring(L,'invalid id');
2: lua_pushstring(L,'not active');
else
lua_pushstring(L,'unknown');
end;
exit(2);
end;
end;
end;
function lua_dbvm_bp_setBrokenThreadEventFull(L: PLua_state): integer; cdecl;
var
id: integer;
state: TPageEventExtended;
watchid, status: integer;
fi: integer;
begin
result:=0;
if lua_gettop(L)>=2 then
begin
id:=lua_tointeger(L,1);
if lua_istable(L,2) then
begin
//get the old state
if dbvm_bp_getBrokenThreadEventFull(id,watchid, status, state)=0 then
begin
lua_pushstring(L,'FLAGS');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.FLAGS:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'RAX');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.RAX:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'RBX');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.RBX:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'RCX');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.RCX:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'RDX');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.RDX:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'RSI');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.RSI:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'RDI');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.RDI:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'R8');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.R8:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'R9');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.R9:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'R10');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.R10:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'R11');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.R11:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'R12');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.R12:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'R13');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.R13:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'R14');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.R14:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'R15');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.R15:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'RBP');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.RBP:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'RSP');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.RSP:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'RIP');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.RIP:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'DR0');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.DR0:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'DR1');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.DR1:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'DR2');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.DR2:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'DR3');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.DR3:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'DR6');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.DR6:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'DR7');
lua_gettable(L,2);
if not lua_isnil(L,-1) then state.basic.DR7:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'FXSAVBE64');
lua_gettable(L,2);
if lua_istable(L,-1) then
begin
//fxsave fields
fi:=lua_gettop(L);
lua_pushstring(L,'FCW');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then state.fpudata.FCW:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'FSW');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then state.fpudata.FSW:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'FTW');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then state.fpudata.FTW:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'FOP');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then state.fpudata.FOP:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'IP');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then state.fpudata.FPU_IP:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'DP');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then state.fpudata.FPU_DP:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'MXCSR');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then state.fpudata.MXCSR:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'MXCSR_MASK');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then state.fpudata.MXCSR_MASK:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'FP_MM0');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.FP_MM0,16);
lua_pop(L,1);
lua_pushstring(L,'FP_MM1');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.FP_MM1,16);
lua_pop(L,1);
lua_pushstring(L,'FP_MM2');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.FP_MM2,16);
lua_pop(L,1);
lua_pushstring(L,'FP_MM3');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.FP_MM3,16);
lua_pop(L,1);
lua_pushstring(L,'FP_MM4');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.FP_MM4,16);
lua_pop(L,1);
lua_pushstring(L,'FP_MM5');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.FP_MM5,16);
lua_pop(L,1);
lua_pushstring(L,'FP_MM6');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.FP_MM6,16);
lua_pop(L,1);
lua_pushstring(L,'FP_MM7');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.FP_MM7,16);
lua_pop(L,1);
lua_pushstring(L,'XMM0');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.XMM0,16);
lua_pop(L,1);
lua_pushstring(L,'XMM1');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.XMM1,16);
lua_pop(L,1);
lua_pushstring(L,'XMM2');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.XMM2,16);
lua_pop(L,1);
lua_pushstring(L,'XMM3');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.XMM3,16);
lua_pop(L,1);
lua_pushstring(L,'XMM4');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.XMM4,16);
lua_pop(L,1);
lua_pushstring(L,'XMM5');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.XMM5,16);
lua_pop(L,1);
lua_pushstring(L,'XMM6');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.XMM6,16);
lua_pop(L,1);
lua_pushstring(L,'XMM7');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.XMM7,16);
lua_pop(L,1);
lua_pushstring(L,'XMM8');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.XMM8,16);
lua_pop(L,1);
lua_pushstring(L,'XMM9');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.XMM9,16);
lua_pop(L,1);
lua_pushstring(L,'XMM10');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.XMM10,16);
lua_pop(L,1);
lua_pushstring(L,'XMM11');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.XMM11,16);
lua_pop(L,1);
lua_pushstring(L,'XMM12');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.XMM12,16);
lua_pop(L,1);
lua_pushstring(L,'XMM13');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.XMM13,16);
lua_pop(L,1);
lua_pushstring(L,'XMM14');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.XMM14,16);
lua_pop(L,1);
lua_pushstring(L,'XMM15');
lua_gettable(L,fi);
if not lua_isnil(L,-1) then readBytesFromTable(L,lua_gettop(L), @state.fpudata.XMM15,16);
lua_pop(L,1);
end;
lua_pop(L,1);
lua_pushinteger(L, dbvm_bp_setBrokenThreadEventFull(id,state));
result:=1;
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'the given ID is not valid (anymore)');
exit(2);
end;
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'param2 has to be a table');
exit(2);
end;
end;
end;
function lua_dbvm_bp_resumeBrokenThread(L: PLua_state): integer; cdecl;
var
id, continueMethod: integer;
r: integer;
begin
result:=0;
if lua_Gettop(L)>=2 then
begin
id:=lua_tointeger(L,1);
continuemethod:=lua_tointeger(L,2);
r:=dbvm_bp_resumeBrokenThread(id,continueMethod);
if r=0 then
begin
lua_pushboolean(L,true);
exit(1);
end
else
begin
lua_pushnil(L);
case r of
1: lua_pushstring(L,'invalid id');
2: lua_pushstring(L,'not active');
3: lua_pushstring(L,'was already set to continue');
4: lua_pushstring(L,'abandoned. Has been marked as free now');
else
lua_pushstring(L,'unknown');
end;
exit(2);
end;
end;
end;
function dbk_readMSR(L: PLua_State): integer; cdecl;
var
parameters: integer;
msr: dword;
begin
result:=0;
{$IFDEF windows}
parameters:=lua_gettop(L);
if parameters=1 then
begin
msr:=lua_tointeger(L,-1);
lua_pushinteger(L, readMSR(msr));
result:=1;
end else lua_pop(L, parameters);
{$ENDIF}
end;
function dbk_writeMSR(L: PLua_State): integer; cdecl;
var
parameters: integer;
msr: dword;
msrvalue: qword;
begin
result:=0;
{$IFDEF windows}
parameters:=lua_gettop(L);
if parameters=2 then
begin
msr:=lua_tointeger(L,1);
msrvalue:=lua_tointeger(L,2);
writemsr(msr, msrvalue);
end;
lua_pop(L, parameters);
{$ENDIF}
end;
function createSplitter(L: Plua_State): integer; cdecl;
var
Splitter: TCESplitter;
parameters: integer;
owner: TWincontrol;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
owner:=lua_toceuserdata(L, -parameters)
else
owner:=nil;
lua_pop(L, lua_gettop(L));
Splitter:=TCESplitter.Create(owner);
if owner<>nil then
Splitter.Parent:=owner;
luaclass_newClass(L, splitter);
result:=1;
end;
function createPaintBox(L: Plua_State): integer; cdecl;
var
paintbox: TPaintbox;
parameters: integer;
owner: TWincontrol;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
owner:=lua_toceuserdata(L, 1)
else
owner:=nil;
lua_pop(L, lua_gettop(L));
paintbox:=TPaintBox.Create(owner);
if owner<>nil then
paintbox.Parent:=owner;
luaclass_newClass(L, paintbox);
result:=1;
end;
function allocateSharedMemoryLocal(L: PLua_State): integer; cdecl;
var
parameters: integer;
sharedmemoryname: string;
size: ptruint;
address: pointer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
begin
sharedmemoryname:=Lua_ToString(L,1);
if parameters>=2 then
size:=lua_tointeger(L, 2)
else
size:=4096;
lua_pop(L, parameters);
address:=allocateSharedMemory(sharedmemoryname, size);
if address<>nil then
begin
lua_pushinteger(L, ptruint(address));
result:=1;
end;
end else lua_pop(L, parameters);
end;
function deallocateSharedMemoryLocal(L: PLua_State): integer; cdecl;
var address: ptruint;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
address:=lua_tointeger(L,1);
UnmapViewOfFile(pointer(address));
end;
end;
function allocateSharedMemory(L: PLua_State): integer; cdecl;
var
parameters: integer;
sharedmemoryname: string;
size: ptruint;
address: pointer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
begin
sharedmemoryname:=Lua_ToString(L,-parameters);
if parameters>=2 then
size:=lua_tointeger(L, -parameters+1)
else
size:=4096;
lua_pop(L, parameters);
address:=allocateSharedMemoryIntoTargetProcess(sharedmemoryname, size);
if address<>nil then
begin
lua_pushinteger(L, ptruint(address));
result:=1;
end;
end else lua_pop(L, parameters);
end;
function deallocateSharedMemory(L: PLua_State): integer; cdecl;
var parameters: integer;
address: ptruint;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
lua_pop(L, parameters);
lua_pushstring(L, rsDeallocateSharedMemoryIsNotImplemented);
lua_error(L);
end;
function getCheatEngineDir(L: PLua_State): integer; cdecl;
begin
lua_pop(L, lua_gettop(l));
lua_pushstring(L, CheatEngineDir);
result:=1;
end;
function lua_getCheatEngineProcessID(L: PLua_State): integer; cdecl;
begin
lua_pop(L, lua_gettop(l));
lua_pushinteger(L, GetCurrentProcessId);
result:=1;
end;
function getInstructionSize(L: PLua_State): integer; cdecl;
var parameters: integer;
address, address2: ptruint;
d: TDisassembler;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
address:=lua_toaddress(L,1);
lua_pop(L, parameters);
address2:=address;
d:=TDisassembler.create;
d.disassemble(address);
d.free;
lua_pushinteger(L, address-address2);
result:=1;
end
else
lua_pop(L, parameters);
end;
function getPreviousOpcode(L: PLua_State): integer; cdecl;
var parameters: integer;
address, address2: ptruint;
d: TDisassembler;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
address:=lua_toaddress(L,1);
lua_pop(L, parameters);
d:=TDisassembler.create;
lua_pushinteger(L, previousopcode(address,d));
d.free;
result:=1;
end
else
lua_pop(L, parameters);
end;
function disassemblebytes(L: PLua_State): integer; cdecl;
var
d: TUserByteDisassembler;
bytes: tbytes;
bytelength: integer;
address: ptruint=0;
s: string;
t: integer;
begin
if lua_gettop(L)>=1 then
begin
if lua_istable(L,1) then
begin
bytelength:=lua_objlen(L,1);
setlength(bytes, bytelength);
readBytesFromTable(L,1,@bytes[0],bytelength);
end
else
ConvertStringToBytes(Lua_ToString(L,1), true, bytes);
if length(bytes)>0 then
begin
if lua_gettop(L)>=2 then
address:=lua_toaddress(L,2);
d:=TUserByteDisassembler.create;
d.setBytes(@bytes[0], length(bytes));
s:=d.disassemble(address);
lua_pushstring(L,s);
lua_newtable(L);
t:=lua_gettop(L);
LastDisassemblerDataToTable(L, t, d.LastDisassembleData);
d.free;
exit(2);
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'Invalid hexadecimal bytestring or bytetable in the first parameter');
exit(2);
end;
end
else
begin
lua_pushnil(L);
lua_pushstring(L,rsIncorrectNumberOfParameters);
exit(2);
end;
end;
function disassemble_lua(L: PLua_State): integer; cdecl;
var parameters: integer;
address: ptruint;
d: TDisassembler;
x: string;
s: string;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
address:=lua_toaddress(L,1);
lua_pop(L, parameters);
d:=TDisassembler.Create;
try
d.showmodules:=false;
d.showsymbols:=false;
d.showsections:=false;
s:=d.disassemble(address, x);
finally
d.free;
end;
result:=1;
lua_pushstring(L, s);
end else lua_pop(L, parameters);
end;
function splitDisassembledString(L: PLua_State): integer; cdecl;
var parameters: integer;
disassembledstring: string;
address, bytes, opcode, special: string;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
disassembledstring:=lua_tostring(L,-parameters);
lua_pop(L, parameters);
disassembler.splitDisassembledString(disassembledstring, true, address, bytes, opcode, special);
result:=4;
lua_pushstring(L, special);
lua_pushstring(L, opcode);
lua_pushstring(L, bytes);
lua_pushstring(L, address);
end
else
lua_pop(L, parameters);
end;
function hexadecimalview_getTopAddress(L: PLua_State): integer; cdecl;
var
hv: THexView;
begin
hv:=luaclass_getClassObject(L);
lua_pushinteger(L, hv.address);
result:=1;
end;
function hexadecimalview_setTopAddress(L: PLua_State): integer; cdecl;
var
hv: THexView;
address: ptruint;
begin
result:=0;
hv:=luaclass_getClassObject(L);
if lua_gettop(L)>=1 then
begin
address:=lua_toaddress(L,1);
hv.address:=address;
end
end;
function hexadecimalview_onAddressChange(L: PLua_State): integer; cdecl;
var
parameters: integer;
hexadecimalview: THexView;
f: integer;
routine: string;
lc: TLuaCaller;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=2 then
begin
hexadecimalview:=lua_toceuserdata(L,-2);
CleanupLuaCall(tmethod(hexadecimalview.onAddressChange));
hexadecimalview.onAddressChange:=nil;
if lua_isfunction(L,-1) then
begin
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
hexadecimalview.onAddressChange:=lc.AddressChangeEvent;
end
else
if lua_isstring(L,-1) then
begin
routine:=lua_tostring(L,-1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
hexadecimalview.onAddressChange:=lc.AddressChangeEvent;
end;
end;
lua_pop(L, parameters);
end;
function hexadecimalview_onByteSelect(L: PLua_State): integer; cdecl;
var
parameters: integer;
hexadecimalview: THexView;
f: integer;
routine: string;
lc: TLuaCaller;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=2 then
begin
hexadecimalview:=lua_toceuserdata(L,-2);
CleanupLuaCall(tmethod(hexadecimalview.onByteSelect));
hexadecimalview.onByteSelect:=nil;
if lua_isfunction(L,-1) then
begin
routine:=Lua_ToString(L,-1);
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
hexadecimalview.onByteSelect:=lc.ByteSelectEvent;
end
else
if lua_isstring(L,-1) then
begin
routine:=lua_tostring(L,-1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
hexadecimalview.onByteSelect:=lc.ByteSelectEvent;
end;
end;
lua_pop(L, parameters);
end;
function disassemblerview_getSelectedAddress(L: PLua_State): integer; cdecl; //6.2-
var
dv: TDisassemblerview;
begin
dv:=luaclass_getClassObject(L);
result:=2;
lua_pushinteger(L, dv.SelectedAddress);
lua_pushinteger(L, dv.SelectedAddress2); //6.2: Returns both addresses
end;
function disassemblerview_setSelectedAddress(L: PLua_State): integer; cdecl; //6.2-
var
dv: TDisassemblerview;
address: ptruint;
begin
result:=0;
dv:=luaclass_getClassObject(L);
if lua_gettop(L)>=1 then
begin
address:=lua_toaddress(L,1);
dv.SelectedAddress:=address;
end;
end;
function disassemblerview_onSelectionChange(L: PLua_State): integer; cdecl;
var
parameters: integer;
disassemblerview: TDisassemblerview;
f: integer;
routine: string;
lc: TLuaCaller;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=2 then
begin
disassemblerview:=lua_toceuserdata(L,-2);
CleanupLuaCall(tmethod(disassemblerview.onselectionchange));
disassemblerview.onselectionchange:=nil;
if lua_isfunction(L,-1) then
begin
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
disassemblerview.onselectionchange:=lc.DisassemblerSelectionChangeEvent;
end
else
if lua_isstring(L,-1) then
begin
routine:=lua_tostring(L,-1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
disassemblerview.onselectionchange:=lc.DisassemblerSelectionChangeEvent;
end;
lua_pop(L, lua_gettop(L));
end;
lua_pop(L, parameters);
end;
function getForegroundProcess(L: PLua_State): integer; cdecl;
var h: thandle;
pid: dword;
begin
result:=0;
{$IFDEF windows}
lua_pop(L, lua_gettop(L));
h:=GetForegroundWindow;
GetWindowThreadProcessId(h, pid);
lua_pushinteger(L, pid);
result:=1;
{$ENDIF}
end;
function cheatEngineIs64Bit(L: PLua_State): integer; cdecl;
begin
lua_pop(L, lua_gettop(L));
lua_pushboolean(L, {$ifdef cpu64}true{$else}false{$endif});
result:=1;
end;
function targetIs64Bit(L: PLua_State): integer; cdecl;
begin
lua_pop(L, lua_gettop(L));
lua_pushboolean(L, processhandler.is64Bit);
result:=1;
end;
function targetIsX86(L: PLua_State): integer; cdecl;
begin
lua_pop(L, lua_gettop(L));
lua_pushboolean(L, processhandler.SystemArchitecture=archX86);
result:=1;
end;
function targetIsArm(L: PLua_State): integer; cdecl;
begin
lua_pop(L, lua_gettop(L));
lua_pushboolean(L, processhandler.SystemArchitecture=archArm);
result:=1;
end;
function targetIsAndroid(L: PLua_State): integer; cdecl;
begin
lua_pop(L, lua_gettop(L));
if getConnection<>nil then
lua_pushboolean(L, getConnection.isAndroid)
else
begin
lua_pushboolean(L, {$ifdef android}true{$else}false{$endif});
end;
result:=1;
end;
{$ifdef darwin}
function targetIsRosetta(L: PLua_State): integer; cdecl;
begin
lua_pop(L, lua_gettop(L));
lua_pushboolean(L, isProcessTranslated(processid));
result:=1;
end;
{$endif}
function getABI(L: PLua_State): integer; cdecl;
begin
lua_pushinteger(L, integer(processhandler.OSABI));
result:=1;
end;
function unregisterFormAddNotification(L: PLua_State): integer; cdecl;
var lc: TLuacaller;
begin
result:=0;
if lua_gettop(L)=1 then
begin
lc:=lua_ToCEUserData(L, -1);
if lc<>nil then
screen.RemoveHandlerFormAdded(lc.ScreenFormEvent);
lc.Free;
end;
end;
function registerFormAddNotification(L: PLua_State): integer; cdecl;
var lc: TLuaCaller;
f: integer;
routine: string;
begin
result:=0;
if lua_gettop(L)=1 then
begin
lc:=nil;
if lua_isfunction(L,-1) then
begin
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
screen.AddHandlerFormAdded(lc.ScreenFormEvent);
end
else
if lua_isstring(L,-1) then
begin
routine:=lua_tostring(L,-1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
screen.AddHandlerFormAdded(lc.ScreenFormEvent);
end;
luaclass_newClass(L, lc);
result:=1;
end;
end;
function getFormCount(L: PLua_State): integer; cdecl;
begin
lua_pop(L, lua_gettop(L));
lua_pushinteger(L, screen.FormCount);
result:=1;
end;
function getForm(L: PLua_State): integer; cdecl;
var
parameters: integer;
f: TCustomForm;
index: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
index:=lua_tointeger(L, -1);
lua_pop(L, lua_gettop(L));
if index<screen.formcount then
begin
luaclass_newClass(L, screen.Forms[index]);
result:=1;
end;
end
else
lua_pop(L, lua_gettop(L));
end;
function onAutoGuess(L: PLua_State): integer; cdecl;
var
parameters: integer;
lc: TLuaCaller;
routine: string;
f: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
CleanupLuaCall(tmethod(onAutoGuessRoutine));
onAutoGuessRoutine:=nil;
if lua_isfunction(L,-1) then
begin
f:=luaL_ref(L,LUA_REGISTRYINDEX); //pop the last item of the stack, which is what I need
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
onAutoGuessRoutine:=lc.AutoGuessEvent;
end
else
if lua_isstring(L,-1) then
begin
routine:=Lua_ToString(L, -1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
onAutoGuessRoutine:=lc.AutoGuessEvent;
end;
end;
lua_pop(L, lua_gettop(L));
end;
function onAPIPointerChange(L: PLua_State): integer; cdecl;
var
parameters: integer;
lc: TLuaCaller;
routine: string;
f: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
CleanupLuaCall(tmethod(plugin.onAPIPointerChange));
plugin.onAPIPointerChange:=nil;
if lua_isfunction(L,-1) then
begin
f:=luaL_ref(L,LUA_REGISTRYINDEX); //pop the last item of the stack, which is what I need
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
plugin.onAPIPointerChange:=lc.NotifyEvent;
end
else
if lua_isstring(L,-1) then
begin
routine:=Lua_ToString(L, -1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
plugin.onAPIPointerChange:=lc.NotifyEvent;
end;
end;
lua_pop(L, lua_gettop(L));
end;
function setAPIPointer(L: PLua_State): integer; cdecl;
var parameters: integer;
apiID: integer;
address: ptruint;
begin
result:=0;
{$IFDEF windows}
parameters:=lua_gettop(L);
if parameters=2 then
begin
apiID:=lua_tointeger(L, -2);
address:=lua_toaddress(L,-1);
lua_pop(L, parameters);
case apiid of
0: newkernelhandler.OpenProcess:=pointer(address);
1: newkernelhandler.ReadProcessMemoryActual:=pointer(address);
2: newkernelhandler.WriteProcessMemoryActual:=pointer(address);
3: newkernelhandler.VirtualQueryExActual:=pointer(address);
end;
end
else
lua_pop(L, parameters);
{$ENDIF}
end;
function dbvm_initialize(L: PLua_State): integer; cdecl;
var
parameters: integer;
offload: boolean;
r: boolean;
reason: string;
begin
result:=0;
{$IFDEF windows}
//for now use the default
if (dbvm_version>0) then
begin
//already loaded and initialized
lua_pop(L, lua_gettop(L));
lua_pushboolean(L, true);
result:=1;
exit;
end;
//not yet loaded/initialized
if (vmx_password1=0) and (vmx_password2=0) and (vmx_password3=0) then
begin
vmx_password1:=$76543210;
vmx_password2:=$fedcba98;
vmx_password3:=$90909090;
end;
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
begin
offload:=lua_toboolean(L, 1);
if offload then
begin
if isRunningDBVM=false then
begin
reason:='A lua script wants to launch the DBVM hypervisor. Reason:';
if parameters>=2 then
reason:=Lua_ToString(L,2)
else
reason:='No reason given';
//not yet loaded.
if isDBVMCapable then
r:=loaddbvmifneeded(reason);
end;
end;
end
else
lua_pop(L, lua_gettop(L));
result:=1;
lua_pushboolean(L, dbvm_version>0);
{$ENDIF}
end;
function dbvm_setKeys(L: PLua_State): integer; cdecl;
var key1, key3: qword;
key2: dword;
begin
if lua_gettop(L)>=3 then
begin
key1:=lua_tointeger(L,1);
key2:=lua_tointeger(L,2);
key3:=lua_tointeger(L,3);
configure_vmx(key1, key2, key3);
lua_pushboolean(L, dbvm_version>=$ce000000);
result:=1;
end
else
begin
lua_pushnil(L);
lua_pushstring(L,rsIncorrectNumberOfParameters);
result:=2;
end;
end;
function lua_dbvm_getMemory(L: PLua_State): integer; cdecl;
var
size: qword;
pages: qword;
begin
size:=dbvm_getMemory(pages);
lua_pushinteger(L,size);
lua_pushinteger(L,pages);
result:=2;
end;
function dbvm_addMemory(L: PLua_State): integer; cdecl;
var pagecount: qword;
begin
{$IFDEF windows}
LoadDBK32;
if lua_gettop(L)>=1 then
begin
pagecount:=lua_tointeger(L,1);
allocateMemoryForDBVM(pagecount);
dbvm_getMemory(pagecount); //get the new count
lua_pushinteger(L, pagecount);
result:=1;
end
else
{$ENDIF}
result:=0;
end;
type
TNewProcess=class(TProcess)
// function ges: boolean;
function RunCommandLoop(out outputstring: string; out stderrstring: string;
out anexitstatus: integer): integer; override;
end;
{
function tnewprocess.ges: boolean;
begin
Result:=GetExitCodeProcess(ProcessHandle,FExitCode) and (FExitCode<>Still_Active);
if not result then
WaitForSingleObject(FProcessHandle,10);
end; }
function TNewProcess.RunCommandLoop(out outputstring:string;
out stderrstring:string; out anexitstatus:integer):integer;
var
bytesread : integer;
outputlength, stderrlength : integer;
stderrbytesread : integer;
gotoutput,gotoutputstderr : boolean;
tries: integer;
begin
OutputString:='';
result:=-1;
try
Options := Options + [poUsePipes];
bytesread:=0;
outputlength:=0;
stderrbytesread:=0;
stderrlength:=0;
Execute;
{$ifdef windows}
while WaitForSingleObject(FProcessHandle,0)=WAIT_TIMEOUT do
{$else}
while running do
{$endif}
begin
// Only call ReadFromStream if Data from corresponding stream
// is already available, otherwise, on linux, the read call
// is blocking, and thus it is not possible to be sure to handle
// big data amounts bboth on output and stderr pipes. PM.
gotoutput:=ReadInputStream(output,BytesRead,OutputLength,OutputString,1);
// The check for assigned(P.stderr) is mainly here so that
// if we use poStderrToOutput in p.Options, we do not access invalid memory.
gotoutputstderr:=false;
if assigned(stderr) then
gotoutputstderr:=ReadInputStream(StdErr,StdErrBytesRead,StdErrLength,StdErrString,1);
{ if (porunidle in options) and not gotoutput and not gotoutputstderr and Assigned(FOnRunCommandEvent) Then
FOnRunCommandEvent(self,Nil,RunCommandIdle,''); }
end;
// Get left output after end of execution
// WaitForSingleObject(FProcessHandle,INFINITE);
// WaitForThreadTerminate(FThreadHandle, 0);
//ThreadSwitch;
ReadInputStream(output,BytesRead,OutputLength,OutputString,2500);
setlength(outputstring,BytesRead);
if assigned(stderr) then
ReadInputStream(StdErr,StdErrBytesRead,StdErrLength,StdErrString,250);
setlength(stderrstring,StderrBytesRead);
anexitstatus:=exitstatus;
result:=0; // we came to here, document that.
{ if Assigned(FOnRunCommandEvent) then // allow external apps to react to that and finish GUI
FOnRunCommandEvent(self,Nil,RunCommandFinished,'');}
except
on e : Exception do
begin
result:=1;
setlength(outputstring,BytesRead);
setlength(stderrstring,StderrBytesRead);
{if Assigned(FOnRunCommandEvent) then
FOnRunCommandEvent(self,Nil,RunCommandException,e.Message); }
end;
end;
end;
function RunCommandIndir2(const curdir:TProcessString;const exename:TProcessString;const commands:array of TProcessString;out outputstring:string;out exitstatus:integer; Options : TProcessOptions = [];SWOptions:TShowWindowOptions=swoNone):integer;
Var
p : TNewProcess;
i : integer;
ErrorString : String;
begin
p:=TNewProcess.create(nil);
if Options<>[] then
P.Options:=Options-[poWaitOnExit];
P.ShowWindow:=SwOptions;
p.Executable:=exename;
if curdir<>'' then
p.CurrentDirectory:=curdir;
if high(commands)>=0 then
for i:=low(commands) to high(commands) do
p.Parameters.add(commands[i]);
try
result:=p.RunCommandLoop(outputstring,errorstring,exitstatus);
finally
p.free;
end;
end;
function lua_runCommand(L: PLua_State): integer; cdecl;
var
p: array of TProcessString;
curdir: string;
exe: string;
parameters: string;
s: string;
i,pl: integer;
exitstatus: integer;
begin
p:=[];
if lua_gettop(L)>=1 then
begin
s:='';
exe:=Lua_ToString(L,1);
if lua_gettop(L)>=2 then
begin
if lua_istable(L,2) then
begin
pl:=lua_objlen(L, 2);
setlength(p,pl);
for i:=1 to pl do
begin
lua_pushinteger(L,i);
lua_gettable(L,2);
if lua_isstring(L,-1) then
begin
p[i-1]:=Lua_ToString(L,-1);
lua_pop(L,1);
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'Invalid parameter at index '+inttostr(i));
exit(2);
end;
end;
end
else
if lua_isstring(L,2) then
begin
SetLength(p,1);
p[0]:=Lua_ToString(L,2);
end;
end
else
setlength(p,0);
if lua_gettop(L)>=3 then
curdir:=Lua_ToString(L,3)
else
curdir:='';
RunCommandInDir2(curdir, exe, p, s, exitstatus, [poNoConsole]);
lua_pushstring(L,s);
lua_pushinteger(L,exitstatus);
exit(2);
end
else
begin
lua_pushnil(L);
lua_pushstring(L,rsIncorrectNumberOfParameters);
exit(2);
end;
end;
function lua_shellExecute(L: PLua_State): integer; cdecl;
var
pcount: integer;
command: string;
parameters: string;
folder: string;
showcommand: integer;
begin
pcount:=lua_gettop(L);
if pcount>=1 then
begin
command:=utf8toansi(lua_tostring(L, -pcount));
if pcount>=2 then
parameters:=utf8toansi(lua_tostring(L, -pcount+1))
else
parameters:='';
if pcount>=3 then
folder:=utf8toansi(lua_tostring(L, -pcount+2))
else
folder:='';
if pcount>=4 then
showcommand:=lua_tointeger(L, -pcount+3)
else
showcommand:=SW_NORMAL;
shellexecute(0,'open',pchar(command),pchar(parameters),pchar(folder),showcommand);
end;
lua_pop(L, lua_gettop(L));
result:=0;
end;
function getTickCount_lua(L: PLua_State): integer; cdecl;
begin
lua_pop(L, lua_gettop(L));
result:=1;
lua_pushinteger(L, GetTickCount64);
end;
function lua_rdtsc(L: PLua_State): integer; cdecl;
var v: qword;
begin
{$ifndef darwinarm64}
{$ifdef cpu32}
asm
push edx
push edi
rdtsc
lea edi,v
mov [edi],eax
mov [edi+4],edx
pop edi
pop edx
end;
{$else}
asm
push rdx
rdtsc
shl rax,32
shr rax,32
shl rdx,32
or rax,rdx
pop rdx
mov v,rax
end;
{$endif}
lua_pushinteger(L,v);
result:=1;
{$else}
exit(0);
{$endif}
end;
function processMessages(L: PLua_State): integer; cdecl;
begin
lua_pop(L, lua_gettop(L));
result:=0;
application.ProcessMessages;
end;
function integerToUserData(L: PLua_State): integer; cdecl;
var
i: integer;
parameters: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
i:=lua_tointeger(L,-1);
lua_pop(L, parameters);
luaclass_newClass(L, pointer(ptruint(i)));
result:=1;
end else lua_pop(L, parameters);
end;
function userDataToInteger(L: PLua_State): integer; cdecl;
var
u: pointer;
parameters: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
u:=lua_toceuserdata(L,-1);
lua_pop(L, parameters);
lua_pushinteger(L, ptruint(u));
result:=1;
end else lua_pop(L, parameters);
end;
function writeToClipboard(L: PLua_State): integer; cdecl;
var
parameters: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
Clipboard.AsText:=Lua_ToString(L, -1);
lua_pop(L, parameters);
end;
function readFromClipboard(L: PLua_State): integer; cdecl;
var s: string;
begin
lua_pop(L, lua_gettop(L));
lua_pushstring(L, Clipboard.AsText);
result:=1;
end;
function createBitmap(L: Plua_State): integer; cdecl;
var
Bitmap: TBitmap;
parameters: integer;
width, height: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
width:=lua_tointeger(L, 1)
else
width:=screen.width;
if parameters>=2 then
height:=lua_tointeger(L, 2)
else
height:=screen.height;
lua_pop(L, parameters);
Bitmap:=TBitmap.Create;
bitmap.Width:=width;
bitmap.Height:=height;
luaclass_newClass(L, Bitmap);
result:=1;
end;
function createPNG(L: Plua_State): integer; cdecl;
var
png: TPortableNetworkGraphic;
parameters: integer;
width, height: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
width:=lua_tointeger(L, 1)
else
width:=screen.width;
if parameters>=2 then
height:=lua_tointeger(L, 2)
else
height:=screen.height;
lua_pop(L, parameters);
png:=TPortableNetworkGraphic.Create;
png.Width:=width;
png.Height:=height;
luaclass_newClass(L, Png);
result:=1;
end;
function createJpeg(L: Plua_State): integer; cdecl;
var
jpeg: TJPEGImage;
parameters: integer;
width, height: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
width:=lua_tointeger(L, 1)
else
width:=screen.width;
if parameters>=2 then
height:=lua_tointeger(L, 2)
else
height:=screen.height;
lua_pop(L, parameters);
jpeg:=TJPEGImage.Create;
jpeg.Width:=width;
jpeg.Height:=height;
luaclass_newClass(L, jpeg);
result:=1;
end;
function createIcon(L: Plua_State): integer; cdecl;
var
Icon: TIcon;
parameters: integer;
width, height: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
width:=lua_tointeger(L, 1)
else
width:=64;
if parameters>=2 then
height:=lua_tointeger(L, 2)
else
height:=64;
lua_pop(L, parameters);
icon:=TIcon.Create;
icon.Width:=width;
icon.Height:=height;
luaclass_newClass(L, icon);
result:=1;
end;
function lua_waitforsymbols(L: Plua_State): integer; cdecl;
begin
result:=1;
lua_pushboolean(L,waitforsymbols);
if lua_gettop(L)>0 then
waitforsymbols:=lua_toboolean(L,1);
end;
function errorOnLookupFailure(L: Plua_State): integer; cdecl;
var
parameters: integer;
oldvalue: boolean;
begin
result:=0;
parameters:=lua_gettop(L);
oldvalue:=symhandler.ExceptionOnLuaLookup;
if parameters=1 then
begin
symhandler.ExceptionOnLuaLookup:=lua_toboolean(L, -1);
lua_pop(L, parameters);
lua_pushboolean(L, oldvalue);
result:=1;
end
else
lua_pop(L, parameters);
end;
function loadPlugin(L: PLua_State): integer; cdecl;
var
p: string;
parameters: integer;
pluginid: integer;
begin
result:=1;
pluginid:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
p:=Lua_ToString(L, -1);
try
pluginid:=pluginhandler.LoadPlugin(p);
if pluginid<>-1 then
pluginhandler.EnablePlugin(pluginid);
except
pluginid:=-1;
end;
end;
lua_pop(L, parameters);
if pluginid=-1 then
lua_pushnil(L)
else
lua_pushinteger(L, pluginid);
end;
function getCEVersion(L: PLua_State): integer; cdecl;
var
p: string;
parameters: integer;
pluginid: integer;
begin
lua_pop(L, lua_gettop(L));
result:=1;
lua_pushnumber(L, ceversion);
end;
function lua_Utf8ToAnsi(L: Plua_State): integer; cdecl;
var
s: string;
parameters: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
s:=Lua_ToString(L, -1);
lua_pop(L, parameters);
lua_pushstring(L, UTF8ToWinCP(s));
result:=1;
end
else
lua_pop(L, parameters);
end;
function lua_AnsitoUTF8(L: Plua_State): integer; cdecl;
var
s: string;
parameters: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
s:=Lua_ToString(L, -1);
lua_pop(L, parameters);
lua_pushstring(L, WinCPToUTF8(s));
result:=1;
end
else
lua_pop(L, parameters);
end;
function fullAccess(L: PLua_state): integer; cdecl;
var parameters: integer;
address: ptruint;
size: integer;
op: dword;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=2 then
begin
address:=lua_toaddress(L,1);
size:=lua_tointeger(L,2);
lua_pop(L, lua_gettop(l));
if virtualprotectex(processhandle,pointer(address),size,PAGE_EXECUTE_READWRITE,op) then
lua_pushboolean(L,true)
else
lua_pushboolean(L,false);
result:=1;
end;
end;
function lua_setMemoryProtection(L: PLua_state): integer; cdecl;
var parameters: integer;
address: ptruint;
size: integer;
prot: dword;
op: dword;
R,W,X: boolean;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=3 then
begin
address:=lua_toaddress(L,1);
size:=lua_tointeger(L,2);
if lua_istable(L,3) then
begin
lua_pushstring(L,'R');
lua_gettable(L,3);
if lua_isnil(L,-1) then
r:=false
else
r:=lua_toboolean(L,-1);
lua_pop(L,1);
lua_pushstring(L,'W');
lua_gettable(L,3);
if lua_isnil(L,-1) then
w:=false
else
w:=lua_toboolean(L,-1);
lua_pop(L,1);
lua_pushstring(L,'X');
lua_gettable(L,3);
if lua_isnil(L,-1) then
x:=false
else
x:=lua_toboolean(L,-1);
lua_pop(L,1);
if (not SystemSupportsWritableExecutableMemory) and (w and x) then
begin
lua_pushboolean(L,false);
lua_pushstring(L,'This system does not support writable executable memory. Tip: Pause the process, make writable, write, make executable, continue');
exit(2);
end;
prot:=PAGE_NOACCESS;
if (r or w or x) then
begin
if not w and not x then
prot:=PAGE_READONLY
else
if w and not x then
prot:=PAGE_READWRITE
else
if not w and x then
prot:=PAGE_EXECUTE_READ
else
if w and x then
prot:=PAGE_EXECUTE_READWRITE;
end;
end
else
if lua_isnumber(L,3) then //undocumented
prot:=lua_tointeger(L,3)
else
begin
lua_pushboolean(L,false);
lua_pushstring(L,'Unexpected type for memory protection');
exit(2);
end;
lua_pop(L, lua_gettop(l));
if virtualprotectex(processhandle,pointer(address),size,prot,op) then
begin
lua_pushboolean(L,true);
lua_pushinteger(L, op);
end
else
lua_pushboolean(L,false);
result:=1;
end;
end;
function getWindowList_lua(L: PLua_state): integer; cdecl;
var
parameters: integer;
s: tstrings;
i,j: integer;
pid: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
begin
s:=lua_toceuserdata(L,1);
lua_pop(L, lua_gettop(l));
if (s<>nil) and (s is TStrings) then
begin
GetWindowList(s);
sanitizeProcessList(s);
end
else
begin
lua_pushstring(L,rsGetProcessListTheProvidedListObjectIsNotValid);
lua_error(L);
end;
end
else
begin
//table version
s:=tstringlist.create;
GetWindowList(s);
sanitizeProcessList(s);
lua_newtable(L);
for i:=0 to s.Count-1 do
begin
if TryStrToInt('0x'+copy(s[i],1,8), pid) then
begin
lua_pushinteger(L, pid);
lua_gettable(L,1);
if lua_isnil(L,-1) then
begin
//not yet in the list
j:=lua_gettop(L);
lua_pop(L,1);
lua_pushinteger(L, pid);
lua_newtable(L);
lua_settable(L,1);
lua_pushinteger(L, pid);
lua_gettable(L,1);
end;
j:=lua_objlen(L,-1);
lua_pushinteger(L, j+1);
lua_pushstring(L, copy(s[i], 10, length(s[i])));
lua_settable(L, -3);
lua_pop(L,1); //pop the current processid table
end;
end;
s.free;
result:=1; //table
end;
end;
function getProcesslist_lua(L: PLua_state): integer; cdecl;
var
parameters: integer;
s: tstrings;
i: integer;
pid: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
begin
s:=lua_toceuserdata(L,1);
lua_pop(L, lua_gettop(l));
if (s<>nil) and (s is TStrings) then
GetProcessList(s, false, true)
else
begin
lua_pushstring(L,rsGetProcessListTheProvidedListObjectIsNotValid);
lua_error(L);
end;
end
else
begin
//table version
s:=tstringlist.create;
GetProcessList(s, false, true);
lua_newtable(L);
for i:=0 to s.Count-1 do
begin
if TryStrToInt('0x'+copy(s[i],1,8), pid) then
begin
lua_pushinteger(L, pid);
lua_pushstring(L, copy(s[i], 10, length(s[i])));
lua_settable(L, 1);
end;
end;
s.free;
result:=1; //table
end;
end;
function getThreadlist_lua(L: PLua_state): integer; cdecl;
var parameters: integer;
s: tstrings;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
begin
s:=lua_toceuserdata(L,1);
lua_pop(L, lua_gettop(l));
if (s<>nil) and (s is TStrings) then
GetThreadList(s)
else
begin
lua_pushstring(L,rsGetThreadlistTheProvidedListObjectIsNotValid);
lua_error(L);
end;
end
else
lua_pop(L, lua_gettop(l));
end;
function lua_loadTable(L: Plua_State): integer; cdecl;
var
filename: string='';
parameters: integer;
merge: boolean;
doc: TXMLDocument;
s: Tstream;
ignoreluascriptdialog: boolean;
begin
result:=0;
s:=nil;
parameters:=lua_gettop(L);
if parameters>=1 then
begin
if lua_isstring(L, 1) then
begin
filename:=Lua_ToString(L, 1);
if (not fileexists(filename)) and (fileexists(wincptoutf8(filename))) then
filename:=wincptoutf8(filename);
end
else
begin
s:=lua_toceuserdata(L, 1);
if s=nil then
exit;
end;
if parameters>=2 then
merge:=lua_toboolean(L,2)
else
merge:=false;
try
if s<>nil then //read a stream
begin
ignoreluascriptdialog:=false;
if parameters>=3 then
ignoreluascriptdialog:=lua_toboolean(L,3);
ReadXMLFile(doc, s);
loadxml(doc, merge, ignoreluascriptdialog);
end
else
loadtable(filename,merge);
lua_pushboolean(L,true);
result:=1;
except
on e:exception do
begin
lua_pushboolean(L,false);
lua_pushstring(L,e.message);
result:=2;
end
end;
end;
end;
function lua_saveTable(L: Plua_State): integer; cdecl;
var
filename: string;
s: tstream=nil;
parameters: integer;
protect: boolean;
dontDeactivateDesignerForms: boolean;
doc: TXMLDocument;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters>=1 then
begin
if lua_isstring(L, 1) then
begin
filename:=Lua_ToString(L, 1);
end
else
begin
s:=lua_toceuserdata(L, 1);
if s=nil then
exit;
if not (s is TStream) then
exit;
end;
if parameters>=2 then
protect:=lua_toboolean(L,2)
else
protect:=false;
if parameters>=3 then
dontDeactivateDesignerForms:=lua_toboolean(L,3)
else
dontDeactivateDesignerForms:=true;
if s<>nil then
begin
doc:=TXMLDocument.Create;
try
SaveXML(doc, dontDeactivateDesignerForms, true);
WriteXMLFile(doc, s);
lua_pushboolean(L,true);
result:=1;
except
on e:exception do
begin
lua_pushboolean(L,false);
lua_pushstring(L,e.message);
result:=2;
end
end;
doc.free;
end
else
begin
try
savetable(filename, protect, dontDeactivateDesignerForms);
lua_pushboolean(L,true);
result:=1;
except
on e:exception do
begin
lua_pushboolean(L,false);
lua_pushstring(L,e.message);
result:=2;
end
end;
end;
end;
end;
function lua_signTable(L: Plua_State): integer; cdecl;
var
filename: string;
begin
{$ifdef windows}
if lua_gettop(L)>0 then
begin
filename:=Lua_ToString(L,1);
if FileExists(filename) then
begin
try
signTableFile(filename);
lua_pushboolean(L,true);
exit(1);
except
on e: exception do
begin
lua_pushboolean(L,false);
lua_pushstring(L,e.message);
exit(2);
end;
end;
end
else
begin
lua_pushboolean(L,false);
lua_pushstring(L,filename+' not found');
exit(2);
end;
end
else
begin
lua_pushboolean(L,false);
lua_pushstring(L, rsIncorrectNumberOfParameters);
exit(2);
end;
{$else}
lua_pushboolean(L,false);
lua_pushstring(L,'This version does not support signing yet');
exit(2);
{$endif}
end;
function lua_detachIfPossible(L: Plua_State): integer; cdecl;
begin
result:=0;
DetachIfPossible;
lua_pop(L, lua_gettop(L));
end;
function getComment(L: PLua_state): integer; cdecl;
var address: ptruint;
begin
result:=0;
if lua_gettop(L)=1 then
begin
address:=lua_toaddress(L,1);
lua_pushstring(L, dassemblercomments.comments[address]);
result:=1;
end;
end;
function setComment(L: PLua_state): integer; cdecl;
var address: ptruint;
comment: string;
begin
result:=0;
if lua_gettop(L)=2 then
begin
address:=lua_toaddress(L,1);
comment:=Lua_ToString(L, 2);
dassemblercomments.comments[address]:=comment;
end;
end;
function getHeader(L: PLua_state): integer; cdecl;
var address: ptruint;
begin
result:=0;
if lua_gettop(L)=1 then
begin
address:=lua_toaddress(L,1);
lua_pushstring(L, dassemblercomments.commentHeader[address]);
result:=1;
end;
end;
function setHeader(L: PLua_state): integer; cdecl;
var address: ptruint;
Header: string;
begin
result:=0;
if lua_gettop(L)=2 then
begin
address:=lua_toaddress(L,1);
Header:=Lua_ToString(L, 2);
dassemblercomments.commentHeader[address]:=Header;
end;
end;
function lua_createClass(L: PLua_State): integer; cdecl;
var
classname: string;
c: TPersistentClass;
begin
result:=0;
if lua_gettop(L)=1 then
begin
classname:=Lua_ToString(L,1);
c:=GetClass(classname);
if c=nil then
begin
lua_pushnil(L);
lua_pushstring(L,Classname+' is not available');
exit(2);
end;
luaclass_newClass(L, c.Create);
result:=1;
end;
end;
function lua_createComponentClass(L: PLua_State): integer; cdecl;
var
classname: string;
owner: TComponent;
c: TPersistentClass;
begin
result:=0;
if lua_gettop(L)=2 then
begin
classname:=Lua_ToString(L,1);
c:=GetClass(classname);
if c=nil then
begin
lua_pushnil(L);
lua_pushstring(L,Classname+' is not available');
exit(2);
end;
owner:=lua_ToCEUserData(L,2);
luaclass_newClass(L, TComponentClass(c).Create(owner));
result:=1;
end;
end;
function openLuaServer(L: PLua_State): integer; cdecl;
var name: string;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)=1 then
name:=Lua_ToString(L, 1)
else
name:='cheatenginebla';
if luaserverExists(name)=false then
tluaserver.create(name);
{$ENDIF}
end;
function lua_registerAutoAssemblerCommand(L: PLua_State): integer; cdecl;
var command: string;
f: integer;
routine: string;
lc: tluacaller;
begin
result:=0;
if lua_gettop(L)=2 then
begin
if lua_isstring(L, 1) then
begin
command:=Lua_ToString(L, 1);
if lua_isfunction(L,2) then
begin
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
end
else
if lua_isstring(L,2) then
begin
routine:=lua_tostring(L,2);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
end
else exit;
RegisterAutoAssemblerCommand(command, lc.AutoAssemblerCallback);
end;
end;
end;
function lua_unregisterAutoAssemblerCommand(L: PLua_State): integer; cdecl;
var command: string;
begin
result:=0;
if lua_gettop(L)=1 then
begin
command:=Lua_ToString(L, 1);
UnregisterAutoAssemblerCommand(command);
end;
end;
function lua_registerSymbolLookupCallback(L: PLua_State): integer; cdecl;
var
f: integer;
sltype: TSymbolLookupCallbackPoint;
routine: string;
lc: tluacaller;
i: integer;
begin
result:=0;
if lua_gettop(L)=2 then
begin
if lua_isnumber(L, 2) then sltype:=TSymbolLookupCallbackPoint(lua_tointeger(L, 2)) else exit;
if lua_isfunction(L, 1) then
begin
lua_pushvalue(L, 1);
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
end
else
if lua_isstring(L,1) then
begin
routine:=lua_tostring(L,1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
end
else exit;
i:=registerSymbolLookupCallback(lc.SymbolLookupCallback, sltype);
lua_pushinteger(L, lua_integer(i));
result:=1;
end;
end;
function lua_unregisterSymbolLookupCallback(L: PLua_State): integer; cdecl;
var id: integer;
begin
result:=0;
if lua_gettop(L)>0 then
unregisterSymbolLookupCallback(lua_tointeger(L, 1));
end;
function lua_registerAddressLookupCallback(L: PLua_State): integer; cdecl;
var
f: integer;
routine: string;
lc: tluacaller;
begin
result:=0;
if lua_gettop(L)=1 then
begin
if lua_isfunction(L, 1) then
begin
lua_pushvalue(L, 1);
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
end
else
if lua_isstring(L,1) then
begin
routine:=lua_tostring(L,1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
end
else exit;
lua_pushinteger(L, registerAddressLookupCallback(lc.AddressLookupCallback));
result:=1;
end;
end;
function lua_unregisterAddressLookupCallback(L: PLua_State): integer; cdecl;
begin
result:=0;
if lua_gettop(L)>0 then
unregisterAddressLookupCallback(lua_tointeger(L, 1));
end;
//----
function lua_registerStructureAndElementListCallback(L: PLua_State): integer; cdecl;
var
f: integer;
routine: string;
lc,lc2: tluacaller;
begin
result:=0;
if lua_gettop(L)>=2 then
begin
if lua_isfunction(L, 1) then
begin
lua_pushvalue(L, 1);
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
end
else
if lua_isstring(L,1) then
begin
routine:=lua_tostring(L,1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
end
else exit;
if lua_isfunction(L, 2) then
begin
lua_pushvalue(L, 2);
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc2:=TLuaCaller.create;
lc2.luaroutineIndex:=f;
end
else
if lua_isstring(L,2) then
begin
routine:=lua_tostring(L,2);
lc2:=TLuaCaller.create;
lc2.luaroutine:=routine;
end
else exit;
lua_pushinteger(L, registerStructureAndElementListCallback(lc.StructureListCallback, lc2.ElementListCallback));
result:=1;
end;
end;
function lua_unregisterStructureAndElementListCallback(L: PLua_State): integer; cdecl;
begin
result:=0;
if lua_gettop(L)>0 then
unregisterStructureAndElementListCallback(lua_tointeger(L, 1));
end;
//----
function lua_registerSpeedhackCallbacks(L: PLua_State): integer; cdecl;
var
f: integer;
routine: string;
lc,lc2: tluacaller;
begin
result:=0;
if lua_gettop(L)>=2 then
begin
if lua_isfunction(L, 1) then
begin
lua_pushvalue(L, 1);
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
end
else
if lua_isstring(L,1) then
begin
routine:=lua_tostring(L,1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
end
else exit;
if lua_isfunction(L, 2) then
begin
lua_pushvalue(L, 2);
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc2:=TLuaCaller.create;
lc2.luaroutineIndex:=f;
end
else
if lua_isstring(L,2) then
begin
routine:=lua_tostring(L,2);
lc2:=TLuaCaller.create;
lc2.luaroutine:=routine;
end
else exit;
lua_pushinteger(L, registerSpeedhackCallbacks(lc.SpeedHackOnActivate, lc2.SpeedHackSetSpeedEvent));
result:=1;
end;
end;
function lua_unregisterSpeedhackCallbacks(L: PLua_State): integer; cdecl;
var i: integer;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
i:=lua_tointeger(L,1);
unregisterSpeedhackCallbacks(i);
end;
end;
function lua_registerGlobalDisassembleOverride(L: PLua_State): integer; cdecl;
var
f: integer;
routine: string;
lc: tluacaller;
begin
result:=0;
if lua_gettop(L)=1 then
begin
if lua_isfunction(L, 1) then
begin
lua_pushvalue(L, 1);
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
end
else
if lua_isstring(L,1) then
begin
routine:=lua_tostring(L,1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
end
else exit;
lua_pushinteger(L, registerGlobalDisassembleOverride(lc.DisassembleEvent));
result:=1;
end;
end;
function lua_unregisterGlobalDisassembleOverride(L: PLua_State): integer; cdecl;
begin
result:=0;
if lua_gettop(L)>0 then
unregisterGlobalDisassembleOverride(lua_tointeger(L, 1));
end;
function lua_registerStructureDissectOverride(L: PLua_State): integer; cdecl;
var
f: integer;
routine: string;
lc: tluacaller;
m: Tmethod;
begin
result:=0;
if lua_gettop(L)=1 then
begin
if lua_isfunction(L, 1) then
begin
lua_pushvalue(L, 1);
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
end
else
if lua_isstring(L,1) then
begin
routine:=lua_tostring(L,1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
end
else exit;
lua_pushinteger(L, registerStructureDissectOverride(lc.StructureDissectEvent));
result:=1;
end;
end;
function lua_unregisterStructureDissectOverride(L: PLua_State): integer; cdecl;
begin
result:=0;
if lua_gettop(L)>0 then
unregisterStructureDissectOverride(lua_tointeger(L, 1));
end;
function lua_registerStructureNameLookup(L: PLua_State): integer; cdecl;
var
f: integer;
routine: string;
lc: tluacaller;
begin
result:=0;
if lua_gettop(L)=1 then
begin
if lua_isfunction(L, 1) then
begin
lua_pushvalue(L, 1);
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
end
else
if lua_isstring(L,1) then
begin
routine:=lua_tostring(L,1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
end
else exit;
lua_pushinteger(L, registerStructureNameLookup(lc.StructureNameLookup));
result:=1;
end;
end;
function lua_unregisterStructureNameLookup(L: PLua_State): integer; cdecl;
begin
result:=0;
if lua_gettop(L)>0 then
unregisterStructureNameLookup(lua_tointeger(L, 1));
end;
//
function lua_registerGlobalStructureListUpdateNotification(L: PLua_State): integer; cdecl;
var
f: integer;
routine: string;
lc: tluacaller;
begin
result:=0;
if lua_gettop(L)=1 then
begin
if lua_isfunction(L, 1) then
begin
lua_pushvalue(L, 1);
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
end
else
if lua_isstring(L,1) then
begin
routine:=lua_tostring(L,1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
end
else exit;
lua_pushinteger(L, registerGlobalStructureListUpdateNotification(lc.NotifyEvent));
result:=1;
end;
end;
function lua_unregisterGlobalStructureListUpdateNotification(L: PLua_State): integer; cdecl;
begin
result:=0;
if lua_gettop(L)>0 then
unregisterGlobalStructureListUpdateNotification(lua_tointeger(L, 1));
end;
//
function lua_registerAssembler(L: PLua_State): integer; cdecl;
var
f: integer;
routine: string;
lc: tluacaller;
begin
result:=0;
if lua_gettop(L)=1 then
begin
if lua_isfunction(L, 1) then
begin
lua_pushvalue(L, 1);
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
end
else
if lua_isstring(L,1) then
begin
routine:=lua_tostring(L,1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
end
else exit;
lua_pushinteger(L, registerAssembler(lc.AssemblerEvent));
result:=1;
end;
end;
function lua_unregisterAssembler(L: PLua_State): integer; cdecl;
begin
result:=0;
if lua_gettop(L)>0 then
unregisterAssembler(lua_tointeger(L, 1));
end;
function lua_registerAutoAssemblerPrologue(L: PLua_State): integer; cdecl;
var
f: integer;
routine: string;
lc: tluacaller;
postaob: boolean;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
if lua_isfunction(L, 1) then
begin
lua_pushvalue(L, 1);
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
end
else
if lua_isstring(L,1) then
begin
routine:=lua_tostring(L,-1);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
end
else exit;
if lua_gettop(L)=2 then
postaob:=lua_toboolean(L,2)
else
postaob:=false;
lua_pushinteger(L, registerAutoAssemblerPrologue(lc.AutoAssemblerPrologueEvent, postaob));
result:=1;
end;
end;
function lua_unregisterAutoAssemblerPrologue(L: PLua_State): integer; cdecl;
begin
result:=0;
if lua_gettop(L)>0 then
unregisterAutoAssemblerPrologue(lua_tointeger(L, 1));
end;
function lua_shortCutToText(L: PLua_State): integer; cdecl;
begin
if lua_gettop(L)>0 then
begin
lua_pushstring(L, ShortCutToText(TShortCut(lua_tointeger(L, 1))));
result:=1;
end
else
result:=0;
end;
function lua_textToShortCut(L: PLua_State): integer; cdecl;
begin
if lua_gettop(L)>0 then
begin
lua_pushinteger(L, TextToShortCut(Lua_ToString(L, 1)));
result:=1;
end
else
result:=0;
end;
function lua_outputDebugString(L: PLua_State): integer; cdecl;
begin
if lua_gettop(L)>0 then
OutputDebugString(pchar(Lua_ToString(L, 1)));
result:=0;
end;
function getUserRegistryEnvironmentVariable(L: PLua_State): integer; cdecl;
var
name: string;
r: Tregistry;
begin
result:=0;
if lua_gettop(L)>0 then
begin
name:=Lua_ToString(L, 1);
r:=tregistry.Create;
try
r.RootKey:=HKEY_CURRENT_USER;
if r.OpenKey('\Environment',false) then
begin
if r.ValueExists(name) then
begin
lua_pushstring(L, r.ReadString(name));
result:=1;
end;
end;
finally
r.free;
end;
end;
end;
function setUserRegistryEnvironmentVariable(L: PLua_State): integer; cdecl;
var
name, value: string;
r: tregistry;
begin
result:=0;
if lua_gettop(L)>1 then
begin
name:=Lua_ToString(L, 1);
value:=Lua_ToString(L, 2);
r:=tregistry.Create;
try
r.RootKey:=HKEY_CURRENT_USER;
if r.OpenKey('\Environment',false) then
r.WriteString(name, value);
finally
r.free;
end;
end;
end;
function broadcastEnvironmentUpdate(L: PLua_State): integer; cdecl;
{$if FPC_FULLVERSION<=30002}
var rv: DWORD; //bug in laz 1.6.4 (not the end of the world, as rv is on a 8 byte boundary in the stack and not used)
{$else}
var rv: DWORD_PTR;
{$endif}
begin
result:=0;
{$IFDEF windows}
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, LPARAM(pchar('Environment')), SMTO_ABORTIFHUNG, 5000, rv);
{$ENDIF}
end;
{$IFDEF windows}
var winmm: THandle=0;
var PlaySoundA: function (pszSound: LPCSTR; hmod: HModule; fdwSound: DWORD): BOOL; stdcall;
{$ENDIF}
function lua_playSound(L: PLua_State): integer; cdecl;
const
SND_NODEFAULT = 2;
SND_MEMORY = 4;
SND_LOOP = 8;
SND_NOSTOP = 16;
SND_SYNC = 0;
SND_ASYNC = 1;
SND_PURGE = 64;
SND_APPLICATION = 128;
var
o: tobject;
ms: TMemorystream;
playparam: dword;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)>=1 then
begin
if winmm=0 then
winmm:=LoadLibrary('winmm.dll');
if (winmm<>0) then
begin
if not assigned(PlaySoundA) then
PlaySoundA:=GetProcAddress(winmm,'PlaySoundA');
if assigned(PlaySoundA) then
begin
if lua_isuserdata(L,1) then
begin
o:=lua_ToCEUserData(L, 1);
if o is TLuafile then
ms:=TLuaFile(o).stream
else
if o is TMemoryStream then
ms:=TMemoryStream(o)
else
raise exception.create(rsPlaySoundTheParameterMustBeATableFileOrAMemoryStream);
playparam:=SND_MEMORY;
if (lua_gettop(L)>=2) and lua_toboolean(L,2) then
playparam:=playparam or SND_SYNC
else
playparam:=playparam or SND_ASYNC;
PlaySoundA(ms.Memory, 0, playparam);
end;
end;
end;
end;
{$ENDIF}
end;
function createRef(L: PLua_State): integer; cdecl;
begin
lua_pushinteger(L, luaL_ref(L, LUA_REGISTRYINDEX));
result:=1;
end;
function getRef(L: PLua_State): integer; cdecl;
begin
lua_rawgeti(Luavm, LUA_REGISTRYINDEX, lua_tointeger(L,1));
result:=1;
end;
function destroyRef(L: PLua_State): integer; cdecl;
begin
luaL_unref(L, LUA_REGISTRYINDEX, lua_tointeger(L,1));
result:=0;
end;
function activateProtection(L: PLua_State): integer; cdecl;
begin
result:=0;
if lua_gettop(L)=0 then
protectme
else
protectme(lua_tointeger(L,1));
end;
function getLuaEngine(L:PLua_State): integer; cdecl;
begin
if frmLuaEngine=nil then
frmLuaEngine:=TfrmLuaEngine.Create(application);
luaclass_newClass(L, frmLuaEngine);
result:=1;
end;
function createLuaEngine(L:PLua_State): integer; cdecl;
var f: TfrmLuaEngine;
begin
f:=TfrmLuaEngine.Create(application);
if frmLuaEngine<>nil then
f.miView.Visible:=false
else
frmLuaEngine:=f;
luaclass_newClass(L, f);
result:=1;
end;
function getApplication(L:PLua_State): integer; cdecl;
begin
luaclass_newClass(L, application);
result:=1;
end;
function lua_stringToMD5String(L:PLua_State): integer; cdecl;
var msg: pchar;
size: size_t;
begin
if lua_gettop(L)=1 then
begin
msg:=lua_tolstring(L, 1, @size);
lua_pushstring(L, MD5Print(MD5Buffer(msg^,size)));
result:=1;
end
else
result:=0;
end;
function lua_ConvertKeyComboToString(L:PLua_State): integer; cdecl;
var
keycombo: TKeyCombo;
keycount: integer;
i: integer;
begin
zeromemory(@keycombo, sizeof(keycombo));
keycount:=min(lua_gettop(L), 5);
if (keycount=1) and lua_istable(L,1) then
begin
for i:=0 to 4 do
begin
lua_pushinteger(L, i+1);
lua_gettable(L, 1);
if lua_isnil(L, -1) then //end of the list
begin
lua_pop(L,1);
break;
end
else
begin
keycombo[i]:=lua_tointeger(L,-1);
lua_pop(L,1);
end;
end;
end
else
begin
for i:=0 to keycount-1 do
keycombo[i]:=lua_tointeger(L, i+1);
end;
lua_pushstring(L, ConvertKeyComboToString(keycombo));
result:=1;
end;
function restoreSeDebugPrivilege(L:PLua_State): integer; cdecl;
{$IFDEF windows}
var
tp: TTokenPrivileges;
prev: TTokenPrivileges;
returnlength: dword;
tokenhandle: thandle;
{$ENDIF}
begin
result:=0;
{$IFDEF windows}
if ownprocesshandle <> 0 then
begin
if OpenProcessToken(ownprocesshandle, TOKEN_QUERY or TOKEN_ADJUST_PRIVILEGES, tokenhandle) then
begin
ZeroMemory(@tp, sizeof(tp));
if lookupPrivilegeValue(nil, 'SeDebugPrivilege', tp.Privileges[0].Luid) then
begin
tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
tp.PrivilegeCount := 1; // One privilege to set
if AdjustTokenPrivileges(tokenhandle, False, tp, sizeof(tp), prev, returnlength) then
begin
lua_pushboolean(L, true);
result:=1;
end
end;
closehandle(tokenhandle);
end;
end;
{$ENDIF}
end;
function lua_frexp(L:PLua_State): integer; cdecl;
var
d: float;
m: float;
e: integer;
begin
result:=0;
if lua_gettop(l)>=1 then
begin
d:=lua_tonumber(L, 1);
Frexp(d, m,e);
lua_pushnumber(l,m);
lua_pushnumber(l, e);
result:=2;
end
else
begin
lua_pushstring(L, rsNumberRequired);
lua_error(L);
end;
end;
function lua_cosh(L:PLua_State): integer; cdecl;
begin
result:=0;
if lua_gettop(l)>=1 then
begin
lua_pushnumber(L, cosh(lua_tonumber(L,1)));
result:=1;
end
else
begin
lua_pushstring(L, rsNumberRequired);
lua_error(L);
end;
end;
function lua_sinh(L:PLua_State): integer; cdecl;
begin
result:=0;
if lua_gettop(l)>=1 then
begin
lua_pushnumber(L, sinh(lua_tonumber(L,1)));
result:=1;
end
else
begin
lua_pushstring(L, rsNumberRequired);
lua_error(L);
end;
end;
function lua_tanh(L:PLua_State): integer; cdecl;
begin
result:=0;
if lua_gettop(l)>=1 then
begin
lua_pushnumber(L, tanh(lua_tonumber(L,1)));
result:=1;
end
else
begin
lua_pushstring(L, rsNumberRequired);
lua_error(L);
end;
end;
function lua_getTranslationFolder(L: PLua_State): integer; cdecl;
begin
lua_pushstring(L, translationfilepath);
result:=1;
end;
function lua_loadPOFile(L: PLua_State): integer; cdecl;
var
POFile: TPOFile;
filename: string;
postrings: TStringlist;
begin
if lua_gettop(L)>=1 then
begin
postrings:=Tstringlist.create;
try
filename:=Lua_ToString(L, 1);
postrings.LoadFromFile(filename{$if FPC_FULLVERSION>=030200}, true{$endif});
if assigned(LRSTranslator) then
begin
if (LRSTranslator is TPOTranslator) then
begin
pofile:=TPOTranslator(LRSTranslator).POFile;
pofile.ReadPOText(postrings.text);
end;
end;
lua_pushboolean(L, true);
except
lua_pushboolean(L, false);
end;
postrings.free;
result:=1;
end
else
result:=0;
end;
function lua_translateid(L:PLua_state): integer; cdecl;
var
POFile: TPOFile;
id, orig: string;
r: string;
begin
if lua_gettop(L)>=1 then
begin
id:=Lua_ToString(L, 1);
if lua_gettop(L)>=2 then
orig:=Lua_ToString(L,2)
else
orig:='';
r:=orig;
if assigned(LRSTranslator) then
begin
if (LRSTranslator is TPOTranslator) then
begin
pofile:=TPOTranslator(LRSTranslator).POFile;
if assigned(pofile) then
r:=pofile.Translate(id, orig);
end;
end;
{$ifdef altname}
r:=altnamer(r);
{$endif}
lua_pushstring(L, r);
result:=1;
end
else
result:=0;
end;
function lua_translate(L:PLua_state): integer; cdecl;
var
s: string;
POFile: TPOFile;
r: string;
z: TStringList;
begin
if lua_gettop(L)>=1 then
begin
r:=Lua_ToString(L, 1);
if assigned(LRSTranslator) then
begin
if (LRSTranslator is TPOTranslator) then
begin
pofile:=TPOTranslator(LRSTranslator).POFile;
if assigned(pofile) then
r:=pofile.Translate('',r);
end;
end;
{$ifdef altname}
r:=altnamer(r);
{$endif}
lua_pushstring(L, r);
result:=1;
end
else
result:=1;
end;
function lua_registerBinUtil (L:PLua_state): integer; cdecl;
var
name, description: string;
path: string;
prefix: string;
ASParam: string;
LDParam: string;
OBJDUMPParam: string;
DisassemblerCommentChar: string;
bu: TBinUtils;
miBu: TMenuItem;
OnDisassemble: integer;
arch: string;
i: integer;
begin
result:=0;
if (lua_gettop(L)>0) and (lua_istable(L, 1)) then
begin
//get the data from the provided table
lua_pushstring(L, 'Name');
lua_gettable(L, 1);
if lua_isnil(L,-1) then
name:='No name'
else
name:=Lua_ToString(L,-1);
lua_pop(L,1);
lua_pushstring(L, 'Description');
lua_gettable(L, 1);
if lua_isnil(L,-1) then
description:=''
else
description:=Lua_ToString(L,-1);
lua_pop(L,1);
lua_pushstring(L, 'Path');
lua_gettable(L, 1);
if lua_isnil(L,-1) then
path:=''
else
path:=Lua_ToString(L,-1);
lua_pop(L,1);
lua_pushstring(L, 'Prefix');
lua_gettable(L, 1);
if lua_isnil(L,-1) then
prefix:=''
else
prefix:=Lua_ToString(L,-1);
lua_pop(L,1);
lua_pushstring(L, 'OnDisassemble');
lua_gettable(L, 1);
i:=lua_gettop(L);
if lua_isnil(L,-1) then
begin
onDisassemble:=0;
lua_pop(L,1);
end
else
OnDisassemble:=luaL_ref(L, LUA_REGISTRYINDEX);
lua_pushstring(L, 'Architecture');
lua_gettable(L, 1);
if lua_isnil(L,-1) then
arch:=''
else
arch:=Lua_ToString(L,-1);
lua_pop(L,1);
lua_pushstring(L, 'ASParam');
lua_gettable(L, 1);
if lua_isnil(L,-1) then
ASParam:=''
else
ASParam:=Lua_ToString(L,-1);
lua_pop(L,1);
lua_pushstring(L, 'LDParam');
lua_gettable(L, 1);
if lua_isnil(L,-1) then
LDParam:=''
else
LDParam:=Lua_ToString(L,-1);
lua_pop(L,1);
lua_pushstring(L, 'OBJDUMPParam');
lua_gettable(L, 1);
if lua_isnil(L,-1) then
OBJDUMPParam:=''
else
OBJDUMPParam:=Lua_ToString(L,-1);
lua_pop(L,1);
lua_pushstring(L, 'DisassemblerCommentChar');
lua_gettable(L, 1);
if lua_isnil(L,-1) then
DisassemblerCommentChar:=''
else
DisassemblerCommentChar:=Lua_ToString(L,-1);
lua_pop(L,1);
bu:=TBinUtils.create;
bu.Name:=name;
bu.description:=description;
bu.prefix:=prefix;
bu.path:=path;
bu.OnDisassemble:=ondisassemble;
bu.arch:=Arch;
bu.ASParam:=ASParam;
bu.LDParam:=LDParam;
bu.OBJDUMPParam:=OBJDUMPParam;
bu.DisassemblerCommentChar:=DisassemblerCommentChar;
binutilslist.add(bu);
miBu:=TMenuItem.Create(MemoryBrowser.miBinUtils);
if bu.description<>'' then
miBu.caption:=bu.name+' - '+bu.description
else
miBu.caption:=bu.name;
miBu.Tag:=binutilslist.count-1;
miBu.AutoCheck:=true;
miBu.RadioItem:=true;
miBu.OnClick:=MemoryBrowser.miBinutilsSelect.OnClick;
MemoryBrowser.miBinUtils.Add(miBu);
if binutilslist.count>0 then //make a menu visible so the user can choose at runtime
begin
MemoryBrowser.miBinUtils.visible:=true;
MemoryBrowser.miGNUAssembler.visible:=true;
end;
end;
end;
function setPointerSize(L:PLua_state): integer; cdecl;
begin
if lua_gettop(L)>=1 then
processhandler.overridePointerSize(lua_tointeger(L, 1));
result:=0;
end;
function getPointerSize(L:PLua_state): integer; cdecl;
begin
lua_pushinteger(L, processhandler.pointersize);
result:=1;
end;
function getDebugContext(L:PLua_state): integer; cdecl;
var extraregs: boolean;
begin
result:=1;
if lua_gettop(L)>=1 then
extraregs:=lua_toboolean(L,1)
else
extraregs:=false;
if (debuggerthread<>nil) and (debuggerthread.isWaitingToContinue) and (debuggerthread.CurrentThread<>nil) then
begin
LUA_SetCurrentContextState(debuggerthread.CurrentThread.ThreadId, debuggerthread.CurrentThread.context, extraregs);
lua_pushboolean(L, true);
end
else
lua_pushboolean(L, false);
end;
function setDebugContext(L:PLua_state): integer; cdecl;
var extraregs: boolean;
begin
result:=1;
if lua_gettop(L)>=1 then
extraregs:=lua_toboolean(L,1)
else
extraregs:=false;
if (debuggerthread<>nil) and (debuggerthread.isWaitingToContinue) and (debuggerthread.CurrentThread<>nil) then
begin
LUA_GetNewContextState(debuggerthread.CurrentThread.context, extraregs);
lua_pushboolean(L, true);
end
else
lua_pushboolean(L, false);
end;
function debug_updateGUI(L:PLua_state): integer; cdecl;
begin
result:=0;
if (debuggerthread<>nil) and (debuggerthread.isWaitingToContinue) and (debuggerthread.CurrentThread<>nil) then
begin
debuggerthread.CurrentThread.UpdateMemoryBrowserContext;
MemoryBrowser.UpdateDebugContext(debuggerthread.CurrentThread.handle,debuggerthread.CurrentThread.ThreadID, false);
end;
end;
function createExecuteMethodStub(L:PLua_state): integer; cdecl;
(*
assembles a function that takes a set parameter format and returns that address
createExecuteCodeExStub(callmethod, address, {type=x} or param1,{type=x,value=param2} or param2,...)
*)
//callmethod:
//0: stdcall
//1: cdecl
//other, not implemented yet
//
//timeout:
//0: don't wait (no return value)
//nil or -1: infinite
//else time in milliseconds
//
//
//paramtypes:
//0: integer/pointer
//1: float
//2: double
//3: asciistring (turns into 0:pointer after writing the string)
//4: widestring
//5: bytetable
var
callmethod: integer;
address: ptruint;
paramcount: integer;
i,j: integer;
s: tstringlist;
valuetype: integer;
stackalloc: integer;
instancereg: integer=1;
regstr: string;
stackpointer: integer;
value: qword;
f: single;
floatdword: dword absolute f;
d: double;
doubleqword: qword absolute d;
z: PDwordArray;
sai: integer;
x: ptruint;
y,wr: dword;
stubaddress, resultaddress: ptruint;
// allocs: TCEAllocArray;
// exceptionlist: TCEExceptionListArray;
disableinfo: TDisableinfo;
r: ptruint;
dontfree: boolean;
thread:thandle;
instanceSelector: TStringlist=nil;
valuesize: integer;
IsInputOnly, IsOutputOnly: boolean;
parameterlist: array of integer;
begin
if lua_gettop(L)<3 then
begin
lua_pushnil(L);
lua_pushstring(L,'Not enough parameters. Minimum: callmethod, address, instance');
exit(2);
end;
paramcount:=lua_gettop(L)-3;
callmethod:=lua_tointeger(L,1);
if callmethod>=2 then
begin
lua_pushnil(L);
lua_pushstring(L,'Invalid callmethod:'+inttostr(callmethod));
exit(2);
end;
address:=lua_toaddress(L,2);
setlength(parameterlist,0);
disableinfo:=TDisableInfo.create;
s:=tstringlist.create;
s.Add('allocXO(stub,4096)'); //+inttohex(address,8)+')');
s.add('stub:');
stackpointer:=0;
if processhandler.is64Bit then
begin
s.add('push rbp');
s.add('mov rbp,rsp');
//rbp=old rbp
//rbp+8=return address
//rbp+10=scratch space for param1
s.add('mov [rbp+10],rcx'); //store rcx(the parameters) in the scratch space for this function
s.add('mov rax,rcx');
stackalloc:=s.add('sub rsp,'+inttohex(align(max(4,paramcount)*8,$10),1))
end
else
begin
s.add('push ebp');
s.add('mov ebp,esp');
s.add('mov eax,[ebp+8]'); //ebp=old ebp, ebp+4=return address, ebp+8=parameter1
stackalloc:=s.add('sub esp,'+inttohex(paramcount*4,1)); //save this linenr in case doubles are used
end;
if lua_isnil(L,3)=false then //check if instance is nil
begin
//instance is provided
if lua_istable(L,3) then
begin
//table
lua_pushstring(L,'regnr');
lua_gettable(L,3);
if lua_isnil(L,-1) then
begin
lua_pushinteger(L,1);
lua_gettable(L,3);
if not lua_isnil(L,-1) then
instancereg:=lua_tointeger(L,-1)
else
instancereg:=1; //assume the user used a table and left out the instancereg cause he wants ecx/rcx
lua_pop(L,1);
end
else
instanceReg:=lua_tointeger(L,-1);
lua_pop(L,1);
end
else
instanceReg:=1; //ECX/RCX
case instancereg of
0: regstr:='rax';
1:
begin
regstr:='rcx';
if processhandler.is64Bit then
begin
stackpointer:=1; //unlike 32-bit, in 64-bit method calls it's the first param
end;
end;
2: regstr:='rdx';
3: regstr:='rbx';
4: regstr:='rsp';
5: regstr:='rbp';
6: regstr:='rsi';
7: regstr:='rdi';
8: regstr:='r8';
9: regstr:='r9';
10: regstr:='r10';
11: regstr:='r11';
12: regstr:='r12';
13: regstr:='r13';
14: regstr:='r14';
15: regstr:='r15';
end;
if processhandler.is64Bit=false then
begin
if instancereg>=8 then raise exception.create('Invalid instance register');
regstr[1]:='e';
end;
instanceSelector:=tstringlist.Create;
if processhandler.is64bit then
begin
//this gets added right in front of the call instruction
instanceSelector.add('mov eax,[rbp+10]'); //get the address of the parameters
instanceSelector.add('mov '+regstr+',[rax]'); //the first parameter is the instance
s.add('add rax,8') //rax now points to the first real parameter
end
else
begin
instanceSelector.add('mov eax,[ebp+8]');
instanceSelector.add('mov '+regstr+',[eax]');
s.add('add eax,4') //eax now points to the first real parameter
end;
setlength(parameterlist, length(parameterlist)+1);
parameterlist[length(parameterlist)-1]:=0; //pointer
end;
try
//setup the types
for i:=4 to lua_gettop(L) do
begin
valuetype:=0;
valuesize:=0;
IsInputOnly:=false;
IsOutputOnly:=false;
if lua_istable(l,i) then
begin
lua_pushstring(L,'type');
lua_gettable(L,i);
if lua_isnil(L,-1) then
valuetype:=5
else
valuetype:=lua_tointeger(L,-1);
lua_pop(L,1);
if valuetype=5 then
begin
//check for a 'size' field, and a 'IsOutputOnly' or 'IsInputOnly'
lua_pushstring(L,'size');
lua_gettable(L,i);
if not lua_isnil(L,-1) then
valuesize:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L, 'isOutputOnly');
lua_gettable(L,i);
if not lua_isnil(L,-1) then
IsOutputOnly:=lua_toboolean(L,-1);
lua_pop(L,1);
lua_pushstring(L, 'isInputOnly');
lua_gettable(L,i);
if not lua_isnil(L,-1) then
IsOutputOnly:=lua_toboolean(L,-1);
lua_pop(L,1);
end;
end
else
if lua_isinteger(L,i) then //just typenumbers
valuetype:=lua_tointeger(L,i)
else
begin
lua_pushnil(L);
lua_pushstring(L,'Unknown type for param '+inttostr(i));
exit(2);
end;
case valuetype of
0,3,4,5: //vt5 is a bytetable
begin
if processhandler.is64Bit then
begin
case stackpointer of
0: s.add('mov rcx,[rax+'+inttohex(stackpointer*8,2)+']');
1: s.add('mov rdx,[rax+'+inttohex(stackpointer*8,2)+']');
2: s.add('mov r8,[rax+'+inttohex(stackpointer*8,2)+']');
3: s.add('mov r9,[rax+'+inttohex(stackpointer*8,2)+']');
else
begin
s.add('mov rbx,[rax+'+inttohex(stackpointer*8,2)+']');
s.add('mov qword ptr [rsp+'+inttohex(stackpointer*8,8)+'],rbx');
end;
end;
end
else
begin
s.add('push [eax+'+inttohex(stackpointer*4,2)+']'); //could be faster with a rep movsd , or even use edi as a pointer, but meh
end;
inc(stackpointer);
end;
1: //float(single)
begin
if processhandler.is64Bit then
begin
if stackpointer<4 then
begin
s.add('movss xmm'+inttostr(stackpointer)+',[rax+'+inttohex(stackpointer*8,2)+']');
end
else
begin
s.add('mov rbx,[rax+'+inttohex(stackpointer*8,2)+']');
s.add('mov qword ptr [rsp+'+inttohex(stackpointer*8,8)+'],rbx');
end;
end
else
begin
s.add('mov ebx,[eax+'+inttohex(stackpointer*4,2)+']');
s.add('mov dword ptr [esp+'+inttohex(stackpointer*4,1)+'],ebx');
end;
inc(stackpointer);
end;
2: //double
begin
if processhandler.is64Bit then
begin
if stackpointer<4 then
s.add('movsd xmm'+inttostr(stackpointer)+',[rax+'+inttohex(stackpointer*8,2)+']')
else
begin
s.add('mov rbx,[rax+'+inttohex(stackpointer*8,2)+']');
s.add('mov qword ptr [rsp+'+inttohex(stackpointer*8,8)+'],rbx');
end;
end
else
begin
s.add('mov ebx,[eax+'+inttohex(stackpointer*4,2)+']');
s.add('mov dword ptr [esp+'+inttohex(stackpointer*4,1)+'],ebx');
inc(stackpointer);
s.add('mov ebx,[eax+'+inttohex(stackpointer*4,2)+']');
s.add('mov dword ptr [esp+'+inttohex(stackpointer*4,1)+'],ebx');
end;
inc(stackpointer);
end;
else
begin
lua_pushnil(L);
lua_pushstring(L,'Invalid parametertype '+inttostr(i+3)+'('+inttostr(valuetype)+')');
exit(2);
end;
end;
setlength(parameterlist, length(parameterlist)+1);
if valuetype=5 then //convert it to a native type
begin
valuetype:=(1 shl 31) or valuesize;
if IsOutputOnly then valuetype:=valuetype or (1 shl 30);
if IsInputOnly then valuetype:=valuetype or (1 shl 29);
end;
parameterlist[length(parameterlist)-1]:=valuetype;
end;
if processhandler.is64Bit=false then //fix the stack for the caller
s[stackalloc]:='sub esp,'+inttohex(stackpointer*4,1);
if instanceSelector<>nil then
begin
s.AddStrings(instanceSelector);
freeandnil(instanceSelector);
end;
s.add('call '+inttohex(address,8)); //ce will make it a 16 byte call if needed
if processhandler.is64Bit then
begin
s.add('add rsp,'+inttohex(align(max(4,paramcount)*8,$10),1));
s.add('pop rbp');
s.add('ret');
end
else
begin
if callmethod=1 then
s.add('add esp,'+inttohex(paramcount*4,1));
s.add('pop ebp');
s.add('ret 4');
end;
if autoassemble(s,false,true,false,false,disableinfo) then
begin
//return a table describing this stub so it can be executed
//addressToCall
//paramlist (types)
lua_createtable(L,0,1);
for i:=0 to length(disableinfo.allocs)-1 do
begin
if disableinfo.allocs[i].varname='stub' then
begin
lua_pushstring(L,'StubAddress');
lua_pushinteger(L,disableinfo.allocs[i].address);
lua_settable(L,-3);
lua_pushstring(L,'Parameters');
lua_createtable(L,0,length(parameterlist));
for j:=0 to length(parameterlist)-1 do
begin
lua_pushinteger(L,j+1);
lua_pushinteger(L, parameterlist[j]);
lua_settable(L,-3);
end;
lua_settable(L,-3);
break;
end;
end;
exit(1);
end
else
exit(0);
finally
s.free;
if disableinfo<>nil then
freeandnil(disableinfo);
end;
end;
function createExecuteCodeExStub(L:PLua_state): integer; cdecl;
var paramcount: integer;
begin
paramcount:=lua_gettop(L);
if paramcount<2 then
begin
lua_pushnil(L);
lua_pushstring(L,'Not enough parameters. Minimum: callmethod, address');
exit(2);
end;
lua_pushnil(L);
lua_insert(L, 3); //instance=nil
exit(createExecuteMethodStub(L));
end;
function freeExecuteCodeExStub(L:PLua_state): integer; cdecl;
begin
result:=0;
end;
function executeMethod(L:PLua_state): integer; cdecl; //executecodeex(callmethod, timeout, address, {instance},{param1},{param2},{param3},{...})
//executeCodeEx(callmethod, timeout, address, {type=x,value=param1} or param1,{type=x,value=param2} or param2,...)
//callmethod:
//0: stdcall
//1: cdecl
//other, not implemented yet
//
//timeout:
//0: don't wait (no return value)
//nil or -1: infinite
//else time in milliseconds
//
//
//paramtypes:
//0: integer/pointer
//1: float
//2: double
//3: asciistring (turns into 0:pointer after writing the string)
//4: widestring
var
callmethod: integer;
address: ptruint;
paramcount: integer;
i: integer;
s: tstringlist;
floatvalues: tstringlist;
valuetype: integer;
stackalloc: integer;
floatvalueallocs: integer;
instanceValue: ptruint;
instancereg: integer=1;
regstr: string;
stackpointer: integer;
value: qword;
f: single;
floatdword: dword absolute f;
d: double;
doubleqword: qword absolute d;
z: PDwordArray;
stringsize: integer;
str: string;
wstr: widestring;
stringallocs: array of pointer;
sai: integer;
x: ptruint;
y,wr: dword;
stubaddress, resultaddress: ptruint;
//allocs: TCEAllocArray;
//exceptionlist: TCEExceptionListArray;
disableinfo: TDisableInfo;
r: ptruint;
dontfree: boolean;
timeout: dword;
thread:thandle;
begin
if lua_gettop(L)<4 then
begin
lua_pushnil(L);
lua_pushstring(L,'Not enough parameters. Minimum: callmethod, timeout, address, instance');
exit(2);
end;
paramcount:=lua_gettop(L)-4;
setlength(stringallocs,0);
callmethod:=lua_tointeger(L,1);
if callmethod>=2 then
begin
lua_pushnil(L);
lua_pushstring(L,'Invalid callmethod:'+inttostr(callmethod));
exit(2);
end;
if lua_isnil(L,2) then
timeout:=INFINITE
else
timeout:=lua_tointeger(L,2);
address:=lua_toaddress(L,3);
disableinfo:=tdisableinfo.create;
s:=tstringlist.create;
floatvalues:=tstringlist.create;
s.Add('allocXO(stub, 4096)');
if processhandler.is64Bit then
begin
floatvalueallocs:=s.add('allocXO(addressToCall, 8)');
s.add('allocNX(result,8)');
end
else
begin
floatvalueallocs:=s.add('allocXO(addressToCall, 4)');
s.add('allocNX(result,4)');
end;
s.add('addressToCall:');
if processhandler.is64Bit then
s.add('dq '+inttohex(address,8))
else
s.add('dd '+inttohex(address,8));
s.add('stub:');
if processhandler.is64Bit then
stackalloc:=s.add('sub rsp,'+inttohex(align(max(4,paramcount)*8,$10)+8,1))
else
stackalloc:=s.add('sub esp,'+inttohex(paramcount*4,1)); //save this linenr in case doubles are used
if lua_isnil(L,4)=false then //check if instance is nil
begin
//instance is provided
if lua_istable(L,4) then
begin
//table
lua_pushstring(L,'regnr');
lua_gettable(L,4);
if lua_isnil(L,-1) then
begin
lua_pushinteger(L,1);
lua_gettable(L,4);
if not lua_isnil(L,-1) then
instancereg:=lua_tointeger(L,-1)
else
instancereg:=1; //assume the user used a table and left out the instancereg cause he wants ecx/rcx
lua_pop(L,1);
end
else
instanceReg:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'classinstance');
lua_gettable(L,4);
if lua_isnil(L,-1) then
begin
//fu
lua_pushinteger(L,2);
lua_gettable(L,4);
if lua_isnil(L,-1) then
begin
lua_pushnil(L);
lua_pushstring(L,'Invalid instance');
exit(2);
end;
instanceValue:=lua_tointeger(L,-1);
lua_pop(L,1);
end
else
instanceValue:=lua_tointeger(L,-1);
lua_pop(L,1);
end
else
begin
instanceValue:=lua_tointeger(L,4);
instanceReg:=1; //ECX/RCX
end;
case instancereg of
0: regstr:='rax';
1: regstr:='rcx';
2: regstr:='rdx';
3: regstr:='rbx';
4: regstr:='rsp';
5: regstr:='rbp';
6: regstr:='rsi';
7: regstr:='rdi';
8: regstr:='r8';
9: regstr:='r9';
10: regstr:='r10';
11: regstr:='r11';
12: regstr:='r12';
13: regstr:='r13';
14: regstr:='r14';
15: regstr:='r15';
end;
if processhandler.is64Bit=false then
begin
if instancereg>=8 then raise exception.create('Invalid instance register');
regstr[1]:='e';
end;
s.add('mov '+regstr+','+inttohex(instanceValue,8));
end;
try
//setup the parameters:
stackpointer:=0;
for i:=5 to lua_gettop(L) do
begin
valuetype:=0;
if lua_istable(l,i) then
begin
lua_pushstring(L,'type');
lua_gettable(L,i);
if lua_isnil(L,-1) then
begin
lua_pop(L,1);
lua_pushinteger(L,1);
lua_gettable(L,i);
if lua_isnil(L,-1) then
begin
lua_pushnil(L);
lua_pushstring(L,'Invalid parametertype '+inttostr(i+3));
exit(2);
end;
end;
valuetype:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'value');
lua_gettable(L,i);
if lua_isnil(L,-1) then
begin
lua_pop(L,1);
lua_pushinteger(L,2);
lua_gettable(L,i);
if lua_isnil(L,-1) then
begin
lua_pushnil(L);
lua_pushstring(L,'Invalid parametervalue '+inttostr(i+3));
exit(2);
end;
end;
end
else
begin
//no specific type is given, guess it based on the parameters (damn those lazy ass users)
if lua_type(L,i)=LUA_TSTRING then
valuetype:=3
else
begin
if lua_isnumber(L,i) then
begin
if lua_isinteger(L,i) then
valuetype:=0 //integer/pointer
else
valuetype:=1; //float (if you want double then give a proper typespecficiation and FU)
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'No idea how to handle the type you provided for parameter '+inttostr(i));
exit(2);
end;
end;
lua_pushvalue(L,i); //-1 now contains the value
end;
case valuetype of
0,3,4:
begin
if valuetype in [3..4] then
begin
sai:=length(stringallocs);
setlength(stringallocs, sai+1);
if valuetype=3 then
begin
//ascii
str:=Lua_ToString(L,-1);
stringallocs[sai]:=virtualallocex(processhandle,nil,length(str)+1,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE);
WriteProcessMemory(processhandle, stringallocs[sai],@str[1],length(str)+1,x);
end
else
begin
//widestring
wstr:=Lua_ToString(L,-1);
stringallocs[sai]:=virtualallocex(processhandle,nil,length(wstr)*2+2,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE);
WriteProcessMemory(processhandle, stringallocs[sai],@wstr[1],length(wstr)*2+2,x);
end;
value:=ptruint(stringallocs[sai]);
end
else
value:=lua_tointeger(L,-1);
if processhandler.is64Bit then
begin
case stackpointer of
0: s.add('mov rcx,'+inttohex(value,8));
1: s.add('mov rdx,'+inttohex(value,8));
2: s.add('mov r8,'+inttohex(value,8));
3: s.add('mov r9,'+inttohex(value,8));
else
begin
s.add('mov rax,'+inttohex(lua_tointeger(L,-1),8));
s.add('mov qword ptr [rsp+'+inttohex(stackpointer*8,8)+'],rax');
end;
end;
end
else
begin
s.add('mov dword ptr [esp+'+inttohex(stackpointer*4,1)+'],'+inttohex(value,8));
end;
inc(stackpointer);
end;
1: //float(single)
begin
f:=lua_tonumber(L,-1);
if processhandler.is64Bit then
begin
floatvalues.Add('floatvalue'+inttostr(stackpointer)+':');
floatvalues.add('dd '+inttohex(floatdword,8));
if stackpointer<4 then
begin
s.add('movss xmm'+inttostr(stackpointer)+',[floatvalue'+inttostr(stackpointer)+']')
end
else
begin
s.add('xor rax,rax');
s.add('mov eax,[floatvalue'+inttostr(stackpointer)+']');
s.add('mov qword ptr [rsp+'+inttohex(stackpointer*8,8)+'],rax');
end;
end
else
s.add('mov dword ptr [esp+'+inttohex(stackpointer*4,1)+'],'+inttohex(floatdword,8));
inc(stackpointer);
end;
2: //double
begin
d:=lua_tonumber(L,-1);
if processhandler.is64Bit then
begin
floatvalues.Add('floatvalue'+inttostr(stackpointer)+':');
floatvalues.add('dq '+inttohex(doubleqword,16));
if stackpointer<4 then
s.add('movsd xmm'+inttostr(stackpointer)+',[floatvalue'+inttostr(stackpointer)+']')
else
begin
s.add('mov rax,[floatvalue'+inttostr(stackpointer)+']');
s.add('mov qword ptr [rsp+'+inttohex(stackpointer*8,8)+'],rax');
end;
end
else
begin
z:=@doubleqword;
s.add('mov dword ptr [esp+'+inttohex(stackpointer*4,1)+'],'+inttohex(z[0],8));
inc(stackpointer);
s.add('mov dword ptr [esp+'+inttohex(stackpointer*4,1)+'],'+inttohex(z[0],8));
end;
inc(stackpointer);
end;
else
begin
lua_pushnil(L);
lua_pushstring(L,'Invalid parametertype '+inttostr(i+3)+'('+inttostr(valuetype)+')');
exit(2);
end;
end;
lua_pop(L,1);
end;
if processhandler.is64Bit=false then //fix the stackfor the caller
s[stackalloc]:='sub esp,'+inttohex(stackpointer*4,1);
s.add('call [addressToCall]');
if processhandler.is64Bit then
begin
s.add('mov [result],rax');
s.add('add rsp,'+inttohex(align(max(4,paramcount)*8,$10)+8,1));
s.add('ret');
end
else
begin
s.add('mov [result],eax');
if callmethod=1 then
s.add('add esp,'+inttohex(stackpointer*4,1));
s.add('ret 4');
end;
if floatvalues.count>0 then
s.add('align 10,0');
for i:=0 to floatvalues.count-1 do
s.add(floatvalues[i]);
dontfree:=false;
if autoassemble(s,false,true,false,false,disableinfo) then
begin
for i:=0 to length(disableinfo.allocs)-1 do
begin
if disableinfo.allocs[i].varname='stub' then
stubaddress:=disableinfo.allocs[i].address;
if disableinfo.allocs[i].varname='result' then
resultaddress:=disableinfo.allocs[i].address;
end;
{
lua_pop(L,lua_gettop(L));
lua_pushstring(L,pchar('stub at '+inttohex(stubaddress,8)));
print(L);
dontfree:=true;
exit(0);
}
thread:=CreateRemoteThread(processhandle, nil, 0, pointer(stubaddress), nil, 0, y);
if (thread<>0) then
begin
dontfree:=timeout=0;
{$ifdef darwin}
if macWaitForRemoteThread(thread,timeout) then
wr:=WAIT_OBJECT_0
else
wr:=WAIT_TIMEOUT;
{$endif}
{$ifdef windows}
wr:=WaitForSingleObject(thread, timeout);
{$endif}
if wr=WAIT_OBJECT_0 then
begin
if ReadProcessMemory(processhandle, pointer(resultaddress), @r, sizeof(r), x) then
begin
lua_pushinteger(L, r);
exit(1);
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'Failure reading the result address');
exit(2);
end;
end
else
if wr=WAIT_TIMEOUT then
begin
dontfree:=true;
lua_pushnil(L);
lua_pushstring(L,'Execution timeout');
exit(2);
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'Wait failure');
exit(2);
end;
closehandle(thread);
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'Failure launching thread');
exit(2);
end;
end;
finally
s.free;
floatvalues.free;
disableinfo.free;
if (dontfree=false) then
begin
if stubaddress<>0 then VirtualFreeEx(processhandle, pointer(stubaddress), 0, MEM_RELEASE);
if resultaddress<>0 then VirtualFreeEx(processhandle, pointer(resultaddress), 0, MEM_RELEASE);
for i:=0 to length(stringallocs)-1 do
VirtualFreeEx(processhandle, pointer(stringallocs[i]), 0, MEM_RELEASE);
end;
//free allocated strings
end;
end;
function executeCodeEx(L:PLua_state): integer; cdecl; //executecodeex(callmethod, timeout, address, {param1},{param2},{param3},{...})
var
paramcount: integer;
i: integer;
begin
//convert to
//executeMethod(callmethod, timeout, address, nil, param1, param2, param3, ...
paramcount:=lua_gettop(L);
if paramcount<3 then
begin
lua_pushnil(L);
lua_pushstring(L,'Not enough parameters. Minimum: callmethod, timeout, address');
exit(2);
end;
lua_pushnil(L);
lua_insert(L, 4); //instance=nil
exit(executeMethod(L));
end;
function executeCode(L:PLua_state): integer; cdecl; //executecode(address, parameter)
var
s: tstringlist;
//allocs: TCEAllocArray;
//exceptionlist: TCEExceptionListArray;
Disableinfo: TDisableinfo;
address: ptruint;
i: integer;
stubaddress: ptruint;
resultaddress: ptruint;
parameter: ptruint;
timeout: dword;
thread: thandle;
r: ptruint;
x: dword;
y: ptruint;
wr: DWORD;
dontfree: boolean;
begin
//creates a thread in the target process. calls stdcall function(parameter):pointer and wait for it's return
stubaddress:=0;
result:=0;
dontfree:=false;
if lua_gettop(L)>=1 then
begin
if lua_isnil(L,1) then exit(0);
address:=lua_toaddress(L,1);
if lua_gettop(L)>=2 then
begin
if lua_isnumber(L,2) then
parameter:=lua_tointeger(L, 2)
else
parameter:=symhandler.getAddressFromName(Lua_ToString(L,2), waitforsymbols);
end
else
parameter:=0;
if lua_gettop(L)>=3 then
timeout:=lua_tointeger(L,3)
else
timeout:=INFINITE;
end
else
exit;
s:=tstringlist.create;
disableinfo:=TDisableinfo.create;
try
s.Add('allocXO(stub, 2048)');
if processhandler.is64Bit then
begin
s.add('allocXO(addressToCall, 8)');
s.add('allocNX(result,8)');
end
else
s.add('allocNX(result,4)');
s.add('stub:');
if processhandler.is64Bit then
begin
s.add('sub rsp,28');
s.add('call [addressToCall]');
s.add('mov [result],rax');
s.add('add rsp,28');
s.add('ret');
end
else
begin
s.add('push [esp+4]'); //push the parameter again
s.add('call '+inttohex(address,8));
s.add('mov [result],eax');
s.add('ret 4');
end;
if processhandler.is64Bit then
begin
s.add('addressToCall:');
s.add('dq '+inttohex(address,8));
end;
if autoassemble(s, false, true, false, false, disableinfo) then
begin
for i:=0 to length(disableinfo.allocs)-1 do
begin
if disableinfo.allocs[i].varname='stub' then
stubaddress:=disableinfo.allocs[i].address;
if disableinfo.allocs[i].varname='result' then
resultaddress:=disableinfo.allocs[i].address;
end;
if stubaddress<>0 then
begin
thread:=CreateRemoteThread(processhandle, nil, 0, pointer(stubaddress), pointer(parameter), 0, x);
if (thread<>0) then
begin
{$ifdef darwin}
if macWaitForRemoteThread(thread,timeout) then
wr:=WAIT_OBJECT_0
else
wr:=WAIT_TIMEOUT;
{$endif}
{$ifdef windows}
wr:=WaitForSingleObject(thread, timeout);
{$endif}
if wr=WAIT_OBJECT_0 then
begin
if ReadProcessMemory(processhandle, pointer(resultaddress), @r, sizeof(r), y) then
begin
lua_pushinteger(L, r);
result:=1;
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'Failure reading the result address');
exit(2);
end;
end
else
if wr=WAIT_TIMEOUT then
begin
dontfree:=true;
lua_pushnil(L);
lua_pushstring(L,'Execution timeout');
exit(2);
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'Wait failure');
exit(2);
end;
closehandle(thread);
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'Failure launching thread');
exit(2);
end;
end;
end;
finally
s.free;
disableinfo.free;
if (dontfree=false) and (stubaddress<>0) then
VirtualFreeEx(processhandle, pointer(stubaddress), 0, MEM_RELEASE);
if (dontfree=false) and (resultaddress<>0) then
VirtualFreeEx(processhandle, pointer(resultaddress), 0, MEM_RELEASE);
end;
end;
function test(x: integer): qword;
begin
result:=x+12;
end;
function executeCodeLocalEx(L:PLua_state): integer; cdecl; //address,{param},{param},{param}
//paramtypes:
//0: integer/pointer
//1: float
//2: double
//3: asciistring (turns into 0:pointer after writing the string)
//4: widestring
label
p1typeisint, p1typeisfloat, afterp1,
p2typeisint, p2typeisfloat, afterp2,
p3typeisint, p3typeisfloat, afterp3,
p4typeisint, p4typeisfloat, afterp4;
var
//callstack: pointer;
oldstack: pointer;
callstack: array of byte; //stoprage to hold the parameters pushed on the stack (gets copied when needed)
p1type: byte;
p2type: byte;
p3type: byte;
p4type: byte;
valuetype: integer;
AddressToCall: pointer;
paramcount: integer;
paramsize: qword;
paramstart,paramstart2: pointer;
r: qword;
i: integer;
s: string;
ws: widestring;
ts: array of string;
tws: array of widestring;
begin
{$ifndef darwinarm64}
{$ifdef cpu64}
//allocate a stack for this call and fill in the parameters
//setup the parameters at callstack $fff0-parametersize
//getmem(callstack, 65536);
setlength(ts,0);
setlength(tws,0);
if lua_gettop(L)>=1 then
begin
AddressToCall:=pointer(lua_toaddress(L,1,true));
paramcount:=lua_gettop(L)-1;
paramsize:=max(32,8*paramcount);
setlength(callstack,paramsize);
paramstart:=@callstack[0];
if paramcount>0 then
begin
setlength(ts,paramcount);
setlength(tws,paramcount);
for i:=2 to 2+paramcount-1 do //
begin
if lua_istable(L,i) then
begin
lua_pushstring(L,'type');
lua_gettable(L,i);
if lua_isnil(L,-1) then
begin
lua_pop(L,1);
lua_pushinteger(L,1);
lua_gettable(L,i);
if lua_isnil(L,-1) then
begin
lua_pushnil(L);
lua_pushstring(L,'Invalid parametertype '+inttostr(i));
exit(2);
end;
end;
valuetype:=lua_tointeger(L,-1);
lua_pop(L,1);
lua_pushstring(L,'value');
lua_gettable(L,i);
if lua_isnil(L,-1) then
begin
lua_pop(L,1);
lua_pushinteger(L,2);
lua_gettable(L,i);
if lua_isnil(L,-1) then
begin
lua_pushnil(L);
lua_pushstring(L,'Invalid parametervalue '+inttostr(i));
exit(2);
end;
end;
end
else
begin
//no typedefinition
if lua_type(L,i)=LUA_TSTRING then
valuetype:=3
else
begin
if lua_isnumber(L,i) then
begin
if lua_isinteger(L,i) then
valuetype:=0 //integer/pointer
else
valuetype:=1; //float (if you want double then give a proper typespecficiation and FU)
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'No idea how to handle the type you provided for parameter '+inttostr(i));
exit(2);
end;
end;
lua_pushvalue(L,i); //-1 now contains the value
end;
case valuetype of
0: pqword(ptruint(paramstart)+(i-2)*sizeof(pointer))^:=lua_tointeger(L,-1);
1: psingle(ptruint(paramstart)+(i-2)*sizeof(pointer))^:=lua_tonumber(L,-1);
2: pdouble(ptruint(paramstart)+(i-2)*sizeof(pointer))^:=lua_tonumber(L,-1);
3:
begin
ts[i-2]:=Lua_ToString(L,-1);
pqword(ptruint(paramstart)+(i-2)*sizeof(pointer))^:=ptruint(pchar(ts[i-2]));
valuetype:=0;
end;
4:
begin
tws[i-2]:=Lua_ToString(L,-1);
pqword(ptruint(paramstart)+(i-2)*sizeof(pointer))^:=ptruint(pwidechar(tws[i-2]));
valuetype:=0;
end;
end;
case i-1 of
1: p1type:=valuetype;
2: p2type:=valuetype;
3: p3type:=valuetype;
4: p4type:=valuetype;
end;
lua_pop(L,1);
end;
asm
//parameters are accessed by use of RBP which is unaffected by this code
mov oldstack,rsp
sub rsp,paramsize
and rsp,$fffffffffffffff0 //align just in case it was an unaligned paramcount
mov paramstart2,rsp
push rsi
push rdi
push rcx
mov rsi,paramstart
mov rdi,paramstart2
mov rcx,paramsize
rep movsb
pop rcx
pop rdi
pop rsi
cmp paramcount,1
jb afterp4
//p1:
cmp p1type,0
je p1typeisint
cmp p1type,1
je p1typeisfloat
movsd xmm0,[rsp]
jmp afterp1
p1typeisint:
mov rcx,[rsp]
jmp afterp1
p1typeisfloat:
movss xmm0,[rsp]
afterp1:
//p2:
cmp paramcount,2
jb afterp4
cmp [p2type],0
je p2typeisint
cmp [p2type],1
je p2typeisfloat
movsd xmm1,[rsp+8]
jmp afterp2
p2typeisint:
mov rdx,[rsp+8]
jmp afterp2
p2typeisfloat:
movss xmm1,[rsp+8]
afterp2:
//p3
cmp paramcount,3
jb afterp4
cmp [p3type],0
je p3typeisint
cmp [p3type],1
je p3typeisfloat
movsd xmm2,[rsp+$10]
jmp afterp3
p3typeisint:
mov r8,[rsp+$10]
jmp afterp3
p3typeisfloat:
movss xmm2,[rsp+$10]
afterp3:
//p4
cmp paramcount,4
jb afterp4
cmp [p4type],0
je p4typeisint
cmp [p4type],1
je p4typeisfloat
movsd xmm3,[rsp+$18]
jmp afterp4
p4typeisint:
mov r9,[rsp+$18]
jmp afterp4
p4typeisfloat:
movss xmm3,[rsp+$18]
afterp4:
call AddressToCall
mov r,rax
mov rsp,oldstack
end;
lua_pushinteger(L,r);
exit(1);
end;
end
else exit(0);
{$else}
lua_pushstring(L,'executeCodeLocalEx is currently not supported on the 32-bit build');
lua_error(L);
{$endif}
{$else}
lua_pushstring(L,'executeCodeLocalEx is currently not supported on the aarch64 build');
lua_error(L);
{$endif}
end;
function executeCodeLocal(L:PLua_state): integer; cdecl;
type
TFunction=function(parameter: pointer):pointer; stdcall;
var
address, parameter: PtrUInt;
f: TFunction;
begin
//executes the given address
result:=0;
if lua_gettop(L)>=1 then
begin
address:=lua_toaddress(L,1,true);
if lua_gettop(L)>=2 then
begin
if lua_isstring(L,2) then
parameter:=selfsymhandler.getAddressFromName(Lua_ToString(L,2), waitforsymbols)
else
parameter:=lua_tointeger(L, 2)
end
else
parameter:=0;
f:=pointer(address);
lua_pushinteger(L, ptruint(f(pointer(parameter))));
result:=1;
end
else
exit;
end;
function md5file(L:PLua_state): integer; cdecl;
var
filename: string;
f: TMemoryStream;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
filename:=Lua_ToString(L,1);
f:=TMemoryStream.create;
try
f.LoadFromFile(filename);
lua_pushstring(L, MD5Print(MD5Buffer(f.Memory^, f.Size)));
result:=1;
finally
f.free;
end;
end;
end;
function md5memory(L:PLua_state): integer; cdecl;
var
startaddress: ptruint;
size: integer;
buf: PByteArray;
x: ptruint;
begin
result:=0;
if lua_gettop(L)>=2 then
begin
startaddress:=lua_toaddress(L,1);
size:=lua_tointeger(L, 2);
if size>0 then
begin
getmem(buf, size);
if ReadProcessMemory(processhandle, pointer(startaddress), buf, size, x) then
begin
if x>0 then
begin
lua_pushstring(L, MD5Print(MD5Buffer(buf^, x)));
result:=1;
end;
end;
FreeMemAndNil(buf);
end;
end;
end;
function allocateKernelMemory(L:PLua_state): integer; cdecl;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)=1 then
begin
lua_pushinteger(L, ptruint(KernelAlloc(lua_tointeger(L,1))));
result:=1;
end;
{$ENDIF}
end;
function freeKernelMemory(L:PLua_state): integer; cdecl;
begin
{$IFDEF windows}
if lua_gettop(L)=1 then
KernelFree(lua_tointeger(L,1));
{$ENDIF}
result:=0; //you'll know it worked by not having a BSOD
end;
function lua_mapMemory(L:PLua_state): integer; cdecl;
var
address: uint64;
size: dword;
frompid, topid: dword;
mmr: TMapMemoryResult;
begin
result:=0;
{$IFDEF windows}
frompid:=0;
topid:=0;
if lua_gettop(L)>=2 then
begin
address:=lua_toaddress(L,1);
size:=lua_tointeger(L,2);
end
else
exit(0);
if lua_gettop(L)>=3 then
frompid:=lua_tointeger(L,3);
if lua_gettop(L)>=4 then
topid:=lua_tointeger(L,4);
mmr:=MapMemory(address, size, frompid, topid);
lua_pushinteger(L, mmr.address);
lua_pushinteger(L, mmr.mdladdress);
result:=2;
{$ENDIF}
end;
function lua_unmapMemory(L:PLua_state): integer; cdecl;
var
mmr: TMapMemoryResult;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(l)>=2 then
begin
mmr.address:=lua_toaddress(L, 1);
mmr.mdladdress:=lua_toaddress(L, 2);
UnmapMemory(mmr);
end;
{$ENDIF}
end;
function lua_lockMemory(L:PLua_state): integer; cdecl;
var
address: qword;
size: integer;
mdl: qword;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)>=2 then
begin
address:=lua_tointeger(L,1);
size:=lua_tointeger(L,2);
mdl:=DBK32functions.LockMemory(processid, address, size);
lua_pushinteger(L,mdl);
result:=1;
end;
{$ENDIF}
end;
function lua_unlockMemory(L:PLua_state): integer; cdecl;
var
mdl: qword;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)>=1 then
begin
mdl:=lua_tointeger(L,1);
DBK32functions.unLockMemory(mdl);
end;
{$ENDIF}
end;
function lua_sendMessage(L:PLua_state): integer; cdecl;
var h: HWND;
Msg: UINT;
wp: WPARAM;
lp: LPARAM;
begin
result:=0;
if lua_gettop(L)=4 then
begin
h:=lua_tointeger(L,1);
msg:=lua_tointeger(L,2);
wp:=lua_tointeger(L,3);
lp:=lua_tointeger(L,4);
lua_pushinteger(L, SendMessage(h, Msg, wp, lp));
result:=1;
end;
end;
function lua_sendMessageTimeout(L:PLua_state): integer; cdecl;
var h: HWND;
Msg: UINT;
wp: WPARAM;
lp: LPARAM;
flags, timeout: uint;
r: DWORD_PTR;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)=4 then
begin
h:=lua_tointeger(L,1);
msg:=lua_tointeger(L,2);
wp:=lua_tointeger(L,3);
lp:=lua_tointeger(L,4);
flags:=lua_tointeger(L,5);
timeout:=lua_tointeger(L,6);
if SendMessageTimeoutA(h, Msg, wp, lp, flags,timeout, r)<>0 then
lua_pushinteger(L,r)
else
lua_pushnil(L);
result:=1;
end;
{$ENDIF}
end;
function lua_findWindow(L:PLua_state): integer; cdecl;
var
classname, windowname: pchar;
begin
result:=0;
{$IFDEF windows}
classname:=nil;
windowname:=nil;
if lua_gettop(L)>=1 then
classname:=lua.lua_tostring(L,1);
if lua_gettop(L)>=2 then
windowname:=lua.Lua_ToString(L, 2);
lua_pushinteger(L, FindWindow(classname, windowname));
result:=1;
{$ENDIF}
end;
function lua_getWindow(L:PLua_state): integer; cdecl;
var
h: hwnd;
cmd: uint;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)>=2 then
begin
h:=lua_tointeger(L, 1);
cmd:=lua_tointeger(L, 2);
lua_pushinteger(L, GetWindow(h, cmd));
result:=1;
end;
{$ENDIF}
end;
function lua_getWindowProcessID(L:PLua_state): integer; cdecl;
var
h: hwnd;
pid: DWORD;
tid: dword;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)>=1 then
begin
pid:=0;
tid:=0;
h:=lua_tointeger(L,1);
tid:=GetWindowThreadProcessId(h, pid);
lua_pushinteger(L, pid);
lua_pushinteger(L, tid);
result:=2;
end;
{$ENDIF}
end;
function lua_getWindowCaption(L:PLua_state): integer; cdecl;
var
h: hwnd;
s: pchar;
i: integer;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)=1 then
begin
h:=lua_tointeger(L, 1);
getmem(s,256);
try
i:=GetWindowText(h, s, 255);
s[i]:=#0;
lua_pushstring(L,s);
result:=1;
finally
FreeMemAndNil(s);
end;
end;
{$ENDIF}
end;
function lua_getWindowClassName(L:PLua_state): integer; cdecl;
var
h: hwnd;
s: pchar;
i: integer;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)=1 then
begin
h:=lua_tointeger(L, 1);
getmem(s,256);
try
i:=GetClassNameA(h, s, 255);
s[i]:=#0;
lua_pushstring(L,s);
result:=1;
finally
FreeMemAndNil(s);
end;
end;
{$ENDIF}
end;
function lua_getForegroundWindow(L:PLua_state): integer; cdecl;
begin
result:=1;
lua_pushinteger(L, GetForegroundWindow());
end;
function getXBox360ControllerKeyPress(L:PLua_state): integer; cdecl;
{$IFDEF windows}
var
i: integer;
index: integer;
ks: XINPUT_KEYSTROKE;
state: XINPUT_STATE;
{$ENDIF}
begin
result:=0;
{$IFDEF windows}
XInputMessages(false); //you don't want to use gui support for hotkeys, but handle it yourself
index:=-1;
if InitXinput=false then exit;
if not assigned(XInputGetKeystroke) then exit;
if lua_gettop(L)>=1 then
begin
index:=lua_tointeger(L, 1);
if XInputGetKeystroke(index, 0, @ks)<>0 then exit;
end
else
begin
for i:=0 to XUSER_MAX_COUNT-1 do
begin
if (XInputGetState(i, state)=0) and (XInputGetKeystroke(i, 0, @ks)=0) then //found a controller (usually 0)
begin
index:=i;
break;
end;
end;
end;
if index<>-1 then
begin
lua_newtable(L);
i:=lua_gettop(L);
lua_setbasictableentry(L, i, 'VirtualKey', ks.VirtualKey);
lua_setbasictableentry(L, i, 'Unicode', ks.Unicode);
lua_setbasictableentry(L, i, 'Flags', ks.Flags);
lua_setbasictableentry(L, i, 'UserIndex', ks.UserIndex);
lua_setbasictableentry(L, i, 'HidCode', ks.HidCode);
result:=1;
end;
{$ENDIF}
end;
function getXBox360ControllerState(L:PLua_state): integer; cdecl;
{$IFDEF windows}
var
index: integer;
i: integer;
state: XINPUT_STATE;
{$ENDIF}
begin
result:=0;
{$IFDEF windows}
index:=-1;
if InitXinput=false then exit;
if lua_gettop(L)>=1 then
begin
index:=lua_tointeger(L, 1);
if XInputGetState(index, state)<>0 then exit;
end
else
begin
for i:=0 to XUSER_MAX_COUNT-1 do
begin
if XInputGetState(i, state)=0 then //found a controller (usually 0)
begin
index:=i;
break;
end;
end;
end;
if index<>-1 then
begin
//state is now filled in, convert it to a readable table
lua_newtable(L);
i:=lua_gettop(L);
lua_setbasictableentry(L, i, 'ControllerID', index);
lua_setbasictableentry(L, i, 'PacketNumber', state.dwPacketNumber);
lua_setbasictableentry(L, i, 'GAMEPAD_DPAD_UP', (state.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_UP)<>0);
lua_setbasictableentry(L, i, 'GAMEPAD_DPAD_DOWN', (state.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_DOWN)<>0);
lua_setbasictableentry(L, i, 'GAMEPAD_DPAD_LEFT', (state.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_LEFT)<>0);
lua_setbasictableentry(L, i, 'GAMEPAD_DPAD_RIGHT', (state.Gamepad.wButtons and XINPUT_GAMEPAD_DPAD_RIGHT)<>0);
lua_setbasictableentry(L, i, 'GAMEPAD_START', (state.Gamepad.wButtons and XINPUT_GAMEPAD_START)<>0);
lua_setbasictableentry(L, i, 'GAMEPAD_BACK', (state.Gamepad.wButtons and XINPUT_GAMEPAD_BACK)<>0);
lua_setbasictableentry(L, i, 'GAMEPAD_LEFT_THUMB', (state.Gamepad.wButtons and XINPUT_GAMEPAD_LEFT_THUMB)<>0);
lua_setbasictableentry(L, i, 'GAMEPAD_RIGHT_THUMB', (state.Gamepad.wButtons and XINPUT_GAMEPAD_RIGHT_THUMB)<>0);
lua_setbasictableentry(L, i, 'GAMEPAD_LEFT_SHOULDER', (state.Gamepad.wButtons and XINPUT_GAMEPAD_LEFT_SHOULDER)<>0);
lua_setbasictableentry(L, i, 'GAMEPAD_RIGHT_SHOULDER', (state.Gamepad.wButtons and XINPUT_GAMEPAD_RIGHT_SHOULDER)<>0);
lua_setbasictableentry(L, i, 'GAMEPAD_A', (state.Gamepad.wButtons and XINPUT_GAMEPAD_A)<>0);
lua_setbasictableentry(L, i, 'GAMEPAD_B', (state.Gamepad.wButtons and XINPUT_GAMEPAD_B)<>0);
lua_setbasictableentry(L, i, 'GAMEPAD_X', (state.Gamepad.wButtons and XINPUT_GAMEPAD_X)<>0);
lua_setbasictableentry(L, i, 'GAMEPAD_Y', (state.Gamepad.wButtons and XINPUT_GAMEPAD_Y)<>0);
lua_setbasictableentry(L, i, 'wButtons', state.Gamepad.wButtons);
lua_setbasictableentry(L, i, 'LeftTrigger', state.Gamepad.bLeftTrigger);
lua_setbasictableentry(L, i, 'RightTrigger', state.Gamepad.bRightTrigger);
lua_setbasictableentry(L, i, 'ThumbLeftX', state.Gamepad.sThumbLX);
lua_setbasictableentry(L, i, 'ThumbLeftY', state.Gamepad.sThumbLY);
lua_setbasictableentry(L, i, 'ThumbRightX', state.Gamepad.sThumbRX);
lua_setbasictableentry(L, i, 'ThumbRightY', state.Gamepad.sThumbRY);
result:=1;
end;
{$ENDIF}
end;
function setXBox360ControllerVibration(L:PLua_state): integer; cdecl;
{$IFDEF windows}
var
index: integer;
left, right: word;
vib: XINPUT_VIBRATION;
{$ENDIF}
begin
result:=0;
{$IFDEF windows}
if InitXinput=false then exit;
if lua_gettop(L)>=3 then
begin
index:=lua_tointeger(L,1);
left:=lua_tointeger(L,2);
right:=lua_tointeger(L, 3);
vib.wLeftMotorSpeed:=left;
vib.wRightMotorSpeed:=right;
result:=1;
lua_pushboolean(L, XInputSetState(index, @vib)=0);
end;
{$ENDIF}
end;
function lua_AddSnapshotAsComment(L:PLua_state): integer; cdecl;
var
script: TStrings;
address: ptruint;
radius: integer;
begin
result:=0;
if lua_gettop(L)>=2 then
begin
script:=lua_ToCEUserData(L,1);
address:=lua_tointeger(L,2);
if lua_gettop(L)>=3 then
radius:=lua_tointeger(L,3)
else
radius:=10;
AddSnapshotAsComment(script, address, radius);
result:=1;
end;
end;
function lua_getNextAllocNumber(L:PLua_state): integer; cdecl;
var script: TStrings;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
script:=lua_ToCEUserData(L,1);
lua_pushinteger(L, GetNextAllocNumber(script));
result:=1;
end;
end;
function lua_getUniqueAOB(L:PLua_state): integer; cdecl;
var
address: ptruint;
mi: TModuleInfo;
offset: integer;
r: string;
codesize: integer;
ca: ptruint;
x: string;
d: TDisassembler;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
address:=lua_tointeger(L,1);
if lua_gettop(L)>=2 then
codesize:=lua_tointeger(L,2)
else
begin
//no codesize given, calculate the number of bytes needed to put a 5 byte jmp in here. (make sure to use 3th alloc param, bitch please if you don't)
codesize:=0;
ca:=address;
d:=TDisassembler.create;
while (ca-address)<5 do
d.disassemble(ca,x);
codesize:=ca-address;
d.free;
end;
if address<>0 then
begin
mi.baseaddress:=0;
symhandler.getmodulebyaddress(address,mi);
r:=GetUniqueAOB(mi,address,codesize,offset);
lua_pushstring(L,r);
lua_pushinteger(L,offset);
result:=2;
end;
end;
end;
function lua_registerAutoAssemblerTemplate(L:PLua_state): integer; cdecl;
var
f: integer;
routine: string;
lc: tluacaller;
name: string;
shortcut: TShortCut;
begin
result:=0;
if lua_gettop(L)>=2 then
begin
name:=Lua_ToString(L, 1);
if lua_isfunction(L, 2) then
begin
lua_pushvalue(L, 2);
f:=luaL_ref(L,LUA_REGISTRYINDEX);
lc:=TLuaCaller.create;
lc.luaroutineIndex:=f;
end
else
if lua_isstring(L,2) then
begin
routine:=lua_tostring(L,2);
lc:=TLuaCaller.create;
lc.luaroutine:=routine;
end
else exit;
shortcut:=0;
if lua_gettop(L)>=3 then
begin
if lua_isinteger(L,3) then
shortcut:=lua_tointeger(L,3)
else
if lua_isstring(L,3) then
shortcut:=textToShortCut(Lua_ToString(L,3))
end;
lua_pushinteger(L, registerAutoAssemblerTemplate(name, lc.AutoAssemblerTemplateCallback, shortcut));
result:=1;
end;
end;
function lua_unregisterAutoAssemblerTemplate(L:PLua_state): integer; cdecl;
var id: integer;
begin
result:=0;
if lua_gettop(L)=1 then
begin
id:=lua_tointeger(L, 1);
unregisterAutoAssemblerTemplate(id);
end;
end;
function lua_GenerateCodeInjectionScript(L: PLua_state): integer; cdecl;
var
script: TStrings;
address: string;
farjmp: boolean;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
script:=lua_ToCEUserData(L,1);
if lua_gettop(L)>=2 then
address:=Lua_ToString(L,2)
else
address:=inttohex(MemoryBrowser.disassemblerview.SelectedAddress,8);
if lua_gettop(L)>=3 then
farjmp:=lua_toboolean(L,3)
else
farjmp:=false;
try
GenerateCodeInjectionScript(script, address,farjmp);
lua_pushboolean(L,true);
result:=1;
except
end;
end;
end;
function lua_GenerateAOBInjectionScript(L: PLua_state): integer; cdecl;
var
script: TStrings;
address, symbolname: string;
lineCountToCopy: integer;
farjmp: boolean;
begin
result:=0;
if lua_gettop(L)>=2 then
begin
script:=lua_ToCEUserData(L,1);
symbolname:=Lua_ToString(L,2);
if lua_gettop(L)>=3 then
address:=Lua_ToString(L,3)
else
address:=inttohex(MemoryBrowser.disassemblerview.SelectedAddress,8);
if lua_gettop(L)>=4 then
lineCountToCopy:=lua_tointeger(L,4)
else
linecountToCopy:=20;
if lua_gettop(L)>=5 then
farjmp:=lua_toboolean(L,5)
else
farjmp:=false;
try
GenerateAOBInjectionScript(script, address, symbolname, lineCountToCopy);
lua_pushboolean(L,true);
result:=1;
except
end;
end;
end;
function lua_GenerateFullInjectionScript(L: PLua_state): integer; cdecl;
var
script: TStrings;
address: string;
lineCountToCopy: integer;
farjmp: boolean;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
script:=lua_ToCEUserData(L,1);
if lua_gettop(L)>=2 then
address:=Lua_ToString(L,2)
else
address:=inttohex(MemoryBrowser.disassemblerview.SelectedAddress,8);
if lua_gettop(L)>=3 then
lineCountToCopy:=lua_tointeger(L,3)
else
linecountToCopy:=20;
if lua_gettop(L)>=4 then
farjmp:=lua_toboolean(L,4)
else
farjmp:=false;
try
GenerateFullInjectionScript(script, address, lineCountToCopy);
lua_pushboolean(L,true);
result:=1;
except
end;
end;
end;
function lua_unloadLoadedFont(L: PLua_state): integer; cdecl;
begin
{$IFDEF windows}
if lua_isnumber(L, 1) then
RemoveFontMemResourceEx(lua_tointeger(L,1));
{$ENDIF}
result:=0;
end;
function lua_loadFontFromStream(L: PLua_state): integer; cdecl;
var
s: TStream;
ms: TMemoryStream absolute s;
f: TFont;
pc: dword;
h: THandle;
begin
result:=0;
{$IFDEF windows}
if lua_isuserdata(L, 1) then
begin
s:=lua_toceuserdata(L, 1);
if s is TMemoryStream then
begin
pc:=1;
h:=AddFontMemResourceEx(ms.Memory, ms.Size, nil, @pc);
lua_pushinteger(L, h);
result:=1;
end;
end;
{$ENDIF}
end;
function lua_speakex(engLang: boolean; L: Plua_State): integer; cdecl;
var
pc: integer;
s: widestring;
begin
result:=0;
{$IFDEF windows}
pc:=lua_gettop(L);
if pc>=1 then
s:=Lua_ToString(L, 1)
else
exit(0);
if engLang then
begin
s:=StringReplace(s,'&','&amp;',[rfReplaceAll]);
s:=StringReplace(s,'<','&lt;',[rfReplaceAll]);
s:=StringReplace(s,'>','&gt;',[rfReplaceAll]);
//s:='<speak version="1.0" xml:lang="en">'+s+'</speak>';
//s:='<lang langid="409">'+s+'</lang>';
s:='<voice required="Language=409">'+s+'</voice>'; //413=dutch (while running under a debugger, this is slow. But normal usage is fine)
end;
if pc>=2 then
begin
if lua_isboolean(l,2) then
begin
lua_pushinteger(L, speak(s, lua_toboolean(L,2)));
exit(1);
end
else
begin
lua_pushinteger(L, speak(s, lua_tointeger(L,2)));
exit(1);
end;
end
else
begin
lua_pushinteger(L, speak(s));
exit(1);
end;
{$ENDIF}
end;
function lua_speak(L: Plua_State): integer; cdecl;
begin
lua_speakEx(false,L);
result:=0;
end;
function lua_speakEnglish(L: Plua_State): integer; cdecl;
begin
lua_speakEx(true,L);
result:=0;
end;
function lua_getFileVersion(L: Plua_State): integer; cdecl;
{$IFDEF windows}
var
filepath: string;
h: THandle;
size: integer;
data: pointer;
ffi: ^VS_FIXEDFILEINFO;
t: integer;
v: qword;
s: UINT;
{$ENDIF}
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)=1 then
begin
filepath:=Lua_ToString(l,1);
size:=GetFileVersionInfoSize(pchar(filepath), @h);
if size<>0 then
begin
getmem(data, size);
if GetFileVersionInfo(pchar(filepath), h, size, data) then
begin
s:=sizeof(ffi);
if VerQueryValue(data, pchar('\'), @ffi, @s) then
begin
v:=(qword(ffi^.dwFileVersionMS) shl 32) or ffi^.dwFileVersionLS;
result:=2;
lua_pushinteger(L, v);
lua_newtable(L);
t:=lua_gettop(L);
lua_setbasictableentry(L, t, 'major', (v shr 48) and $ffff);
lua_setbasictableentry(L, t, 'minor', (v shr 32) and $ffff);
lua_setbasictableentry(L, t, 'release', (v shr 16) and $ffff);
lua_setbasictableentry(L, t, 'build', v and $ffff);
end;
end;
FreeMemAndNil(data);
end;
end;
{$ENDIF}
end;
function lua_getCheatEngineFileVersion(L: Plua_State): integer; cdecl;
begin
lua_pushstring(L,application.ExeName);
exit(lua_getFileVersion(L));
end;
function lua_hookWndProc(L: Plua_State): integer; cdecl;
{$IFDEF windows}
var
s: tstringlist;
hWnd: THandle;
f: integer;
orig: qword;
ts: string;
wndhooklist_table, hwnd_table: integer;
i: integer;
b: boolean;
async: boolean;
pc: TLuaPipeClient;
{$ENDIF}
begin
result:=0;
{$IFDEF windows}
lua_getglobal(L, 'CEWindowProcEvent_Internal');
if lua_isnil(L, -1) then
begin
lua_pop(L, 1);
s:=TStringList.Create;
s.add('wndhooklist={}');
s.add('function CEWindowProcEvent_Internal(hWnd, Msg, lParam, wParam)');
s.add(' if (wndhooklist[hWnd].f) then');
s.add(' local r, hWnd2, Msg2, lParam2, wParam2');
s.add(' r,hWnd2,Msg2,lParam2,wParam2=wndhooklist[hWnd].f(hWnd, Msg, lParam, wParam)');
s.add(' if (r==0) or (r==1) then return r,(hWnd2 or hWnd),(Msg2 or Msg),(lParam2 or lParam),(wParam2 or wParam) end');
s.add(' end');
s.add(' return wndhooklist[hWnd].orig,(hWnd2 or hWnd),(Msg2 or Msg),(lParam2 or lParam),(wParam2 or wParam)');
s.add('end');
LUA_DoScript(s.Text);
s.free;
end
else
lua_pop(L, 1);
//setup the server if needed
ts:='CEWINHOOK'+inttostr(processid);
if luaserverExists(ts)=false then
begin
tluaserver.create(ts);
if processhandler.is64Bit then
ts:='x86_64'
else
ts:='i386';
try
cefuncproc.InjectDll(CheatEngineDir+'winhook-'+ts+'.dll');
except
end;
end;
//get the windowhandle and function parameter
if (lua_gettop(L)>=2) and lua_isnumber(L, 1) and lua_isfunction(L, 2) then
begin
if lua_gettop(L)>=3 then
async:=lua_toboolean(L, 3)
else
async:=false;
hWnd:=lua_tointeger(L, 1);
pc:=TLuaPipeClient.create('CEWINHOOKC'+inttostr(processid));
try
pc.writeByte(1);
pc.writeQword(hWnd);
orig:=pc.readQword;
lua_getglobal(L, 'wndhooklist');
wndhooklist_table:=lua_gettop(L);
lua_pushinteger(L, hWnd);
lua_newtable(L);
//fill the hWnd table entry
hwnd_table:=lua_gettop(L);
lua_pushstring(L, 'f');
lua_pushvalue(L, 2);
lua_settable(L, hwnd_table);
lua_pushstring(L, 'orig');
lua_pushinteger(L, orig);
lua_settable(L, hwnd_table);
lua_settable(L, wndhooklist_table);
pc.writeByte(4); //set async state
pc.writeByte(ifthen(async,1,0));
pc.readByte;
pc.writeByte(2); //hook
pc.writeQword(hWnd);
if pc.readByte=1 then
begin
lua_pushboolean(L, true);
result:=1;
end;
finally
pc.free;
end;
end;
//get the old proc event of the window
{$ENDIF}
end;
function lua_unhookWndProc(L: Plua_State): integer; cdecl;
{$IFDEF windows}
var pc: TLuaPipeClient;
{$ENDIF}
begin
result:=0;
{$IFDEF windows}
if (lua_gettop(L)=1) and lua_isnumber(L, 1) then
begin
lua_getglobal(L, 'wndhooklist');
lua_pushinteger(L, lua_tointeger(L, 1));
lua_gettable(L,-2);
if lua_istable(L, -1) then
begin
lua_pushstring(L, 'orig');
lua_gettable(L, -2);
if lua_isnumber(L, -1) then
begin
pc:=TLuaPipeClient.create('CEWINHOOKC'+inttostr(processid));
try
pc.writeByte(3);
pc.writeQword(lua_tointeger(L, 1));
pc.writeQword(lua_tointeger(L, -1));
if pc.readByte=1 then
begin
lua_pushboolean(L, true);
result:=1;
end;
finally
pc.free;
end;
end;
end;
end;
{$ENDIF}
end;
function lua_registerEXETrainerFeature(L: Plua_State): integer; cdecl;
var i,j: integer;
begin
result:=0;
if (lua_gettop(L)=2) and lua_isstring(L,1) and lua_isfunction(L,2) then
begin
j:=length(exeTrainerFeatures);
for i:=0 to length(exeTrainerFeatures)-1 do
if exeTrainerFeatures[i].featurename='' then
begin
j:=i;
break;
end;
if j=length(exeTrainerFeatures) then
setlength(exeTrainerFeatures,j+1);
exeTrainerFeatures[j].featurename:=Lua_ToString(L, 1);
exeTrainerFeatures[j].functionid:=luaL_ref(L, LUA_REGISTRYINDEX);
lua_pushinteger(L, j);
result:=1;
end;
end;
function lua_unregisterEXETrainerFeature(L: Plua_State): integer; cdecl;
var i: integer;
begin
if (lua_gettop(L)=1) and lua_isnumber(L, 1) then
begin
i:=lua_tointeger(L,1);
if i<length(exeTrainerFeatures) then
begin
exeTrainerFeatures[i].featurename:='';
luaL_unref(L, LUA_REGISTRYINDEX, exeTrainerFeatures[i].functionid);
exeTrainerFeatures[i].functionid:=0;
end;
end;
result:=0;
end;
function lwriter(L: Plua_State; const p: Pointer; sz: size_t; ud: Pointer): Integer; cdecl;
var s: TStream;
begin
s:=tstream(ud);
s.WriteBuffer(p^,sz);
result:=0;
end;
function lua_encodeFunction(L: Plua_State): integer; cdecl;
var
s: TMemoryStream;
cs: Tcompressionstream;
i: integer;
output: pchar;
new: pchar;
begin
s:=TMemoryStream.Create;
cs:=Tcompressionstream.create(clmax, s);
if (lua_gettop(L)=1) and (lua_isfunction(L, 1)) then
lua_dump(L, @lwriter, cs, 1);
cs.free;
getmem(output, (s.size div 4) * 5 + 5 );
BinToBase85(pchar(s.Memory), output, s.size);
lua_pushstring(L, output);
FreeMemAndNil(output);
s.free;
result:=1;
end;
function lua_encodeFunctionEx(L: Plua_State): integer; cdecl;
//takes a string and an optional lua dll and encode it with that dll instead
var
s: TMemoryStream;
cs: Tcompressionstream;
script,luadll: string;
hm: HModule;
_luaL_newstate: function : Plua_State; cdecl;
_luaL_openlibs: procedure(L: Plua_State); cdecl;
_luaL_loadstring: function(L: Plua_State; const s: PChar): Integer; cdecl;
_lua_dump: function(L: Plua_State; writer: lua_Writer; data: Pointer; strip: integer): Integer; cdecl;
_lua_close: procedure(L: Plua_State); cdecl;
l2: Plua_State;
r: integer;
rs: string;
output: pchar;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
script:=Lua_ToString(L,1);
if lua_gettop(L)>=2 then
luadll:=Lua_ToString(L,2)
else
luadll:=LUA_LIB_NAME;
hm:=LoadLibrary(pchar(luadll));
if hm<>0 then
begin
_luaL_newstate:=getprocaddress(hm,'luaL_newstate');
_luaL_openlibs:=getprocaddress(hm,'luaL_openlibs');
_luaL_loadstring:=getprocaddress(hm,'luaL_loadstring');
_lua_dump:=getprocaddress(hm,'lua_dump');
_lua_close:=getprocaddress(hm,'lua_close');
l2:=_luaL_newstate;
_luaL_openlibs(l2);
if _luaL_loadstring(l2, pchar(script))=0 then
begin
//encode the function.
s:=TMemoryStream.Create;
cs:=Tcompressionstream.create(clmax, s);
_lua_dump(L2, @lwriter, cs, 1);
cs.free;
getmem(output, (s.size div 4) * 5 + 5 );
BinToBase85(pchar(s.Memory), output, s.size);
lua_pushstring(L, output);
FreeMemAndNil(output);
s.free;
result:=1;
_lua_close(l2);
FreeLibrary(hm);
end;
end;
end;
end;
function lreader(L: Plua_State; ud: Pointer; sz: Psize_t): PChar; cdecl;
var s: TMemoryStream;
begin
s:=TMemoryStream(ud);
result:=pchar(ptruint(s.Memory)+s.Position);
sz^:=s.Size-s.position;
s.position:=s.position+sz^;
end;
function lua_decodeFunction(L: Plua_State): integer; cdecl;
var
ds: Tdecompressionstream;
s: TMemoryStream;
decompressed: TMemoryStream;
i: integer;
size: integer;
input, output: pchar;
begin
result:=1;
if (lua_gettop(L)=1) and lua_isstring(L,1) then
begin
input:=lua.lua_tostring(L,1);
size:=(length(input) div 5)*4+(length(input) mod 5);
getmem(output, size*2);
size:=Base85ToBin(input, output);
lua_pushlstring(L, output, size);
s:=TMemoryStream.Create;
s.WriteBuffer(output^, size);
s.position:=0;
ds:=Tdecompressionstream.create(s);
decompressed:=TMemoryStream.create;
decompressed.CopyFrom(ds,0);
decompressed.position:=0;
lua_load(L, @lreader, decompressed,'cechunk', 'b');
freeandnil(decompressed);
freeandnil(ds);
freeandnil(s);
FreeMemAndNil(output);
result:=1;
end;
end;
function lua_getFileList(L: Plua_State): integer; cdecl;
var
list: Tstringlist;
path: string;
mask: string;
subdirs: boolean;
attrib: word;
paramcount: integer;
i: integer;
begin
paramcount:=lua_gettop(L);
if paramcount=0 then exit(0);
path:=lua_tostring(L,1);
if paramcount>1 then
mask:=Lua_ToString(L, 2)
else
mask:='';
if paramcount>2 then
subdirs:=lua_toboolean(L,3)
else
subdirs:=false;
if paramcount>3 then
attrib:=lua_tointeger(L, 4)
else
attrib:=faDirectory;
lua_pop(L, paramcount);
list:=FindAllFiles(path,mask,subdirs,attrib);
lua_createtable(L, list.count, 0);
result:=1;
for i:=0 to list.count-1 do
begin
lua_pushinteger(L, i+1);
lua_pushstring(L, list[i]);
lua_settable(L, 1);
end;
list.free;
end;
function lua_getDirectoryList(L: Plua_State): integer; cdecl;
var
list: Tstringlist;
path: string;
mask: string;
subdirs: boolean;
attrib: word;
paramcount: integer;
i: integer;
begin
paramcount:=lua_gettop(L);
if paramcount=0 then exit(0);
path:=lua_tostring(L,1);
if paramcount>1 then
subdirs:=lua_toboolean(L,2)
else
subdirs:=false;
lua_pop(L, paramcount);
list:=FindAllDirectories(path,subdirs);
lua_createtable(L, list.count, 0);
result:=1;
for i:=0 to list.count-1 do
begin
lua_pushinteger(L, i+1);
lua_pushstring(L, list[i]);
lua_settable(L, 1);
end;
list.free;
end;
function lua_connectToCEServer(L: Plua_State): integer; cdecl;
var
hostname: string;
port: integer;
begin
result:=0;
if lua_gettop(L)=2 then
begin
hostname:=Lua_ToString(L, 1);
port:=lua_tointeger(L, 2);
CEconnect(hostname, port);
end;
end;
function lua_copyMemory(L: Plua_State): integer; cdecl;
var
sourceAddress: ptruint;
destinationAddress: ptruint;
Method: integer;
size: integer;
pc: integer;
temp: Pointer;
ar: ptruint;
begin
result:=0;
pc:=lua_gettop(L);
if pc=0 then exit;
sourceAddress:=lua_toaddress(L,1);
if pc>1 then
size:=lua_tointeger(L,2);
if pc>3 then
Method:=lua_tointeger(L, 4)
else
Method:=0;
if (pc>2) and (not lua_isnil(L,3)) then
destinationAddress:=lua_toaddress(L, 3)
else
begin
//allocate the memory
case method of
0,2:
begin
//target process
destinationAddress:=ptruint(VirtualAllocEx(processhandle, nil,size,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE));
if destinationAddress=0 then exit;
end;
1,3:
begin
//ce memory
destinationAddress:=ptruint(VirtualAlloc(nil,size,MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE));
if destinationAddress=0 then exit;
end;
end;
end;
case method of
0: //target to target
begin
temp:=VirtualAlloc(nil,size,MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
try
if readprocessmemory(processhandle, pointer(sourceAddress), temp, size, ar) then
begin
if ar=size then
begin
if WriteProcessMemory(processhandle, pointer(destinationAddress), temp, size, ar) then
begin
if ar=size then
begin
lua_pushinteger(L, destinationAddress);
exit(1);
end;
end;
end;
end;
finally
VirtualFree(temp,0, MEM_RELEASE);
end;
end;
1: //target to CE
begin
if readprocessmemory(processhandle, pointer(sourceAddress), pointer(destinationAddress), size, ar) then
begin
if ar=size then
begin
lua_pushinteger(L, destinationAddress);
exit(1);
end;
end;
end;
2: //CE to target
begin
if writeprocessmemory(processhandle, pointer(destinationAddress), pointer(sourceAddress), size, ar) then
begin
if ar=size then
begin
lua_pushinteger(L, destinationAddress);
exit(1);
end;
end;
end;
3: //CE to CE
begin
try
{$ifdef windows}
RtlCopyMemory(pointer(destinationAddress), pointer(sourceAddress), size);
{$else}
copymemory(pointer(destinationAddress), pointer(sourceAddress), size);
{$endif}
lua_pushinteger(L, destinationAddress);
exit(1);
except
end;
end;
end;
end;
function lua_compareMemory(L: PLua_state): integer; cdecl;
var
address1,address2: ptruint;
Method: integer;
size,i: integer;
pc: integer;
temp: Pointer;
ar: ptruint;
buf1, buf2: PByteArray;
begin
result:=0;
pc:=lua_gettop(L);
if pc<3 then exit;
if pc>=4 then
method:=lua_tointeger(L,4)
else
method:=0;
if method=2 then
address1:=lua_toaddress(L,1,true)
else
address1:=lua_toaddress(L,1);
if method>0 then
address2:=lua_toaddress(L,2,true)
else
address2:=lua_toaddress(L,2);
size:=lua_tointeger(L,3);
if size=0 then exit;
buf1:=nil;
buf2:=nil;
case method of
0:
begin
getmem(buf1,size);
getmem(buf2,size);
ReadProcessMemory(processhandle, pointer(address1),buf1,size,ar);
ReadProcessMemory(processhandle, pointer(address2),buf2,size,ar);
end;
1:
begin
getmem(buf1,size);
ReadProcessMemory(processhandle, pointer(address1),buf1,size,ar);
buf2:=pointer(address2);
end;
2:
begin
buf1:=pointer(address1);
buf2:=pointer(address2);
end;
end;
//compare
result:=1;
{$ifdef windows}
i:=RtlCompareMemory(buf1,buf2,size);
{$else}
i:=CompareMemRange(buf1,buf2,size);
{$endif}
lua_pushboolean(L,i=size);
if i<>size then
begin
lua_pushinteger(L, i);
result:=2;
end;
case method of
0:
begin
if buf1<>nil then
FreeMemAndNil(buf1);
if buf2<>nil then
FreeMemAndNil(buf2);
end;
1:
begin
if buf1<>nil then
freeMemAndNil(buf1);
end;
end;
end;
function lua_enableDRM(L: Plua_State): integer; cdecl;
var
PreferedAltitude: word;
ProtectedProcess: dword; //pid
begin
result:=0;
{$IFDEF windows}
DBK32Initialize;
if lua_gettop(L)>=1 then
PreferedAltitude:=lua_tointeger(L,1)
else
PreferedAltitude:=0;
if lua_gettop(L)>=2 then
begin
if lua_isstring(L,2) then
ProtectedProcess:=ce_getProcessIDFromProcessName(pchar(Lua_ToString(L,2)))
else
ProtectedProcess:=lua_tointeger(L,2);
end
else
ProtectedProcess:=0;
result:=1;
lua_pushboolean(L, dbk_enabledrm(preferedAltitude, GetPEProcess(ProtectedProcess)));
{$ENDIF}
end;
function lua_saveOpenedFile(L: Plua_State): integer; cdecl;
begin
if lua_gettop(L)>=1 then
filehandler.commitchanges(Lua_ToString(L,1))
else
Filehandler.commitChanges;
result:=0;
end;
function lua_getOpenedFileSize(L: Plua_State): integer; cdecl;
begin
if (filehandler.filedata<>nil) then
begin
lua_pushinteger(L, filehandler.filedata.Size);
result:=1;
end
else
result:=0;
end;
function lua_openFileAsProcess(L: Plua_State): integer; cdecl;
var
filename: string;
is64bit: boolean;
oldprocessname: string;
oldprocess: dword;
oldprocesshandle: thandle;
parameters: integer;
startaddress: ptruint;
begin
result:=0;
result:=1;
parameters:=lua_gettop(L);
if parameters>=1 then
begin
filename:=Lua_ToString(L,1);
if parameters>=2 then
is64bit:=lua_toboolean(L,2)
else
is64bit:=false;
if parameters>=3 then
startaddress:=lua_tointeger(L,3)
else
startaddress:=0;
DetachIfPossible;
oldprocessname := copy(mainform.ProcessLabel.Caption, pos('-', mainform.ProcessLabel.Caption) + 1, length(mainform.ProcessLabel.Caption));
oldprocess := processID;
oldprocesshandle := processhandle;
try
DBKFileAsMemory(filename,startaddress);
except
lua_pushboolean(L,false);
exit;
end;
ProcessHandler.ProcessHandle:=THandle(-2);
MainForm.ProcessLabel.caption:=extractfilename(filename);
MainForm.miSaveFile.visible:=true;
ProcessHandler.processid:=$FFFFFFFF;
ProcessHandler.is64Bit:=is64bit;
mainform.openProcessEpilogue(oldprocessname, oldprocess, oldprocesshandle,true);
lua_pushboolean(L,true);
end;
end;
function lua_getPEB(L: Plua_State): integer; cdecl;
var peb: qword;
pbi: TProcessBasicInformation;
x: ulong;
begin
result:=0;
{$IFDEF windows}
if DBKLoaded then
peb:=dbk_getPEB(GetPEProcess(processid))
else
begin
if NtQueryInformationProcess(processhandle, ProcessBasicInformation, @pbi, sizeof(pbi), @x)=STATUS_SUCCESS then
peb:=qword(pbi.PebBaseAddress)
else
peb:=0;
end;
lua_pushinteger(L, peb);
result:=1;
{$ENDIF}
end;
function lua_createAPC(L: Plua_State): integer; cdecl;
var address: ptruint;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)>=1 then
begin
address:=lua_toaddress(L,1);
CreateRemoteAPC(getathreadid(processid), pointer(address));
end;
{$ENDIF}
end;
function lua_setAssemblerMode(L: Plua_State): integer; cdecl;
var mode: integer;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
mode:=lua_tointeger(L,1);
if mode=0 then
processhandler.is64Bit:=false;
if mode=1 then
processhandler.is64Bit:=true;
end;
end;
function lua_allocateMemory(l: Plua_State): integer; cdecl;
var
size: integer;
a: pointer;
base: pointer;
prot: dword;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
size:=lua_tointeger(L,1);
if lua_gettop(L)>=2 then
base:=pointer(lua_tointeger(L,2))
else
base:=nil;
if lua_gettop(L)>=3 then
prot:=lua_tointeger(L,3)
else
begin
if SystemSupportsWritableExecutableMemory then
prot:=PAGE_EXECUTE_READWRITE
else
prot:=PAGE_READWRITE;
end;
a:=VirtualAllocEx(processhandle,base,size,MEM_COMMIT or MEM_RESERVE, prot);
if a=nil then
begin
//try to fix a mistake
base:=FindFreeBlockForRegion(ptruint(base),size);
a:=VirtualAllocEx(processhandle,base,size,MEM_COMMIT or MEM_RESERVE, prot);
if a=nil then exit(0);
end;
lua_pushinteger(L, ptruint(a));
result:=1;
end;
end;
function lua_try(l: Plua_State): integer; cdecl;
//nice idea, but the return value of this function seems broken after an raise exception in a function called by pcall (lua_error does function properly)
begin
result:=2;
if lua_gettop(L)>=1 then
begin
if lua_isfunction(L,1) then
begin
try
if lua.lua_pcall(L,lua_gettop(L)-1,LUA_MULTRET,0)=0 then
begin
lua_pushboolean(L,true);
lua_insert(L,1);
result:=lua_gettop(L);
end
else
begin
lua_pushboolean(L,false);
lua_pushvalue(L,-2);
end;
except
on e:exception do
begin
lua_pop(L,lua_gettop(L));
lua_pop(L,1);
lua_pushboolean(L,false);
lua_pushstring(L,e.message);
end;
end;
end
else
begin
lua_pushboolean(L,false);
lua_pushstring(L,'First parameter for try is not a function');
end;
end
else
begin
lua_pushboolean(L,false);
lua_pushstring(L,'No parameter given');
end;
end;
function lua_getSystemMetrics(l: Plua_State): integer; cdecl;
var parameters, nIndex: integer;
begin
result:=0;
parameters:=lua_gettop(L);
if parameters=1 then
begin
nIndex:=lua_tointeger(L,-1);
lua_pop(L, parameters);
lua_pushinteger(L, GetSystemMetrics(nIndex));
result:=1;
end else lua_pop(L, parameters);
end;
function lua_getScreenDPI(l: Plua_State): integer; cdecl;
begin
lua_pushinteger(L, Screen.PixelsPerInch);
result:=1;
end;
function lua_getScreenHeight(l: Plua_State): integer; cdecl;
begin
lua_pushinteger(L, screen.Height);
result:=1;
end;
function lua_getScreenWidth(l: Plua_State): integer; cdecl;
begin
lua_pushinteger(L, screen.Width);
result:=1;
end;
function lua_getWorkAreaHeight(l: Plua_State): integer; cdecl;
begin
lua_pushinteger(L, screen.WorkAreaHeight);
result:=1;
end;
function lua_getWorkAreaWidth(l: Plua_State): integer; cdecl;
begin
lua_pushinteger(L, screen.WorkAreaWidth);
result:=1;
end;
var screencanvas: TCanvas=nil;
function lua_getScreenCanvas(L: PLua_state): integer; cdecl;
begin
if screencanvas=nil then
begin
screencanvas:=tcanvas.Create;
screencanvas.Handle:=GetDC(0);
end;
luaclass_newClass(L, screencanvas);
result:=1;
end;
function lua_getHandleList(L: PLua_state): integer; cdecl;
var
shi: PSYSTEM_HANDLE_INFORMATION=nil;
rl: ulong;
r: ntstatus;
i,j: integer;
filter: integer;
peprocess: ptruint=0;
begin
result:=0;
{$IFDEF windows}
i:=sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO)+128*sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO);
getmem(shi,i);
repeat
zeromemory(shi,i);
r:=NtQuerySystemInformation(SystemHandleInformation, shi,i,@rl);
if r=STATUS_INFO_LENGTH_MISMATCH then
begin
FreeMemAndNil(shi);
i:=i*2-2;
getmem(shi,i);
end;
until (r<>STATUS_INFO_LENGTH_MISMATCH) or (i>256*1024*1024);
if r=STATUS_INFO_LENGTH_MISMATCH then exit(0);
if r<>0 then exit(0);
if lua_gettop(L)>=1 then
begin
filter:=lua_tointeger(L,1);
//0=everything
//1=all handles from the opened process
//2=all handles to the opened process
//3=all handles to cheat engine
case filter of
2:
begin
LoadDBK32;
peprocess:=GetPEProcess(processid);
end;
3:
begin
LoadDBK32;
peprocess:=GetPEProcess(GetCurrentProcessId);
filter:=2;
end;
end;
end
else
filter:=0;
lua_pop(l, lua_gettop(L));
lua_createtable(L, shi.HandleCount,0);
j:=0;
for i:=0 to shi.HandleCount-1 do
begin
if (filter=0) or
((filter=1) and (shi.list[i].ProcessId=processid)) or
((filter=2) and (ptruint(shi.list[i].obj)=peprocess)) then
begin
inc(j);
lua_pushinteger(L,j);
lua_createtable(L,0,6);
lua_pushstring(L, 'ProcessID');
lua_pushinteger(L, shi.list[i].ProcessId );
lua_settable(L,-3);
lua_pushstring(L, 'ObjectTypeIndex');
lua_pushinteger(L, shi.list[i].ObjectTypeIndex );
lua_settable(L,-3);
lua_pushstring(L, 'HandleAttributes');
lua_pushinteger(L, shi.list[i].HandleAttributes );
lua_settable(L,-3);
lua_pushstring(L, 'HandleValue');
lua_pushinteger(L, shi.list[i].HandleValue );
lua_settable(L,-3);
lua_pushstring(L, 'Object');
lua_pushinteger(L, ptruint(shi.list[i].obj));
lua_settable(L,-3);
lua_pushstring(L, 'GrantedAccess');
lua_pushinteger(L, shi.list[i].GrantedAccess );
lua_settable(L,-3);
lua_settable(L,1);
end;
end;
if shi<>nil then
FreeMemAndNil(shi);
result:=1;
{$ENDIF}
end;
function lua_closeRemoteHandle(L: PLua_state): integer; cdecl;
var
handle, newhandle: THandle;
ph: thandle;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)>=1 then
begin
handle:=lua_tointeger(L,1);
if lua_gettop(L)>=2 then
begin
ph:=newkernelhandler.openProcess(PROCESS_DUP_HANDLE,false,lua_tointeger(L,2));
if ph=0 then exit
end
else
ph:=processhandle;
DuplicateHandle(ph, handle, 0,nil, 0, false, DUPLICATE_CLOSE_SOURCE);
if (lua_gettop(L)>=2) then
closehandle(ph);
end;
{$ENDIF}
end;
function lua_showSelectionList(L: PLua_state): integer; cdecl;
var
title,
caption: string;
list: Tstringlist;
output: string;
custominput: boolean;
formname: string;
r: integer;
begin
if lua_gettop(L)>=3 then
begin
title:=Lua_ToString(L,1);
caption:=Lua_ToString(L,2);
list:=lua_ToCEUserData(L,3);
if lua_gettop(L)>=4 then
custominput:=lua_toboolean(L,4)
else
custominput:=false;
if lua_gettop(L)>=5 then
formname:=Lua_ToString(L,5)
else
formname:='';
r:=ShowSelectionList(application,title, caption,list, output, custominput,nil,formname);
lua_pushinteger(L,r);
lua_pushstring(L, output);
result:=2;
end
else result:=0;
end;
function lua_cpuid(L: PLua_state): integer; cdecl;
var a,c: dword;
var r: TCPUIDResult;
i: integer;
begin
if lua_gettop(L)>=1 then
a:=lua_tointeger(L,1)
else
exit(0);
if lua_gettop(L)>=2 then
c:=lua_tointeger(L,2)
else
c:=0;
r:=CPUID(a,c);
lua_newtable(L);
i:=lua_gettop(L);
lua_setbasictableentry(L, i, 'EAX', r.eax);
lua_setbasictableentry(L, i, 'EBX', r.ebx);
lua_setbasictableentry(L, i, 'ECX', r.ecx);
lua_setbasictableentry(L, i, 'EDX', r.edx);
result:=1;
end;
function lua_gc_setPassive(L: PLua_state): integer; cdecl;
begin
if lua_gettop(L)>=1 then
mainform.tLuaGCPassive.enabled:=lua_toboolean(L,1);
result:=0;
end;
function lua_gc_setActive(L: PLua_state): integer; cdecl;
begin
if lua_gettop(L)>=1 then
mainform.tLuaGCActive.enabled:=lua_toboolean(L,1);
if lua_gettop(L)>=2 then
mainform.tLuaGCActive.interval:=lua_tointeger(L,2);
if lua_gettop(L)>=3 then
luagc_MinSize:=lua_tointeger(L,3);
result:=0;
end;
function lua_getHotkeyHandlerThread(L: PLua_state): integer; cdecl;
begin
luaclass_newClass(L, hotkeythread);
result:=1;
end;
function lua_setForceCR3VirtualQueryEx(L: PLua_state): integer; cdecl;
begin
if lua_gettop(L)>=1 then
forceCR3VirtualQueryEx:=lua_toboolean(L,1);
result:=0;
end;
function lua_enumMemoryRegionsCR3(L: PLua_state): integer; cdecl;
var
mbi: TMEMORYBASICINFORMATION;
cr3: qword;
maxaddress: qword;
address: ptruint;
oldaddress: ptruint;
i: integer;
begin
{$ifdef windows}
address:=0;
if lua_gettop(L)>=2 then
cr3:=lua_tointeger(L,1)
else
cr3:=0;
if lua_gettop(L)>=2 then
maxAddress:=lua_tointeger(L,2)
else
maxaddress:=0;
lua_newtable(L);
i:=1;
while ((maxaddress=0) or (address<maxaddress) ) and (newkernelhandler.VirtualQueryExCR3(cr3, pointer(address),mbi,sizeof(mbi))=sizeof(mbi)) do
begin
lua_pushinteger(L,i);
lua_newtable(L);
lua_pushstring(L,'BaseAddress');
lua_pushinteger(L,ptruint(mbi.BaseAddress));
lua_settable(L,-3);
lua_pushstring(L,'AllocationBase');
lua_pushinteger(L,ptruint(mbi.AllocationBase));
lua_settable(L,-3);
lua_pushstring(L,'AllocationProtect');
lua_pushinteger(L,mbi.AllocationProtect);
lua_settable(L,-3);
lua_pushstring(L,'RegionSize');
lua_pushinteger(L,mbi.RegionSize);
lua_settable(L,-3);
lua_pushstring(L,'State');
lua_pushinteger(L,mbi.State);
lua_settable(L,-3);
lua_pushstring(L,'Protect');
lua_pushinteger(L,mbi.Protect);
lua_settable(L,-3);
lua_pushstring(L,'Type');
lua_pushinteger(L,mbi._Type);
lua_settable(L,-3);
lua_settable(L,-3);
oldaddress:=address;
address:=address+mbi.RegionSize;
if address<oldaddress then break;
inc(i);
end;
result:=1;
{$else}
result:=2;
lua_pushnil(L);
lua_pushstring(L,'Not yet implemented');
{$endif}
end;
function lua_enumMemoryRegions(L: PLua_state): integer; cdecl;
var
mbi: TMEMORYBASICINFORMATION;
address: ptruint;
oldaddress: ptruint;
i: integer;
maxAddress: ptruint;
begin
address:=0;
if lua_gettop(L)>=1 then
maxAddress:=lua_tointeger(L,1)
else
maxaddress:=0;
lua_newtable(L);
i:=1;
while ((maxaddress=0) or (address<maxaddress) ) and (newkernelhandler.VirtualQueryEx(processhandle, pointer(address),mbi,sizeof(mbi))=sizeof(mbi)) do
begin
lua_pushinteger(L,i);
lua_newtable(L);
lua_pushstring(L,'BaseAddress');
lua_pushinteger(L,ptruint(mbi.BaseAddress));
lua_settable(L,-3);
lua_pushstring(L,'AllocationBase');
lua_pushinteger(L,ptruint(mbi.AllocationBase));
lua_settable(L,-3);
lua_pushstring(L,'AllocationProtect');
lua_pushinteger(L,mbi.AllocationProtect);
lua_settable(L,-3);
lua_pushstring(L,'RegionSize');
lua_pushinteger(L,mbi.RegionSize);
lua_settable(L,-3);
lua_pushstring(L,'State');
lua_pushinteger(L,mbi.State);
lua_settable(L,-3);
lua_pushstring(L,'Protect');
lua_pushinteger(L,mbi.Protect);
lua_settable(L,-3);
lua_pushstring(L,'Type');
lua_pushinteger(L,mbi._Type);
lua_settable(L,-3);
lua_settable(L,-3);
oldaddress:=address;
address:=address+mbi.RegionSize;
if address<oldaddress then break;
inc(i);
end;
result:=1;
end;
function lua_enableWindowsSymbols(L: PLua_state): integer; cdecl;
begin
EnableWindowsSymbols(false);
result:=0;
end;
function lua_enableKernelSymbols(L: PLua_state): integer; cdecl;
begin
result:=0;
symhandler.kernelsymbols:=true;
MemoryBrowser.Kernelmodesymbols1.checked:=true;
symhandler.reinitialize(true);
end;
function lua_enumExports(L: PLua_state): integer; cdecl;
var
address: ptruint;
path: string;
self: boolean;
e: boolean;
list: Tstringlist;
i: integer;
begin
result:=0;
{$IFDEF windows}
if lua_gettop(L)>=1 then
begin
list:=Tstringlist.create;
try
if lua_gettop(L)>=2 then
self:=lua_toboolean(L,2);
try
address:=lua_toaddress(L,1,self);
try
peinfo_getExportList(address,list);
except
exit(0); //no export list
end;
except
if lua_isstring(L,1) then
begin
path:=Lua_ToString(L,1);
try
peinfo_getExportList(path,list);
except
exit(0);
end;
end;
end;
lua_newtable(L);
for i:=0 to list.count-1 do
begin
lua_pushstring(L,list[i]);
lua_pushinteger(L,ptruint(list.Objects[i]));
lua_settable(L,-3);
end;
result:=1;
finally
list.free;
end;
end;
{$ENDIF}
end;
function lua_duplicateHandle(L: PLua_state): integer; cdecl;
//three formats:
//(handle): Duplicates a CE handle to the target process
//(handle, mode) : where mode is 0: CE to Target, 1: Target to CE
//(handle, frompid,topid)
var
fromprocess: THandle;
toprocess: THandle;
sourcehandle: THandle;
newhandle: THandle;
frompid, topid: qword;
openedfromprocess: boolean=false;
openedtoprocess: boolean=false;
begin
result:=0;
{$IFDEF windows}
try
fromprocess:=GetCurrentProcess;
toprocess:=processhandle;
if lua_gettop(L)>=1 then
begin
sourcehandle:=lua_tointeger(L,1);
if lua_gettop(L)>=2 then
begin
if lua_gettop(L)>=3 then
begin
//frompid,topid
frompid:=lua_tointeger(L,2);
topid:=lua_tointeger(L,3);
if frompid=GetCurrentProcessId then
fromprocess:=GetCurrentProcess
else
if frompid=processid then
fromprocess:=processhandle
else
begin
fromprocess:=newkernelhandler.openProcess(PROCESS_DUP_HANDLE,false,frompid);
if fromprocess<>0 then
openedfromprocess:=true
else
begin
lua_pushnil(L);
lua_pushstring(L,'Failure opening process '+inttostr(frompid)+' ('+SysErrorMessage(GetLastOSError)+')');
exit(2); //failed to open the process
end;
end;
if topid=GetCurrentProcessId then
toprocess:=GetCurrentProcess
else
if topid=processid then
toprocess:=processhandle
else
begin
toprocess:=newkernelhandler.openProcess(PROCESS_DUP_HANDLE,false,topid);
if toprocess<>0 then
openedtoprocess:=true
else
begin
lua_pushnil(L);
lua_pushstring(L,'Failure opening process '+inttostr(topid)+' ('+SysErrorMessage(GetLastOSError)+')');
exit(2); //failed to open the process
end;
end;
end
else
begin
//mode
if lua_tointeger(L,2)=1 then //target to CE, so switch processes
begin
toprocess:=GetCurrentProcess;
fromprocess:=processhandle;
end; //else as it was
end;
end;
if DuplicateHandle(fromprocess, sourcehandle,toprocess,@newhandle, 0, false, DUPLICATE_SAME_ACCESS) then
begin
lua_pushinteger(L,newhandle);
exit(1);
end
else
begin
lua_pushnil(L);
lua_pushstring(L, 'Duplication failed due to :'+SysErrorMessage(GetLastOSError));
exit(2);
end;
end;
finally
if openedfromprocess then closehandle(fromprocess);
if openedtoprocess then closehandle(toprocess);
end;
{$ENDIF}
end;
function lua_getOperatingSystem(L: PLua_state): integer; cdecl;
begin
lua_pushinteger(L,{$ifdef windows}0{$else}1{$endif});
result:=1;
end;
function lua_createColorDialog(L: Plua_State): integer; cdecl;
var
owner: TComponent;
cd: TColorDialog;
begin
result:=0;
if lua_gettop(L)=1 then
owner:=lua_toceuserdata(L, 1)
else
owner:=nil;
cd:=TColorDialog.Create(owner);
luaclass_newClass(L, cd);
result:=1;
end;
function lua_createColorBox(L: Plua_State): integer; cdecl;
var
owner: TComponent;
cb: TColorBox;
begin
result:=0;
if lua_gettop(L)=1 then
owner:=lua_toceuserdata(L, 1)
else
owner:=nil;
cb:=TColorBox.Create(owner);
luaclass_newClass(L, cb);
result:=1;
end;
function lua_createAutoAssemblerForm(L: Plua_State): integer; cdecl;
var f: TfrmAutoInject;
begin
f:=TfrmAutoInject.Create(application);
if lua_gettop(L)>=1 then
f.assemblescreen.Text:=Lua_ToString(L,1);
f.show;
luaclass_newClass(L, f);
result:=1;
end;
function lua_getRTTIClassName(L: Plua_State): integer; cdecl;
var address: ptruint;
classname: string;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
address:=lua_tointeger(L,1);
if getRTTIClassName(address, classname) then
begin
lua_pushstring(L,classname);
exit(1);
end;
end;
end;
function lua_getAutoRunPath(L: Plua_State): integer; cdecl;
begin
lua_pushstring(L,autorunpath);
exit(1);
end;
function lua_extractfilenamewithoutext(L: Plua_State): integer; cdecl;
begin
if lua_gettop(L)>=1 then
begin
lua_pushstring(L, ExtractFileNameWithoutExt(Lua_ToString(L,1)));
exit(1);
end
else
exit(0);
end;
function lua_extractfileext(L: Plua_State): integer; cdecl;
begin
if lua_gettop(L)>=1 then
begin
lua_pushstring(L, ExtractFileExt(Lua_ToString(L,1)));
exit(1);
end
else
exit(0);
end;
function lua_extractFileName(L: Plua_State): integer; cdecl;
begin
if lua_gettop(L)>=1 then
begin
lua_pushstring(L, ExtractFileName(Lua_ToString(L,1)));
exit(1);
end
else
exit(0);
end;
function lua_extractFilePath(L: Plua_State): integer; cdecl;
begin
if lua_gettop(L)>=1 then
begin
lua_pushstring(L, ExtractFilePath(Lua_ToString(L,1)));
exit(1);
end
else
exit(0);
end;
function lua_trim(L: Plua_State): integer; cdecl;
var s: string;
begin
if lua_gettop(L)>=1 then
begin
s:=Lua_ToString(L,1);
lua_pushstring(L,trim(s));
end
else
lua_pushnil(L);
result:=1;
end;
function lua_string_split(L: Plua_State): integer; cdecl;
var
s: string;
sep: string;
arr: TStringDynArray;
i: integer;
begin
result:=0;
if lua_gettop(L)>=2 then
begin
s:=Lua_ToString(L,1);
sep:=Lua_ToString(L,2);
arr:=SplitString(s,sep);
lua_pop(L,lua_gettop(L));
if lua_checkstack(L, length(arr)) then
begin
for i:=0 to length(arr)-1 do
lua_pushstring(L, arr[i]);
result:=length(arr);
end;
end;
end;
function lua_string_endswith(L: Plua_State): integer; cdecl;
var
s, endswith: string;
ignoreCase: boolean;
begin
result:=0;
if lua_gettop(L)>=2 then
begin
s:=Lua_ToString(L,1);
endswith:=Lua_ToString(L,2);
if lua_gettop(L)>=3 then
ignorecase:=lua_toboolean(L,3)
else
ignorecase:=false;
lua_pushboolean(L, s.EndsWith(endswith,ignorecase));
result:=1;
end;
end;
function lua_string_startswith(L: Plua_State): integer; cdecl;
var
s, searchstring: string;
ignoreCase: boolean;
begin
result:=0;
if lua_gettop(L)>=2 then
begin
s:=Lua_ToString(L,1);
searchstring:=Lua_ToString(L,2);
if lua_gettop(L)>=3 then
ignorecase:=lua_toboolean(L,3)
else
ignorecase:=false;
lua_pushboolean(L, s.StartsWith(searchstring,ignorecase));
result:=1;
end;
end;
function lua_registerLuaFunctionHighlight(L: Plua_State): integer; cdecl;
begin
if luasyntaxStringHashList<>nil then
luasyntaxStringHashList.Add(Lua_ToString(L,-1));
result:=0;
end;
function lua_unregisterLuaFunctionHighlight(L: Plua_State): integer; cdecl;
begin
if luasyntaxStringHashList<>nil then
luasyntaxStringHashList.Remove(Lua_ToString(L,-1));
result:=0;
end;
function lua_setProgressState(L: Plua_State): integer; cdecl;
begin
{$ifdef windows}
if lua_gettop(L)>=1 then
SetProgressState(TTaskBarProgressState(lua_tointeger(L,1)));
{$endif}
result:=0;
end;
function lua_setProgressValue(L: Plua_State): integer; cdecl;
begin
{$ifdef windows}
if lua_gettop(L)>=2 then
SetProgressValue(lua_tointeger(L,1), lua_tointeger(L,2));
{$endif}
result:=0;
end;
function _lua_compile(L: Plua_State; isfile: boolean): integer; cdecl;
var
s: string;
a: ptruint=0;
bytes: tmemorystream=nil;
symbollist: TStringlist=nil;
errorlog: tstringlist=nil;
bw: size_t;
targetself: boolean;
ph: THandle;
i: integer;
list: TStringlist=nil;
count: integer;
useKernelAlloc: boolean;
NoDebug: boolean;
ln: TSourceCodeInfo;
tr: TTCCRegionList;
oldprotect: dword;
mbi: TMEMORYBASICINFORMATION;
begin
{$ifdef darwin}
outputdebugstring('lua compile()');
{$endif}
if lua_gettop(L)>=1 then
begin
if lua_isstring(L,1) then
begin
s:=Lua_ToString(L,1);
end
else
if lua_istable(L,1) then
begin
list:=tstringlist.create;
count:=lua_objlen(L,1);
for i:=1 to count do
begin
lua_pushinteger(L,i);
lua_gettable(L,1);
list.add(Lua_ToString(L,-1));
lua_pop(L,1);
end;
end;
if (s='') and ((list=nil) or (list.count=0)) then
begin
lua_pushnil(L);
lua_pushstring(L,'Nothing to compile');
exit(2);
end;
if lua_gettop(L)>=2 then
a:=lua_toaddress(L,2)
else
a:=0;
if lua_gettop(L)>=3 then
targetself:=lua_toboolean(L,3)
else
targetself:=false;
if targetself then
ph:=GetCurrentProcess
else
ph:=processhandle;
if lua_gettop(L)>=4 then
useKernelAlloc:=lua_toboolean(L,4)
else
useKernelAlloc:=false;
if lua_gettop(L)>=5 then
NoDebug:=lua_toboolean(L,5)
else
NoDebug:=false;
bytes:=tmemorystream.Create;
errorlog:=tstringlist.create;
if isfile and (list=nil) then
begin
list:=tstringlist.create;
list.add(s);
end;
try
if a=0 then //allocate myself
begin
{$ifdef darwin}
outputdebugstring('testcompiling()');
{$endif}
//test compile to get the size
if ((list=nil) and (tcc.compileScript(s,$00400000,bytes,nil,nil,nil,errorlog,nil,targetself)=false)) or
((list<>nil) and (
((isfile=false) and (tcc.compileScripts(list,$00400000,bytes,nil,nil,nil,errorlog,targetself)=false) ) or
((isfile=true) and (tcc.compileProject(list,$00400000,bytes,nil,nil,nil,errorlog,targetself)=false) )
))
then
begin
lua_pop(L,lua_gettop(L));
lua_pushnil(L);
lua_pushstring(L, errorlog.Text);
if list<>nil then
freeandnil(list);
exit(2);
end;
{$ifdef darwin}
outputdebugstring('testcompile success');
{$endif}
{$ifdef windows}
if useKernelAlloc then
a:=ptruint(kernelalloc(bytes.size*2))
else
{$endif}
begin
if SystemSupportsWritableExecutableMemory then
begin
{$ifdef darwin}
outputdebugstring('allocating as RWX');
{$endif}
a:=ptruint(VirtualAllocEx(ph,nil, bytes.Size*2,MEM_RESERVE or MEM_COMMIT,PAGE_EXECUTE_READWRITE));
end
else
begin
{$ifdef darwin}
outputdebugstring('allocating as RW');
{$endif}
a:=ptruint(VirtualAllocEx(ph,nil, bytes.Size*2,MEM_RESERVE or MEM_COMMIT,PAGE_READWRITE));
{$ifdef darwin}
if VirtualQueryEx(ph, pointer(a),mbi,sizeof(mbi))=sizeof(mbi) then
begin
outputdebugstring('protect='+mbi.Protect.ToString+' ('+mbi.macProtect.ToString+')');
end
else
outputdebugstring('VirtualQueryEx failed');
{$endif}
end;
end;
if a=0 then
begin
lua_pop(L,lua_gettop(L));
lua_pushnil(L);
lua_pushstring(L, 'Allocation error. Failed to allocate '+inttostr(bytes.size)+' bytes of memory');
if list<>nil then
freeandnil(list);
exit(2);
end;
bytes.Clear;
errorlog.Clear;
end;
symbollist:=TStringlist.create;
//actual compile
if nodebug=false then
ln:=TSourceCodeInfo.create
else
ln:=nil;
tr:=TTCCRegionList.Create;
if ((list=nil) and (tcc.compileScript(s,a,bytes,symbollist,tr,ln,errorlog,nil,targetself)=false)) or
((list<>nil) and (
((isfile=false) and (tcc.compileScripts(list,a,bytes,symbollist,tr,ln,errorlog,targetself)=false) ) or
((isfile=true) and (tcc.compileProject(list,a,bytes,symbollist,tr,ln,errorlog,targetself)=false) )
)) then
begin
lua_pop(L,lua_gettop(L));
lua_pushnil(L);
lua_pushstring(L, errorlog.Text);
if list<>nil then
freeandnil(list);
if symbollist<>nil then
freeandnil(symbollist);
exit(2);
end;
if writeprocessmemory(ph,pointer(a),bytes.memory,bytes.size, bw) then
begin
lua_newtable(L);
for i:=0 to symbollist.count-1 do
begin
if ptruint(symbollist.objects[i])<a+bytes.size then
begin
lua_pushstring(L,symbollist[i]);
lua_pushinteger(L,ptruint(symbollist.objects[i]));
lua_settable(L,-3);
end;
end;
result:=1;
if errorlog.count>0 then
begin
lua_pushstring(L,errorlog.text);
result:=2;
end;
if not SystemSupportsWritableExecutableMemory then
begin
OutputDebugString('Setting protections accordingly');
for i:=0 to tr.Count-1 do
begin
OutputDebugString(format('%p : %d',[pointer(tr[i].address), tr[i].protection]));
virtualprotectex(processhandle, pointer(tr[i].address), tr[i].size, tr[i].protection, oldprotect);
end;
end;
end
else
begin
lua_pop(L,lua_gettop(L));
lua_pushnil(L);
lua_pushstring(L, 'Failure writing memory');
exit(2);
end;
finally
if symbollist<>nil then freeandnil(symbollist);
freeandnil(bytes);
freeandnil(errorlog);
end;
end;
end;
function lua_compile(L: Plua_State): integer; cdecl;
begin
exit(_lua_compile(L,false));
end;
function lua_compilefiles(L: Plua_State): integer; cdecl;
begin
exit(_lua_compile(L,true));
end;
function lua_addCIncludePath(L: Plua_State): integer; cdecl;
begin
result:=0;
if lua_gettop(L)>=1 then
tcc_addCIncludePath(Lua_ToString(L,1));
end;
function lua_removeCIncludePath(L: Plua_State): integer; cdecl;
begin
result:=0;
if lua_gettop(L)>=1 then
tcc_removeCIncludePath(Lua_ToString(L,1));
end;
function lua_compiletcclib(L: Plua_State): integer; cdecl;
var
libfile: string;
sname: string;
address: ptruint;
slist: TSymbolListHandler;
lowestAddress: ptruint=0;
highestAddress: ptruint=0;
begin
libfile:=CheatEngineDir+'tcclib'+PathDelim+'lib'+PathDelim+'libtcc1.c'; //release
if not fileexists(libfile) then
libfile:=CheatEngineDir+'..'+PathDelim+'tcclib'+PathDelim+'lib'+PathDelim+'libtcc1.c'; //development
if fileexists(libfile) then
begin
lua_settop(L,0);
lua_newtable(L);
lua_pushinteger(L,1);
lua_pushstring(L, libfile);
lua_settable(L,-3);
result:=lua_compilefiles(L);
if result>0 then
begin
if lua_istable(L,-1) then
begin
//succesful compilation, register the symbols
slist:=TSymbolListHandler.create;
slist.PID:=processhandler.processid;
slist.name:='TCC Library';
lua_pushnil(L); //first key (nil)
while lua_next(L, -2)<>0 do
begin
sname:=Lua_ToString(L,-2);
address:=lua_tointeger(L,-1);
if lowestAddress=0 then lowestAddress:=address else lowestAddress:=min(lowestaddress, address);
if highestAddress=0 then highestAddress:=address else highestAddress:=max(highestAddress, address);
try
slist.AddSymbol('tcclib',sname,address,1);
except
end;
lua_pop(L,1);
end;
slist.AddModule('tcc.lib',libfile,lowestAddress,highestAddress-lowestAddress, processhandler.is64Bit);
symhandler.AddSymbolList(slist);
lua_pushboolean(L, true);
exit(1);
end
else exit;
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'invalid compilation result');
exit(2);
end;
end
else
begin
lua_pushnil(L);
lua_pushstring(L, libfile+' could not be found');
exit(2);
end;
end;
function lua_dotNetExecuteClassMethod(L: Plua_State): integer; cdecl;
var
path: string;
namespace: string;
methodname: string;
classname: string;
parameters: string;
r: integer;
begin
//function DotNetExecuteClassMethod(assemblypath: string; namespace: string; classname: string; methodname: string; parameters: string): integer;
if lua_gettop(L)<5 then
begin
lua_pushnil(L);
lua_pushstring(L,'Incorrect parameter count (needed 5: path,namespace,classname,methodname, parameters)');
exit(2);
end;
path:=Lua_ToString(L,1);
namespace:=Lua_ToString(L,2);
classname:=Lua_ToString(L,3);
methodname:=Lua_ToString(L,4);
parameters:=Lua_ToString(L,5);
r:=DotNetExecuteClassMethod(path,namespace,classname,methodname, parameters);
lua_pushinteger(L,r);
result:=1;
end;
function lua_compilecs(L: Plua_State): integer; cdecl;
var
references: tstringlist;
script: string;
fn: string;
coreAssembly: string;
begin
try
if lua_gettop(L)<1 then raise exception.create('script parameter missing');
script:=Lua_ToString(L,1);
references:=tstringlist.create;
try
if lua_gettop(L)>1 then
begin
if lua_isstring(L,2) then //only one string
references.add(lua_tostring(L,2))
else
begin
//go through the whole list
lua_pushnil(L); //first key (nil)
while lua_next(L, 2)<>0 do
begin
references.add(Lua_ToString(L,-1));
lua_pop(L,1);
end;
end;
end;
if lua_gettop(L)>2 then
coreAssembly:=Lua_ToString(L,3)
else
coreAssembly:='';
fn:=compilecsharp(script, references, coreAssembly);
lua_pushstring(L,fn);
result:=1;
finally
references.free;
end;
except
on e: exception do
begin
lua_pushnil(L);
lua_pushstring(L,e.message);
exit(2);
end;
end;
end;
function lua_signExtend(L: Plua_State): integer; cdecl;
var
value: qword;
mostsignificantBit: integer;
begin
result:=0;
if lua_gettop(L)>=2 then
begin
value:=lua_tointeger(L,1);
mostsignificantBit:=lua_tointeger(L,2);
if (value shr mostSignificantBit)=1 then //needs to be sign extended
value:=value or ((qword($ffffffffffffffff) shl mostSignificantBit));
lua_pushinteger(L,value);
result:=1;
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'Incorrect paremeters: signExtend(value,mostSignificantBit)');
exit(2);
end;
end;
function lua_darkMode(L: Plua_State): integer; cdecl;
begin
result:=1;
lua_pushboolean(L, ShouldAppsUseDarkMode);
end;
function lua_getCEName(L: Plua_State): integer; cdecl;
begin
lua_pushstring(L, strCheatEngine);
exit(1);
end;
function lua_getTempFolder(L: Plua_State): integer; cdecl;
begin
lua_pushstring(L, GetTempDir);
exit(1);
end;
function lua_deleteFile(L: Plua_State): integer; cdecl;
var s: string;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
s:=Lua_ToString(L,1);
lua_pushboolean(L, DeleteFile(s));
exit(1);
end;
end;
function lua_fileExists(L: Plua_State): integer; cdecl;
var s: string;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
s:=Lua_ToString(L,1);
lua_pushboolean(L, FileExists(s) );
exit(1);
end;
end;
function lua_getNextReadablePageCR3(L: Plua_State): integer; cdecl;
var
cr3: qword;
address: qword;
newaddress: ptruint;
begin
result:=0;
{$ifdef windows}
if lua_gettop(L)>=2 then
begin
cr3:=lua_tointeger(L,1) and MAXPHYADDRMASKPB;
address:=lua_toaddress(L,2);
if GetNextReadablePageCR3(cr3, address, newaddress) then
begin
lua_pushinteger(L,newaddress);
result:=1;
end;
end;
{$endif}
end;
function lua_getPageInfoCR3(L: Plua_State): integer; cdecl;
var
cr3: qword;
address: qword;
mbi: TMEMORYBASICINFORMATION;
begin
result:=0;
{$ifdef windows}
if lua_gettop(L)>=2 then
begin
cr3:=lua_tointeger(L,1) and MAXPHYADDRMASKPB;
address:=lua_toaddress(L,2);
if GetPageInfoCR3(cr3,address,mbi) then
begin
lua_newtable(L);
lua_pushstring(L,'BaseAddress');
lua_pushinteger(L,ptruint(mbi.BaseAddress));
lua_settable(L,-3);
lua_pushstring(L,'RegionSize');
lua_pushinteger(L,mbi.RegionSize);
lua_settable(L,-3);
lua_pushstring(L,'Protect');
lua_pushinteger(L,mbi.Protect);
lua_settable(L,-3);
result:=1;
end;
end;
{$endif}
end;
function lua_growMemoryRegion(L: Plua_State): integer; cdecl;
//Not very useful at the moment.
var
address: qword;
paddress: pointer;
newsize: integer;
mbi, mbi2: TMemoryBasicInformation;
mem: pointer;
bc: size_t;
p: dword;
r: boolean;
begin
{$ifdef windows}
if processid=GetCurrentProcessId then
begin
lua_pushnil(L);
lua_pushstring(L,'Can''t grow memoryregions inside myself');
exit(2);
end;
result:=0;
if lua_Gettop(L)>=2 then
begin
address:=lua_toaddress(L,1);
newsize:=lua_tointeger(L,2);
ntsuspendProcess(processhandle);
try
if virtualqueryex(processhandle, pointer(address), mbi, sizeof(mbi))=sizeof(mbi) then
begin
if mbi._Type<>MEM_PRIVATE then
begin
lua_pushnil(L);
lua_pushstring(L,'Can only resize private type memory');
exit(2);
end;
if mbi.State<>MEM_COMMIT then
begin
lua_pushnil(L);
lua_pushstring(L,'Must be commited memory');
exit(2);
end;
if mbi.RegionSize>newsize then
begin
lua_pushnil(L);
lua_pushstring(L,'New size is smaller than the given region');
exit(2);
end;
if (ptruint(mbi.BaseAddress) and qword(not qword($fff)))<>ptruint(mbi.AllocationBase) then
begin
lua_pushnil(L);
lua_pushstring(L,'Can only resize a standalone memoryregion');
exit(2);
end;
if virtualqueryex(processhandle, pointer(address+mbi.RegionSize), mbi2, sizeof(mbi2))<>sizeof(mbi2) then
begin
lua_pushnil(L);
lua_pushstring(L,'Failure obtaining subsequent memoryregion info');
exit(2);
end;
if mbi2.State<>MEM_FREE then
begin
lua_pushnil(L);
lua_pushstring(L,'Failure growing the region as the next region is not free');
exit(2);
end;
mem:=getmem(newsize);
ZeroMemory(mem,newsize);
try
r:=ReadProcessMemory(processhandle, pointer(mbi.BaseAddress), mem, mbi.RegionSize,bc);
if (not r) or (bc<>mbi.RegionSize) then
begin
lua_pushnil(L);
lua_pushstring(L,'Failure reading original memory');
exit(2);
end;
if VirtualFreeEx(processhandle, mbi.BaseAddress, 0, MEM_RELEASE)=false then
begin
lua_pushnil(L);
lua_pushstring(L,'Failure releasing the original memoryregion');
exit(2);
end;
paddress:=VirtualAllocEx(processhandle,mbi.BaseAddress,newsize,MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (paddress=nil) or (paddress<>mbi.BaseAddress) then
begin
//fuuuuuuuuuuuuuu
errorbeep;
//try to restore it...
paddress:=VirtualAllocEx(processhandle,mbi.BaseAddress,mbi.RegionSize,MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (paddress=nil) or (paddress<>mbi.BaseAddress) then
begin
//double fuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
errorbeep;
errorbeep;
lua_pushnil(L);
lua_pushstring(L,'Failure allocating memory at the original region. Failed to restore original allocation. ALL DATA LOST, EXPECT MEMORY ERRORS!');
exit(2);
end;
//managed to restore the original memory
if WriteProcessMemory(processhandle, mbi.BaseAddress,mem,mbi.RegionSize,bc)=false then
begin
lua_pushnil(L);
lua_pushstring(L,'Failure allocating memory at the original region. Restoration of data failed. ALL DATA LOST!');
exit(2);
end;
VirtualProtectEx(processhandle, mbi.BaseAddress, mbi.RegionSize, mbi.Protect,p);
lua_pushnil(L);
lua_pushstring(L,'Failure allocating memory at the original region. No data lost');
exit(2);
end;
r:=WriteProcessMemory(processhandle, mbi.BaseAddress,mem,newsize,bc);
if (r=false) or (bc<>newsize) then
begin
lua_pushnil(L);
lua_pushstring(L,'Failure restoring data in reallocated block. ALL DATA LOST!');
exit(2);
end;
lua_pushinteger(L,ptruint(mbi.BaseAddress)+mbi.RegionSize);
exit(1);
finally
freemem(mem);
end;
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'Failure obtaining target memory information');
exit(2);
end;
finally
ntResumeProcess(processhandle);
end
end;
{$else}
exit(0);
{$endif}
end;
function lua_getGlobalVariable(L: Plua_State):integer; cdecl;
var s: string;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
s:=Lua_ToString(L,1);
lua_getglobal(LuaVM, pchar(s));
result:=1;
case lua_type(LuaVM,-1) of
LUA_TNIL: lua_pushnil(L);
LUA_TBOOLEAN: lua_pushboolean(L, lua_toboolean(LuaVM,-1));
LUA_TLIGHTUSERDATA: lua_pushlightuserdata(L, lua_ToCEUserData(LuaVM,-1));
LUA_TNUMBER: lua_pushnumber(L, lua_tonumber(LuaVM,-1));
LUA_TSTRING: lua_pushstring(L, Lua_ToString(LuaVM,-1));
LUA_TUSERDATA: lua_pushlightuserdata(L, lua_touserdata(LuaVM,-1));
else
result:=0;
end;
lua_pop(LuaVM,1);
end;
end;
function lua_setGlobalVariable(L: Plua_State):integer; cdecl;
var s: string;
begin
result:=0;
if lua_gettop(L)>=2 then
begin
s:=Lua_ToString(L,1);
case lua_type(L,2) of
LUA_TNIL: lua_pushnil(LuaVM);
LUA_TBOOLEAN: lua_pushboolean(LuaVM, lua_toboolean(L,-1));
LUA_TLIGHTUSERDATA: lua_pushlightuserdata(L, lua_ToCEUserData(LuaVM,-1));
LUA_TNUMBER: lua_pushnumber(LuaVM, lua_tonumber(L,-1));
LUA_TSTRING: lua_pushstring(LuaVM, Lua_ToString(L,-1));
LUA_TUSERDATA: lua_pushlightuserdata(LuaVM, lua_touserdata(L,-1));
else exit(0);
end;
lua_setglobal(LuaVM, pchar(s));
lua_pushboolean(L,true);
exit(1);
end;
end;
function lua_releaseDebugFiles(L: Plua_State):integer; cdecl;
begin
symhandler.StopSymbolLoaderThread;
exit(0);
end;
function lua_enumRegisteredSymbols(L: Plua_State):integer; cdecl;
var
list: TUserdefinedSymbolsList;
s: integer;
i: integer;
begin
list:=[];
symhandler.EnumerateUserdefinedSymbols(list);
lua_createtable(L,length(list),0);
for i:=0 to length(list)-1 do
begin
s:=2;
if list[i].allocsize>0 then inc(s,2);
if list[i].doNotSave then inc(s);
lua_pushinteger(L,i+1);
lua_createtable(L,0,s);
lua_pushstring(L,'symbolname');
lua_pushstring(L,list[i].symbolname);
lua_settable(L,-3);
lua_pushstring(L,'address');
lua_pushinteger(L,list[i].address);
lua_settable(L,-3);
if list[i].allocsize>0 then
begin
lua_pushstring(L,'allocsize');
lua_pushinteger(L,list[i].allocsize);
lua_settable(L,-3);
lua_pushstring(L,'processid');
lua_pushinteger(L,list[i].processid);
lua_settable(L,-3);
end;
if list[i].doNotSave then
begin
lua_pushstring(L,'donotsave');
lua_pushboolean(L,list[i].donotsave);
lua_settable(L,-3);
end;
lua_settable(L,-3);
end;
result:=1;
end;
function lua_deleteAllUserdefinedSymbols(L: Plua_State):integer; cdecl;
begin
symhandler.deleteAllUserdefinedSymbols;
exit(0);
end;
function lua_loadCEServerExtension(L: Plua_State):integer; cdecl;
var c: TCEconnection;
begin
c:=getConnection;
if c<>nil then
begin
if processhandle<>0 then
begin
lua_pushboolean(L, c.loadExtension(processhandle));
exit(1);
end
else
begin
lua_pushboolean(L,false);
lua_pushstring(L,'No process open');
exit(2);
end;
end
else
begin
lua_pushboolean(L,false);
lua_pushstring(L,'Not connected');
exit(2);
end;
end;
function lua_isConnectedToCEServer(L: Plua_State):integer; cdecl;
begin
lua_pushboolean(L,getConnection<>nil);
result:=1;
end;
function lua_getCEServerPath(L: Plua_State):integer; cdecl;
begin
if getconnection<>nil then
lua_pushstring(L, getconnection.getServerPath)
else
lua_pushnil(L);
result:=1;
end;
{$ifdef darwin}
function lua_createMachThread(L: Plua_State):integer; cdecl;
var
address: qword;
createdThread: thread_act_t;
ca64: TARM64CONTEXT;
stack: pointer;
i: integer;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
address:=lua_tointeger(L,1);
stack:=VirtualAllocEx(processhandle,nil,64*1024,MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
if stack=nil then
begin
lua_pushnil(L);
lua_pushstring(L,'stack creation failure');
exit(2);
end;
if macport.thread_create(processhandle, createdThread)=0 then
begin
//createdThread is an unintialized thread, init it
//c.ContextFlags:=CONTEXT_ALL;
//GetThreadContext(createdThread, c);
if processhandler.SystemArchitecture=archArm then
begin
ca64.ContextFlags:=MACAARCH64_CONTEXT_ALL;
macport.GetThreadContextArm64(createdThread,ca64);
ca64.SP:=ptruint(stack)+64*1024-1;
ca64.SP:=ca64.SP and $ffffffffffffff80; //128 bit alignment
ca64.PC:=address;
macport.SetThreadContextArm64(createdThread, ca64);
i:=ResumeThread(createdThread);
lua_pushinteger(L,i);
lua_pushinteger(L, createdThread);
exit(2);
end
else
begin
//x86.
end;
end
else
begin
lua_pushnil(L);
lua_pushstring(L,'thread_create failure');
exit(2);
end;
end;
end;
{$endif}
function lua_InvertColor(L: Plua_State):integer; cdecl;
begin
result:=0;
if lua_gettop(L)>=1 then
begin
lua_pushinteger(L, InvertColor(lua_tointeger(L,1)));
result:=1;
end;
end;
function lua_convertToUTF8(L: Plua_State):integer; cdecl;
var
s: rawbytestring;
b: pbytearray;
p: pchar;
size: size_t;
cp: TSystemCodePage;
begin
result:=0;
if lua_gettop(L)>=2 then
begin
if lua_istable(L,1) then
begin
//aob
size:=lua_objlen(L, 2);
getmem(b, size+1);
readBytesFromTable(L,1,b,size);
b[size]:=0;
setlength(s,size);
copymemory(@s[1],b,size);
freemem(b);
end
else
begin
p:=lua_tolstring(L,1,@size);
setlength(s,size);
copymemory(@s[1],b,size);
end;
cp:=lua_tointeger(L,2);
SetCodePage(s,cp,false);
SetCodePage(s,CP_UTF8,true);
lua_pushstring(L,s);
end;
end;
function lua_syncSymbolsNow(L: Plua_State): integer; cdecl;
var retrieveOnly: boolean;
begin
if lua_gettop(L)>=1 then
retrieveOnly:=lua_toboolean(L,1)
else
retrieveOnly:=false;
syncSymbolsNow(retrieveOnly);
result:=0;
end;
function lua_setThreadSafetyCheck(L: Plua_State): integer; cdecl;
begin
if lua_gettop(L)>=1 then
threadsafetycheck:=lua_toboolean(L,1);
result:=0;
end;
function lua_gdb_connected(L: Plua_State): integer; cdecl;
begin
result:=0;
if (CurrentDebuggerInterface<>nil) and (CurrentDebuggerInterface is TGDBServerDebuggerInterface) then
begin
lua_pushboolean(L, TGDBServerDebuggerInterface(CurrentDebuggerInterface).isConnected);
result:=1;
end
end;
function lua_gdb_stopped(L: Plua_State): integer; cdecl;
begin
result:=0;
if (CurrentDebuggerInterface<>nil) and (CurrentDebuggerInterface is TGDBServerDebuggerInterface) then
begin
lua_pushboolean(L, TGDBServerDebuggerInterface(CurrentDebuggerInterface).isStopped);
result:=1;
end;
end;
function lua_gdb_break(L: Plua_State): integer; cdecl;
begin
result:=0;
if (CurrentDebuggerInterface<>nil) and (CurrentDebuggerInterface is TGDBServerDebuggerInterface) then
begin
TGDBServerDebuggerInterface(CurrentDebuggerInterface).ObtainLock;
TGDBServerDebuggerInterface(CurrentDebuggerInterface).suspendProcess;
lua_pushboolean(L, true);
result:=2;
end;
end;
function lua_gdb_getCurrentInstructionpointer(L: Plua_State): integer; cdecl;
begin
result:=0;
if (CurrentDebuggerInterface<>nil) and (CurrentDebuggerInterface is TGDBServerDebuggerInterface) then
begin
lua_pushinteger(L, TGDBServerDebuggerInterface(CurrentDebuggerInterface).currentprogramcounter);
result:=1;
end;
end;
function lua_gdb_setCurrentInstructionpointer(L: Plua_State): integer; cdecl;
var a: ptruint;
begin
result:=0;
if (lua_gettop(L)>=1) and (CurrentDebuggerInterface<>nil) and (CurrentDebuggerInterface is TGDBServerDebuggerInterface) then
begin
a:=lua_toaddress(L, 1);
TGDBServerDebuggerInterface(CurrentDebuggerInterface).currentprogramcounter:=a;
end;
end;
function lua_gdb_resumefrombreak(L: Plua_State): integer; cdecl;
begin
result:=0;
if (CurrentDebuggerInterface<>nil) and (CurrentDebuggerInterface is TGDBServerDebuggerInterface) then
begin
TGDBServerDebuggerInterface(CurrentDebuggerInterface).resumeProcess;
TGDBServerDebuggerInterface(CurrentDebuggerInterface).ReleaseLock;
result:=1;
end;
end;
function lua_gdb_command(L: Plua_State): integer; cdecl;
var
s: string;
timeout: dword;
r: string;
begin
result:=0;
if (CurrentDebuggerInterface<>nil) and (CurrentDebuggerInterface is TGDBServerDebuggerInterface) then
begin
if lua_gettop(L)>=1 then
s:=Lua_ToString(L,1)
else
s:='';
if lua_gettop(L)>=2 then
timeout:=lua_tointeger(L,2)
else
timeout:=2000;
r:=TGDBServerDebuggerInterface(CurrentDebuggerInterface).debugPacket(s,timeout);
lua_pushstring(L, r);
result:=1;
end;
end;
function lua_gdb_getcurrentstopreason(L: Plua_State): integer; cdecl;
begin
result:=0;
if (CurrentDebuggerInterface<>nil) and (CurrentDebuggerInterface is TGDBServerDebuggerInterface) and TGDBServerDebuggerInterface(CurrentDebuggerInterface).isStopped then
begin
lua_pushstring(L, TGDBServerDebuggerInterface(CurrentDebuggerInterface).getCurrentStopPacket);
result:=1;
end;
end;
procedure InitLimitedLuastate(L: Plua_State);
begin
//don't put functioncallback events in here, as limited luastates can be destroyed
luaL_openlibs(L);
lua_register(L, 'print', print);
lua_register(L, 'sleep', lua_sleep);
lua_register(L, 'cheatEngineIs64Bit', cheatEngineIs64Bit);
lua_register(L, 'targetIs64Bit', targetIs64Bit);
lua_register(L, 'targetIsX86', targetIsX86);
lua_register(L, 'targetIsArm', targetIsArm);
lua_register(L, 'targetIsAndroid', targetIsAndroid);
{$ifdef darwin}
lua_register(L, 'targetIsRosetta', targetIsRosetta);
{$endif}
lua_register(L, 'getABI', getABI);
lua_register(L, 'readBytes', readbytes);
lua_register(L, 'writeBytes', writebytes);
lua_register(L, 'readByte', readShortInteger);
lua_register(L, 'readShortInteger', readShortInteger);
lua_register(L, 'readSmallInteger', readSmallInteger);
lua_register(L, 'readInteger', readInteger);
lua_register(L, 'readQword', readQword);
lua_register(L, 'readPointer', readPointer);
lua_register(L, 'readFloat', readFloat);
lua_register(L, 'readDouble', readDouble);
lua_register(L, 'readString', readString);
lua_register(L, 'readByteLocal', readShortIntegerLocal);
lua_register(L, 'readShortIntegerLocal', readShortIntegerLocal);
lua_register(L, 'readSmallIntegerLocal', readSmallIntegerLocal);
lua_register(L, 'readIntegerLocal', readIntegerLocal);
lua_register(L, 'readQwordLocal', readQwordLocal);
lua_register(L, 'readPointerLocal', readPointerLocal);
lua_register(L, 'readFloatLocal', readFloatLocal);
lua_register(L, 'readDoubleLocal', readDoubleLocal);
lua_register(L, 'readStringLocal', readStringLocal);
lua_register(L, 'writeShortInteger', writeShortInteger);
lua_register(L, 'writeByte', writeShortInteger);
lua_register(L, 'writeSmallInteger', writeSmallInteger);
lua_register(L, 'writeInteger', writeInteger);
lua_register(L, 'writeQword', writeQword);
lua_register(L, 'writePointer', writePointer);
lua_register(L, 'writeFloat', writeFloat);
lua_register(L, 'writeDouble', writeDouble);
lua_register(L, 'writeString', writeString);
lua_register(L, 'writeByteLocal', writeShortIntegerLocal);
lua_register(L, 'writeShortIntegerLocal', writeShortIntegerLocal);
lua_register(L, 'writeSmallIntegerLocal', writeSmallIntegerLocal);
lua_register(L, 'writeIntegerLocal', writeIntegerLocal);
lua_register(L, 'writeQwordLocal', writeQwordLocal);
lua_register(L, 'writePointerLocal', writePointerLocal);
lua_register(L, 'writeFloatLocal', writeFloatLocal);
lua_register(L, 'writeDoubleLocal', writeDoubleLocal);
lua_register(L, 'writeStringLocal', writeStringLocal);
lua_register(L, 'readBytesLocal', readbyteslocal);
lua_register(L, 'writeBytesLocal', writebyteslocal);
lua_register(L, 'getAddress', getAddress);
lua_register(L, 'getAddressSafe', getAddressSafe);
lua_register(L, 'getCurrentThreadID', lua_getCurrentThreadID);
lua_register(L, 'inMainThread', inMainThread);
lua_register(L, 'synchronize', lua_synchronize);
lua_register(L, 'queue', lua_queue);
lua_register(L, 'pause', pause);
lua_register(L, 'unpause', unpause);
lua_register(L, 'autoAssemble', autoAssemble_lua);
lua_register(L, 'autoAssembleCheck', AutoAssembleCheck_lua);
lua_register(L, 'assemble', lua_assemble);
lua_register(L, 'deAlloc', deAlloc_lua);
lua_register(L, 'deAllocLocal', deAllocLocal_lua);
lua_register(L, 'showMessage', showMessage_lua);
lua_register(L, 'inputQuery', inputQuery_lua);
lua_register(L, 'getPixel', getPixel);
lua_register(L, 'getMousePos', getMousePos);
lua_register(L, 'setMousePos', setMousePos);
lua_register(L, 'createTableEntry', createTableEntry);
lua_register(L, 'getTableEntry', getTableEntry);
lua_register(L, 'createSection',lua_createSection);
lua_register(L, 'mapViewOfSection',lua_MapViewOfSection);
lua_register(L, 'unMapViewOfSection', lua_unMapViewOfSection);
lua_register(L, 'getSystemMetrics', lua_getSystemMetrics);
lua_register(L, 'getScreenHeight', lua_getScreenHeight);
lua_register(L, 'getScreenWidth', lua_getScreenWidth);
lua_register(L, 'getScreenDPI', lua_getScreenDPI);
lua_register(L, 'getWorkAreaHeight', lua_getWorkAreaHeight);
lua_register(L, 'getWorkAreaWidth', lua_getWorkAreaWidth);
lua_register(L, 'getScreenCanvas', lua_getScreenCanvas);
lua_register(L, 'getHandleList', lua_getHandleList);
lua_register(L, 'closeRemoteHandle', lua_closeRemoteHandle);
lua_register(L, 'injectDLL', injectDLL);
lua_register(L, 'injectLibrary', injectDLL);
lua_register(L, 'getGlobalVariable', lua_getGlobalVariable);
lua_register(L, 'setGlobalVariable', lua_setGlobalVariable);
lua_register(L, 'loadPlugin', loadPlugin);
lua_register(L, 'getCEVersion', getCEVersion);
lua_register(L, 'utf8ToAnsi', lua_Utf8ToAnsi);
lua_register(L, 'UTF8ToAnsi', lua_Utf8ToAnsi);
lua_register(L, 'ansiToUtf8', lua_AnsiToUtf8);
lua_register(L, 'ansiToUTF8', lua_AnsiToUtf8);
lua_register(L, 'fullAccess', fullAccess);
lua_register(L, 'setMemoryProtection', lua_setMemoryProtection);
lua_register(L, 'waitForSections', waitForSections);
lua_register(L, 'waitForExports', waitForExports);
lua_register(L, 'waitForDotNet', waitForDotNet);
lua_register(L, 'waitForPDB', waitForPDB);
lua_register(L, 'waitforExports', waitForExports);
lua_register(L, 'waitforDotNet', waitForDotNet);
lua_register(L, 'waitforPDB', waitForPDB);
lua_register(L, 'searchPDBWhileLoading', searchPDBWhileLoading);
lua_register(L, 'reinitializeSymbolhandler', reinitializeSymbolhandler);
lua_register(L, 'reinitializeDotNetSymbolhandler', reinitializeDotNetSymbolhandler);
lua_register(L, 'reinitializeSelfSymbolhandler', reinitializeSelfSymbolhandler);
lua_register(L, 'enumModules', enumModules);
initializeLuaDisassembler(L);
initializeLuaCanvas(L);
lua_register(L, 'releaseDebugFiles', lua_releaseDebugFiles);
lua_register(L, 'enumRegisteredSymbols', lua_enumRegisteredSymbols);
lua_register(L, 'deleteAllRegisteredSymbols', lua_deleteAllUserdefinedSymbols);
lua_register(L, 'isConnectedToCEServer', lua_isConnectedToCEServer);
lua_register(L, 'getCEServerPath',lua_getCEServerPath);
lua_register(L, 'invertColor',lua_InvertColor);
lua_register(L, 'convertToUTF8',lua_convertToUTF8);
lua_register(L, 'syncSymbolsNow',lua_syncSymbolsNow);
lua_register(L, 'setThreadSafetyCheck', lua_setThreadSafetyCheck);
initializeLuaNetworkInterface(L);
{$ifdef darwin}
lua_register(L, 'createMachThread', lua_createMachThread);
{$endif}
end;
procedure InitializeLua;
var
s: tstringlist;
k32: THandle;
i: integer;
l: PLUA_STATE;
begin
{$ifdef darwin}
if assigned(luaL_newstate)=false then
begin
lua.initializeLua;
if assigned(luaL_newstate)=false then
begin
outputdebugstring('Invalid lua config');
exit;
end;
end;
{$endif}
if Thread_LuaVM<>nil then
Thread_LuaVM:=nil;
if _LuaVM<>nil then
_LuaVM:=nil;
_LuaVM:=lua_open();
L:=LUAVM;
if L<>nil then
begin
lua_atpanic(L, LuaPanic);
InitLimitedLuastate(L);
initializeLuaMemoryRecord;
lua_register(L, 'mouse_event', lua_mouse_event);
lua_register(L, 'isKeyPressed', isKeyPressed);
lua_register(L, 'keyDown', keyDown);
lua_register(L, 'keyUp', keyUp);
lua_register(L, 'doKeyPress', doKeyPress);
lua_register(L, 'getProcessIDFromProcessName', getProcessIDFromProcessName);
lua_register(L, 'openProcess', openProcess);
lua_register(L, 'debugProcess', debugProcess);
lua_register(L, 'debug_getBreakpointList', debug_getBreakpointList);
lua_register(L, 'debug_isDebugging', debug_isDebugging);
lua_register(L, 'debug_getCurrentDebuggerInterface', debug_getCurrentDebuggerInterface);
lua_register(L, 'debug_canBreak', debug_canBreak);
lua_register(L, 'debug_breakThread', debug_breakThread);
lua_register(L, 'debug_isBroken', debug_isBroken);
lua_register(L, 'debug_isStepping', debug_isStepping);
lua_register(L, 'debug_setBreakpoint', debug_setBreakpoint);
lua_register(L, 'debug_setBreakpointForThread', debug_setBreakpointForThread);
lua_register(L, 'debug_removeBreakpoint', debug_removeBreakpoint);
lua_register(L, 'debug_continueFromBreakpoint', debug_continueFromBreakpoint);
lua_register(L, 'debug_addThreadToNoBreakList', debug_addThreadToNoBreakList);
lua_register(L, 'debug_removeThreadFromNoBreakList', debug_removeThreadFromNoBreakList);
lua_register(L, 'debug_getContext', getDebugContext);
lua_register(L, 'debug_setContext', setDebugContext);
lua_register(L, 'debug_updateGUI', debug_updateGUI);
lua_register(L, 'getDebugContext', getDebugContext);
lua_register(L, 'setDebugContext', setDebugContext);
lua_register(L, 'closeCE', closeCE);
lua_register(L, 'hideAllCEWindows', hideAllCEWindows);
lua_register(L, 'unhideMainCEwindow', unhideMainCEwindow);
initializeLuaGroupbox;
lua_register(L, 'createLabel', createLabel);
lua_register(L, 'createSplitter', createSplitter);
lua_register(L, 'createPaintBox', createPaintBox);
lua_register(L, 'messageDialog', messageDialog);
lua_register(L, 'speedhack_setSpeed', speedhack_setSpeed);
lua_register(L, 'speedhack_getSpeed', speedhack_getSpeed);
lua_register(L, 'getAutoAttachList', getAutoAttachList);
lua_register(L, 'generateAPIHookScript', generateAPIHookScript_lua);
lua_register(L, 'createProcess', createProcess);
lua_register(L, 'AOBScan', AOBScan);
lua_register(L, 'AOBScanUnique', AOBScanUnique);
lua_register(L, 'AOBScanModuleUnique', AOBScanModuleUnique);
lua_register(L, 'getOpenedProcessID', getOpenedProcessID);
lua_register(L, 'getOpenedProcessHandle', getOpenedProcessHandle);
lua_register(L, 'getModuleSize', getModuleSize);
//ce6.1
lua_register(L, 'getNameFromAddress', getNameFromAddress);
lua_register(L, 'inModule', inModule);
lua_register(L, 'inSystemModule', inSystemModule);
lua_register(L, 'getCommonModuleList', getCommonModuleList);
initializeLuaImage;
initializeLuaRasterImage;
initializeLuaGenericHotkey;
initializeLuaObject;
InitializeLuaComponent;
InitializeLuaControl;
initializeLuaWinControl;
initializeLuaStrings;
initializeLuaStringlist;
initializeLuaForm;
initializeLuaPanel;
initializeLuaEdit;
initializeLuaMemo;
InitializeLuaButton;
lua_register(L, 'createToggleBox', createToggleBox);
initializeLuaCheckbox;
initializeLuaRadioGroup;
initializeLuaListbox;
initializeLuaCheckListbox;
initializeLuaCombobox;
initializeLuaProgressbar;
initializeLuaTrackbar;
initializeLuaListColumn;
initializeLuaCollection;
initializeLuaListColumns;
initializeLuaListItem;
initializeLuaListItems;
initializeLuaListview;
initializeLuaTreeview;
initializeLuaTimer;
lua_register(L, 'openDialog_execute', openDialog_execute);
lua_register(L, 'createOpenDialog', createOpenDialog);
lua_register(L, 'createSaveDialog', createSaveDialog);
lua_register(L, 'createSelectDirectoryDialog', createSelectDirectoryDialog);
lua_register(L, 'createMemoryStream', createMemoryStream);
lua_register(L, 'createFileStream', createFileStream);
lua_register(L, 'createStringStream', createStringStream);
Lua_register(L, 'getSettingsForm', getSettingsForm);
Lua_register(L, 'getMemoryViewForm', getMemoryViewForm);
Lua_register(L, 'getMainForm', getMainForm);
Lua_register(L, 'getAddressList', getAddressList);
Lua_register(L, 'getFreezeTimer', getFreezeTimer);
Lua_register(L, 'getUpdateTimer', getUpdateTimer);
lua_register(L, 'setGlobalKeyPollInterval', setGlobalKeyPollInterval);
lua_register(L, 'setGlobalDelayBetweenHotkeyActivation', setGlobalDelayBetweenHotkeyActivation);
initializeLuaMemoryview;
initializeLuaTableFile;
InitializeLuaXMPlayer;
Lua_register(L, 'writeRegionToFile', writeRegionToFile);
Lua_register(L, 'readRegionFromFile', readRegionFromFile);
Lua_register(L, 'registerSymbol', registersymbol);
Lua_register(L, 'unregisterSymbol', unregistersymbol);
Lua_register(L, 'getSymbolInfo', getSymbolInfo);
Lua_register(L, 'resetLuaState', resetLuaState);
Lua_register(L, 'reloadSettingsFromRegistry', reloadSettingsFromRegistry);
InitializeLuaCheatComponent;
initializeMemoryRecordHotkey;
InitializeLuaAddresslist;
Lua_register(L, 'createMemScan', createMemScan);
Lua_register(L, 'getCurrentMemscan', getCurrentMemscan);
InitializeMemscan;
InitializeFoundlist;
Lua_register(L, 'supportCheatEngine', supportCheatEngine);
Lua_register(L, 'fuckCheatEngine', fuckCheatEngine);
lua_register(L, 'inheritsFromObject', inheritsFromObject);
lua_register(L, 'inheritsFromComponent', inheritsFromComponent);
lua_register(L, 'inheritsFromControl', inheritsFromControl);
lua_register(L, 'inheritsFromWinControl', inheritsFromWinControl);
Lua_register(L, 'beep', beep);
lua_register(L, 'dbk_initialize', dbk_initialize);
lua_register(L, 'dbk_useKernelmodeOpenProcess', dbk_useKernelmodeOpenProcess);
lua_register(L, 'dbk_useKernelmodeProcessMemoryAccess', dbk_useKernelmodeProcessMemoryAccess);
lua_register(L, 'dbk_useKernelmodeQueryMemoryRegions', dbk_useKernelmodeQueryMemoryRegions);
lua_register(L, 'dbk_usePhysicalMemoryAccess', dbk_usePhysicalMemoryAccess);
lua_register(L, 'dbk_setSaferPhysicalMemoryScanning', dbk_setSaferPhysicalMemoryScanning);
lua_register(L ,'dbk_readPhysicalMemory', lua_dbk_readphysicalmemory);
lua_register(L ,'dbk_writePhysicalMemory', lua_dbk_writephysicalmemory);
lua_register(L, 'dbk_getPEProcess', dbk_getPEProcess);
lua_register(L, 'dbk_getPEThread', dbk_getPEThread);
lua_register(L, 'dbk_executeKernelMemory', dbk_executeKernelMemory);
lua_register(L, 'dbk_readMSR', dbk_readMSR);
lua_register(L, 'dbk_writeMSR', dbk_writeMSR);
lua_register(L, 'dbk_getCR0', dbk_getCR0);
lua_register(L, 'dbk_getCR3', dbk_getCR3);
lua_register(L, 'dbk_getCR4', dbk_getCR4);
lua_register(L, 'dbk_test', lua_dbk_test);
lua_register(L, 'dbvm_getCR0', dbvm_getCR0);
lua_register(L, 'dbvm_getCR3', dbvm_getCR3);
lua_register(L, 'dbvm_getCR4', dbvm_getCR4);
lua_register(L, 'dbvm_readMSR', lua_dbvm_readMSR);
lua_register(L, 'dbvm_writeMSR', lua_dbvm_writeMSR);
lua_register(L, 'dbvm_jtagbp', lua_dbvm_jtagbp);
lua_register(L ,'dbvm_readPhysicalMemory', lua_dbvm_readphysicalmemory);
lua_register(L ,'dbvm_writePhysicalMemory', lua_dbvm_writephysicalmemory);
lua_register(L ,'dbvm_psod', lua_dbvm_psod);
lua_register(L ,'dbvm_getNMIcount', lua_dbvm_getNMIcount);
lua_register(L, 'dbvm_get_statistics',lua_dbvm_get_statistics);
lua_register(L, 'dbvm_debug_setSpinlockTimeout', lua_dbvm_debug_setSpinlockTimeout);
lua_register(L, 'dbvm_watch_writes', lua_dbvm_watch_writes);
lua_register(L, 'dbvm_watch_reads', lua_dbvm_watch_reads);
lua_register(L, 'dbvm_watch_executes', lua_dbvm_watch_executes);
lua_register(L, 'dbvm_watch_retrievelog', lua_dbvm_watch_retrievelog);
lua_register(L, 'dbvm_watch_disable', lua_dbvm_watch_disable);
lua_register(L, 'dbvm_watch_getstatus', lua_dmvm_watch_getstatus);
lua_register(L, 'dbvm_cloak_activate', lua_dbvm_cloak_activate);
lua_register(L, 'dbvm_cloak_deactivate', lua_dbvm_cloak_deactivate);
lua_register(L, 'dbvm_cloak_readOriginal', lua_dbvm_cloak_readOriginal);
lua_register(L, 'dbvm_cloak_writeOriginal', lua_dbvm_cloak_writeOriginal);
lua_register(L, 'dbvm_changeregonbp', lua_dbvm_changeregonbp);
lua_register(L, 'dbvm_removechangeregonbp', lua_dbvm_removechangeregonbp);
lua_register(L, 'dbvm_traceonbp', lua_dbvm_traceonbp);
lua_register(L, 'dbvm_traceonbp_getstatus', lua_dbvm_traceonbp_getstatus);
lua_register(L, 'dbvm_traceonbp_stoptrace', lua_dbvm_traceonbp_stoptrace);
lua_register(L, 'dbvm_traceonbp_remove', lua_dbvm_traceonbp_remove);
lua_register(L, 'dbvm_traceonbp_retrievelog', lua_dbvm_traceonbp_retrievelog);
lua_register(L, 'dbvm_bp_getBrokenThreadListSize', lua_dbvm_bp_getBrokenThreadListSize);
lua_register(L, 'dbvm_bp_getBrokenThreadEventShort', lua_dbvm_bp_getBrokenThreadEventShort);
lua_register(L, 'dbvm_bp_getBrokenThreadEventFull', lua_dbvm_bp_getBrokenThreadEventFull);
lua_register(L, 'dbvm_bp_setBrokenThreadEventFull', lua_dbvm_bp_setBrokenThreadEventFull);
lua_register(L, 'dbvm_bp_resumeBrokenThread', lua_dbvm_bp_resumeBrokenThread);
lua_register(L, 'dbvm_bp_getProcessAndThreadIDFromEvent', lua_dbvm_bp_getProcessAndThreadIDFromEvent);
lua_register(L, 'dbvm_ept_reset', lua_dbvm_ept_reset);
lua_register(L, 'dbvm_log_cr3_start', lua_dbvm_log_cr3_start);
lua_register(L, 'dbvm_log_cr3_stop', lua_dbvm_log_cr3_stop);
lua_register(L, 'dbvm_registerPlugin', lua_dbvm_registerPlugin);
lua_register(L, 'dbvm_raisePMI', lua_dbvm_raisePMI); //mostly just for debugging
lua_register(L, 'dbvm_ultimap2_hideRangeUsage', lua_dbvm_ultimap2_hideRangeUsage); //same
lua_register(L, 'dbvm_ultimap_getDebugInfo', lua_dbvm_ultimap_getDebugInfo); //more debugging
lua_register(L, 'dbvm_setTSCAdjust', lua_dbvm_setTSCAdjust);
lua_register(L, 'dbvm_speedhack_setSpeed', lua_dbvm_speedhack_setSpeed);
lua_register(L, 'dbvm_enableTSCHook', lua_dbvm_enableTSCHook);
lua_register(L, 'dbvm_disableTSCHook', lua_dbvm_disableTSCHook);
lua_register(L, 'dbvm_findCR3', lua_dbvm_findCR3);
lua_register(L, 'dbvm_hidephysicalmemory', lua_dbvm_hidephysicalmemory);
lua_register(L, 'dbvm_hidephysicalmemoryall', lua_dbvm_hidephysicalmemoryall);
lua_register(L, 'getPageInfoCR3', lua_getPageInfoCR3);
lua_register(L, 'getNextReadablePageCR3', lua_getNextReadablePageCR3);
lua_register(L, 'dbk_getPhysicalAddress', dbk_getPhysicalAddress);
lua_register(L, 'dbk_writesIgnoreWriteProtection', dbk_writesIgnoreWriteProtection);
lua_register(L, 'getPhysicalAddressCR3', lua_getPhysicalAddressCR3);
lua_register(L, 'readProcessMemoryCR3', lua_readProcessMemoryCR3);
lua_register(L, 'writeProcessMemoryCR3', lua_writeProcessMemoryCR3);
lua_register(L, 'allocateSharedMemoryLocal', allocateSharedMemoryLocal);
lua_register(L, 'deallocateSharedMemoryLocal', deallocateSharedMemoryLocal);
lua_register(L, 'allocateSharedMemory', allocateSharedMemory);
lua_register(L, 'deallocateSharedMemory', deallocateSharedMemory);
lua_register(L, 'getCheatEngineDir', getCheatEngineDir);
lua_register(L, 'getCheatEngineProcessID', lua_getCheatEngineProcessID);
lua_register(L, 'disassemble', disassemble_lua);
lua_register(L, 'splitDisassembledString', splitDisassembledString);
lua_register(L, 'getInstructionSize', getInstructionSize);
lua_Register(L, 'getPreviousOpcode', getPreviousOpcode);
lua_Register(L, 'disassembleBytes', disassembleBytes);
initializegraphiccontrol;
lua_register(L, 'disassemblerview_getSelectedAddress', disassemblerview_getSelectedAddress);
lua_register(L, 'disassemblerview_setSelectedAddress', disassemblerview_setSelectedAddress);
lua_register(L, 'disassemblerview_onSelectionChange', disassemblerview_onSelectionChange);
lua_register(L, 'hexadecimalview_getTopAddress', hexadecimalview_getTopAddress);
lua_register(L, 'hexadecimalview_setTopAddress', hexadecimalview_setTopAddress);
lua_register(L, 'hexadecimalview_onAddressChange', hexadecimalview_onAddressChange);
lua_register(L, 'hexadecimalview_onByteSelect', hexadecimalview_onByteSelect);
lua_register(L, 'getForegroundProcess', getForegroundProcess);
lua_register(L, 'getFormCount', getFormCount);
lua_register(L, 'getForm', getForm);
lua_register(L, 'registerFormAddNotification', registerFormAddNotification);
Lua_Register(L, 'unregisterFormAddNotification', unregisterFormAddNotification);
lua_register(L, 'onAutoGuess', onAutoGuess);
lua_register(L, 'onAPIPointerChange', onAPIPointerChange);
lua_register(L, 'setAPIPointer', setAPIPointer);
lua_register(L, 'dbvm_initialize', dbvm_initialize);
lua_register(L, 'dbvm_setKeys', dbvm_setKeys);
lua_register(L, 'dbvm_getMemory', lua_dbvm_getMemory);
lua_register(L, 'dbvm_addMemory', dbvm_addMemory);
lua_register(L, 'shellExecute', lua_shellExecute);
lua_register(L, 'runCommand', lua_runCommand);
lua_register(L, 'getTickCount', getTickCount_lua);
lua_register(L, 'rdtsc', lua_rdtsc);
lua_register(L, 'processMessages', processMessages);
lua_register(L, 'integerToUserData', integerToUserData);
lua_register(L, 'userDataToInteger', userDataToInteger);
lua_register(L, 'writeToClipboard', writeToClipboard);
lua_register(L, 'readFromClipboard', readFromClipboard);
lua_register(L, 'createBitmap', createBitmap);
lua_register(L, 'createPNG', createPNG);
lua_register(L, 'createJpeg', createJpeg);
lua_register(L, 'createIcon', createIcon);
lua_register(L, 'errorOnLookupFailure', errorOnLookupFailure);
lua_register(L, 'waitforsymbols', lua_waitforsymbols);
lua_register(L, 'getWindowlist', getWindowList_lua);
lua_register(L, 'getWindowList', getWindowList_lua);
lua_register(L, 'getProcesslist', getProcessList_lua);
lua_register(L, 'getProcessList', getProcessList_lua);
lua_register(L, 'getThreadlist', getThreadlist_lua);
lua_register(L, 'getThreadList', getThreadlist_lua);
Lua_register(L, 'loadTable', lua_loadTable);
Lua_register(L, 'saveTable', lua_saveTable);
Lua_register(L, 'signTable', lua_signTable);
Lua_register(L, 'detachIfPossible', lua_DetachIfPossible);
Lua_register(L, 'getComment', getComment);
Lua_register(L, 'setComment', setComment);
Lua_register(L, 'getHeader', getHeader);
Lua_register(L, 'setHeader', setHeader);
lua_register(L, 'createClass', lua_createClass);
lua_register(L, 'createComponentClass', lua_createComponentClass);
lua_register(L, 'openLuaServer', openLuaServer);
lua_register(L, 'registerAutoAssemblerCommand', lua_registerAutoAssemblerCommand);
lua_register(L, 'unregisterAutoAssemblerCommand', lua_unregisterAutoAssemblerCommand);
lua_register(L, 'registerSymbolLookupCallback', lua_registerSymbolLookupCallback);
lua_register(L, 'unregisterSymbolLookupCallback', lua_unregisterSymbolLookupCallback);
lua_register(L, 'registerAddressLookupCallback', lua_registerAddressLookupCallback);
lua_register(L, 'unregisterAddressLookupCallback', lua_unregisterAddressLookupCallback);
lua_register(L, 'registerGlobalDisassembleOverride', lua_registerGlobalDisassembleOverride);
lua_register(L, 'unregisterGlobalDisassembleOverride', lua_unregisterGlobalDisassembleOverride);
lua_register(L, 'registerGlobalStructureListUpdateNotification', lua_registerGlobalStructureListUpdateNotification);
lua_register(L, 'unregisterGlobalStructureListUpdateNotification', lua_unregisterGlobalStructureListUpdateNotification);
lua_register(L, 'registerStructureDissectOverride', lua_registerStructureDissectOverride);
lua_register(L, 'unregisterStructureDissectOverride', lua_unregisterStructureDissectOverride);
lua_register(L, 'registerStructureNameLookup', lua_registerStructureNameLookup);
lua_register(L, 'unregisterStructureNameLookup', lua_unregisterStructureNameLookup);
lua_register(L, 'registerAssembler', lua_registerAssembler);
lua_register(L, 'unregisterAssembler', lua_unregisterAssembler);
lua_register(L, 'registerAutoAssemblerPrologue', lua_registerAutoAssemblerPrologue);
lua_register(L, 'unregisterAutoAssemblerPrologue', lua_unregisterAutoAssemblerPrologue);
lua_register(L, 'registerStructureAndElementListCallback', lua_registerStructureAndElementListCallback);
lua_register(L, 'unregisterStructureAndElementListCallback', lua_unregisterStructureAndElementListCallback);
lua_register(L, 'registerSpeedhackCallbacks', lua_registerSpeedhackCallbacks);
lua_register(L, 'unregisterSpeedhackCallbacks', lua_unregisterSpeedhackCallbacks);
lua_register(L, 'shortCutToText', lua_shortCutToText);
lua_register(L, 'textToShortCut', lua_textToShortCut);
lua_register(L, 'checkSynchronize', lua_checkSynchronize);
lua_register(L, 'playSound', lua_playSound);
lua_register(L, 'outputDebugString', lua_outputDebugString);
lua_register(L, 'broadcastEnvironmentUpdate', broadcastEnvironmentUpdate);
lua_register(L, 'getUserRegistryEnvironmentVariable', getUserRegistryEnvironmentVariable);
lua_register(L, 'setUserRegistryEnvironmentVariable', setUserRegistryEnvironmentVariable);
lua_register(L, 'createRef', createRef);
lua_register(L, 'getRef', getRef);
lua_register(L, 'destroyRef', destroyRef);
lua_register(L, 'activateProtection', activateProtection);
lua_register(L, 'getLuaEngine', getLuaEngine);
lua_register(L, 'createLuaEngine', createLuaEngine);
lua_register(L, 'getApplication', getApplication);
lua_Register(L, 'stringToMD5String', lua_stringToMD5String);
lua_register(L, 'convertKeyComboToString', lua_ConvertKeyComboToString);
lua_register(L, 'restoreSeDebugPrivilege', restoreSeDebugPrivilege);
lua_register(L, 'translate', lua_translate);
lua_register(L, 'translateID', lua_translateid);
lua_register(L, 'loadPOFile', lua_loadPOFile);
lua_register(L, 'getTranslationFolder', lua_getTranslationFolder);
lua_register(L, 'registerBinUtil', lua_registerBinUtil);
lua_register(L, 'setPointerSize', setPointerSize);
lua_register(L, 'getPointerSize', getPointerSize);
lua_register(L, 'executeCode', executeCode);
lua_register(L, 'executeCodeEx', executeCodeEx);
lua_register(L, 'executeMethod', executeMethod);
lua_register(L, 'createExecuteMethodStub', createExecuteMethodStub);
lua_register(L, 'createExecuteCodeExStub', createExecuteCodeExStub);
lua_register(L, 'executeCodeLocal', executeCodeLocal);
lua_register(L, 'executeCodeLocalEx', executeCodeLocalEx);
lua_register(L, 'md5file', md5file);
lua_register(L, 'md5memory', md5memory);
lua_register(L, 'allocateKernelMemory', allocateKernelMemory);
lua_register(L, 'freeKernelMemory', freeKernelMemory);
lua_register(L, 'mapMemory', lua_mapMemory);
lua_register(L, 'unmapMemory', lua_unmapMemory);
lua_register(L, 'lockMemory', lua_lockMemory);
lua_register(L, 'unlockMemory', lua_unlockMemory);
lua_register(L, 'sendMessage', lua_sendMessage);
lua_register(L, 'sendMessageTimeout', lua_sendMessageTimeout);
lua_register(L, 'findWindow', lua_findWindow);
lua_register(L, 'getWindow', lua_getWindow);
lua_register(L, 'getWindowProcessID', lua_getWindowProcessID);
lua_register(L, 'getWindowCaption', lua_getWindowCaption);
lua_register(L, 'getWindowClassName', lua_getWindowClassName);
lua_register(L, 'getForegroundWindow', lua_getForegroundWindow);
lua_register(L, 'getXBox360ControllerKeyPress', getXBox360ControllerKeyPress);
lua_register(L, 'getXBox360ControllerState', getXBox360ControllerState);
lua_register(L, 'setXBox360ControllerVibration', setXBox360ControllerVibration);
lua_register(L, 'registerAutoAssemblerTemplate', lua_registerAutoAssemblerTemplate);
lua_register(L, 'unregisterAutoAssemblerTemplate', lua_unregisterAutoAssemblerTemplate);
lua_register(L, 'getUniqueAOB', lua_getUniqueAOB);
lua_register(L, 'addSnapshotAsComment',lua_addSnapshotAsComment);
lua_register(L, 'getNextAllocNumber',lua_getNextAllocNumber);
lua_register(L, 'generateCodeInjectionScript', lua_GenerateCodeInjectionScript);
lua_register(L, 'generateAOBInjectionScript', lua_GenerateAOBInjectionScript);
lua_register(L, 'generateFullInjectionScript', lua_GenerateFullInjectionScript);
lua_register(L, 'loadFontFromStream', lua_loadFontFromStream);
lua_register(L, 'unloadLoadedFont', lua_unloadLoadedFont);
lua_register(L, 'speak', lua_speak);
lua_register(L, 'speakEnglish', lua_speakEnglish);
lua_register(L, 'getFileVersion', lua_getFileVersion);
lua_register(L, 'getCheatEngineFileVersion', lua_getCheatEngineFileVersion);
lua_register(L, 'hookWndProc', lua_hookWndProc);
lua_register(L, 'unhookWndProc', lua_unhookWndProc);
lua_register(L, 'registerEXETrainerFeature', lua_registerEXETrainerFeature);
lua_register(L, 'unregisterEXETrainerFeature', lua_unregisterEXETrainerFeature);
lua_register(L, 'encodeFunction', lua_encodefunction);
lua_register(L, 'decodeFunction', lua_decodeFunction);
lua_register(L, 'encodeFunctionEx', lua_encodefunctionEx);
lua_register(L, 'getFileList', lua_getFileList);
lua_register(L, 'getDirectoryList', lua_getDirectoryList);
lua_register(L, 'connectToCEServer', lua_connectToCEServer);
lua_register(L, 'copyMemory', lua_copyMemory);
lua_register(L, 'enableDRM', lua_enableDRM);
lua_register(L, 'openFileAsProcess', lua_openFileAsProcess);
lua_register(L, 'getOpenedFileSize', lua_getOpenedFileSize);
lua_register(L, 'saveOpenedFile', lua_saveOpenedFile);
lua_register(L, 'getPEB', lua_getPEB);
lua_register(L, 'createAPC', lua_createAPC);
lua_register(L, 'setAssemblerMode', lua_setAssemblerMode);
lua_register(L, 'allocateMemory', lua_allocateMemory);
lua_register(L, 'try', lua_try);
lua_register(L, 'showSelectionList', lua_showSelectionList);
lua_register(L, 'cpuid', lua_cpuid);
lua_register(L, 'gc_setPassive', lua_gc_setPassive);
lua_register(L, 'gc_setActivate', lua_gc_setPassive);
lua_register(L, 'gc_setActive', lua_gc_setPassive);
lua_register(L, 'getHotkeyHandlerThread', lua_getHotkeyHandlerThread);
lua_register(L, 'enumMemoryRegions', lua_enumMemoryRegions);
lua_register(L, 'enumMemoryRegionsCR3', lua_enumMemoryRegionsCR3);
lua_register(L, 'setForceCR3VirtualQueryEx', lua_setForceCR3VirtualQueryEx);
lua_register(L, 'enableWindowsSymbols', lua_enableWindowsSymbols);
lua_register(L, 'enableKernelSymbols', lua_enableKernelSymbols);
lua_register(L, 'compareMemory', lua_compareMemory);
lua_register(L, 'enumExports', lua_enumExports);
lua_register(L, 'duplicateHandle', lua_duplicateHandle);
lua_register(L, 'getOperatingSystem', lua_getOperatingSystem);
lua_register(L, 'createColorDialog', lua_createColorDialog);
lua_register(L, 'createColorBox', lua_createColorBox);
lua_register(L, 'createAutoAssemblerForm', lua_createAutoAssemblerForm);
lua_register(L, 'getRTTIClassName', lua_getRTTIClassName);
lua_register(L, 'getAutoRunPath', lua_getAutoRunPath);
lua_register(L, 'getAutorunPath', lua_getAutoRunPath);
lua_register(L, 'extractFileName', lua_extractFileName);
lua_register(L, 'extractFileExt', lua_extractFileExt);
lua_register(L, 'extractFileNameWithoutExt', lua_extractFileNameWithoutExt);
lua_register(L, 'extractFilePath', lua_extractFilePath);
lua_register(L, 'registerLuaFunctionHighlight', lua_registerLuaFunctionHighlight);
lua_register(L, 'unregisterLuaFunctionHighlight', lua_unregisterLuaFunctionHighlight);
lua_register(L, 'setProgressState', lua_SetProgressState);
lua_register(L, 'setProgressValue', lua_SetProgressValue );
lua_register(L, 'compile', lua_compile);
lua_register(L, 'compileFiles', lua_compilefiles);
lua_register(L, 'compileTCCLib', lua_compiletcclib);
lua_register(L, 'addCIncludePath', lua_addCIncludePath);
lua_register(L, 'removeCIncludePath', lua_removeCIncludePath);
lua_register(L, 'dotNetExecuteClassMethod', lua_dotNetExecuteClassMethod);
lua_register(L, 'compileCS', lua_compilecs);
lua_register(L, 'compileCSharp', lua_compilecs);
lua_register(L, 'compilecsharp', lua_compilecs);
lua_register(L, 'signExtend', lua_signExtend);
lua_register(L, 'darkMode', lua_darkMode);
lua_register(L, 'getCEName', lua_getCEName);
lua_register(L, 'getTempFolder', lua_getTempFolder);
lua_register(L, 'fileExists', lua_fileExists);
lua_register(L, 'deleteFile', lua_deleteFile);
lua_register(L, 'growMemoryRegion', lua_growMemoryRegion);
lua_register(L, 'loadCEServerExtension', lua_loadCEServerExtension);
lua_register(L, 'gdb_connected', lua_gdb_connected);
lua_register(L, 'gdb_stopped', lua_gdb_stopped);
lua_register(L, 'gdb_break', lua_gdb_break);
lua_register(L, 'gdb_resumefrombreak', lua_gdb_resumefrombreak);
lua_register(L, 'gdb_command', lua_gdb_command);
lua_register(L, 'gdb_getcurrentstopreaon', lua_gdb_getcurrentstopreason);
lua_register(L, 'gdb_setCurrentInstructionPointer', lua_gdb_setCurrentInstructionPointer);
lua_register(L, 'gdb_getCurrentInstructionPointer', lua_gdb_getCurrentInstructionPointer);
initializeLuaRemoteThread;
initializeLuaCustomControl;
initializeLuaPicture;
initializeLuaPen;
initializeLuaBrush;
initializeLuaFont;
initializeLuaMenu;
initializeLuaDebug; //eventually I should add a LuaLuaDebug...
initializeLuaThread;
initializeLuaGraphic;
initializeLuaOldD3DHook;
initializeLuaD3DHook;
initializeLuaStructure;
initializeLuaRegion;
initializeLuaDisassembler(L);
initializeLuaDissectCode;
initializeLuaByteTable;
initializeLuaBinary;
initializeLuaPipeClient;
{$IFDEF windows}
initializeLuaPipeServer;
{$ENDIF}
initializeLuaSymbolListHandler;
initializeLuaFindDialog;
initializeLuaSettings;
initializeLuaPageControl;
initializeLuaCalendar;
initializeLuaRipRelativeScanner;
initializeLuaStructureFrm;
initializeLuaInternet;
initializeLuaCustomType;
initializeLuaSQL;
{$IFDEF windows}
initializeLuaModuleLoader;
{$ENDIF}
initializeLuaPointerValueList;
initializeLuaWriteLog;
initializeLuaDiagram;
initializeLuaUltimap2;
initializeLuaCodeFilter;
initializeLuaSynEdit;
initializeLuaCustomImageList;
initializeLuaDotNetPipe;
InitializeLuaRemoteExecutor;
initializeLuaCECustomButton;
initializeLuaVirtualStringTree;
s:=tstringlist.create;
try
//ce 6.0 compatibility. 6.0 has these methods in the stringlist instead of the strings class
s.add('package.path = package.path .. ";?.lua";');
{$ifdef darwin}
s.add('package.path = package.path .. [[;'+getcedir+'?.lua]]');
s.add('package.path = package.path .. [[;'+extractfiledir(extractfiledir(application.exename))+'/Lua/?.lua]]');
{$endif}
{$ifdef cpu64}
s.add('package.cpath = package.cpath .. [[;'+getcedir+'clibs64'+pathdelim+'?'+{$ifdef windows}'.dll'{$endif}{$ifdef darwin}'.dylib'{$endif}+']]');
s.add('package.cpath = package.cpath .. [[;.'+pathdelim+'clibs64'+pathdelim+'?'+{$ifdef windows}'.dll'{$endif}{$ifdef darwin}'.dylib'{$endif}+']]');
{$else}
s.add('package.cpath = package.cpath .. [[;'+getcedir+'clibs32'+pathdelim+'?'+{$ifdef windows}'.dll'{$endif}{$ifdef darwin}'.dylib'{$endif}+']]');
s.add('package.cpath = package.cpath .. [[;.'+pathdelim+'clibs32'+pathdelim+'?'+{$ifdef windows}'.dll'{$endif}{$ifdef darwin}'.dylib'{$endif}+']]');
{$endif}
s.add('stringlist_getCount=strings_getCount');
s.add('stringlist_getString=strings_getString');
s.add('stringlist_add=strings_add');
s.add('stringlist_remove=strings_remove');
//same for the rename of memrec to memoryrecord
s.add('memrec_setDescription = memoryrecord_setDescription');
s.add('memrec_getDescription = memoryrecord_getDescription');
s.add('memrec_getAddress = memoryrecord_getAddress');
s.add('memrec_setAddress = memoryrecord_setAddress');
s.add('memrec_getType = memoryrecord_getType');
s.add('memrec_setType = memoryrecord_setType');
s.add('memrec_getValue = memoryrecord_getValue');
s.add('memrec_setValue = memoryrecord_setValue');
s.add('memrec_getScript = memoryrecord_getScript');
s.add('memrec_isActive = memoryrecord_isActive');
s.add('memrec_freeze = memoryrecord_freeze');
s.add('memrec_unfreeze = memoryrecord_unfreeze');
s.add('memrec_setColor = memoryrecord_setColor');
s.add('memrec_appendToEntry = memoryrecord_appendToEntry');
s.add('memrec_delete = memoryrecord_delete');
s.add('getAddressFromName = getAddress');
//timer onInterval has been renamed to timer onTimer
s.add('timer_onInterval = timer_onTimer');
{$ifdef windows}
k32:=loadlibrary('kernel32.dll');
s.add('windows_OpenProcess=0x'+inttohex(ptruint(getProcAddress(k32, 'OpenProcess')),8));
s.add('windows_ReadProcessMemory=0x'+inttohex(ptruint(getProcAddress(k32, 'ReadProcessMemory')),8));
s.add('windows_WriteProcessMemory=0x'+inttohex(ptruint(getProcAddress(k32, 'WriteProcessMemory')),8));
s.add('windows_VirtualQueryEx=0x'+inttohex(ptruint(getProcAddress(k32, 'VirtualQueryEx')),8));
s.add('dbk_OpenProcess=0x'+inttohex(ptruint(@DBK32functions.OP),8));
s.add('dbk_NtOpenProcess=0x'+inttohex(ptruint(@DBK32functions.NOP),8));
s.add('dbk_ReadProcessMemory=0x'+inttohex(ptruint(@DBK32functions.RPM),8));
s.add('dbk_WriteProcessMemory=0x'+inttohex(ptruint(@DBK32functions.WPM),8));
s.add('dbk_VirtualQueryEx=0x'+inttohex(ptruint(@DBK32functions.VQE),8));
s.add('dbk_ReadPhysicalMemory=0x'+inttohex(ptruint(@DBK32functions.ReadPhysicalMemory),8));
s.add('dbk_WritePhysicalMemory=0x'+inttohex(ptruint(@DBK32functions.WritePhysicalMemory),8));
s.add('VirtualQueryExPhysical=0x'+inttohex(ptruint(@VirtualQueryExPhysical),8));
s.add('dbvm_ReadPhysicalMemory=0x'+inttohex(ptruint(@vmxfunctions.dbvm_read_physical_memory),8));
s.add('dbvm_WritePhysicalMemory=0x'+inttohex(ptruint(@vmxfunctions.dbvm_write_physical_memory),8));
s.add('dbvm_block_interrupts=0x'+inttohex(ptruint(@vmxfunctions.dbvm_block_interrupts),8));
s.add('dbvm_raise_privilege=0x'+inttohex(ptruint(@vmxfunctions.dbvm_raise_privilege),8));
s.add('dbvm_restore_interrupts=0x'+inttohex(ptruint(@vmxfunctions.dbvm_restore_interrupts),8));
s.add('dbvm_changeselectors=0x'+inttohex(ptruint(@vmxfunctions.dbvm_changeselectors),8));
s.add('clWindow=0x'+inttohex(clWindow,8));
s.add('clWindowText=0x'+inttohex(clWindowtext,8));
{$endif}
//5.2 backward compatibility:
s.add('math.log10=function(v) return math.log(v,10) end');
s.add('loadstring=load');
s.add('unpack=table.unpack');
s.add('package.loaders=package.searchers');
//5.3 backward compatibility:
s.add('math.pow=function(x,y) return x^y end');
s.add('math.atan2=math.atan');
s.add('math.ldexp=function(x,exp) return x * 2.0^exp end');
s.add('math.mod=math.fmod');
s.add('string.gfind=string.gmatch');
s.add('BinUtils={}');
s.add('math.randomseed(os.time())');
lua_doscript(s.text);
s.clear;
s.add('function printf(...) print(string.format(...)) end');
s.add('registerLuaFunctionHighlight("printf")');
lua_doscript(s.text);
lua_getglobal(L, 'string');
lua_pushstring(L,'split');
lua_pushcfunction(L, lua_string_split);
lua_settable(L,-3);
lua_pushstring(L,'endsWith');
lua_pushcfunction(L, lua_string_endswith);
lua_settable(L,-3);
lua_pushstring(L,'startsWith');
lua_pushcfunction(L, lua_string_startswith);
lua_settable(L,-3);
lua_pushstring(L,'trim');
lua_pushcfunction(L, lua_trim);
lua_settable(L,-3);
lua_pop(L,1);
lua_getglobal(L, 'math');
i:=lua_gettop(L);
lua_pushstring(L, 'frexp');
lua_pushcfunction(L, lua_frexp);
lua_settable(L,i);
lua_pushstring(L, 'cosh');
lua_pushcfunction(L, lua_cosh);
lua_settable(L,i);
lua_pushstring(L, 'sinh');
lua_pushcfunction(L, lua_sinh);
lua_settable(L,i);
lua_pushstring(L, 'tanh');
lua_pushcfunction(L, lua_tanh);
lua_settable(L,i);
lua_settop(L,i-1);
{$ifdef darwin}
autorunpath:=extractfiledir(extractfiledir(Application.ExeName))+'/Lua/Autorun/';
{$else}
autorunpath:=CheatEngineDir+'autorun'+pathdelim;
{$endif}
finally
s.free;
end;
end;
end;
var
tm: TThreadManager;
oldReleaseThreadVars: procedure;
{$ifdef DEBUGTHREADERRORS}
oldEndThreadHandler: TEndThreadHandler;
{$endif}
procedure ReleaseLuaThreadVars;
var s: pstring;
begin
if Thread_LuaVM<>nil then
begin
if Thread_LuaRef<>0 then
lua_unref(Thread_LuaVM, Thread_LuaRef);
Thread_LuaVM:=nil;
end;
if assigned(oldReleaseThreadVars) then
oldReleaseThreadVars();
end;
{$ifdef DEBUGTHREADERRORS}
procedure ThreadError(data: Exception);
begin
MessageDlg('Error in thread '+GetThreadName+':'+data.Message, mtError,[mbok],0);
end;
Procedure EndThreadHandler(ExitCode : DWord);
var m: tmethod;
begin
if TThread.CurrentThread.FreeOnTerminate=false then
begin
if TThread.CurrentThread.FatalException<>nil then
begin
m.code:=@threadError;
m.data:=TThread.CurrentThread.FatalException;
tthread.Synchronize(nil, TThreadMethod(m));
end;
end;
if assigned(oldEndThreadHandler) then
oldEndThreadHandler(Exitcode);
end;
{$endif}
initialization
_LuaCS:=TCriticalSection.create;
luarefcs:=TCriticalSection.create;
GetThreadManager(tm);
oldReleaseThreadVars:=tm.ReleaseThreadVars;
tm.ReleaseThreadVars:=@ReleaseLuaThreadVars;
{$ifdef DEBUGTHREADERRORS}
oldEndThreadHandler:=tm.EndThread;
tm.EndThread:=@EndThreadHandler;
{$endif}
SetThreadManager(tm);
InitializeLua;
finalization
if _LuaVM<>nil then
begin
lua_close(_LuaVM);
_LuaVM:=nil;
end;
if _LuaCS<>nil then
begin
_LuaCS.free;
_LuaCS:=nil;
end;
end.