unit LuaDisassembler; {$mode delphi} interface uses Classes, SysUtils, disassembler, lua, lauxlib, lualib, symbolhandler, LastDisassembleData; procedure initializeLuaDisassembler; procedure LastDisassemblerDataToTable(L: PLua_State; t: integer; const ldd: TLastDisassembleData); procedure LastDisassemblerDataFromTable(L: PLua_State; t: integer; var ldd: TLastDisassembleData); implementation uses LuaHandler, LuaClass, LuaObject; function disassembler_disassemble(L: PLua_State): integer; cdecl; var d: TDisassembler; s,desc: string; address: ptruint; begin result:=0; d:=luaclass_getClassObject(L); if lua_gettop(L)=1 then begin if lua_type(L,1)=LUA_TSTRING then address:=symhandler.getAddressFromNameL(Lua_ToString(L, 1)) else address:=lua_tointeger(L, 1); s:=d.disassemble(address, desc); lua_pushstring(L, s); result:=1; end; end; function disassembler_decodeLastParametersToString(L: PLua_State): integer; cdecl; var d: TDisassembler; begin d:=luaclass_getClassObject(L); lua_pushstring(L, d.DecodeLastParametersToString); result:=1; end; procedure LastDisassemblerDataFromTable(L: PLua_State; t: integer; var ldd: TLastDisassembleData); var bytestable: integer; i, size: integer; begin lua_pushstring(L,'address'); lua_gettable(L, t); ldd.address:=lua_tointeger(L, -1); lua_pop(L, 1); lua_pushstring(L,'opcode'); lua_gettable(L, t); ldd.opcode:=Lua_ToString(L, -1); lua_pop(L, 1); lua_pushstring(L,'parameters'); lua_gettable(L, t); ldd.parameters:=Lua_ToString(L, -1); lua_pop(L, 1); lua_pushstring(L,'description'); lua_gettable(L, t); ldd.description:=Lua_ToString(L, -1); lua_pop(L, 1); lua_pushstring(L,'bytes'); lua_gettable(L, t); bytestable:=lua_gettop(L); size:=lua_objlen(L, bytestable); setlength(ldd.Bytes, size); for i:=1 to size do begin lua_pushinteger(L, i); lua_gettable(L, bytestable); ldd.bytes[i-1]:=lua_tointeger(L, -1); lua_pop(L, 1); end; lua_pop(L, 1); lua_pushstring(L,'modrmValueType'); lua_gettable(L, t); ldd.modrmValueType:=TDisAssemblerValueType(lua_tointeger(L, -1)); lua_pop(L, 1); lua_pushstring(L,'modrmValue'); lua_gettable(L, t); ldd.modrmValue:=lua_tointeger(L, -1); lua_pop(L, 1); lua_pushstring(L,'parameterValueType'); lua_gettable(L, t); ldd.parameterValueType:=TDisAssemblerValueType(lua_tointeger(L, -1)); lua_pop(L, 1); lua_pushstring(L,'parameterValue'); lua_gettable(L, t); ldd.parameterValue:=lua_tointeger(L, -1); lua_pop(L, 1); lua_pushstring(L,'isJump'); lua_gettable(L, t); ldd.isjump:=lua_toboolean(L, -1); lua_pop(L, 1); lua_pushstring(L,'isCall'); lua_gettable(L, t); ldd.isCall:=lua_toboolean(L, -1); lua_pop(L, 1); lua_pushstring(L,'isRet'); lua_gettable(L, t); ldd.isRet:=lua_toboolean(L, -1); lua_pop(L, 1); lua_pushstring(L,'isConditionalJump'); lua_gettable(L, t); ldd.isconditionaljump:=lua_toboolean(L, -1); lua_pop(L, 1); end; procedure LastDisassemblerDataToTable(L: PLua_State; t: integer; const ldd: TLastDisassembleData); var temptable: integer; i: integer; begin lua_pushstring(L,'address'); lua_pushinteger(L, ldd.address); lua_settable(L, t); lua_pushstring(L,'opcode'); lua_pushstring(L, ldd.opcode); lua_settable(L, t); lua_pushstring(L,'parameters'); lua_pushstring(L, ldd.parameters); lua_settable(L, t); lua_pushstring(L,'description'); lua_pushstring(L, ldd.description); lua_settable(L, t); lua_pushstring(L, 'bytes'); lua_newtable(L); temptable:=lua_gettop(L); for i:=0 to length(ldd.Bytes)-1 do begin lua_pushinteger(L, i+1); lua_pushinteger(L, ldd.Bytes[i]); lua_settable(L, temptable); end; lua_settable(L, t); lua_pushstring(L, 'modrmValueType'); lua_pushinteger(L, integer(ldd.modrmValueType)); lua_settable(L, t); lua_pushstring(L,'modrmValue'); lua_pushinteger(L, ldd.modrmValue); lua_settable(L, t); lua_pushstring(L, 'parameterValueType'); lua_pushinteger(L, integer(ldd.parameterValueType)); lua_settable(L, t); lua_pushstring(L,'parameterValue'); lua_pushinteger(L, ldd.parameterValue); lua_settable(L, t); lua_pushstring(L,'isJump'); lua_pushboolean(L, ldd.isJump); lua_settable(L, t); lua_pushstring(L,'isCall'); lua_pushboolean(L, ldd.isCall); lua_settable(L, t); lua_pushstring(L,'isRet'); lua_pushboolean(L, ldd.isret); lua_settable(L, t); lua_pushstring(L,'isConditionalJump'); lua_pushboolean(L, ldd.isConditionalJump); lua_settable(L, t); end; function disassembler_getLastDisassembleData(L: PLua_State): integer; cdecl; var d: TDisassembler; t: integer; i: integer; begin result:=1; d:=luaclass_getClassObject(L); lua_newtable(L); t:=lua_gettop(L); LastDisassemblerDataToTable(L, t, d.LastDisassembleData); end; function createDisassembler(L: PLua_State): integer; cdecl; begin luaclass_newClass(L, TDisassembler.Create); result:=1; end; function getDefaultDisassembler(L: PLua_State): integer; cdecl; begin luaclass_newClass(L, defaultDisassembler); result:=1; end; function getVisibleDisassembler(L: PLua_State): integer; cdecl; begin luaclass_newClass(L, visibleDisassembler); result:=1; end; procedure disassembler_addMetaData(L: PLua_state; metatable: integer; userdata: integer ); begin object_addMetaData(L, metatable, userdata); luaclass_addClassFunctionToTable(L, metatable, userdata, 'disassemble', disassembler_disassemble); luaclass_addClassFunctionToTable(L, metatable, userdata, 'decodeLastParametersToString', disassembler_decodeLastParametersToString); luaclass_addClassFunctionToTable(L, metatable, userdata, 'getLastDisassembleData', disassembler_getLastDisassembleData); luaclass_addPropertyToTable(L, metatable, userdata, 'LastDisassembleData', disassembler_getLastDisassembleData, nil); end; procedure initializeLuaDisassembler; begin lua_register(LuaVM, 'createDisassembler', createDisassembler); lua_register(LuaVM, 'getDefaultDisassembler', getDefaultDisassembler); lua_register(LuaVM, 'getVisibleDisassembler', getVisibleDisassembler); end; initialization luaclass_register(TDisassembler, disassembler_addMetaData); end.