2013-02-17 12:08:42 +00:00
|
|
|
unit LuaDissectCode;
|
|
|
|
|
|
|
|
|
|
{$mode delphi}
|
|
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
|
|
uses
|
2021-03-28 22:09:07 +02:00
|
|
|
{$ifdef darwin}MacPort,{$endif}Classes, SysUtils, lua, lauxlib, lualib;
|
2013-02-24 23:49:26 +00:00
|
|
|
|
|
|
|
|
procedure initializeLuaDissectCode;
|
2013-02-17 12:08:42 +00:00
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
2018-06-30 08:50:27 +02:00
|
|
|
uses DissectCodeThread, luahandler, LuaClass, LuaObject, symbolhandler, symbolhandlerstructs,
|
2018-06-12 20:23:45 +02:00
|
|
|
newkernelhandler, ProcessHandlerUnit;
|
2013-02-24 23:49:26 +00:00
|
|
|
|
2016-08-20 23:30:19 +03:00
|
|
|
resourcestring
|
|
|
|
|
rsTheModuleNamed = 'The module named ';
|
|
|
|
|
rsCouldNotBeFound = ' could not be found';
|
|
|
|
|
rsInvalidParametersForDissect = 'Invalid parameters for dissect';
|
|
|
|
|
|
2013-02-24 23:49:26 +00:00
|
|
|
function getDissectCode(L: PLua_State): integer; cdecl;
|
|
|
|
|
begin
|
|
|
|
|
if dissectcode=nil then
|
|
|
|
|
dissectcode:=TDissectCodeThread.create(false);
|
|
|
|
|
|
|
|
|
|
luaclass_newClass(L, dissectcode);
|
|
|
|
|
result:=1;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
function dissectcode_dissect(L: PLua_State): integer; cdecl;
|
|
|
|
|
var dc: TDissectCodeThread;
|
|
|
|
|
start: ptruint;
|
|
|
|
|
size: integer;
|
|
|
|
|
mi: TModuleInfo;
|
|
|
|
|
modulename: string;
|
|
|
|
|
begin
|
|
|
|
|
//2 versions, modulename and base,size
|
|
|
|
|
//base can be a string too, so check paramcount
|
|
|
|
|
|
|
|
|
|
result:=0;
|
|
|
|
|
dc:=luaclass_getClassObject(L);
|
|
|
|
|
dc.waitTillDone; //just in case...
|
|
|
|
|
|
|
|
|
|
if lua_gettop(L)=1 then
|
|
|
|
|
begin
|
|
|
|
|
//modulename
|
|
|
|
|
modulename:=Lua_ToString(L,1);
|
|
|
|
|
if symhandler.getmodulebyname(modulename, mi) then
|
|
|
|
|
begin
|
|
|
|
|
start:=mi.baseaddress;
|
|
|
|
|
size:=mi.basesize;
|
|
|
|
|
end
|
|
|
|
|
else
|
2016-08-20 23:30:19 +03:00
|
|
|
raise exception.create(rsTheModuleNamed+modulename+rsCouldNotBeFound)
|
2013-02-24 23:49:26 +00:00
|
|
|
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
if lua_gettop(L)=2 then
|
|
|
|
|
begin
|
|
|
|
|
if lua_type(L,1)=LUA_TSTRING then
|
|
|
|
|
start:=symhandler.getAddressFromName(Lua_ToString(L,1))
|
|
|
|
|
else
|
|
|
|
|
start:=lua_tointeger(L,1);
|
|
|
|
|
|
|
|
|
|
size:=lua_tointeger(L, 2);
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
else
|
2016-08-20 23:30:19 +03:00
|
|
|
raise exception.create(rsInvalidParametersForDissect);
|
2013-02-24 23:49:26 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
//all date is here, setup a scan config
|
|
|
|
|
setlength(dissectcode.memoryregion,1);
|
|
|
|
|
dissectcode.memoryregion[0].BaseAddress:=start;
|
|
|
|
|
dissectcode.memoryregion[0].MemorySize:=size;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dc.dowork;
|
|
|
|
|
dc.waitTillDone;
|
|
|
|
|
result:=0;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function dissectcode_clear(L: PLua_State): integer; cdecl;
|
|
|
|
|
var dc: TDissectCodeThread;
|
|
|
|
|
begin
|
|
|
|
|
dc:=luaclass_getClassObject(L);
|
|
|
|
|
dc.clear;
|
|
|
|
|
result:=0;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
function dissectcode_addReference(L: PLua_State): integer; cdecl;
|
|
|
|
|
var dc: TDissectCodeThread;
|
|
|
|
|
fromaddress, toaddress: ptruint;
|
|
|
|
|
reftype: tjumptype;
|
|
|
|
|
isstring: boolean;
|
|
|
|
|
begin
|
|
|
|
|
dc:=luaclass_getClassObject(L);
|
|
|
|
|
if lua_type(L,1)=LUA_TSTRING then
|
|
|
|
|
fromaddress:=symhandler.getAddressFromName(Lua_ToString(L,1))
|
|
|
|
|
else
|
|
|
|
|
fromaddress:=lua_tointeger(L,1);
|
|
|
|
|
|
|
|
|
|
if lua_type(L,2)=LUA_TSTRING then
|
|
|
|
|
toaddress:=symhandler.getAddressFromName(Lua_ToString(L,2))
|
|
|
|
|
else
|
|
|
|
|
toaddress:=lua_tointeger(L,2);
|
|
|
|
|
|
|
|
|
|
reftype:=tjumptype(lua_tointeger(L,3));
|
|
|
|
|
|
|
|
|
|
if lua_gettop(L)=4 then
|
|
|
|
|
isstring:=lua_toboolean(L, 4)
|
|
|
|
|
else
|
|
|
|
|
isstring:=false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dc.addReference(fromaddress, toaddress,reftype, isstring);
|
|
|
|
|
result:=0;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
function dissectcode_deleteReference(L: PLua_State): integer; cdecl;
|
|
|
|
|
var dc: TDissectCodeThread;
|
|
|
|
|
fromaddress, toaddress: ptruint;
|
|
|
|
|
begin
|
|
|
|
|
dc:=luaclass_getClassObject(L);
|
|
|
|
|
if lua_type(L,1)=LUA_TSTRING then
|
|
|
|
|
fromaddress:=symhandler.getAddressFromName(Lua_ToString(L,1))
|
|
|
|
|
else
|
|
|
|
|
fromaddress:=lua_tointeger(L,1);
|
|
|
|
|
|
|
|
|
|
if lua_type(L,2)=LUA_TSTRING then
|
|
|
|
|
toaddress:=symhandler.getAddressFromName(Lua_ToString(L,2))
|
|
|
|
|
else
|
|
|
|
|
toaddress:=lua_tointeger(L,2);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dc.removeReference(fromaddress, toaddress);
|
|
|
|
|
result:=0;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
function dissectcode_getReferences(L: PLua_State): integer; cdecl;
|
|
|
|
|
var dc: TDissectCodeThread;
|
|
|
|
|
address: ptruint;
|
|
|
|
|
|
|
|
|
|
da: tdissectarray;
|
|
|
|
|
i,t: integer;
|
|
|
|
|
begin
|
2015-12-06 15:44:46 +01:00
|
|
|
result:=1;
|
2013-02-24 23:49:26 +00:00
|
|
|
dc:=luaclass_getClassObject(L);
|
|
|
|
|
if lua_type(L,1)=LUA_TSTRING then
|
|
|
|
|
address:=symhandler.getAddressFromName(Lua_ToString(L,1))
|
|
|
|
|
else
|
|
|
|
|
address:=lua_tointeger(L,1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setlength(da,0);
|
|
|
|
|
|
|
|
|
|
if dc.CheckAddress(address, da) then
|
|
|
|
|
begin
|
|
|
|
|
lua_newtable(L);
|
|
|
|
|
t:=lua_gettop(L);
|
|
|
|
|
|
|
|
|
|
for i:=0 to length(da)-1 do
|
|
|
|
|
begin
|
|
|
|
|
lua_pushinteger(L, da[i].address);
|
|
|
|
|
lua_pushinteger(L, integer(da[i].jumptype));
|
|
|
|
|
lua_settable(L, t);
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
else
|
2015-12-06 15:44:46 +01:00
|
|
|
lua_pushnil(L);
|
2013-02-24 23:49:26 +00:00
|
|
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
function dissectcode_getReferencedStrings(L: PLua_State): integer; cdecl;
|
|
|
|
|
var dc: TDissectCodeThread;
|
|
|
|
|
s: tstringlist;
|
|
|
|
|
|
|
|
|
|
i,t: integer;
|
|
|
|
|
|
|
|
|
|
sr: TStringReference;
|
2018-06-12 20:23:45 +02:00
|
|
|
|
|
|
|
|
str: pchar;
|
|
|
|
|
strw: pwidechar absolute str;
|
|
|
|
|
|
|
|
|
|
x: ptruint;
|
|
|
|
|
|
|
|
|
|
temps: string;
|
2013-02-24 23:49:26 +00:00
|
|
|
begin
|
2015-12-06 15:44:46 +01:00
|
|
|
result:=1;
|
2013-02-24 23:49:26 +00:00
|
|
|
dc:=luaclass_getClassObject(L);
|
|
|
|
|
|
|
|
|
|
s:=TStringList.create;
|
|
|
|
|
dc.getstringlist(s);
|
|
|
|
|
|
|
|
|
|
if s.count>0 then
|
|
|
|
|
begin
|
|
|
|
|
|
|
|
|
|
lua_newtable(L);
|
|
|
|
|
t:=lua_gettop(L);
|
|
|
|
|
|
2018-06-12 20:23:45 +02:00
|
|
|
getmem(str,512);
|
|
|
|
|
|
2013-02-24 23:49:26 +00:00
|
|
|
for i:=0 to s.count-1 do
|
|
|
|
|
begin
|
2013-02-26 13:56:49 +00:00
|
|
|
sr:=TStringReference(s.Objects[i]);
|
2018-06-12 20:23:45 +02:00
|
|
|
|
|
|
|
|
if readprocessmemory(processhandle, pointer(sr.address), str,512,x) then
|
|
|
|
|
begin
|
|
|
|
|
str[511]:=#0;
|
|
|
|
|
str[510]:=#0;
|
|
|
|
|
if strlen(str)>strlen(strw) then
|
|
|
|
|
temps:=str
|
|
|
|
|
else
|
|
|
|
|
temps:=strw;
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
temps:='';
|
|
|
|
|
|
2013-02-24 23:49:26 +00:00
|
|
|
lua_pushinteger(L, sr.address);
|
2018-06-12 20:23:45 +02:00
|
|
|
lua_pushstring(L, temps);
|
2013-02-24 23:49:26 +00:00
|
|
|
lua_settable(L, t);
|
2018-06-12 20:27:01 +02:00
|
|
|
|
|
|
|
|
freeandnil(sr);
|
2013-02-24 23:49:26 +00:00
|
|
|
end;
|
|
|
|
|
|
2018-06-12 20:27:01 +02:00
|
|
|
FreeMemAndNil(str);
|
|
|
|
|
|
2015-12-06 15:44:46 +01:00
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
lua_pushnil(L);
|
2013-02-24 23:49:26 +00:00
|
|
|
|
|
|
|
|
s.free;
|
|
|
|
|
|
|
|
|
|
end;
|
|
|
|
|
|
2015-12-06 15:44:46 +01:00
|
|
|
function dissectcode_getReferencedFunctions(L: PLua_State): integer; cdecl;
|
|
|
|
|
var
|
|
|
|
|
dc: TDissectCodeThread;
|
|
|
|
|
callList: TList;
|
|
|
|
|
i: integer;
|
|
|
|
|
begin
|
|
|
|
|
result:=1;
|
|
|
|
|
dc:=luaclass_getClassObject(L);
|
|
|
|
|
lua_pop(L, lua_gettop(L));
|
|
|
|
|
|
|
|
|
|
callList:=tlist.create;
|
|
|
|
|
dc.getCallList(callList);
|
|
|
|
|
|
|
|
|
|
if callList.count>0 then
|
|
|
|
|
begin
|
|
|
|
|
lua_newtable(L);
|
|
|
|
|
|
|
|
|
|
for i:=0 to callList.count-1 do
|
|
|
|
|
begin
|
|
|
|
|
lua_pushinteger(L, i+1);
|
|
|
|
|
lua_pushinteger(L, TDissectReference(callList[i]).address);
|
|
|
|
|
lua_settable(L, -3);
|
|
|
|
|
TDissectReference(callList[i]).free;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
lua_pushnil(L);
|
|
|
|
|
|
|
|
|
|
callList.free;
|
|
|
|
|
end;
|
2013-02-24 23:49:26 +00:00
|
|
|
|
2014-01-07 00:28:32 +00:00
|
|
|
function dissectcode_saveToFile(L: PLua_State): integer; cdecl;
|
|
|
|
|
var dc: TDissectCodeThread;
|
|
|
|
|
begin
|
|
|
|
|
result:=0;
|
|
|
|
|
dc:=luaclass_getClassObject(L);
|
|
|
|
|
try
|
|
|
|
|
if lua_gettop(L)=1 then
|
|
|
|
|
dc.saveToFile(Lua_ToString(L,1));
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
function dissectcode_loadFromFile(L: PLua_State): integer; cdecl;
|
|
|
|
|
var dc: TDissectCodeThread;
|
|
|
|
|
begin
|
|
|
|
|
result:=0;
|
|
|
|
|
dc:=luaclass_getClassObject(L);
|
|
|
|
|
try
|
|
|
|
|
if lua_gettop(L)=1 then
|
|
|
|
|
dc.loadFromFile(Lua_ToString(L,1));
|
|
|
|
|
|
|
|
|
|
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;
|
2013-02-24 23:49:26 +00:00
|
|
|
|
|
|
|
|
procedure dissectcode_addMetaData(L: PLua_state; metatable: integer; userdata: integer );
|
|
|
|
|
begin
|
|
|
|
|
object_addMetaData(L, metatable, userdata);
|
|
|
|
|
luaclass_addClassFunctionToTable(L, metatable, userdata, 'dissect', dissectcode_dissect);
|
|
|
|
|
luaclass_addClassFunctionToTable(L, metatable, userdata, 'clear', dissectcode_clear);
|
|
|
|
|
luaclass_addClassFunctionToTable(L, metatable, userdata, 'addReference', dissectcode_addReference);
|
|
|
|
|
luaclass_addClassFunctionToTable(L, metatable, userdata, 'deleteReference', dissectcode_deleteReference);
|
|
|
|
|
|
|
|
|
|
luaclass_addClassFunctionToTable(L, metatable, userdata, 'getReferences', dissectcode_getReferences);
|
|
|
|
|
luaclass_addClassFunctionToTable(L, metatable, userdata, 'getReferencedStrings', dissectcode_getReferencedStrings);
|
2015-12-06 15:44:46 +01:00
|
|
|
luaclass_addClassFunctionToTable(L, metatable, userdata, 'getReferencedFunctions', dissectcode_getReferencedFunctions);
|
2013-02-24 23:49:26 +00:00
|
|
|
|
2014-01-07 00:28:32 +00:00
|
|
|
luaclass_addClassFunctionToTable(L, metatable, userdata, 'saveToFile', dissectcode_saveToFile);
|
|
|
|
|
luaclass_addClassFunctionToTable(L, metatable, userdata, 'loadFromFile', dissectcode_loadFromFile);
|
|
|
|
|
|
2013-02-24 23:49:26 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure initializeLuaDissectCode;
|
|
|
|
|
begin
|
|
|
|
|
lua_register(LuaVM, 'getDissectCode', getDissectCode);
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
initialization
|
|
|
|
|
luaclass_register(TDissectCodeThread, dissectcode_addMetaData);
|
|
|
|
|
|
2013-02-17 12:08:42 +00:00
|
|
|
end.
|
|
|
|
|
|