From 97712089bd09f29de82e3471438429b8810d219e Mon Sep 17 00:00:00 2001 From: Warmist Date: Fri, 19 Aug 2011 18:09:00 +0300 Subject: [PATCH 01/15] Added dfusion thready flag to spawn another thread --- plugins/Dfusion/CMakeLists.txt | 1 + plugins/Dfusion/dfusion.cpp | 31 ++++++++++++++++++++-------- plugins/Dfusion/luafiles/offsets.lua | 4 +++- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/plugins/Dfusion/CMakeLists.txt b/plugins/Dfusion/CMakeLists.txt index d17e66a23..7b6724dde 100644 --- a/plugins/Dfusion/CMakeLists.txt +++ b/plugins/Dfusion/CMakeLists.txt @@ -4,6 +4,7 @@ FILE(GLOB DFUSION_CPPS src/*.c*) set( DFUSION_CPPS_ALL dfusion.cpp + ${dfhack_SOURCE_DIR}/library/depends/tthread/tinythread.cpp ${DFUSION_CPPS} ) DFHACK_PLUGIN(dfusion ${DFUSION_CPPS_ALL} LINK_LIBRARIES lua) diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp index f75ce69b2..2495f1a25 100644 --- a/plugins/Dfusion/dfusion.cpp +++ b/plugins/Dfusion/dfusion.cpp @@ -24,6 +24,7 @@ using std::string; using namespace DFHack; static tthread::mutex* mymutex=0; +static tthread::thread* thread_dfusion=0; uint64_t timeLast=0; DFhackCExport command_result dfusion (Core * c, vector & parameters); @@ -43,9 +44,8 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector lua::RegisterHexsearch(lua::glua::Get()); lua::RegisterMisc(lua::glua::Get()); lua::RegisterVersionInfo(lua::glua::Get()); - commands.push_back(PluginCommand("dfusion","Init dfusion system.",dfusion)); - commands.push_back(PluginCommand("lua", "Run interactive interpreter.\ -\n Options: = run instead",lua_run)); + commands.push_back(PluginCommand("dfusion","Init dfusion system. Use 'dfusion thready' to spawn a different thread.",dfusion)); + commands.push_back(PluginCommand("lua", "Run interactive interpreter. Use 'lua ' to run instead.",lua_run)); mymutex=new tthread::mutex; return CR_OK; @@ -55,11 +55,13 @@ DFhackCExport command_result plugin_shutdown ( Core * c ) { // shutdown stuff + if(thread_dfusion) + delete thread_dfusion; delete mymutex; return CR_OK; } -DFhackCExport command_result plugin_onupdate ( Core * c ) +DFhackCExport command_result plugin_onupdate_DISABLED ( Core * c ) { uint64_t time2 = GetTimeMs64(); uint64_t delta = time2-timeLast; @@ -137,13 +139,12 @@ DFhackCExport command_result lua_run (Core * c, vector & parameters) mymutex->unlock(); return CR_OK; } -DFhackCExport command_result dfusion (Core * c, vector & parameters) +void RunDfusion(void *p) { - - Console &con=c->con; + Console &con=static_cast(p)->con; mymutex->lock(); + lua::state s=lua::glua::Get(); - try{ s.loadfile("dfusion/init.lua"); //load script s.pcall(0,0);// run it @@ -151,9 +152,21 @@ DFhackCExport command_result dfusion (Core * c, vector & parameters) catch(lua::exception &e) { con.printerr("Error:%s\n",e.what()); - c->con.printerr("%s\n",lua::DebugDump(lua::glua::Get()).c_str()); + con.printerr("%s\n",lua::DebugDump(lua::glua::Get()).c_str()); } s.settop(0);// clean up mymutex->unlock(); +} +DFhackCExport command_result dfusion (Core * c, vector & parameters) +{ + if(thread_dfusion==0) + thread_dfusion=new tthread::thread(RunDfusion,c); + if(parameters[0]!="thready") + { + thread_dfusion->join(); + delete thread_dfusion; + thread_dfusion=0; + } + return CR_OK; } diff --git a/plugins/Dfusion/luafiles/offsets.lua b/plugins/Dfusion/luafiles/offsets.lua index 9d684b62a..e15f5b7e9 100644 --- a/plugins/Dfusion/luafiles/offsets.lua +++ b/plugins/Dfusion/luafiles/offsets.lua @@ -1,7 +1,9 @@ function f_dwarves() - pos_=offsets.findall(0,0x24,0x14,0x07,0,0,0) --search pattern + //mov DWORD PTR [ESP+14],7 + //jmp +0x08 + pos_=offsets.findall(0,0x24,0x14,0x07,0,0,0) --search pattern for _,v in pairs(pos_) do print(string.format("Possible hit:%x",v)) end From 68fbd4a78deee46fdc7d8ea5ab580f023fb804d2 Mon Sep 17 00:00:00 2001 From: Warmist Date: Fri, 19 Aug 2011 19:12:25 +0300 Subject: [PATCH 02/15] fixed few formating things, and annoying 'g' error. (work-around somehow the '..' operator does not work with numbers) --- plugins/Dfusion/dfusion.cpp | 1 - plugins/Dfusion/luafiles/common.lua | 2 +- plugins/Dfusion/luafiles/init.lua | 4 ++-- plugins/Dfusion/luafiles/offsets.lua | 4 ++-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp index 2495f1a25..965ee3475 100644 --- a/plugins/Dfusion/dfusion.cpp +++ b/plugins/Dfusion/dfusion.cpp @@ -167,6 +167,5 @@ DFhackCExport command_result dfusion (Core * c, vector & parameters) delete thread_dfusion; thread_dfusion=0; } - return CR_OK; } diff --git a/plugins/Dfusion/luafiles/common.lua b/plugins/Dfusion/luafiles/common.lua index 912862d56..a7ce563ff 100644 --- a/plugins/Dfusion/luafiles/common.lua +++ b/plugins/Dfusion/luafiles/common.lua @@ -204,7 +204,7 @@ end function it_menu:display() print("Select choice (q exits):") for p,c in pairs(self.items) do - print(p..")."..c[2]) + print(string.format("%3d).%s",p,c[2])) end local ans repeat diff --git a/plugins/Dfusion/luafiles/init.lua b/plugins/Dfusion/luafiles/init.lua index d8307eaab..45d328c5c 100644 --- a/plugins/Dfusion/luafiles/init.lua +++ b/plugins/Dfusion/luafiles/init.lua @@ -17,9 +17,9 @@ end function mainmenu(t1) Console.clear() while true do - print("No. Name Desc") + print("No. Name Desc") for k,v in pairs(t1) do - print(string.format("%d %s %s",k,v[1],v[2])) + print(string.format("%3d %15s %s",k,v[1],v[2])) end local q=Console.lineedit("Select plugin to run (q to quit):") if q=='q' then return end diff --git a/plugins/Dfusion/luafiles/offsets.lua b/plugins/Dfusion/luafiles/offsets.lua index e15f5b7e9..8349f73e3 100644 --- a/plugins/Dfusion/luafiles/offsets.lua +++ b/plugins/Dfusion/luafiles/offsets.lua @@ -1,8 +1,8 @@ function f_dwarves() - //mov DWORD PTR [ESP+14],7 - //jmp +0x08 + --mov DWORD PTR [ESP+14],7 + --jmp +0x08 pos_=offsets.findall(0,0x24,0x14,0x07,0,0,0) --search pattern for _,v in pairs(pos_) do print(string.format("Possible hit:%x",v)) From fc745f70aef27f7bca343d3e29d4b5039d5731ea Mon Sep 17 00:00:00 2001 From: Warmist Date: Sat, 20 Aug 2011 01:11:49 +0300 Subject: [PATCH 03/15] Fixed annoying lua bug where number formating was broken (outputed 'g') --- lua/include/luaconf.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lua/include/luaconf.h b/lua/include/luaconf.h index ba9e833bb..660793356 100644 --- a/lua/include/luaconf.h +++ b/lua/include/luaconf.h @@ -520,7 +520,11 @@ */ #define LUA_NUMBER_SCAN "%lf" #define LUA_NUMBER_FMT "%.14g" +#ifdef WIN32 //More specifically MSVC, but did not work, either way only MSVC is used in windows build +#define lua_number2str(s,n) sprintf_s((s),32, LUA_NUMBER_FMT, (n)) +#else #define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +#endif #define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ #define lua_str2number(s,p) strtod((s), (p)) From b29c71953802cdbf73568c7b1c5c225d6d2eb9b6 Mon Sep 17 00:00:00 2001 From: Warmist Date: Sat, 20 Aug 2011 01:12:30 +0300 Subject: [PATCH 04/15] Started working on new plugin --- plugins/Dfusion/luafiles/init.lua | 1 + .../Dfusion/luafiles/onfunction/compile.bat | 1 + .../Dfusion/luafiles/onfunction/functions.asm | 19 +++++++++ .../Dfusion/luafiles/onfunction/functions.o | Bin 0 -> 400 bytes .../Dfusion/luafiles/onfunction/plugin.lua | 36 ++++++++++++++++++ plugins/Dfusion/src/lua_Misc.cpp | 27 +++++++++++++ 6 files changed, 84 insertions(+) create mode 100644 plugins/Dfusion/luafiles/onfunction/compile.bat create mode 100644 plugins/Dfusion/luafiles/onfunction/functions.asm create mode 100644 plugins/Dfusion/luafiles/onfunction/functions.o create mode 100644 plugins/Dfusion/luafiles/onfunction/plugin.lua diff --git a/plugins/Dfusion/luafiles/init.lua b/plugins/Dfusion/luafiles/init.lua index 45d328c5c..a5ca70c6c 100644 --- a/plugins/Dfusion/luafiles/init.lua +++ b/plugins/Dfusion/luafiles/init.lua @@ -44,5 +44,6 @@ table.insert(plugins,{"adv_tools","some tools for (mainly) advneturer hacking"}) table.insert(plugins,{"tools","some misc tools"}) table.insert(plugins,{"triggers","a function calling plug (discontinued...)"}) table.insert(plugins,{"migrants","multi race imigrations"}) +table.insert(plugins,{"onfunction","run lua on some df function"}) mainmenu(plugins) diff --git a/plugins/Dfusion/luafiles/onfunction/compile.bat b/plugins/Dfusion/luafiles/onfunction/compile.bat new file mode 100644 index 000000000..f06fb8c4c --- /dev/null +++ b/plugins/Dfusion/luafiles/onfunction/compile.bat @@ -0,0 +1 @@ +as -anl --32 -o functions.o functions.asm \ No newline at end of file diff --git a/plugins/Dfusion/luafiles/onfunction/functions.asm b/plugins/Dfusion/luafiles/onfunction/functions.asm new file mode 100644 index 000000000..75cc03327 --- /dev/null +++ b/plugins/Dfusion/luafiles/onfunction/functions.asm @@ -0,0 +1,19 @@ +.intel_syntax +push eax +push edx +push ecx +push ebx +push eax +mov eax,[esp+24] +push eax +function: +call 0xdeadbeef +function2: +mov [0xdeadbeef],eax #self modifying code... :/ +pop eax +function3: +call [0xdeadbeef] + + + + diff --git a/plugins/Dfusion/luafiles/onfunction/functions.o b/plugins/Dfusion/luafiles/onfunction/functions.o new file mode 100644 index 0000000000000000000000000000000000000000..ec7310e1cac460d3c10928d43a974624630bc20b GIT binary patch literal 400 zcmeZaWM%+?O+d^IX0b5pm84dbfY}g221xY)@d~IIBal{LFi6l#Ni0c(is7Oh7z_^R zB^4Lrl81>m0M!Kq1qKInyQoM6y!f?m?Y+hCfkecAQ4lo&Rhpg7ExMsSuf0{{z(HCO-u literal 0 HcmV?d00001 diff --git a/plugins/Dfusion/luafiles/onfunction/plugin.lua b/plugins/Dfusion/luafiles/onfunction/plugin.lua new file mode 100644 index 000000000..cf26bc88a --- /dev/null +++ b/plugins/Dfusion/luafiles/onfunction/plugin.lua @@ -0,0 +1,36 @@ +onfunction={} +function onfunction.install() + ModData=engine.installMod("dfusion/onfunction/functions.o","functions") + modpos=ModData.pos + modsize=ModData.size + onfunction.pos=modpos + trgpos=engine.getpushvalue() + print(string.format("Function installed in:%x function to call is: %x",modpos,trgpos)) + local firstpos=modpos+engine.FindMarker(ModData,"function") + engine.poked(firstpos,trgpos-firstpos) --call first function + engine.poked(modpos+engine.FindMarker(ModData,"function2"),modpos+engine.FindMarker(ModData,"function3")) -- function table start + +end +function OnFunction(values) + print("Onfunction called!") + print("Data:") + for k,v in pairs(values) do + print(string.format("%s=%x",k,v)) + end + return 0 --todo return real address +end +function onfunction.patch(addr) + + if(engine.peekb(addr)~=0xe8) then + error("Incorrect address, not a function call") + else + --todo add to list of functions after patch + engine.poked(addr+1,onfunction.pos-addr-1) + end +end +mypos=engine.getmod("functions") +if mypos then + print("Onfunction already installed") +else + onfunction.install() +end \ No newline at end of file diff --git a/plugins/Dfusion/src/lua_Misc.cpp b/plugins/Dfusion/src/lua_Misc.cpp index aacf65e2b..768957c7a 100644 --- a/plugins/Dfusion/src/lua_Misc.cpp +++ b/plugins/Dfusion/src/lua_Misc.cpp @@ -129,6 +129,32 @@ static int GetMod(lua_State *L) st.push(pos); return 1; } +static size_t PushValue(size_t ret,uint32_t eax,uint32_t ebx,uint32_t ecx,uint32_t edx) +{ + lua::state st=lua::glua::Get(); + st.getglobal("OnFunction"); + if(st.is()) + return 0; + st.newtable(); + st.push(eax); + st.setfield("eax"); + st.push(ebx); + st.setfield("ebx"); + st.push(ecx); + st.setfield("ecx"); + st.push(edx); + st.setfield("edx"); + st.push(ret); + st.setfield("ret"); + st.pcall(1,1); + return st.as(); +} +static int Get_PushValue(lua_State *L) +{ + lua::state st(L); + st.push((uint32_t)&PushValue); + return 1; +} const luaL_Reg lua_misc_func[]= { {"loadmod",LoadMod}, @@ -137,6 +163,7 @@ const luaL_Reg lua_misc_func[]= {"loadobjsymbols",LoadObjSymbols}, {"findmarker",FindMarker}, {"newmod",NewMod}, + {"getpushvalue",Get_PushValue}, {NULL,NULL} }; void lua::RegisterMisc(lua::state &st) From e901f615c9226e175432c757e97191f041a87f0c Mon Sep 17 00:00:00 2001 From: Warmist Date: Sat, 20 Aug 2011 02:33:57 +0300 Subject: [PATCH 05/15] Almost working onfunction plugin... need to work out few bugs --- .../Dfusion/luafiles/onfunction/functions.asm | 4 ++-- .../Dfusion/luafiles/onfunction/functions.o | Bin 400 -> 400 bytes .../Dfusion/luafiles/onfunction/plugin.lua | 22 +++++++++++------- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/plugins/Dfusion/luafiles/onfunction/functions.asm b/plugins/Dfusion/luafiles/onfunction/functions.asm index 75cc03327..857481a38 100644 --- a/plugins/Dfusion/luafiles/onfunction/functions.asm +++ b/plugins/Dfusion/luafiles/onfunction/functions.asm @@ -4,10 +4,10 @@ push edx push ecx push ebx push eax -mov eax,[esp+24] +mov eax,[esp+20] push eax function: -call 0xdeadbeef +call 0xdeadbee4 function2: mov [0xdeadbeef],eax #self modifying code... :/ pop eax diff --git a/plugins/Dfusion/luafiles/onfunction/functions.o b/plugins/Dfusion/luafiles/onfunction/functions.o index ec7310e1cac460d3c10928d43a974624630bc20b..cf6e2d05cac9eb67669347f592e279ce99d9f78f 100644 GIT binary patch delta 14 WcmbQhJb`(_6c&+y7w;#|_yGVYbq1>d delta 14 WcmbQhJb`(_6c&kq7r!RX_yGVYy#~4f diff --git a/plugins/Dfusion/luafiles/onfunction/plugin.lua b/plugins/Dfusion/luafiles/onfunction/plugin.lua index cf26bc88a..d1b27ca62 100644 --- a/plugins/Dfusion/luafiles/onfunction/plugin.lua +++ b/plugins/Dfusion/luafiles/onfunction/plugin.lua @@ -1,15 +1,18 @@ -onfunction={} +onfunction=onfunction or {} function onfunction.install() - ModData=engine.installMod("dfusion/onfunction/functions.o","functions") + ModData=engine.installMod("dfusion/onfunction/functions.o","functions",4) modpos=ModData.pos modsize=ModData.size onfunction.pos=modpos trgpos=engine.getpushvalue() print(string.format("Function installed in:%x function to call is: %x",modpos,trgpos)) local firstpos=modpos+engine.FindMarker(ModData,"function") - engine.poked(firstpos,trgpos-firstpos) --call first function - engine.poked(modpos+engine.FindMarker(ModData,"function2"),modpos+engine.FindMarker(ModData,"function3")) -- function table start - + engine.poked(firstpos,trgpos-firstpos-4) --call Lua-Onfunction + onfunction.fpos=modpos+engine.FindMarker(ModData,"function3") + engine.poked(modpos+engine.FindMarker(ModData,"function2"),modpos+modsize) + engine.poked(onfunction.fpos,modpos+modsize) + SetExecute(modpos) + onfunction.calls={} end function OnFunction(values) print("Onfunction called!") @@ -17,20 +20,23 @@ function OnFunction(values) for k,v in pairs(values) do print(string.format("%s=%x",k,v)) end - return 0 --todo return real address + return onfunction.calls[values.ret] --returns real function to call end function onfunction.patch(addr) if(engine.peekb(addr)~=0xe8) then error("Incorrect address, not a function call") else - --todo add to list of functions after patch - engine.poked(addr+1,onfunction.pos-addr-1) + + onfunction.calls[addr+5]=addr+engine.peekd(addr+1)+5 --adds real function to call + engine.poked(addr+1,engine.getmod("functions")-addr-5) + end end mypos=engine.getmod("functions") if mypos then print("Onfunction already installed") + onfunction.patch(0x189dd6+offsets.base()) else onfunction.install() end \ No newline at end of file From f9c1556f7f370c2344ade96db93c6ecd924e9ebf Mon Sep 17 00:00:00 2001 From: Warmist Date: Sat, 20 Aug 2011 17:20:04 +0300 Subject: [PATCH 06/15] Working onfunction... --- .../Dfusion/luafiles/onfunction/functions.asm | 2 +- plugins/Dfusion/luafiles/onfunction/functions.o | Bin 400 -> 400 bytes plugins/Dfusion/src/lua_Misc.cpp | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/Dfusion/luafiles/onfunction/functions.asm b/plugins/Dfusion/luafiles/onfunction/functions.asm index 857481a38..6f877090f 100644 --- a/plugins/Dfusion/luafiles/onfunction/functions.asm +++ b/plugins/Dfusion/luafiles/onfunction/functions.asm @@ -12,7 +12,7 @@ function2: mov [0xdeadbeef],eax #self modifying code... :/ pop eax function3: -call [0xdeadbeef] +jmp [0xdeadbeef] diff --git a/plugins/Dfusion/luafiles/onfunction/functions.o b/plugins/Dfusion/luafiles/onfunction/functions.o index cf6e2d05cac9eb67669347f592e279ce99d9f78f..3fafa5ecdb103eae10aa07a98bbcc5ce514d4254 100644 GIT binary patch delta 11 TcmbQhJb`(_B1YATi{AnO7rX?Z delta 11 TcmbQhJb`(_B1X}Pi{AnO7kmVe diff --git a/plugins/Dfusion/src/lua_Misc.cpp b/plugins/Dfusion/src/lua_Misc.cpp index 768957c7a..d01bb3c12 100644 --- a/plugins/Dfusion/src/lua_Misc.cpp +++ b/plugins/Dfusion/src/lua_Misc.cpp @@ -129,7 +129,7 @@ static int GetMod(lua_State *L) st.push(pos); return 1; } -static size_t PushValue(size_t ret,uint32_t eax,uint32_t ebx,uint32_t ecx,uint32_t edx) +static size_t __stdcall PushValue(size_t ret,uint32_t eax,uint32_t ebx,uint32_t ecx,uint32_t edx) { lua::state st=lua::glua::Get(); st.getglobal("OnFunction"); From 3e75ac015c6be35455390a29a4490f03cc5f1b85 Mon Sep 17 00:00:00 2001 From: Warmist Date: Sat, 20 Aug 2011 17:51:00 +0300 Subject: [PATCH 07/15] more registers supported --- .../Dfusion/luafiles/onfunction/functions.asm | 10 +++++++--- plugins/Dfusion/luafiles/onfunction/functions.o | Bin 400 -> 404 bytes plugins/Dfusion/luafiles/onfunction/plugin.lua | 4 ++++ plugins/Dfusion/src/lua_Misc.cpp | 10 +++++++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/plugins/Dfusion/luafiles/onfunction/functions.asm b/plugins/Dfusion/luafiles/onfunction/functions.asm index 6f877090f..13ef23191 100644 --- a/plugins/Dfusion/luafiles/onfunction/functions.asm +++ b/plugins/Dfusion/luafiles/onfunction/functions.asm @@ -1,15 +1,19 @@ .intel_syntax push eax +push ebp +push esp +push esi +push edi push edx push ecx push ebx push eax -mov eax,[esp+20] +mov eax,[esp+36] push eax function: -call 0xdeadbee4 +call 0xdeadbee0 function2: -mov [0xdeadbeef],eax #self modifying code... :/ +mov [0xdeadbeef],eax pop eax function3: jmp [0xdeadbeef] diff --git a/plugins/Dfusion/luafiles/onfunction/functions.o b/plugins/Dfusion/luafiles/onfunction/functions.o index 3fafa5ecdb103eae10aa07a98bbcc5ce514d4254..7b7d4a33f044cd95156cb204eede5e0cb155714a 100644 GIT binary patch delta 136 zcmbQhJcXIlhmn~91h!4&l;%_bGJ1e`%|zVssoW&~n3AZB1-0b*ewMu>pqCE+4^C8-r9KpqHy)G#y3PnKsa1OPj; B94i0- delta 132 zcmbQjJb{_hhmn~91U60Nl;)HHGJ1e`#YEi%nV`VnfNmERk$@NP_pQCR7(_(;R|QcM yxF@bPb>spnWCUV1AZB1-0b+h2Mu_kMd7^L;y^_?55+Dx*Kx&v7r6(&h76Jf^`x>bL diff --git a/plugins/Dfusion/luafiles/onfunction/plugin.lua b/plugins/Dfusion/luafiles/onfunction/plugin.lua index d1b27ca62..14d6e219c 100644 --- a/plugins/Dfusion/luafiles/onfunction/plugin.lua +++ b/plugins/Dfusion/luafiles/onfunction/plugin.lua @@ -20,6 +20,10 @@ function OnFunction(values) for k,v in pairs(values) do print(string.format("%s=%x",k,v)) end + print("stack:") + for i=0,2 do + print(string.format("%d %x",i,engine.peekd(values.esp+i*4))) + end return onfunction.calls[values.ret] --returns real function to call end function onfunction.patch(addr) diff --git a/plugins/Dfusion/src/lua_Misc.cpp b/plugins/Dfusion/src/lua_Misc.cpp index d01bb3c12..5ac4bd73b 100644 --- a/plugins/Dfusion/src/lua_Misc.cpp +++ b/plugins/Dfusion/src/lua_Misc.cpp @@ -129,7 +129,7 @@ static int GetMod(lua_State *L) st.push(pos); return 1; } -static size_t __stdcall PushValue(size_t ret,uint32_t eax,uint32_t ebx,uint32_t ecx,uint32_t edx) +static size_t __stdcall PushValue(size_t ret,uint32_t eax,uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t edi,uint32_t esi,uint32_t esp,uint32_t ebp) { lua::state st=lua::glua::Get(); st.getglobal("OnFunction"); @@ -144,6 +144,14 @@ static size_t __stdcall PushValue(size_t ret,uint32_t eax,uint32_t ebx,uint32_t st.setfield("ecx"); st.push(edx); st.setfield("edx"); + st.push(edi); + st.setfield("edi"); + st.push(esi); + st.setfield("esi"); + st.push(esp); + st.setfield("esp"); + st.push(ebp); + st.setfield("ebp"); st.push(ret); st.setfield("ret"); st.pcall(1,1); From 97a85f274c2e58bd088d1d70bdea5e10ef36bf75 Mon Sep 17 00:00:00 2001 From: Warmist Date: Sat, 20 Aug 2011 20:23:47 +0300 Subject: [PATCH 08/15] Replaced test function with OnCreature move... --- plugins/Dfusion/luafiles/common.lua | 4 ++-- plugins/Dfusion/luafiles/onfunction/plugin.lua | 5 +++-- plugins/Dfusion/luafiles/triggers/functions.lua | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/plugins/Dfusion/luafiles/common.lua b/plugins/Dfusion/luafiles/common.lua index a7ce563ff..798d19c58 100644 --- a/plugins/Dfusion/luafiles/common.lua +++ b/plugins/Dfusion/luafiles/common.lua @@ -26,7 +26,7 @@ function GetTextRegion() return nil end function GetRegionIn(pos) - ranges__=ranges__ or Process.getMemRanges() + ranges__= Process.getMemRanges() for k,v in pairs(ranges__) do --for k2,v2 in pairs(v) do -- print(string.format("%d %s->%s",k,tostring(k2),tostring(v2))) @@ -449,7 +449,7 @@ end function GetCreatureAtPos(x,y,z) -- gets the creature index @ x,y,z coord --local x,y,z=getxyz() --get 'X' coords local vector=engine.peek(offsets.getEx("AdvCreatureVec"),ptr_vector) -- load all creatures - for i = 0, vector:size() do -- look into all creatures offsets + for i = 0, vector:size()-1 do -- look into all creatures offsets local curoff=vector:getval(i) -- get i-th creatures offset local cx=engine.peek(curoff,ptr_Creature.x) --get its coordinates local cy=engine.peek(curoff,ptr_Creature.y) diff --git a/plugins/Dfusion/luafiles/onfunction/plugin.lua b/plugins/Dfusion/luafiles/onfunction/plugin.lua index 14d6e219c..1ea926fee 100644 --- a/plugins/Dfusion/luafiles/onfunction/plugin.lua +++ b/plugins/Dfusion/luafiles/onfunction/plugin.lua @@ -21,7 +21,7 @@ function OnFunction(values) print(string.format("%s=%x",k,v)) end print("stack:") - for i=0,2 do + for i=0,3 do print(string.format("%d %x",i,engine.peekd(values.esp+i*4))) end return onfunction.calls[values.ret] --returns real function to call @@ -40,7 +40,8 @@ end mypos=engine.getmod("functions") if mypos then print("Onfunction already installed") - onfunction.patch(0x189dd6+offsets.base()) + --onfunction.patch(0x189dd6+offsets.base()) + onfunction.patch(0x55499D+offsets.base()) --on creature move else onfunction.install() end \ No newline at end of file diff --git a/plugins/Dfusion/luafiles/triggers/functions.lua b/plugins/Dfusion/luafiles/triggers/functions.lua index d5fca0773..e6c3a62c9 100644 --- a/plugins/Dfusion/luafiles/triggers/functions.lua +++ b/plugins/Dfusion/luafiles/triggers/functions.lua @@ -4,7 +4,7 @@ function func.Find_Print() end function func.PrintMessage(msg,color1,color2) func.f_print_pos= func.f_print_pos or func.Find_Print() - --print(string.format("%x",func.f_print_pos)) + print(string.format("Print @:%x",func.f_print_pos)) debuger.suspend() d=NewCallTable() -- make a call table t=Allocate(string.len(msg)) From 150e06f1157d8c27c398cc734835b3a0e09f58bd Mon Sep 17 00:00:00 2001 From: Warmist Date: Sat, 20 Aug 2011 23:13:14 +0300 Subject: [PATCH 09/15] OnFunction got new functions to make function callbacks easier (namely SetCallback(name,function) and AddFunction(addr,name)) --- .../Dfusion/luafiles/onfunction/plugin.lua | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/plugins/Dfusion/luafiles/onfunction/plugin.lua b/plugins/Dfusion/luafiles/onfunction/plugin.lua index 1ea926fee..8813b0c8b 100644 --- a/plugins/Dfusion/luafiles/onfunction/plugin.lua +++ b/plugins/Dfusion/luafiles/onfunction/plugin.lua @@ -13,9 +13,11 @@ function onfunction.install() engine.poked(onfunction.fpos,modpos+modsize) SetExecute(modpos) onfunction.calls={} + onfunction.functions={} + onfunction.names={} end function OnFunction(values) - print("Onfunction called!") + --[=[print("Onfunction called!") print("Data:") for k,v in pairs(values) do print(string.format("%s=%x",k,v)) @@ -24,6 +26,11 @@ function OnFunction(values) for i=0,3 do print(string.format("%d %x",i,engine.peekd(values.esp+i*4))) end + --]=] + if onfunction.functions[values.ret] ~=nil then + onfunction.functions[values.ret](values) + end + return onfunction.calls[values.ret] --returns real function to call end function onfunction.patch(addr) @@ -34,14 +41,30 @@ function onfunction.patch(addr) onfunction.calls[addr+5]=addr+engine.peekd(addr+1)+5 --adds real function to call engine.poked(addr+1,engine.getmod("functions")-addr-5) - + end +end +function onfunction.AddFunction(addr,name) + onfunction.patch(addr) + onfunction.names[name]=addr+5 +end +function onfunction.SetCallback(name,func) + if onfunction.names[name]==nil then + error("No such function:"..name) + else + onfunction.functions[onfunction.names[name]]=func end end mypos=engine.getmod("functions") +function DeathMsg(values) + name=engine.peek(values.edi,ptt_dfstring) + print(name:getval().." died") +end if mypos then print("Onfunction already installed") --onfunction.patch(0x189dd6+offsets.base()) - onfunction.patch(0x55499D+offsets.base()) --on creature move else onfunction.install() + onfunction.AddFunction(0x55499D+offsets.base(),"Move") --on creature move found with "watch mem=xcoord" + onfunction.AddFunction(0x275933+offsets.base(),"Die") --on creature death? found by watching dead flag then stepping until new function + onfunction.SetCallback("Die",DeathMsg) end \ No newline at end of file From 1a99121eadeeb4d85760d6c3e6e48f5c0e1927a7 Mon Sep 17 00:00:00 2001 From: Warmist Date: Sun, 21 Aug 2011 00:15:40 +0300 Subject: [PATCH 10/15] Started migration to init/plugin scheme (init files for noninteractive parts). Also added WINDOWS/LINUX flags --- plugins/Dfusion/dfusion.cpp | 19 ++-- plugins/Dfusion/luafiles/adv_tools/init.lua | 89 +++++++++++++++++++ plugins/Dfusion/luafiles/adv_tools/plugin.lua | 89 ------------------- plugins/Dfusion/luafiles/friendship/init.lua | 45 ++++++++++ .../Dfusion/luafiles/friendship/plugin.lua | 72 +++------------ plugins/Dfusion/luafiles/init.lua | 15 +++- 6 files changed, 175 insertions(+), 154 deletions(-) create mode 100644 plugins/Dfusion/luafiles/adv_tools/init.lua create mode 100644 plugins/Dfusion/luafiles/friendship/init.lua diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp index 965ee3475..514a5509d 100644 --- a/plugins/Dfusion/dfusion.cpp +++ b/plugins/Dfusion/dfusion.cpp @@ -38,12 +38,21 @@ DFhackCExport const char * plugin_name ( void ) DFhackCExport command_result plugin_init ( Core * c, std::vector &commands) { commands.clear(); + lua::state st=lua::glua::Get(); //maybe remake it to run automaticaly - lua::RegisterConsole(lua::glua::Get(),&c->con); - lua::RegisterProcess(lua::glua::Get(),c->p); - lua::RegisterHexsearch(lua::glua::Get()); - lua::RegisterMisc(lua::glua::Get()); - lua::RegisterVersionInfo(lua::glua::Get()); + lua::RegisterConsole(st,&c->con); + lua::RegisterProcess(st,c->p); + lua::RegisterHexsearch(st); + lua::RegisterMisc(st); + lua::RegisterVersionInfo(st); + #ifdef LINUX_BUILD + st.push(1); + st.setglobal("LINUX"); + #else + st.push(1); + st.setglobal("WINDOWS"); + #endif + commands.push_back(PluginCommand("dfusion","Init dfusion system. Use 'dfusion thready' to spawn a different thread.",dfusion)); commands.push_back(PluginCommand("lua", "Run interactive interpreter. Use 'lua ' to run instead.",lua_run)); diff --git a/plugins/Dfusion/luafiles/adv_tools/init.lua b/plugins/Dfusion/luafiles/adv_tools/init.lua new file mode 100644 index 000000000..d8317f7ab --- /dev/null +++ b/plugins/Dfusion/luafiles/adv_tools/init.lua @@ -0,0 +1,89 @@ +adv_tools=adv_tools or {} +adv_tools.menu=adv_tools.menu or MakeMenu() +function adv_tools.ressurect() + myoff=offsets.getEx("AdvCreatureVec") + vector=engine.peek(myoff,ptr_vector) + indx=GetCreatureAtPos(getxyz()) + if indx<0 then indx=0 end + --print(string.format("%x",vector:getval(indx))) + v2=engine.peek(vector:getval(indx),ptr_Creature.hurt1) + for i=0,v2:size()-1 do + v2:setval(i,0) + end + v2=engine.peek(vector:getval(indx),ptr_Creature.hurt2) + v2.type=DWORD + for i=0,v2:size()-1 do + v2:setval(i,0) + end + engine.poke(vector:getval(indx),ptr_Creature.bloodlvl,60000) --give blood + engine.poke(vector:getval(indx),ptr_Creature.bleedlvl,0) --stop some bleeding... + local flg=engine.peek(vector:getval(indx),ptr_Creature.flags) + flg:set(1,false) --ALIVE + flg:set(39,false) -- leave body yet again + flg:set(37,false) -- something todo with wounds- lets you walk again. + flg:set(58,true) -- makes them able to breathe + flg:set(61,true) -- gives them sight + engine.poke(vector:getval(indx),ptr_Creature.flags,flg) +end + +function adv_tools.wagonmode() --by rumrusher + --first three lines same as before (because we will need an offset of creature at location x,y,z) + myoff=offsets.getEx("AdvCreatureVec") + vector=engine.peek(myoff,ptr_vector) + indx=GetCreatureAtPos(getxyz()) + --indx=0 + --print(string.format("%x",vector:getval(indx))) + flg=engine.peek(vector:getval(indx),ptr_Creature.flags) --get flags + flg:set(1,false) + flg:set(74,false) + engine.poke(vector:getval(indx),ptr_Creature.flags,flg) + print("To stay normal press y, else hit Enter turn Wagon mode on.") + r=io.stdin:read() -- repeat for it too work... also creature will be dead. + if r== "y" then + flg=engine.peek(vector:getval(indx),ptr_Creature.flags) + flg:set(1,false) + engine.poke(vector:getval(indx),ptr_Creature.flags,flg) + else + flg=engine.peek(vector:getval(indx),ptr_Creature.flags) + flg:set(1,false) + flg:flip(74) + engine.poke(vector:getval(indx),ptr_Creature.flags,flg) + end +end +function selectall() + local retvec={} --return vector (or a list) + myoff=offsets.getEx("AdvCreatureVec") + vector=engine.peek(myoff,ptr_vector) --standart start + for i=0,vector:size()-1 do --check all creatures + local off + off=vector:getval(i) + local flags=engine.peek(off,ptr_Creature.flags) + if flags:get(1)==true then --if dead ... + table.insert(retvec,off)--... add it to return vector + end + end + return retvec --return the "return vector" :) +end +function adv_tools.hostilate() + vector=engine.peek(offsets.getEx("AdvCreatureVec"),ptr_vector) + id=GetCreatureAtPos(getxyz()) + print(string.format("Vec:%d cr:%d",vector:size(),id)) + off=vector:getval(id) + crciv=engine.peek(vector:getval(id),ptr_Creature.civ) + curciv=engine.peek(vector:getval(0),ptr_Creature.civ) + + if curciv==crciv then + print("Friendly-making enemy") + engine.poke(off,ptr_Creature.civ,-1) + flg=engine.peek(off,ptr_Creature.flags) + flg:set(17,true) + engine.poke(off,ptr_Creature.flags,flg) + else + print("Enemy- making friendly") + engine.poke(off,ptr_Creature.civ,curciv) + flg=engine.peek(off,ptr_Creature.flags) + flg:set(17,false) + flg:set(19,false) + engine.poke(off,ptr_Creature.flags,flg) + end +end diff --git a/plugins/Dfusion/luafiles/adv_tools/plugin.lua b/plugins/Dfusion/luafiles/adv_tools/plugin.lua index d8317f7ab..e69de29bb 100644 --- a/plugins/Dfusion/luafiles/adv_tools/plugin.lua +++ b/plugins/Dfusion/luafiles/adv_tools/plugin.lua @@ -1,89 +0,0 @@ -adv_tools=adv_tools or {} -adv_tools.menu=adv_tools.menu or MakeMenu() -function adv_tools.ressurect() - myoff=offsets.getEx("AdvCreatureVec") - vector=engine.peek(myoff,ptr_vector) - indx=GetCreatureAtPos(getxyz()) - if indx<0 then indx=0 end - --print(string.format("%x",vector:getval(indx))) - v2=engine.peek(vector:getval(indx),ptr_Creature.hurt1) - for i=0,v2:size()-1 do - v2:setval(i,0) - end - v2=engine.peek(vector:getval(indx),ptr_Creature.hurt2) - v2.type=DWORD - for i=0,v2:size()-1 do - v2:setval(i,0) - end - engine.poke(vector:getval(indx),ptr_Creature.bloodlvl,60000) --give blood - engine.poke(vector:getval(indx),ptr_Creature.bleedlvl,0) --stop some bleeding... - local flg=engine.peek(vector:getval(indx),ptr_Creature.flags) - flg:set(1,false) --ALIVE - flg:set(39,false) -- leave body yet again - flg:set(37,false) -- something todo with wounds- lets you walk again. - flg:set(58,true) -- makes them able to breathe - flg:set(61,true) -- gives them sight - engine.poke(vector:getval(indx),ptr_Creature.flags,flg) -end - -function adv_tools.wagonmode() --by rumrusher - --first three lines same as before (because we will need an offset of creature at location x,y,z) - myoff=offsets.getEx("AdvCreatureVec") - vector=engine.peek(myoff,ptr_vector) - indx=GetCreatureAtPos(getxyz()) - --indx=0 - --print(string.format("%x",vector:getval(indx))) - flg=engine.peek(vector:getval(indx),ptr_Creature.flags) --get flags - flg:set(1,false) - flg:set(74,false) - engine.poke(vector:getval(indx),ptr_Creature.flags,flg) - print("To stay normal press y, else hit Enter turn Wagon mode on.") - r=io.stdin:read() -- repeat for it too work... also creature will be dead. - if r== "y" then - flg=engine.peek(vector:getval(indx),ptr_Creature.flags) - flg:set(1,false) - engine.poke(vector:getval(indx),ptr_Creature.flags,flg) - else - flg=engine.peek(vector:getval(indx),ptr_Creature.flags) - flg:set(1,false) - flg:flip(74) - engine.poke(vector:getval(indx),ptr_Creature.flags,flg) - end -end -function selectall() - local retvec={} --return vector (or a list) - myoff=offsets.getEx("AdvCreatureVec") - vector=engine.peek(myoff,ptr_vector) --standart start - for i=0,vector:size()-1 do --check all creatures - local off - off=vector:getval(i) - local flags=engine.peek(off,ptr_Creature.flags) - if flags:get(1)==true then --if dead ... - table.insert(retvec,off)--... add it to return vector - end - end - return retvec --return the "return vector" :) -end -function adv_tools.hostilate() - vector=engine.peek(offsets.getEx("AdvCreatureVec"),ptr_vector) - id=GetCreatureAtPos(getxyz()) - print(string.format("Vec:%d cr:%d",vector:size(),id)) - off=vector:getval(id) - crciv=engine.peek(vector:getval(id),ptr_Creature.civ) - curciv=engine.peek(vector:getval(0),ptr_Creature.civ) - - if curciv==crciv then - print("Friendly-making enemy") - engine.poke(off,ptr_Creature.civ,-1) - flg=engine.peek(off,ptr_Creature.flags) - flg:set(17,true) - engine.poke(off,ptr_Creature.flags,flg) - else - print("Enemy- making friendly") - engine.poke(off,ptr_Creature.civ,curciv) - flg=engine.peek(off,ptr_Creature.flags) - flg:set(17,false) - flg:set(19,false) - engine.poke(off,ptr_Creature.flags,flg) - end -end diff --git a/plugins/Dfusion/luafiles/friendship/init.lua b/plugins/Dfusion/luafiles/friendship/init.lua new file mode 100644 index 000000000..12981d166 --- /dev/null +++ b/plugins/Dfusion/luafiles/friendship/init.lua @@ -0,0 +1,45 @@ +function analyzeF(off) + pos=offsets.find(off,0x39,ANYBYTE,0x8c,00,00,00) + print(string.format("Compare at:%x",pos)) + if pos ==0 then + return 0 + end + if(pos-off>0x100) then + print(string.format("Distance to cmp:%x",pos-off)) + pos =offsets.find(off,CALL) + print(string.format("Distance to call:%x",pos-off)) + return 0 + --return analyzeF(pos) + else + return pos + end +end +function minEx(...) + local imin=arg[1] + for _,v in ipairs(arg) do + if imin> v and v~=0 then + imin=v + end + end + return imin +end +function signDword(dw) + if(dw>0xFFFFFFFF) then + return dw-0xFFFFFFFF + end + return dw +end +--[[ + Warning: not all mov's are acounted for. Found one: mov EAX,WORD PTR[EBP+1EF4] WTF?? + Two more compares are missing. There are calls instead (same function) +]]-- + +friendship_in={} +dofile("dfusion/friendship/install.lua") +dofile("dfusion/friendship/patch.lua") + +function friendship(names) + friendship_in.install(names) + friendship_in.patch() +end + diff --git a/plugins/Dfusion/luafiles/friendship/plugin.lua b/plugins/Dfusion/luafiles/friendship/plugin.lua index e820a0ccd..633b30239 100644 --- a/plugins/Dfusion/luafiles/friendship/plugin.lua +++ b/plugins/Dfusion/luafiles/friendship/plugin.lua @@ -1,65 +1,19 @@ ---if(mypos~=0) then ---print("plugin already active") ---maybe set options for reinit? ---return ---end - -function analyzeF(off) - pos=offsets.find(off,0x39,ANYBYTE,0x8c,00,00,00) - print(string.format("Compare at:%x",pos)) - if pos ==0 then - return 0 - end - if(pos-off>0x100) then - print(string.format("Distance to cmp:%x",pos-off)) - pos =offsets.find(off,CALL) - print(string.format("Distance to call:%x",pos-off)) - return 0 - --return analyzeF(pos) - else - return pos - end -end -function minEx(...) - local imin=arg[1] - for _,v in ipairs(arg) do - if imin> v and v~=0 then - imin=v - end - end - return imin -end -function signDword(dw) - if(dw>0xFFFFFFFF) then - return dw-0xFFFFFFFF - end - return dw -end ---[[ - Warning: not all mov's are acounted for. Found one: mov EAX,WORD PTR[EBP+1EF4] WTF?? - Two more compares are missing. There are calls instead (same function) -]]-- if not(FILE) then ---print("race num:"..engine.peekw(offsets.getEx("CurrentRace"))) ---print(string.format("%x vs %x",offsets.getEx("CurrentRace"),VersionInfo.getGroup("Creatures"):getAddress("current_race"))) -add_race=VersionInfo.getGroup("Creatures"):getAddress("current_race") -print("Race num:"..engine.peekw(add_race)) -print("Your current race is:"..GetRaceToken(engine.peekw(add_race))) -print("If this is wrong please type 'q'") -if(io.stdin:read()=='q') then - return -end + --sanity test + --print("race num:"..engine.peekw(offsets.getEx("CurrentRace"))) + --print(string.format("%x vs %x",offsets.getEx("CurrentRace"),VersionInfo.getGroup("Creatures"):getAddress("current_race"))) + add_race=VersionInfo.getGroup("Creatures"):getAddress("current_race") + print("Race num:"..engine.peekw(add_race)) + print("Your current race is:"..GetRaceToken(engine.peekw(add_race))) + print("If this is wrong please type 'q'") + if(io.stdin:read()=='q') then + return + end + end -friendship_in={} -dofile("dfusion/friendship/install.lua") -dofile("dfusion/friendship/patch.lua") + if not(FILE) then names=ParseNames("dfusion/friendship/races.txt")--io.open("plugins/friendship/races.txt"):lines() friendship_in.install(names) friendship_in.patch() -end -function friendship(names) - friendship_in.install(names) - friendship_in.patch() -end - +end \ No newline at end of file diff --git a/plugins/Dfusion/luafiles/init.lua b/plugins/Dfusion/luafiles/init.lua index a5ca70c6c..d5d067ea6 100644 --- a/plugins/Dfusion/luafiles/init.lua +++ b/plugins/Dfusion/luafiles/init.lua @@ -13,7 +13,17 @@ function dofile(filename) --safer dofile, with traceback (very usefull) print(perr) end end - +function dofile_silent(filename) --safer dofile, with traceback, no file not found error + f,perr=loadfile(filename) + if f~=nil then + return xpcall(f,err) + end +end +function loadall(t1) --loads all non interactive plugin parts, so that later they could be used + for k,v in pairs(t1) do + dofile_silent("dfusion/"..v[1].."/init.lua") + end +end function mainmenu(t1) Console.clear() while true do @@ -45,5 +55,8 @@ table.insert(plugins,{"tools","some misc tools"}) table.insert(plugins,{"triggers","a function calling plug (discontinued...)"}) table.insert(plugins,{"migrants","multi race imigrations"}) table.insert(plugins,{"onfunction","run lua on some df function"}) +loadall(plugins) +if not INIT then mainmenu(plugins) +end From 8e68b50ed7460dd2f13367f10302c8fab45bd80f Mon Sep 17 00:00:00 2001 From: Warmist Date: Sun, 21 Aug 2011 01:46:16 +0300 Subject: [PATCH 11/15] Linux tinkerings, moved few offsets and part of creature pattern into memory.xml model --- plugins/Dfusion/luafiles/common.lua | 4 +- plugins/Dfusion/luafiles/onfunction/init.lua | 57 ++++++++++++++++ .../Dfusion/luafiles/onfunction/plugin.lua | 66 ++----------------- plugins/Dfusion/luafiles/patterns.lua | 7 +- plugins/Dfusion/src/lua_Misc.cpp | 4 +- 5 files changed, 72 insertions(+), 66 deletions(-) create mode 100644 plugins/Dfusion/luafiles/onfunction/init.lua diff --git a/plugins/Dfusion/luafiles/common.lua b/plugins/Dfusion/luafiles/common.lua index 798d19c58..83794fb44 100644 --- a/plugins/Dfusion/luafiles/common.lua +++ b/plugins/Dfusion/luafiles/common.lua @@ -438,7 +438,7 @@ function ParseNames(path) end function getxyz() -- this will return pointers x,y and z coordinates. - local off=offsets.getEx("Xpointer") -- lets find where in memory its being held + local off=VersionInfo.getGroup("Position"):getAddress("cursor_xyz") -- lets find where in memory its being held -- now lets read them (they are double words (or unsigned longs or 4 bits each) and go in sucesion local x=engine.peekd(off) local y=engine.peekd(off+4) --next is 4 from start @@ -448,7 +448,7 @@ function getxyz() -- this will return pointers x,y and z coordinates. end function GetCreatureAtPos(x,y,z) -- gets the creature index @ x,y,z coord --local x,y,z=getxyz() --get 'X' coords - local vector=engine.peek(offsets.getEx("AdvCreatureVec"),ptr_vector) -- load all creatures + local vector=engine.peek(VersionInfo.getGroup("Creatures"):getAddress("vector"),ptr_vector) -- load all creatures for i = 0, vector:size()-1 do -- look into all creatures offsets local curoff=vector:getval(i) -- get i-th creatures offset local cx=engine.peek(curoff,ptr_Creature.x) --get its coordinates diff --git a/plugins/Dfusion/luafiles/onfunction/init.lua b/plugins/Dfusion/luafiles/onfunction/init.lua new file mode 100644 index 000000000..5adb73036 --- /dev/null +++ b/plugins/Dfusion/luafiles/onfunction/init.lua @@ -0,0 +1,57 @@ +onfunction=onfunction or {} +function onfunction.install() + ModData=engine.installMod("dfusion/onfunction/functions.o","functions",4) + modpos=ModData.pos + modsize=ModData.size + onfunction.pos=modpos + trgpos=engine.getpushvalue() + print(string.format("Function installed in:%x function to call is: %x",modpos,trgpos)) + local firstpos=modpos+engine.FindMarker(ModData,"function") + engine.poked(firstpos,trgpos-firstpos-4) --call Lua-Onfunction + onfunction.fpos=modpos+engine.FindMarker(ModData,"function3") + engine.poked(modpos+engine.FindMarker(ModData,"function2"),modpos+modsize) + engine.poked(onfunction.fpos,modpos+modsize) + SetExecute(modpos) + onfunction.calls={} + onfunction.functions={} + onfunction.names={} +end +function OnFunction(values) + --[=[print("Onfunction called!") + print("Data:") + for k,v in pairs(values) do + print(string.format("%s=%x",k,v)) + end + print("stack:") + for i=0,3 do + print(string.format("%d %x",i,engine.peekd(values.esp+i*4))) + end + --]=] + if onfunction.functions[values.ret] ~=nil then + onfunction.functions[values.ret](values) + end + + return onfunction.calls[values.ret] --returns real function to call +end +function onfunction.patch(addr) + + if(engine.peekb(addr)~=0xe8) then + error("Incorrect address, not a function call") + else + + onfunction.calls[addr+5]=addr+engine.peekd(addr+1)+5 --adds real function to call + engine.poked(addr+1,engine.getmod("functions")-addr-5) + end +end +function onfunction.AddFunction(addr,name) + onfunction.patch(addr) + onfunction.names[name]=addr+5 +end +function onfunction.SetCallback(name,func) + if onfunction.names[name]==nil then + error("No such function:"..name) + else + onfunction.functions[onfunction.names[name]]=func + end +end + diff --git a/plugins/Dfusion/luafiles/onfunction/plugin.lua b/plugins/Dfusion/luafiles/onfunction/plugin.lua index 8813b0c8b..d3e4d3c16 100644 --- a/plugins/Dfusion/luafiles/onfunction/plugin.lua +++ b/plugins/Dfusion/luafiles/onfunction/plugin.lua @@ -1,59 +1,3 @@ -onfunction=onfunction or {} -function onfunction.install() - ModData=engine.installMod("dfusion/onfunction/functions.o","functions",4) - modpos=ModData.pos - modsize=ModData.size - onfunction.pos=modpos - trgpos=engine.getpushvalue() - print(string.format("Function installed in:%x function to call is: %x",modpos,trgpos)) - local firstpos=modpos+engine.FindMarker(ModData,"function") - engine.poked(firstpos,trgpos-firstpos-4) --call Lua-Onfunction - onfunction.fpos=modpos+engine.FindMarker(ModData,"function3") - engine.poked(modpos+engine.FindMarker(ModData,"function2"),modpos+modsize) - engine.poked(onfunction.fpos,modpos+modsize) - SetExecute(modpos) - onfunction.calls={} - onfunction.functions={} - onfunction.names={} -end -function OnFunction(values) - --[=[print("Onfunction called!") - print("Data:") - for k,v in pairs(values) do - print(string.format("%s=%x",k,v)) - end - print("stack:") - for i=0,3 do - print(string.format("%d %x",i,engine.peekd(values.esp+i*4))) - end - --]=] - if onfunction.functions[values.ret] ~=nil then - onfunction.functions[values.ret](values) - end - - return onfunction.calls[values.ret] --returns real function to call -end -function onfunction.patch(addr) - - if(engine.peekb(addr)~=0xe8) then - error("Incorrect address, not a function call") - else - - onfunction.calls[addr+5]=addr+engine.peekd(addr+1)+5 --adds real function to call - engine.poked(addr+1,engine.getmod("functions")-addr-5) - end -end -function onfunction.AddFunction(addr,name) - onfunction.patch(addr) - onfunction.names[name]=addr+5 -end -function onfunction.SetCallback(name,func) - if onfunction.names[name]==nil then - error("No such function:"..name) - else - onfunction.functions[onfunction.names[name]]=func - end -end mypos=engine.getmod("functions") function DeathMsg(values) name=engine.peek(values.edi,ptt_dfstring) @@ -64,7 +8,11 @@ if mypos then --onfunction.patch(0x189dd6+offsets.base()) else onfunction.install() - onfunction.AddFunction(0x55499D+offsets.base(),"Move") --on creature move found with "watch mem=xcoord" - onfunction.AddFunction(0x275933+offsets.base(),"Die") --on creature death? found by watching dead flag then stepping until new function + if WINDOWS then + onfunction.AddFunction(0x55499D+offsets.base(),"Move") --on creature move found with "watch mem=xcoord" + onfunction.AddFunction(0x275933+offsets.base(),"Die") --on creature death? found by watching dead flag then stepping until new function + else + + end onfunction.SetCallback("Die",DeathMsg) -end \ No newline at end of file +end diff --git a/plugins/Dfusion/luafiles/patterns.lua b/plugins/Dfusion/luafiles/patterns.lua index f4ac43650..baffe09eb 100644 --- a/plugins/Dfusion/luafiles/patterns.lua +++ b/plugins/Dfusion/luafiles/patterns.lua @@ -169,9 +169,10 @@ end ]]-- ptr_Creature={} -ptr_Creature.x={off=144,rtype=WORD} --ok -ptr_Creature.y={off=146,rtype=WORD} --ok -ptr_Creature.z={off=148,rtype=WORD} --ok +local posoff=VersionInfo.getGroup("Creatures"):getGroup("creature"):getOffset("position") +ptr_Creature.x={off=posoff,rtype=WORD} --ok +ptr_Creature.y={off=posoff+2,rtype=WORD} --ok +ptr_Creature.z={off=posoff+4,rtype=WORD} --ok ptr_Creature.flags={off=224,rtype=ptt_dfflag.new(10)} ptr_Creature.name={off=0,rtype=ptt_dfstring} ptr_Creature.ID={off=252,rtype=DWORD} --ok i guess diff --git a/plugins/Dfusion/src/lua_Misc.cpp b/plugins/Dfusion/src/lua_Misc.cpp index 5ac4bd73b..be1de4a24 100644 --- a/plugins/Dfusion/src/lua_Misc.cpp +++ b/plugins/Dfusion/src/lua_Misc.cpp @@ -129,7 +129,7 @@ static int GetMod(lua_State *L) st.push(pos); return 1; } -static size_t __stdcall PushValue(size_t ret,uint32_t eax,uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t edi,uint32_t esi,uint32_t esp,uint32_t ebp) +static size_t __attribute__((stdcall)) PushValue(size_t ret,uint32_t eax,uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t edi,uint32_t esi,uint32_t esp,uint32_t ebp) { lua::state st=lua::glua::Get(); st.getglobal("OnFunction"); @@ -184,4 +184,4 @@ void lua::RegisterMisc(lua::state &st) } lua::RegFunctionsLocal(st, lua_misc_func); st.setglobal("engine"); -} \ No newline at end of file +} From 246f704c680abe5fe32d039c5069b146c96db881 Mon Sep 17 00:00:00 2001 From: Warmist Date: Sun, 21 Aug 2011 15:56:42 +0300 Subject: [PATCH 12/15] Move function found for linux. --- plugins/Dfusion/luafiles/onfunction/plugin.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/Dfusion/luafiles/onfunction/plugin.lua b/plugins/Dfusion/luafiles/onfunction/plugin.lua index d3e4d3c16..6ef90a5a6 100644 --- a/plugins/Dfusion/luafiles/onfunction/plugin.lua +++ b/plugins/Dfusion/luafiles/onfunction/plugin.lua @@ -12,7 +12,9 @@ else onfunction.AddFunction(0x55499D+offsets.base(),"Move") --on creature move found with "watch mem=xcoord" onfunction.AddFunction(0x275933+offsets.base(),"Die") --on creature death? found by watching dead flag then stepping until new function else - + --onfunction.AddFunction(0x0899be82+offsets.base(),"Move") -- found out by attaching watch... + onfunction.AddFunction(0x899befe+offsets.base(),"Move") -- found out by attaching watch... + end onfunction.SetCallback("Die",DeathMsg) end From 78ed7d314b3205ca09be88ca617bd1ed55d1f55b Mon Sep 17 00:00:00 2001 From: Warmist Date: Sun, 21 Aug 2011 16:27:01 +0300 Subject: [PATCH 13/15] Linux support for onfunction/Die. --- plugins/Dfusion/luafiles/common.lua | 2 + .../Dfusion/luafiles/onfunction/plugin.lua | 9 ++- plugins/Dfusion/luafiles/patterns.lua | 77 ++++++++++--------- 3 files changed, 48 insertions(+), 40 deletions(-) diff --git a/plugins/Dfusion/luafiles/common.lua b/plugins/Dfusion/luafiles/common.lua index 83794fb44..55c3793f2 100644 --- a/plugins/Dfusion/luafiles/common.lua +++ b/plugins/Dfusion/luafiles/common.lua @@ -84,6 +84,8 @@ engine.peekb=Process.readByte engine.pokeb=Process.writeByte engine.peekw=Process.readWord engine.pokew=Process.writeWord +engine.peekstr_stl=Process.readSTLString +engine.pokestr_stl=Process.writeSTLString engine.peekstr=Process.readCString --engine.pokestr=Process.readCString engine.peekarb=Process.read diff --git a/plugins/Dfusion/luafiles/onfunction/plugin.lua b/plugins/Dfusion/luafiles/onfunction/plugin.lua index 6ef90a5a6..7de47f588 100644 --- a/plugins/Dfusion/luafiles/onfunction/plugin.lua +++ b/plugins/Dfusion/luafiles/onfunction/plugin.lua @@ -1,6 +1,11 @@ mypos=engine.getmod("functions") function DeathMsg(values) - name=engine.peek(values.edi,ptt_dfstring) + local name + if WINDOWS then + name=engine.peek(values.edi,ptt_dfstring) + else + name=engine.peek(values.ebx,ptt_dfstring) + end print(name:getval().." died") end if mypos then @@ -14,7 +19,7 @@ else else --onfunction.AddFunction(0x0899be82+offsets.base(),"Move") -- found out by attaching watch... onfunction.AddFunction(0x899befe+offsets.base(),"Move") -- found out by attaching watch... - + onfunction.AddFunction(0x850eecd+offsets.base(),"Die") -- same end onfunction.SetCallback("Die",DeathMsg) end diff --git a/plugins/Dfusion/luafiles/patterns.lua b/plugins/Dfusion/luafiles/patterns.lua index baffe09eb..1d15741eb 100644 --- a/plugins/Dfusion/luafiles/patterns.lua +++ b/plugins/Dfusion/luafiles/patterns.lua @@ -1,50 +1,51 @@ ptt_dfstring={} -if(COMPATMODE) then -ptt_dfstring.ptr={off=4,rtype=DWORD} -ptt_dfstring.size={off=20,rtype=DWORD} +if WINDOWS then + ptt_dfstring.ptr={off=0,rtype=DWORD} + ptt_dfstring.size={off=16,rtype=DWORD} + ptt_dfstring.alloc={off=20,rtype=DWORD} -else -ptt_dfstring.ptr={off=0,rtype=DWORD} -ptt_dfstring.size={off=16,rtype=DWORD} -ptt_dfstring.alloc={off=20,rtype=DWORD} -end -function ptt_dfstring:getval() - --print(string.format("GETTING FROM:%x",self.__offset)) - if self.size<16 then + function ptt_dfstring:getval() --print(string.format("GETTING FROM:%x",self.__offset)) - return string.sub(engine.peekstr(self.__offset),1,self.size) - else - --print(string.format("GETTING FROM:%x",self.ptr)) - return string.sub(engine.peekstr(self.ptr),1,self.size) + if self.size<16 then + --print(string.format("GETTING FROM:%x",self.__offset)) + return string.sub(engine.peekstr(self.__offset),1,self.size) + else + --print(string.format("GETTING FROM:%x",self.ptr)) + return string.sub(engine.peekstr(self.ptr),1,self.size) + end end -end -function ptt_dfstring:setval(newstring) - local offset=self.__offset - local strl=string.len(newstring) - if strl<16 then - --print(string.format("GETTING FROM:%x",self.__offset)) + function ptt_dfstring:setval(newstring) + local offset=self.__offset + local strl=string.len(newstring) + if strl<16 then + --print(string.format("GETTING FROM:%x",self.__offset)) - engine.poked(offset+ptt_dfstring.size.off,strl) - engine.poked(offset+ptt_dfstring.alloc.off,15) - engine.pokestr(offset,newstring) + engine.poked(offset+ptt_dfstring.size.off,strl) + engine.poked(offset+ptt_dfstring.alloc.off,15) + engine.pokestr(offset,newstring) - else - local loc - if engine.peekd(offset+ptt_dfstring.alloc.off) > strl then - loc=engine.peekd(offset) - print("Will fit:"..loc.." len:"..strl) else - loc=Allocate(strl+1) - engine.poked(offset+ptt_dfstring.alloc.off,strl) - print("Will not fit:"..loc.." len:"..strl) + local loc + if engine.peekd(offset+ptt_dfstring.alloc.off) > strl then + loc=engine.peekd(offset) + print("Will fit:"..loc.." len:"..strl) + else + loc=Allocate(strl+1) + engine.poked(offset+ptt_dfstring.alloc.off,strl) + print("Will not fit:"..loc.." len:"..strl) + end + --print(string.format("GETTING FROM:%x",self.ptr)) + engine.poked(self.__offset+ptt_dfstring.size.off,strl) + engine.pokestr(loc,newstring) + engine.poked(self.__offset,loc) end - --print(string.format("GETTING FROM:%x",self.ptr)) - engine.poked(self.__offset+ptt_dfstring.size.off,strl) - engine.pokestr(loc,newstring) - engine.poked(self.__offset,loc) + end +else + --ptt_dfstring.ptr={off=0,rtype=DWORD} + function ptt_dfstring:getval() + return engine.peekstr_stl(self.__offset) end end - --if(COMPATMODE) then --ptr_vector={} --ptr_vector.st={off=4,rtype=DWORD} @@ -173,7 +174,7 @@ local posoff=VersionInfo.getGroup("Creatures"):getGroup("creature"):getOffset("p ptr_Creature.x={off=posoff,rtype=WORD} --ok ptr_Creature.y={off=posoff+2,rtype=WORD} --ok ptr_Creature.z={off=posoff+4,rtype=WORD} --ok -ptr_Creature.flags={off=224,rtype=ptt_dfflag.new(10)} +ptr_Creature.flags={off=VersionInfo.getGroup("Creatures"):getGroup("creature"):getOffset("flags1"),rtype=ptt_dfflag.new(10)} ptr_Creature.name={off=0,rtype=ptt_dfstring} ptr_Creature.ID={off=252,rtype=DWORD} --ok i guess ptr_Creature.followID={off=592,rtype=DWORD} --ok From cc73dd31400edb32d8fcd13d9c1af55c0012589a Mon Sep 17 00:00:00 2001 From: Warmist Date: Sun, 21 Aug 2011 20:29:35 +0300 Subject: [PATCH 14/15] Refactored onfunction a bit, added function hints. --- plugins/Dfusion/luafiles/onfunction/init.lua | 6 +++++- plugins/Dfusion/luafiles/onfunction/locations.lua | 7 +++++++ plugins/Dfusion/luafiles/onfunction/plugin.lua | 15 ++------------- 3 files changed, 14 insertions(+), 14 deletions(-) create mode 100644 plugins/Dfusion/luafiles/onfunction/locations.lua diff --git a/plugins/Dfusion/luafiles/onfunction/init.lua b/plugins/Dfusion/luafiles/onfunction/init.lua index 5adb73036..52620ad10 100644 --- a/plugins/Dfusion/luafiles/onfunction/init.lua +++ b/plugins/Dfusion/luafiles/onfunction/init.lua @@ -15,6 +15,7 @@ function onfunction.install() onfunction.calls={} onfunction.functions={} onfunction.names={} + onfunction.hints={} end function OnFunction(values) --[=[print("Onfunction called!") @@ -43,9 +44,12 @@ function onfunction.patch(addr) engine.poked(addr+1,engine.getmod("functions")-addr-5) end end -function onfunction.AddFunction(addr,name) +function onfunction.AddFunction(addr,name,hints) onfunction.patch(addr) onfunction.names[name]=addr+5 + if hints~=nil then + onfunction.hints[name]=hints + end end function onfunction.SetCallback(name,func) if onfunction.names[name]==nil then diff --git a/plugins/Dfusion/luafiles/onfunction/locations.lua b/plugins/Dfusion/luafiles/onfunction/locations.lua new file mode 100644 index 000000000..2f6e4d80c --- /dev/null +++ b/plugins/Dfusion/luafiles/onfunction/locations.lua @@ -0,0 +1,7 @@ +if WINDOWS then --windows function defintions + onfunction.AddFunction(0x55499D+offsets.base(),"Move") --on creature move found with "watch mem=xcoord" + onfunction.AddFunction(0x275933+offsets.base(),"Die",{creature="edi"}) --on creature death? found by watching dead flag then stepping until new function +else --linux + onfunction.AddFunction(0x899befe+offsets.base(),"Move") -- found out by attaching watch... + onfunction.AddFunction(0x850eecd+offsets.base(),"Die",{creature="ebx"}) -- same +end diff --git a/plugins/Dfusion/luafiles/onfunction/plugin.lua b/plugins/Dfusion/luafiles/onfunction/plugin.lua index 7de47f588..7c76af122 100644 --- a/plugins/Dfusion/luafiles/onfunction/plugin.lua +++ b/plugins/Dfusion/luafiles/onfunction/plugin.lua @@ -1,11 +1,7 @@ mypos=engine.getmod("functions") function DeathMsg(values) local name - if WINDOWS then - name=engine.peek(values.edi,ptt_dfstring) - else - name=engine.peek(values.ebx,ptt_dfstring) - end + name=engine.peek(values[onfunction.hints["Die"].creature],ptt_dfstring) print(name:getval().." died") end if mypos then @@ -13,13 +9,6 @@ if mypos then --onfunction.patch(0x189dd6+offsets.base()) else onfunction.install() - if WINDOWS then - onfunction.AddFunction(0x55499D+offsets.base(),"Move") --on creature move found with "watch mem=xcoord" - onfunction.AddFunction(0x275933+offsets.base(),"Die") --on creature death? found by watching dead flag then stepping until new function - else - --onfunction.AddFunction(0x0899be82+offsets.base(),"Move") -- found out by attaching watch... - onfunction.AddFunction(0x899befe+offsets.base(),"Move") -- found out by attaching watch... - onfunction.AddFunction(0x850eecd+offsets.base(),"Die") -- same - end + dofile("dfusion/onfunction/locations.lua") onfunction.SetCallback("Die",DeathMsg) end From 0975b7352ec927d4dab9bb475dd27e77b9bb06d0 Mon Sep 17 00:00:00 2001 From: Warmist Date: Mon, 22 Aug 2011 16:21:13 +0300 Subject: [PATCH 15/15] Memview plugin. --- plugins/CMakeLists.txt | 2 + plugins/memview.cpp | 114 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 plugins/memview.cpp diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 9946ef427..0d3bb57e6 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -118,3 +118,5 @@ DFHACK_PLUGIN(autodump autodump.cpp) DFHACK_PLUGIN(cleanowned cleanowned.cpp) DFHACK_PLUGIN(deramp deramp.cpp) DFHACK_PLUGIN(flows flows.cpp) +DFHACK_PLUGIN(memview memview.cpp) + diff --git a/plugins/memview.cpp b/plugins/memview.cpp new file mode 100644 index 000000000..7c57d010a --- /dev/null +++ b/plugins/memview.cpp @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +using std::vector; +using std::string; +using namespace DFHack; + +DFhackCExport command_result memview (Core * c, vector & parameters); + +DFhackCExport const char * plugin_name ( void ) +{ + return "memview"; +} + +DFhackCExport command_result plugin_init ( Core * c, std::vector &commands) +{ + commands.clear(); + commands.push_back(PluginCommand("memview","Shows memory in real time. Params: adrr length refresh_rate.",memview)); + return CR_OK; +} +size_t convert(const std::string& p,bool ishex=false) +{ + size_t ret; + std::stringstream conv; + if(ishex) + conv<>ret; + return ret; +} +bool isAddr(uint32_t *trg,vector & ranges) +{ + if(trg[0]%4==0) + for(size_t i=0;i & ranges) +{ + + con.clear(); + const size_t page_size=16; + for(size_t i=0;i20) + con.print("%c",buf[j+i]); + else + con.print("."); + con.print("\n"); + } +} +DFhackCExport command_result memview (Core * c, vector & parameters) +{ + size_t addr=convert(parameters[0],true); + size_t len; + if(parameters.size()>1) + len=convert(parameters[1]); + else + len=20*16; + size_t refresh; + if(parameters.size()>2) + refresh=convert(parameters[2]); + else + refresh=0; + Console &con=c->con; + uint8_t *buf,*lbuf; + buf=new uint8_t[len]; + lbuf=new uint8_t[len]; + uint64_t timeLast=0; + vector ranges; + c->p->getMemRanges(ranges); + while(true)//TODO add some sort of way to exit loop??!! + { + uint64_t time2 = GetTimeMs64(); + uint64_t delta = time2-timeLast; + if(refresh!=0) + if(deltap->read(addr,len,buf); + outputHex(buf,lbuf,len,addr,con,ranges); + if(refresh==0) + break; + memcpy(lbuf, buf, len); + } + delete[] buf; + delete[] lbuf; +}