From 7cb0667519fba72a47cbc997bb499ae6fc520ef1 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Mon, 6 Sep 2021 19:56:07 +0200 Subject: [PATCH 01/29] Make buildable --- SMInjector/SMInjector.sln | 14 -------------- SMLibrary/SMLibrary.vcxproj | 2 ++ 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/SMInjector/SMInjector.sln b/SMInjector/SMInjector.sln index a160e7b..5b3cfed 100644 --- a/SMInjector/SMInjector.sln +++ b/SMInjector/SMInjector.sln @@ -24,11 +24,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SMLuaReaderPlugin", "..\Plu {81368E09-9FA2-4F28-9915-22FE758BFD48} = {81368E09-9FA2-4F28-9915-22FE758BFD48} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PlaygroundPlugin", "..\PluginDevFolder\PlaygroundPlugin\PlaygroundPlugin.vcxproj", "{53AE29AD-5DEB-4557-A65E-6E68D2E5336A}" - ProjectSection(ProjectDependencies) = postProject - {81368E09-9FA2-4F28-9915-22FE758BFD48} = {81368E09-9FA2-4F28-9915-22FE758BFD48} - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -68,14 +63,6 @@ Global {13E88C11-DEB6-47D5-9382-4E5D484A58C2}.Release|x64.ActiveCfg = Release|x64 {13E88C11-DEB6-47D5-9382-4E5D484A58C2}.Release|x64.Build.0 = Release|x64 {13E88C11-DEB6-47D5-9382-4E5D484A58C2}.Release|x86.ActiveCfg = Release|x64 - {53AE29AD-5DEB-4557-A65E-6E68D2E5336A}.Debug|x64.ActiveCfg = Debug|x64 - {53AE29AD-5DEB-4557-A65E-6E68D2E5336A}.Debug|x64.Build.0 = Debug|x64 - {53AE29AD-5DEB-4557-A65E-6E68D2E5336A}.Debug|x86.ActiveCfg = Debug|Win32 - {53AE29AD-5DEB-4557-A65E-6E68D2E5336A}.Debug|x86.Build.0 = Debug|Win32 - {53AE29AD-5DEB-4557-A65E-6E68D2E5336A}.Release|x64.ActiveCfg = Release|x64 - {53AE29AD-5DEB-4557-A65E-6E68D2E5336A}.Release|x64.Build.0 = Release|x64 - {53AE29AD-5DEB-4557-A65E-6E68D2E5336A}.Release|x86.ActiveCfg = Release|Win32 - {53AE29AD-5DEB-4557-A65E-6E68D2E5336A}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -84,7 +71,6 @@ Global {F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA} = {4EC6A5BC-FCE4-4FFE-AC55-7D83B6B7C8D7} {16BDCA26-D20C-4AC4-8DB3-9C108719B752} = {4EC6A5BC-FCE4-4FFE-AC55-7D83B6B7C8D7} {13E88C11-DEB6-47D5-9382-4E5D484A58C2} = {4EC6A5BC-FCE4-4FFE-AC55-7D83B6B7C8D7} - {53AE29AD-5DEB-4557-A65E-6E68D2E5336A} = {4EC6A5BC-FCE4-4FFE-AC55-7D83B6B7C8D7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D7E2F6B1-96AC-4FB5-B8AA-FDB43C7F169E} diff --git a/SMLibrary/SMLibrary.vcxproj b/SMLibrary/SMLibrary.vcxproj index aabc594..15788df 100644 --- a/SMLibrary/SMLibrary.vcxproj +++ b/SMLibrary/SMLibrary.vcxproj @@ -94,6 +94,7 @@ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MaxSpeed + Default Console @@ -123,6 +124,7 @@ _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MaxSpeed + Default Console From f2f82f5d8163f80a7165e53abee1ef308859b619 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Tue, 7 Sep 2021 00:22:06 +0200 Subject: [PATCH 02/29] Add SMLuaHook --- PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj | 119 ++++++++++++++++++ .../SMLuaHook/SMLuaHook.vcxproj.filters | 30 +++++ PluginDevFolder/SMLuaHook/hooks.h | 48 +++++++ PluginDevFolder/SMLuaHook/main.cpp | 59 +++++++++ PluginDevFolder/SMLuaHook/packages.config | 4 + .../SMPluginTemplate/SMPluginTemplate.vcxproj | 91 -------------- .../TileEditorUnlockPlugin.vcxproj | 83 ------------ SMInjector/SMInjector.sln | 25 ++-- SMLibrary/SMLibrary.vcxproj | 65 ---------- 9 files changed, 267 insertions(+), 257 deletions(-) create mode 100644 PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj create mode 100644 PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj.filters create mode 100644 PluginDevFolder/SMLuaHook/hooks.h create mode 100644 PluginDevFolder/SMLuaHook/main.cpp create mode 100644 PluginDevFolder/SMLuaHook/packages.config diff --git a/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj b/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj new file mode 100644 index 0000000..fa3849c --- /dev/null +++ b/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj @@ -0,0 +1,119 @@ + + + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + 16.0 + Win32Proj + {93661f1d-21dc-4b5b-88ec-6bea337df56b} + SMLuaHook + 10.0 + + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + true + $(SolutionDir)..\SMLibrary\include;$(IncludePath) + $(OutDir);$(LibraryPath) + + + false + $(SolutionDir)..\SMLibrary\include;$(IncludePath) + $(OutDir);$(LibraryPath) + + + + Level3 + true + _DEBUG;SMLUAHOOK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + pch.h + + + Windows + true + false + smlibrary.lib + + + if not exist "$(OutputPath)plugins\" mkdir "$(OutputPath)plugins\" +copy /B "$(LocalDebuggerCommand)" "$(OutputPath)plugins\$(TargetFileName)" + + + + + Level3 + true + true + true + NDEBUG;SMLUAHOOK_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + pch.h + + + Windows + true + true + true + false + smlibrary.lib + + + if not exist "$(OutputPath)plugins\" mkdir "$(OutputPath)plugins\" +copy /B "$(LocalDebuggerCommand)" "$(OutputPath)plugins\$(TargetFileName)" + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj.filters b/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj.filters new file mode 100644 index 0000000..74a3413 --- /dev/null +++ b/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + + + + \ No newline at end of file diff --git a/PluginDevFolder/SMLuaHook/hooks.h b/PluginDevFolder/SMLuaHook/hooks.h new file mode 100644 index 0000000..e3d508e --- /dev/null +++ b/PluginDevFolder/SMLuaHook/hooks.h @@ -0,0 +1,48 @@ +#pragma once +#include +#include +#include + +#include +using Console::Color; + + +// LUAL_REGISTER +typedef void (*pluaL_register)(lua_State*, const char*, const luaL_Reg*); +Hook* hck_luaL_register; + +// LUAL_LOADSTRING +typedef int (*pluaL_loadstring)(lua_State*, const char*); +Hook* hck_luaL_loadstring; + +// LUA_NEWSTATE +typedef lua_State* (*plua_newstate)(lua_Alloc, void*); +Hook* hck_lua_newstate; + +// LUAL_LOADBUFFER +typedef int (*pluaL_loadbuffer)(lua_State*, const char*, size_t, const char*); +Hook* hck_luaL_loadbuffer; + +// ============= + +namespace Hooks { + void hook_luaL_register(lua_State* L, const char* libname, const luaL_Reg* l) { + Console::log(Color::Aqua, "hook_luaL_register: libname=[%s]", libname); + return ((pluaL_register)hck_luaL_register->Gate())(L, libname, l); + } + + int hook_luaL_loadstring(lua_State* L, const char* s) { + Console::log(Color::Aqua, "hook_luaL_loadstring: s=[ ... ]"); + return ((pluaL_loadstring)hck_luaL_loadstring->Gate())(L, s); + } + + lua_State* hook_lua_newstate(lua_Alloc f, void* ud) { + Console::log(Color::Aqua, "hck_lua_newstate: ud=[%p]", ud); + return ((plua_newstate)hck_lua_newstate->Gate())(f, ud); + } + + int hook_luaL_loadbuffer(lua_State* L, const char* buff, size_t sz, const char* name) { + Console::log(Color::Aqua, "hck_luaL_loadbuffer: buff=[ ... ], sz=[%zu], name=[%s]", sz, name); + return ((pluaL_loadbuffer)hck_luaL_loadbuffer->Gate())(L, buff, sz, name); + } +} diff --git a/PluginDevFolder/SMLuaHook/main.cpp b/PluginDevFolder/SMLuaHook/main.cpp new file mode 100644 index 0000000..a61f0b3 --- /dev/null +++ b/PluginDevFolder/SMLuaHook/main.cpp @@ -0,0 +1,59 @@ +#define _SM_LIBRARY_BUILD_PLUGIN +#define _SM_PLUGIN_NAME SMLuaHook + +#include +#include +using Console::Color; + +#include "hooks.h" +bool InjectLua(); + +LIB_RESULT PluginLoad() { + Console::log(Color::Aqua, "Starting plugin ..."); + + if (!InjectLua()) { + Console::log(Color::Red, "Failed to inject lua functions"); + return PLUGIN_ERROR; + } + + return PLUGIN_SUCCESSFULL; +} + +HookUtility* util; +bool InjectLua() { + Console::log(Color::Aqua, "Installing lua hooks"); + + util = new HookUtility(); + hck_luaL_register = util->InjectFromName("lua51.dll", "luaL_register", &Hooks::hook_luaL_register, 15); + hck_luaL_loadstring = util->InjectFromName("lua51.dll", "luaL_loadstring", &Hooks::hook_luaL_loadstring, 16); + hck_lua_newstate = util->InjectFromName("lua51.dll", "lua_newstate", &Hooks::hook_lua_newstate, -14, 6); + hck_luaL_loadbuffer = util->InjectFromName("lua51.dll", "luaL_loadbuffer", &Hooks::hook_luaL_loadbuffer, 17, 13); + + if (!hck_luaL_register) { + Console::log(Color::Red, "Failed to inject 'luaL_register'"); + return false; + } + + if (!hck_luaL_loadstring) { + Console::log(Color::Red, "Failed to inject 'luaL_loadstring'"); + return false; + } + + if (!hck_lua_newstate) { + Console::log(Color::Red, "Failed to inject 'lua_newstate'"); + return false; + } + + if (!hck_luaL_loadbuffer) { + Console::log(Color::Red, "Failed to inject 'luaL_loadbuffer'"); + return false; + } + + return true; +} + +LIB_RESULT PluginUnload() { + Console::log(Color::Aqua, "Unloading this plugin!"); + util->Unload(); + return PLUGIN_SUCCESSFULL; +} diff --git a/PluginDevFolder/SMLuaHook/packages.config b/PluginDevFolder/SMLuaHook/packages.config new file mode 100644 index 0000000..8226e66 --- /dev/null +++ b/PluginDevFolder/SMLuaHook/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/PluginDevFolder/SMPluginTemplate/SMPluginTemplate.vcxproj b/PluginDevFolder/SMPluginTemplate/SMPluginTemplate.vcxproj index 0003fc3..dc773cd 100644 --- a/PluginDevFolder/SMPluginTemplate/SMPluginTemplate.vcxproj +++ b/PluginDevFolder/SMPluginTemplate/SMPluginTemplate.vcxproj @@ -1,14 +1,6 @@ - - Debug - Win32 - - - Release - Win32 - Debug x64 @@ -29,19 +21,6 @@ 10.0 - - DynamicLibrary - true - v142 - Unicode - - - DynamicLibrary - false - v142 - true - Unicode - DynamicLibrary true @@ -60,12 +39,6 @@ - - - - - - @@ -73,16 +46,6 @@ - - true - $(SolutionDir)..\SMLibrary\include;$(IncludePath) - $(OutDir);$(LibraryPath) - - - false - $(SolutionDir)..\SMLibrary\include;$(IncludePath) - $(OutDir);$(LibraryPath) - true $(SolutionDir)..\SMLibrary\include;$(IncludePath) @@ -93,60 +56,6 @@ $(SolutionDir)..\SMLibrary\include;$(IncludePath) $(OutDir);$(LibraryPath) - - - Level3 - true - WIN32;_DEBUG;SMPLUGINTEMPLATE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - NotUsing - - - - - Windows - true - false - smlibrary.lib;%(AdditionalDependencies) - - - if not exist "$(OutputPath)plugins\" mkdir "$(OutputPath)plugins\" -copy /B "$(LocalDebuggerCommand)" "$(OutputPath)plugins\$(TargetFileName)" - - - - - - - - - Level3 - true - true - true - WIN32;NDEBUG;SMPLUGINTEMPLATE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - NotUsing - - - - - Windows - true - true - true - false - smlibrary.lib;%(AdditionalDependencies) - - - if not exist "$(OutputPath)plugins\" mkdir "$(OutputPath)plugins\" -copy /B "$(LocalDebuggerCommand)" "$(OutputPath)plugins\$(TargetFileName)" - - - - - - Level3 diff --git a/PluginDevFolder/TileEditorUnlockPlugin/TileEditorUnlockPlugin.vcxproj b/PluginDevFolder/TileEditorUnlockPlugin/TileEditorUnlockPlugin.vcxproj index 0973a43..2c8078c 100644 --- a/PluginDevFolder/TileEditorUnlockPlugin/TileEditorUnlockPlugin.vcxproj +++ b/PluginDevFolder/TileEditorUnlockPlugin/TileEditorUnlockPlugin.vcxproj @@ -1,14 +1,6 @@ - - Debug - Win32 - - - Release - Win32 - Debug x64 @@ -29,19 +21,6 @@ 10.0 - - DynamicLibrary - true - v142 - Unicode - - - DynamicLibrary - false - v142 - true - Unicode - DynamicLibrary true @@ -60,12 +39,6 @@ - - - - - - @@ -73,16 +46,6 @@ - - true - $(SolutionDir)..\SMLibrary\include;$(IncludePath) - $(OutDir);$(LibraryPath) - - - false - $(SolutionDir)..\SMLibrary\include;$(IncludePath) - $(OutDir);$(LibraryPath) - true $(SolutionDir)..\SMLibrary\include;$(IncludePath) @@ -93,52 +56,6 @@ $(SolutionDir)..\SMLibrary\include;$(IncludePath) $(OutDir);$(LibraryPath) - - - Level3 - true - WIN32;_DEBUG;TILEEDITORUNLOCKPLUGIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - NotUsing - - - - - Windows - true - false - smlibrary.lib;%(AdditionalDependencies) - - - if not exist "$(OutputPath)plugins\" mkdir "$(OutputPath)plugins\" -copy /B "$(LocalDebuggerCommand)" "$(OutputPath)plugins\$(TargetFileName)" - - - - - Level3 - true - true - true - WIN32;NDEBUG;TILEEDITORUNLOCKPLUGIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - NotUsing - - - - - Windows - true - true - true - false - smlibrary.lib;%(AdditionalDependencies) - - - if not exist "$(OutputPath)plugins\" mkdir "$(OutputPath)plugins\" -copy /B "$(LocalDebuggerCommand)" "$(OutputPath)plugins\$(TargetFileName)" - - Level3 diff --git a/SMInjector/SMInjector.sln b/SMInjector/SMInjector.sln index 5b3cfed..6b362ff 100644 --- a/SMInjector/SMInjector.sln +++ b/SMInjector/SMInjector.sln @@ -24,45 +24,33 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SMLuaReaderPlugin", "..\Plu {81368E09-9FA2-4F28-9915-22FE758BFD48} = {81368E09-9FA2-4F28-9915-22FE758BFD48} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SMLuaHook", "..\PluginDevFolder\SMLuaHook\SMLuaHook.vcxproj", "{93661F1D-21DC-4B5B-88EC-6BEA337DF56B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 Release|x64 = Release|x64 - Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {E94AFAD6-2262-40E4-81D3-CD0130B98C0B}.Debug|x64.ActiveCfg = Debug|x64 - {E94AFAD6-2262-40E4-81D3-CD0130B98C0B}.Debug|x86.ActiveCfg = Debug|x64 {E94AFAD6-2262-40E4-81D3-CD0130B98C0B}.Release|x64.ActiveCfg = Release|x64 {E94AFAD6-2262-40E4-81D3-CD0130B98C0B}.Release|x64.Build.0 = Release|x64 - {E94AFAD6-2262-40E4-81D3-CD0130B98C0B}.Release|x86.ActiveCfg = Release|x64 {81368E09-9FA2-4F28-9915-22FE758BFD48}.Debug|x64.ActiveCfg = Debug|x64 - {81368E09-9FA2-4F28-9915-22FE758BFD48}.Debug|x86.ActiveCfg = Debug|Win32 - {81368E09-9FA2-4F28-9915-22FE758BFD48}.Debug|x86.Build.0 = Debug|Win32 {81368E09-9FA2-4F28-9915-22FE758BFD48}.Release|x64.ActiveCfg = Release|x64 {81368E09-9FA2-4F28-9915-22FE758BFD48}.Release|x64.Build.0 = Release|x64 - {81368E09-9FA2-4F28-9915-22FE758BFD48}.Release|x86.ActiveCfg = Release|Win32 - {81368E09-9FA2-4F28-9915-22FE758BFD48}.Release|x86.Build.0 = Release|Win32 {F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA}.Debug|x64.ActiveCfg = Debug|x64 - {F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA}.Debug|x86.ActiveCfg = Debug|Win32 - {F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA}.Debug|x86.Build.0 = Debug|Win32 {F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA}.Release|x64.ActiveCfg = Release|x64 {F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA}.Release|x64.Build.0 = Release|x64 - {F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA}.Release|x86.ActiveCfg = Release|Win32 - {F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA}.Release|x86.Build.0 = Release|Win32 {16BDCA26-D20C-4AC4-8DB3-9C108719B752}.Debug|x64.ActiveCfg = Debug|x64 - {16BDCA26-D20C-4AC4-8DB3-9C108719B752}.Debug|x86.ActiveCfg = Debug|Win32 - {16BDCA26-D20C-4AC4-8DB3-9C108719B752}.Debug|x86.Build.0 = Debug|Win32 {16BDCA26-D20C-4AC4-8DB3-9C108719B752}.Release|x64.ActiveCfg = Release|x64 {16BDCA26-D20C-4AC4-8DB3-9C108719B752}.Release|x64.Build.0 = Release|x64 - {16BDCA26-D20C-4AC4-8DB3-9C108719B752}.Release|x86.ActiveCfg = Release|Win32 - {16BDCA26-D20C-4AC4-8DB3-9C108719B752}.Release|x86.Build.0 = Release|Win32 {13E88C11-DEB6-47D5-9382-4E5D484A58C2}.Debug|x64.ActiveCfg = Debug|x64 - {13E88C11-DEB6-47D5-9382-4E5D484A58C2}.Debug|x86.ActiveCfg = Debug|x64 {13E88C11-DEB6-47D5-9382-4E5D484A58C2}.Release|x64.ActiveCfg = Release|x64 {13E88C11-DEB6-47D5-9382-4E5D484A58C2}.Release|x64.Build.0 = Release|x64 - {13E88C11-DEB6-47D5-9382-4E5D484A58C2}.Release|x86.ActiveCfg = Release|x64 + {93661F1D-21DC-4B5B-88EC-6BEA337DF56B}.Debug|x64.ActiveCfg = Debug|x64 + {93661F1D-21DC-4B5B-88EC-6BEA337DF56B}.Debug|x64.Build.0 = Debug|x64 + {93661F1D-21DC-4B5B-88EC-6BEA337DF56B}.Release|x64.ActiveCfg = Release|x64 + {93661F1D-21DC-4B5B-88EC-6BEA337DF56B}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -71,6 +59,7 @@ Global {F09BBCFB-A1E3-43E0-8406-FBC8B72A09CA} = {4EC6A5BC-FCE4-4FFE-AC55-7D83B6B7C8D7} {16BDCA26-D20C-4AC4-8DB3-9C108719B752} = {4EC6A5BC-FCE4-4FFE-AC55-7D83B6B7C8D7} {13E88C11-DEB6-47D5-9382-4E5D484A58C2} = {4EC6A5BC-FCE4-4FFE-AC55-7D83B6B7C8D7} + {93661F1D-21DC-4B5B-88EC-6BEA337DF56B} = {4EC6A5BC-FCE4-4FFE-AC55-7D83B6B7C8D7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D7E2F6B1-96AC-4FB5-B8AA-FDB43C7F169E} diff --git a/SMLibrary/SMLibrary.vcxproj b/SMLibrary/SMLibrary.vcxproj index 15788df..4214590 100644 --- a/SMLibrary/SMLibrary.vcxproj +++ b/SMLibrary/SMLibrary.vcxproj @@ -1,14 +1,6 @@ - - Debug - Win32 - - - Release - Win32 - Debug x64 @@ -27,19 +19,6 @@ SMLibrary - - DynamicLibrary - true - v142 - Unicode - - - DynamicLibrary - false - v142 - true - Unicode - DynamicLibrary true @@ -58,12 +37,6 @@ - - - - - - @@ -71,14 +44,6 @@ - - true - $(SourcePath) - - - false - $(SourcePath) - true $(SourcePath) @@ -87,36 +52,6 @@ false $(SourcePath) - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - MaxSpeed - Default - - - Console - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - Level3 From 4dbf41f43638e45c07b101fde0371a8af814c964 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Tue, 7 Sep 2021 16:34:08 +0200 Subject: [PATCH 03/29] Print all functions in luaL_register --- PluginDevFolder/SMLuaHook/hooks.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/PluginDevFolder/SMLuaHook/hooks.h b/PluginDevFolder/SMLuaHook/hooks.h index e3d508e..c14963e 100644 --- a/PluginDevFolder/SMLuaHook/hooks.h +++ b/PluginDevFolder/SMLuaHook/hooks.h @@ -28,6 +28,16 @@ Hook* hck_luaL_loadbuffer; namespace Hooks { void hook_luaL_register(lua_State* L, const char* libname, const luaL_Reg* l) { Console::log(Color::Aqua, "hook_luaL_register: libname=[%s]", libname); + + const luaL_Reg* ptr = l; + + int i = 0; + while (ptr->name != NULL) { + Console::log(Color::Aqua, "hook_luaL_register: luaL_Reg[%d] name=[%s] func=[%p]", i++, ptr->name, (void*)ptr->func); + + ptr++; + } + return ((pluaL_register)hck_luaL_register->Gate())(L, libname, l); } From 035f24f88cf15177a047aa0db706fe70692ee011 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Fri, 10 Sep 2021 00:19:07 +0200 Subject: [PATCH 04/29] Add Console::wlog --- SMLibrary/include/console.h | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/SMLibrary/include/console.h b/SMLibrary/include/console.h index 1c59933..a62fa9d 100644 --- a/SMLibrary/include/console.h +++ b/SMLibrary/include/console.h @@ -37,8 +37,8 @@ namespace Console { }; #ifdef _SM_LIBRARY_BUILD_PLUGIN - _LIB_IMPORT - void vlogf(Color color, const char *plugin_name, const char *format, va_list args); + _LIB_IMPORT void vlogf(Color color, const char* plugin_name, const char* format, va_list args); + _LIB_IMPORT void wvlogf(Color color, const char* plugin_name, const wchar_t* format, va_list args); #else FILE* console_handle = NULL; HANDLE hConsole; @@ -59,8 +59,7 @@ namespace Console { #endif } - _LIB_EXPORT - void vlogf(Color color, const char *plugin_name, const char *format, va_list args) { + _LIB_EXPORT void vlogf(Color color, const char *plugin_name, const char *format, va_list args) { if(!console_handle) return; if(!hConsole) hConsole = GetStdHandle(STD_OUTPUT_HANDLE); @@ -70,12 +69,29 @@ namespace Console { vprintf(format, args); printf("\n"); } + + _LIB_EXPORT void wvlogf(Color color, const char* plugin_name, const wchar_t* format, va_list args) { + if (!console_handle) return; + + if (!hConsole) hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + if (hConsole) SetConsoleTextAttribute(hConsole, (WORD)color); + + printf("[%s]: ", plugin_name); + vwprintf(format, args); + printf("\n"); + } #endif void log(Color color, const char *format, ...) { va_list args; va_start(args, format); vlogf(color, _LIB_PLUGIN_NAME_STR, format, args); } + + void wlog(Color color, const wchar_t* format, ...) { + va_list args; + va_start(args, format); + wvlogf(color, _LIB_PLUGIN_NAME_STR, format, args); + } } #endif From d4bb6440546f954de29c51f2ff6d990685c65e0d Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Fri, 10 Sep 2021 00:20:47 +0200 Subject: [PATCH 05/29] SignatureScanner: Get module info --- SMLibrary/SMLibrary.vcxproj | 1 + SMLibrary/SMLibrary.vcxproj.filters | 3 ++ SMLibrary/include/sigscan.h | 50 +++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 SMLibrary/include/sigscan.h diff --git a/SMLibrary/SMLibrary.vcxproj b/SMLibrary/SMLibrary.vcxproj index 4214590..1d18fae 100644 --- a/SMLibrary/SMLibrary.vcxproj +++ b/SMLibrary/SMLibrary.vcxproj @@ -89,6 +89,7 @@ + diff --git a/SMLibrary/SMLibrary.vcxproj.filters b/SMLibrary/SMLibrary.vcxproj.filters index 362dd6b..cde6122 100644 --- a/SMLibrary/SMLibrary.vcxproj.filters +++ b/SMLibrary/SMLibrary.vcxproj.filters @@ -38,5 +38,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/SMLibrary/include/sigscan.h b/SMLibrary/include/sigscan.h new file mode 100644 index 0000000..b22810a --- /dev/null +++ b/SMLibrary/include/sigscan.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include +#include +#include + +#include "console.h" + +#define ERROR_GETMODULE(reason, ...) Console::log(Color::LightRed, "[SignatureScanner] Failed getting handle of module %s. Reason: " reason, moduleName, __VA_ARGS__) + +using Console::Color; + +class SignatureScanner { +private: + LPCWSTR moduleName; + DWORD64 moduleBase; + DWORD moduleSize; + + MODULEINFO GetModuleInfo(LPCWSTR moduleName) { + MODULEINFO moduleInfo = { 0 }; + HMODULE hModule = GetModuleHandle(moduleName); + if (hModule == NULL) + return moduleInfo; + + GetModuleInformation(GetCurrentProcess(), hModule, &moduleInfo, sizeof(MODULEINFO)); + + return moduleInfo; + } + +public: + SignatureScanner(LPCWSTR moduleName) { + this->moduleName = moduleName; + + MODULEINFO moduleInfo = GetModuleInfo(moduleName); + + if (moduleInfo.SizeOfImage == 0) { + Console::log(Color::LightRed, "[SignatureScanner] Failed getting info of module %s", moduleName); + return; + } + + this->moduleBase = (DWORD64) moduleInfo.lpBaseOfDll; + this->moduleSize = moduleInfo.SizeOfImage; + + Console::wlog(Color::Aqua, L"[SignatureScanner] Found module %s with base=[0x%llX] size=[%ul]", moduleName, this->moduleBase, this->moduleSize); + } + +}; + +#undef ERROR_GETMODULE From fca41f28992e315752c1cbf20f2e823823b59245 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Sun, 12 Sep 2021 02:26:36 +0200 Subject: [PATCH 06/29] Use stdcpp17 --- PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj | 2 ++ PluginDevFolder/SMLuaReaderPlugin/SMLuaReaderPlugin.vcxproj | 2 ++ PluginDevFolder/SMPluginTemplate/SMPluginTemplate.vcxproj | 2 ++ .../TileEditorUnlockPlugin/TileEditorUnlockPlugin.vcxproj | 2 ++ SMLibrary/SMLibrary.vcxproj | 2 ++ 5 files changed, 10 insertions(+) diff --git a/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj b/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj index fa3849c..5fbe19b 100644 --- a/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj +++ b/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj @@ -70,6 +70,7 @@ true NotUsing pch.h + stdcpp17 Windows @@ -92,6 +93,7 @@ copy /B "$(LocalDebuggerCommand)" "$(OutputPath)plugins\$(TargetFileName)"true NotUsing pch.h + stdcpp17 Windows diff --git a/PluginDevFolder/SMLuaReaderPlugin/SMLuaReaderPlugin.vcxproj b/PluginDevFolder/SMLuaReaderPlugin/SMLuaReaderPlugin.vcxproj index c86cf1c..ab501cc 100644 --- a/PluginDevFolder/SMLuaReaderPlugin/SMLuaReaderPlugin.vcxproj +++ b/PluginDevFolder/SMLuaReaderPlugin/SMLuaReaderPlugin.vcxproj @@ -69,6 +69,7 @@ NotUsing + stdcpp17 Windows @@ -96,6 +97,7 @@ copy /B "$(LocalDebuggerCommand)" "$(OutputPath)plugins\$(TargetFileName)"NotUsing + stdcpp17 Windows diff --git a/PluginDevFolder/SMPluginTemplate/SMPluginTemplate.vcxproj b/PluginDevFolder/SMPluginTemplate/SMPluginTemplate.vcxproj index dc773cd..0fb0b04 100644 --- a/PluginDevFolder/SMPluginTemplate/SMPluginTemplate.vcxproj +++ b/PluginDevFolder/SMPluginTemplate/SMPluginTemplate.vcxproj @@ -65,6 +65,7 @@ NotUsing + stdcpp17 Windows @@ -92,6 +93,7 @@ copy /B "$(LocalDebuggerCommand)" "$(OutputPath)plugins\$(TargetFileName)"NotUsing + stdcpp17 Windows diff --git a/PluginDevFolder/TileEditorUnlockPlugin/TileEditorUnlockPlugin.vcxproj b/PluginDevFolder/TileEditorUnlockPlugin/TileEditorUnlockPlugin.vcxproj index 2c8078c..74b2dd6 100644 --- a/PluginDevFolder/TileEditorUnlockPlugin/TileEditorUnlockPlugin.vcxproj +++ b/PluginDevFolder/TileEditorUnlockPlugin/TileEditorUnlockPlugin.vcxproj @@ -65,6 +65,7 @@ NotUsing + stdcpp17 Windows @@ -88,6 +89,7 @@ copy /B "$(LocalDebuggerCommand)" "$(OutputPath)plugins\$(TargetFileName)"NotUsing + stdcpp17 Windows diff --git a/SMLibrary/SMLibrary.vcxproj b/SMLibrary/SMLibrary.vcxproj index 1d18fae..202bf77 100644 --- a/SMLibrary/SMLibrary.vcxproj +++ b/SMLibrary/SMLibrary.vcxproj @@ -60,6 +60,7 @@ true MaxSpeed Default + stdcpp17 Console @@ -74,6 +75,7 @@ true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true + stdcpp17 Console From 39604a21b6547a19e939806222213904969d0387 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Sun, 12 Sep 2021 02:27:12 +0200 Subject: [PATCH 07/29] Add plugin config system --- PluginDevFolder/SMLuaHook/main.cpp | 7 +++ SMLibrary/SMLibrary.vcxproj | 1 + SMLibrary/SMLibrary.vcxproj.filters | 3 + SMLibrary/include/plugin_config.h | 98 +++++++++++++++++++++++++++++ SMLibrary/src/sm_lib.cpp | 13 ++++ 5 files changed, 122 insertions(+) create mode 100644 SMLibrary/include/plugin_config.h diff --git a/PluginDevFolder/SMLuaHook/main.cpp b/PluginDevFolder/SMLuaHook/main.cpp index a61f0b3..19fde81 100644 --- a/PluginDevFolder/SMLuaHook/main.cpp +++ b/PluginDevFolder/SMLuaHook/main.cpp @@ -3,6 +3,9 @@ #include #include +#include +#include + using Console::Color; #include "hooks.h" @@ -49,6 +52,10 @@ bool InjectLua() { return false; } + PluginConfig config(_LIB_PLUGIN_NAME_STR, "test.json"); + config.createIfNotExists(); + config.load(); + return true; } diff --git a/SMLibrary/SMLibrary.vcxproj b/SMLibrary/SMLibrary.vcxproj index 202bf77..1c4462b 100644 --- a/SMLibrary/SMLibrary.vcxproj +++ b/SMLibrary/SMLibrary.vcxproj @@ -91,6 +91,7 @@ + diff --git a/SMLibrary/SMLibrary.vcxproj.filters b/SMLibrary/SMLibrary.vcxproj.filters index cde6122..91d0072 100644 --- a/SMLibrary/SMLibrary.vcxproj.filters +++ b/SMLibrary/SMLibrary.vcxproj.filters @@ -41,5 +41,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/SMLibrary/include/plugin_config.h b/SMLibrary/include/plugin_config.h new file mode 100644 index 0000000..6ce0a03 --- /dev/null +++ b/SMLibrary/include/plugin_config.h @@ -0,0 +1,98 @@ +#pragma once +#include "stdafx.h" +#include +#include +#include +#include "console.h" + +namespace fs = std::filesystem; + +class PluginConfig { +private: + inline static fs::path configDirectory; + + const char* pluginName = NULL; + fs::path path; + fs::path fullPath; + + const char* defaultContent = "// Empty config file\n{}\n"; + +public: + _LIB_FUNCTION static bool setConfigDirectory(const fs::path& configDirectory) { + PluginConfig::configDirectory = fs::absolute(configDirectory); + + if (!fs::is_directory(configDirectory) || !fs::exists(configDirectory)) { + if (!fs::create_directories(configDirectory)) { + Console::wlog(Console::Color::Red, L"Failed creating main config directory \"%s\"", PluginConfig::configDirectory.c_str()); + return false; + } + } + + Console::wlog(Console::Color::Aqua, L"Set main config directory to \"%s\"", PluginConfig::configDirectory.c_str()); + + return true; + } + + _LIB_FUNCTION static fs::path getConfigDirectory() { + return PluginConfig::configDirectory; + } + + PluginConfig(const char *pluginName, const fs::path& path) { + this->pluginName = pluginName; + this->path = path; + + this->fullPath = PluginConfig::getConfigDirectory() /= fs::path(pluginName) /= this->path; + } + +#ifdef _LIB_PLUGIN_NAME_STR + PluginConfig(const fs::path& path) : PluginConfig(_LIB_PLUGIN_NAME_STR, path) {} +#endif + + void setDefaultContent(const char* defaultContent) { + this->defaultContent = defaultContent;; + } + + bool createIfNotExists() { + if (fs::exists(this->fullPath)) { + return false; + } + + Console::wlog(Console::Color::LightYellow, L"Warning: Unable to find config file \"%s\", creating with default content...", this->fullPath.c_str()); + + if (!fs::exists(this->fullPath.parent_path())) { + fs::create_directories(this->fullPath.parent_path()); + } + + std::ofstream ofs(this->fullPath); + + if (!ofs.is_open()) { +#pragma warning(suppress : 4996) + Console::wlog(Console::Color::Red, L"Failed creating config file \"%s\": %s", this->fullPath.c_str(), _wcserror(errno)); + return false; + } + + ofs << this->defaultContent; + ofs.close(); + + return true; + } + + bool load() { + std::ifstream ifs(this->fullPath); + + if (!ifs.is_open()) { +#pragma warning(suppress : 4996) + Console::wlog(Console::Color::Red, L"Failed reading config file \"%s\": %s", this->fullPath.c_str(), _wcserror(errno)); + return false; + } + + Console::wlog(Console::Color::Gray, L"Loaded content of config file \"%s\":", this->fullPath.c_str()); + + std::cout << ifs.rdbuf() << std::endl; + + ifs.close(); + + return true; + } + +}; \ No newline at end of file diff --git a/SMLibrary/src/sm_lib.cpp b/SMLibrary/src/sm_lib.cpp index 29aab28..626c06d 100644 --- a/SMLibrary/src/sm_lib.cpp +++ b/SMLibrary/src/sm_lib.cpp @@ -2,12 +2,16 @@ #include #include #include +#include + +namespace fs = std::filesystem; #define _SM_PLUGIN_NAME SMLibrary #define _SM_OUTPUT_LOGS #include "../include/sm_lib.h" #include "../include/hook.h" +#include "../include/plugin_config.h" #include "../include/console.h" using Console::Color; @@ -33,10 +37,16 @@ HookUtility *util; #include "hooks.h" +fs::path smlibrarydllPath; + BOOL Startup(HMODULE hModule) { HMODULE sm_handle = GetModuleHandleA("ScrapMechanic.exe"); if(!sm_handle) return false; + TCHAR dllPath[MAX_PATH] = { 0 }; + DWORD length = GetModuleFileName(hModule, dllPath, _countof(dllPath)); + smlibrarydllPath = fs::path(dllPath); + hck_init_console = new Hook(); hck_init_console->Inject((void*)((longlong)sm_handle + offset_InitConsole), &Hooks::hook_init_console, 0, 15); return true; @@ -44,6 +54,9 @@ BOOL Startup(HMODULE hModule) { BOOL PostConsoleInjections() { Console::log_open(); + + PluginConfig::setConfigDirectory(smlibrarydllPath.parent_path() /= "config"); + Console::log(Color::Aqua, "Installing the library functions"); util = new HookUtility(); From 89c5049eca50056b363f7f9ae6c48d5a9e5299c3 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Tue, 14 Sep 2021 19:00:37 +0200 Subject: [PATCH 08/29] Inject dependencies before plugins --- SMInjector/src/main.cpp | 53 ++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/SMInjector/src/main.cpp b/SMInjector/src/main.cpp index fa7393c..28589d6 100644 --- a/SMInjector/src/main.cpp +++ b/SMInjector/src/main.cpp @@ -9,6 +9,8 @@ #include "find_steam.h" +namespace fs = std::filesystem; + bool Inject(HANDLE, const wchar_t*); inline bool does_file_exist(const wchar_t* name) { @@ -16,21 +18,13 @@ inline bool does_file_exist(const wchar_t* name) { return (_wstat(name, &buffer) == 0); } -std::wstring get_dir_path() { - wchar_t buffer[MAX_PATH] = { 0 }; - GetModuleFileNameW(NULL, buffer, MAX_PATH); - std::wstring::size_type pos = std::wstring(buffer).find_last_of(L"\\/"); - return std::wstring(buffer).substr(0, pos); -} - -std::wstring get_dll_path(const wchar_t* dll_name) { - wchar_t buffer[MAX_PATH] = { 0 }; - GetModuleFileNameW(NULL, buffer, MAX_PATH); - std::wstring::size_type pos = std::wstring(buffer).find_last_of(L"\\/"); - return std::wstring(buffer).substr(0, pos).append(L"\\").append(dll_name); +fs::path get_dir_path() { + TCHAR dir[MAX_PATH] = { 0 }; + DWORD length = GetModuleFileName(NULL, dir, _countof(dir)); + return fs::path(dir).parent_path(); } -BOOL startup(std::wstring in_exe, std::wstring in_dir, std::wstring in_cmd, HANDLE &hProcess, HANDLE &hThread) { +BOOL startup(fs::path in_exe, fs::path in_dir, std::wstring in_cmd, HANDLE &hProcess, HANDLE &hThread) { STARTUPINFO si; PROCESS_INFORMATION pi; @@ -39,8 +33,8 @@ BOOL startup(std::wstring in_exe, std::wstring in_dir, std::wstring in_cmd, HAND wchar_t cmd[4097] = { 0 }; ZeroMemory(cmd, 4097); - memcpy(exe, in_exe.c_str(), min(in_exe.size() * 2, MAX_PATH + 1)); - memcpy(dir, in_dir.c_str(), min(in_dir.size() * 2, MAX_PATH + 1)); + memcpy(exe, in_exe.c_str(), min(in_exe.string().size() * 2, MAX_PATH + 1)); + memcpy(dir, in_dir.c_str(), min(in_dir.string().size() * 2, MAX_PATH + 1)); swprintf_s(cmd, 4097, L"\"%s\" %s", exe, in_cmd.c_str()); //wprintf(L"EXE: [%s]\n", exe); @@ -78,9 +72,10 @@ BOOL startup(std::wstring in_exe, std::wstring in_dir, std::wstring in_cmd, HAND int main(int argc, char** argv) { printf("SMInjector: startup\n"); - std::wstring game_path = SteamFinder::FindGame(L"Scrap Mechanic"); - std::wstring dll_path = get_dll_path(L"SMLibrary.dll"); - + fs::path game_path = SteamFinder::FindGame(L"Scrap Mechanic"); + fs::path dir_path = get_dir_path(); + fs::path dll_path = dir_path / "SMLibrary.dll"; + wprintf(L"GAME: [%s]\n", game_path.c_str()); wprintf(L"DLL : [%s]\n", dll_path.c_str()); @@ -91,8 +86,8 @@ int main(int argc, char** argv) { HANDLE hProcess; HANDLE hThread; - std::wstring exe_exe = std::wstring(game_path).append(L"\\Release\\ScrapMechanic.exe"); - std::wstring exe_dir = std::wstring(game_path).append(L"\\Release"); + fs::path exe_dir = game_path / "Release"; + fs::path exe_exe = game_path / "Release" / "ScrapMechanic.exe"; if(startup(exe_exe, exe_dir, L"-dev", hProcess, hThread)) { if(!Inject(hProcess, dll_path.c_str())) { printf("SMInjector: failed to inject dll file\n"); @@ -101,8 +96,22 @@ int main(int argc, char** argv) { return 0; } - printf("\nSMInjector: Adding plugins.\n"); - for(const auto& file : std::filesystem::directory_iterator(get_dir_path().append(L"\\plugins"))) { + if (!fs::exists(dir_path / "plugins" / "dependencies")) { + fs::create_directories(dir_path / "plugins" / "dependencies"); + } + + printf("\nSMInjector: Adding dependencies...\n"); + for (const auto& file : fs::directory_iterator(dir_path / "plugins" / "dependencies")) { + if (!Inject(hProcess, file.path().c_str())) { + wprintf(L" Failed to inject '%s'\n", file.path().filename().c_str()); + return 0; + } else { + wprintf(L" Injected '%s'\n", file.path().filename().c_str()); + } + } + + printf("\nSMInjector: Adding plugins...\n"); + for(const auto& file : fs::directory_iterator(get_dir_path() / "plugins")) { if(!Inject(hProcess, file.path().c_str())) { wprintf(L" Failed to inject '%s'\n", file.path().filename().c_str()); return 0; From 5ac0a9f456588fd218fd7b1626d6d9d60ee0c032 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Wed, 15 Sep 2021 22:11:45 +0200 Subject: [PATCH 09/29] Execute SetDllDirectory before injecting SMLibrary.dll --- SMInjector/src/main.cpp | 62 +++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/SMInjector/src/main.cpp b/SMInjector/src/main.cpp index 28589d6..dae7a96 100644 --- a/SMInjector/src/main.cpp +++ b/SMInjector/src/main.cpp @@ -12,6 +12,7 @@ namespace fs = std::filesystem; bool Inject(HANDLE, const wchar_t*); +bool InjectSetDllDirectory(HANDLE, const wchar_t*); inline bool does_file_exist(const wchar_t* name) { struct _stat buffer; @@ -89,29 +90,35 @@ int main(int argc, char** argv) { fs::path exe_dir = game_path / "Release"; fs::path exe_exe = game_path / "Release" / "ScrapMechanic.exe"; if(startup(exe_exe, exe_dir, L"-dev", hProcess, hThread)) { - if(!Inject(hProcess, dll_path.c_str())) { - printf("SMInjector: failed to inject dll file\n"); + + // Set the dll directory so SMLibrary.dll can load all it's dependencies + if (!InjectSetDllDirectory(hProcess, dir_path.c_str())) { + printf("SMInjector: Failed to inject dll directory\n"); TerminateProcess(hProcess, 0); CloseHandle(hProcess); return 0; } - if (!fs::exists(dir_path / "plugins" / "dependencies")) { - fs::create_directories(dir_path / "plugins" / "dependencies"); + // Inject SMLibrary.dll + if (!Inject(hProcess, dll_path.c_str())) { + printf("SMInjector: Failed to inject SMLibrary.dll\n"); + TerminateProcess(hProcess, 0); + CloseHandle(hProcess); + return 0; } - printf("\nSMInjector: Adding dependencies...\n"); - for (const auto& file : fs::directory_iterator(dir_path / "plugins" / "dependencies")) { - if (!Inject(hProcess, file.path().c_str())) { - wprintf(L" Failed to inject '%s'\n", file.path().filename().c_str()); - return 0; - } else { - wprintf(L" Injected '%s'\n", file.path().filename().c_str()); - } + // Create plugin dependencies directory + if (!fs::exists(dir_path / "plugins" / "dependencies")) { + fs::create_directories(dir_path / "plugins" / "dependencies"); } + // Inject plugins printf("\nSMInjector: Adding plugins...\n"); for(const auto& file : fs::directory_iterator(get_dir_path() / "plugins")) { + if (file.path().extension() != ".dll") { + continue; + } + if(!Inject(hProcess, file.path().c_str())) { wprintf(L" Failed to inject '%s'\n", file.path().filename().c_str()); return 0; @@ -156,3 +163,34 @@ bool Inject(HANDLE hProc, const wchar_t* path) { CloseHandle(threadID); return true; } + +bool InjectSetDllDirectory(HANDLE hProc, const wchar_t* path) { + if (!does_file_exist(path)) { + return false; + } + + const size_t path_length = wcslen(path) * 2; + + LPVOID lpvoid = VirtualAllocEx(hProc, NULL, path_length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (!lpvoid) { + return false; + } + + WriteProcessMemory(hProc, lpvoid, path, path_length, NULL); + HMODULE kernel32 = GetModuleHandleA("kernel32.dll"); + if (!kernel32) { + return false; + } + + LPVOID SetDllDirectoryAddr = (LPVOID)GetProcAddress(kernel32, "SetDllDirectoryW"); + + HANDLE threadID = CreateRemoteThread(hProc, NULL, NULL, (LPTHREAD_START_ROUTINE)SetDllDirectoryAddr, lpvoid, NULL, NULL); + if (!threadID) { + return false; + } + + WaitForSingleObject(threadID, INFINITE); + VirtualFreeEx(hProc, lpvoid, 0, MEM_RELEASE); + CloseHandle(threadID); + return true; +} From 2081bd86e9dd92de97fb36cc06aaab970487f23d Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Wed, 15 Sep 2021 22:13:59 +0200 Subject: [PATCH 10/29] Load json plugin config file --- PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj | 2 ++ PluginDevFolder/SMLuaHook/main.cpp | 35 ++++++++++++++++++++- PluginDevFolder/SMLuaHook/packages.config | 1 + SMLibrary/SMLibrary.vcxproj | 10 ++++++ SMLibrary/SMLibrary.vcxproj.filters | 3 ++ SMLibrary/include/plugin_config.h | 29 ++++++++++++----- SMLibrary/packages.config | 4 +++ SMLibrary/src/sm_lib.cpp | 2 +- 8 files changed, 77 insertions(+), 9 deletions(-) create mode 100644 SMLibrary/packages.config diff --git a/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj b/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj index 5fbe19b..70b0110 100644 --- a/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj +++ b/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj @@ -111,11 +111,13 @@ copy /B "$(LocalDebuggerCommand)" "$(OutputPath)plugins\$(TargetFileName)" + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + \ No newline at end of file diff --git a/PluginDevFolder/SMLuaHook/main.cpp b/PluginDevFolder/SMLuaHook/main.cpp index 19fde81..931b33c 100644 --- a/PluginDevFolder/SMLuaHook/main.cpp +++ b/PluginDevFolder/SMLuaHook/main.cpp @@ -22,6 +22,38 @@ LIB_RESULT PluginLoad() { return PLUGIN_SUCCESSFULL; } +const char *defaultConfig = R"(// Configuration file for hooking the Lua C API +{ + "hooks": { + "luaL_loadstring": [ + { + "selector": { + "operator": "contains", + "value": "unsafe_env" + }, + "file": { + "option": "replace_content", + "name": "$PLUGIN_CONFIG/override/unsafe_env.lua" + } + } + ], + "luaL_loadbuffer": [ + { + "selector": { + "field": "name", + "operator": "equals", + "value": "Survival/Scripts/game/SurvivalGame.lua" + }, + "file": { + "option": "replace_content", + "name": "$PLUGIN_CONFIG/override/files/SurvivalGame.lua" + } + } + ] + } +} +)"; + HookUtility* util; bool InjectLua() { Console::log(Color::Aqua, "Installing lua hooks"); @@ -52,7 +84,8 @@ bool InjectLua() { return false; } - PluginConfig config(_LIB_PLUGIN_NAME_STR, "test.json"); + PluginConfig config(_LIB_PLUGIN_NAME_STR, "lua_hooks.json"); + config.setDefaultContent(defaultConfig); config.createIfNotExists(); config.load(); diff --git a/PluginDevFolder/SMLuaHook/packages.config b/PluginDevFolder/SMLuaHook/packages.config index 8226e66..a51867b 100644 --- a/PluginDevFolder/SMLuaHook/packages.config +++ b/PluginDevFolder/SMLuaHook/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file diff --git a/SMLibrary/SMLibrary.vcxproj b/SMLibrary/SMLibrary.vcxproj index 1c4462b..ca35df8 100644 --- a/SMLibrary/SMLibrary.vcxproj +++ b/SMLibrary/SMLibrary.vcxproj @@ -97,7 +97,17 @@ + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + \ No newline at end of file diff --git a/SMLibrary/SMLibrary.vcxproj.filters b/SMLibrary/SMLibrary.vcxproj.filters index 91d0072..f4cfb7b 100644 --- a/SMLibrary/SMLibrary.vcxproj.filters +++ b/SMLibrary/SMLibrary.vcxproj.filters @@ -45,4 +45,7 @@ Header Files + + + \ No newline at end of file diff --git a/SMLibrary/include/plugin_config.h b/SMLibrary/include/plugin_config.h index 6ce0a03..ec56e58 100644 --- a/SMLibrary/include/plugin_config.h +++ b/SMLibrary/include/plugin_config.h @@ -3,9 +3,14 @@ #include #include #include +#pragma warning(push) +#pragma warning(disable : 26819 28020) +#include +#pragma warning(pop) #include "console.h" namespace fs = std::filesystem; +using json = nlohmann::json; class PluginConfig { private: @@ -18,12 +23,14 @@ class PluginConfig { const char* defaultContent = "// Empty config file\n{}\n"; public: + json root; + _LIB_FUNCTION static bool setConfigDirectory(const fs::path& configDirectory) { PluginConfig::configDirectory = fs::absolute(configDirectory); if (!fs::is_directory(configDirectory) || !fs::exists(configDirectory)) { if (!fs::create_directories(configDirectory)) { - Console::wlog(Console::Color::Red, L"Failed creating main config directory \"%s\"", PluginConfig::configDirectory.c_str()); + Console::wlog(Console::Color::LightRed, L"Failed creating main config directory \"%s\"", PluginConfig::configDirectory.c_str()); return false; } } @@ -41,7 +48,7 @@ class PluginConfig { this->pluginName = pluginName; this->path = path; - this->fullPath = PluginConfig::getConfigDirectory() /= fs::path(pluginName) /= this->path; + this->fullPath = PluginConfig::getConfigDirectory() / fs::path(pluginName) / this->path; } #ifdef _LIB_PLUGIN_NAME_STR @@ -49,7 +56,7 @@ class PluginConfig { #endif void setDefaultContent(const char* defaultContent) { - this->defaultContent = defaultContent;; + this->defaultContent = defaultContent; } bool createIfNotExists() { @@ -67,7 +74,7 @@ class PluginConfig { if (!ofs.is_open()) { #pragma warning(suppress : 4996) - Console::wlog(Console::Color::Red, L"Failed creating config file \"%s\": %s", this->fullPath.c_str(), _wcserror(errno)); + Console::wlog(Console::Color::LightRed, L"Failed creating config file \"%s\": %s", this->fullPath.c_str(), _wcserror(errno)); return false; } @@ -82,13 +89,21 @@ class PluginConfig { if (!ifs.is_open()) { #pragma warning(suppress : 4996) - Console::wlog(Console::Color::Red, L"Failed reading config file \"%s\": %s", this->fullPath.c_str(), _wcserror(errno)); + Console::wlog(Console::Color::LightRed, L"Failed reading config file \"%s\": %s", this->fullPath.c_str(), _wcserror(errno)); return false; } - Console::wlog(Console::Color::Gray, L"Loaded content of config file \"%s\":", this->fullPath.c_str()); + Console::wlog(Console::Color::Gray, L"Loaded config file \"%s\"", this->fullPath.c_str()); + - std::cout << ifs.rdbuf() << std::endl; + try { + this->root = json::parse(ifs, nullptr, true, true); + std::cout << this->root.dump(4) << '\n'; + + } catch (json::exception& e) { + Console::wlog(Console::Color::LightRed, L"Failed parsing config file \"%s\":", this->fullPath.c_str()); + Console::log(Console::Color::LightRed, " %s", e.what()); + } ifs.close(); diff --git a/SMLibrary/packages.config b/SMLibrary/packages.config new file mode 100644 index 0000000..db3400a --- /dev/null +++ b/SMLibrary/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/SMLibrary/src/sm_lib.cpp b/SMLibrary/src/sm_lib.cpp index 626c06d..4684d53 100644 --- a/SMLibrary/src/sm_lib.cpp +++ b/SMLibrary/src/sm_lib.cpp @@ -55,7 +55,7 @@ BOOL Startup(HMODULE hModule) { BOOL PostConsoleInjections() { Console::log_open(); - PluginConfig::setConfigDirectory(smlibrarydllPath.parent_path() /= "config"); + PluginConfig::setConfigDirectory(smlibrarydllPath.parent_path() / "config"); Console::log(Color::Aqua, "Installing the library functions"); util = new HookUtility(); From 9acb927ee6be60702331410a02034f5ba47d0f07 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Wed, 15 Sep 2021 23:13:21 +0200 Subject: [PATCH 11/29] Setup dll directories on SMLibrary.dll inject --- SMLibrary/src/sm_lib.cpp | 49 +++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/SMLibrary/src/sm_lib.cpp b/SMLibrary/src/sm_lib.cpp index 4684d53..47b3983 100644 --- a/SMLibrary/src/sm_lib.cpp +++ b/SMLibrary/src/sm_lib.cpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace fs = std::filesystem; @@ -39,13 +40,15 @@ HookUtility *util; fs::path smlibrarydllPath; -BOOL Startup(HMODULE hModule) { - HMODULE sm_handle = GetModuleHandleA("ScrapMechanic.exe"); - if(!sm_handle) return false; - +fs::path GetDllPath(HMODULE hModule) { TCHAR dllPath[MAX_PATH] = { 0 }; DWORD length = GetModuleFileName(hModule, dllPath, _countof(dllPath)); - smlibrarydllPath = fs::path(dllPath); + return fs::path(dllPath); +} + +BOOL Startup() { + HMODULE sm_handle = GetModuleHandleA("ScrapMechanic.exe"); + if(!sm_handle) return false; hck_init_console = new Hook(); hck_init_console->Inject((void*)((longlong)sm_handle + offset_InitConsole), &Hooks::hook_init_console, 0, 15); @@ -75,11 +78,45 @@ BOOL PostConsoleInjections() { return true; } +void SetupDllDirectories() { + fs::path baseDir = smlibrarydllPath.parent_path(); + + fs::path directories[] = { + baseDir, + baseDir / "plugins", + baseDir / "plugins" / "dependencies" + }; + + for (const fs::path& dir : directories) { + if (!AddDllDirectory(dir.c_str())) { + std::string body; + body += "Failed adding dll directory \""; + body += dir.string(); + body += "\"\nSome plugins might not load\n\nReason:\n"; + body += std::system_category().message(GetLastError()); + + MessageBoxA(0, body.c_str(), "AddDllDirectory failed", MB_ICONERROR); + } + } + + if (!SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)) { + std::string body; + body += "Some plugins might not load\n\nReason:\n"; + body += std::system_category().message(GetLastError()); + + MessageBoxA(0, body.c_str(), "SetDefaultDllDirectories failed", MB_ICONERROR); + } +} + BOOL WINAPI DllMain(HMODULE hModule, DWORD fdwReason, LPVOID lpReserved) { switch(fdwReason) { case DLL_PROCESS_ATTACH: MessageBox(0, L"From DLL\n", L"Process Attach", MB_ICONINFORMATION); - CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)Startup, hModule, NULL, NULL); + + smlibrarydllPath = GetDllPath(hModule); + + SetupDllDirectories(); + Startup(); break; case DLL_PROCESS_DETACH: From 6b54d0e7a1117f6b72e32e69a86fdae41109fb80 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Thu, 16 Sep 2021 22:24:37 +0200 Subject: [PATCH 12/29] Use GameHook in SMLuaHook --- PluginDevFolder/SMLuaHook/hooks.h | 18 +++++++++--------- PluginDevFolder/SMLuaHook/main.cpp | 14 ++++++-------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/PluginDevFolder/SMLuaHook/hooks.h b/PluginDevFolder/SMLuaHook/hooks.h index c14963e..23ac071 100644 --- a/PluginDevFolder/SMLuaHook/hooks.h +++ b/PluginDevFolder/SMLuaHook/hooks.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include #include @@ -9,19 +9,19 @@ using Console::Color; // LUAL_REGISTER typedef void (*pluaL_register)(lua_State*, const char*, const luaL_Reg*); -Hook* hck_luaL_register; +GameHook* hck_luaL_register; // LUAL_LOADSTRING typedef int (*pluaL_loadstring)(lua_State*, const char*); -Hook* hck_luaL_loadstring; +GameHook* hck_luaL_loadstring; // LUA_NEWSTATE typedef lua_State* (*plua_newstate)(lua_Alloc, void*); -Hook* hck_lua_newstate; +GameHook* hck_lua_newstate; // LUAL_LOADBUFFER typedef int (*pluaL_loadbuffer)(lua_State*, const char*, size_t, const char*); -Hook* hck_luaL_loadbuffer; +GameHook* hck_luaL_loadbuffer; // ============= @@ -38,21 +38,21 @@ namespace Hooks { ptr++; } - return ((pluaL_register)hck_luaL_register->Gate())(L, libname, l); + return ((pluaL_register)*hck_luaL_register)(L, libname, l); } int hook_luaL_loadstring(lua_State* L, const char* s) { Console::log(Color::Aqua, "hook_luaL_loadstring: s=[ ... ]"); - return ((pluaL_loadstring)hck_luaL_loadstring->Gate())(L, s); + return ((pluaL_loadstring)*hck_luaL_loadstring)(L, s); } lua_State* hook_lua_newstate(lua_Alloc f, void* ud) { Console::log(Color::Aqua, "hck_lua_newstate: ud=[%p]", ud); - return ((plua_newstate)hck_lua_newstate->Gate())(f, ud); + return ((plua_newstate)*hck_lua_newstate)(f, ud); } int hook_luaL_loadbuffer(lua_State* L, const char* buff, size_t sz, const char* name) { Console::log(Color::Aqua, "hck_luaL_loadbuffer: buff=[ ... ], sz=[%zu], name=[%s]", sz, name); - return ((pluaL_loadbuffer)hck_luaL_loadbuffer->Gate())(L, buff, sz, name); + return ((pluaL_loadbuffer)*hck_luaL_loadbuffer)(L, buff, sz, name); } } diff --git a/PluginDevFolder/SMLuaHook/main.cpp b/PluginDevFolder/SMLuaHook/main.cpp index 931b33c..f0b7434 100644 --- a/PluginDevFolder/SMLuaHook/main.cpp +++ b/PluginDevFolder/SMLuaHook/main.cpp @@ -22,7 +22,7 @@ LIB_RESULT PluginLoad() { return PLUGIN_SUCCESSFULL; } -const char *defaultConfig = R"(// Configuration file for hooking the Lua C API +const char* defaultConfig = R"(// Configuration file for hooking the Lua C API { "hooks": { "luaL_loadstring": [ @@ -54,15 +54,13 @@ const char *defaultConfig = R"(// Configuration file for hooking the Lua C API } )"; -HookUtility* util; bool InjectLua() { Console::log(Color::Aqua, "Installing lua hooks"); - util = new HookUtility(); - hck_luaL_register = util->InjectFromName("lua51.dll", "luaL_register", &Hooks::hook_luaL_register, 15); - hck_luaL_loadstring = util->InjectFromName("lua51.dll", "luaL_loadstring", &Hooks::hook_luaL_loadstring, 16); - hck_lua_newstate = util->InjectFromName("lua51.dll", "lua_newstate", &Hooks::hook_lua_newstate, -14, 6); - hck_luaL_loadbuffer = util->InjectFromName("lua51.dll", "luaL_loadbuffer", &Hooks::hook_luaL_loadbuffer, 17, 13); + hck_luaL_register = GameHooks::InjectFromName("lua51.dll", "luaL_register", &Hooks::hook_luaL_register, 15); + hck_luaL_loadstring = GameHooks::InjectFromName("lua51.dll", "luaL_loadstring", &Hooks::hook_luaL_loadstring, 16); + hck_lua_newstate = GameHooks::InjectFromName("lua51.dll", "lua_newstate", &Hooks::hook_lua_newstate, 6); + hck_luaL_loadbuffer = GameHooks::InjectFromName("lua51.dll", "luaL_loadbuffer", &Hooks::hook_luaL_loadbuffer, 13); if (!hck_luaL_register) { Console::log(Color::Red, "Failed to inject 'luaL_register'"); @@ -94,6 +92,6 @@ bool InjectLua() { LIB_RESULT PluginUnload() { Console::log(Color::Aqua, "Unloading this plugin!"); - util->Unload(); + //util->Unload(); return PLUGIN_SUCCESSFULL; } From f4ff1e93dcb4938bc14df80e6e07e6ec7b9fbd53 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Thu, 16 Sep 2021 22:50:29 +0200 Subject: [PATCH 13/29] Improve logging of luaL_register for SMLuaReaderPlugin --- .../SMLuaReaderPlugin.vcxproj | 11 +++++++- .../SMLuaReaderPlugin.vcxproj.filters | 6 ++--- .../SMLuaReaderPlugin/packages.config | 4 +++ PluginDevFolder/SMLuaReaderPlugin/src/hooks.h | 26 ++++++++++++------- PluginDevFolder/SMLuaReaderPlugin/src/lua.h | 7 ----- 5 files changed, 34 insertions(+), 20 deletions(-) create mode 100644 PluginDevFolder/SMLuaReaderPlugin/packages.config delete mode 100644 PluginDevFolder/SMLuaReaderPlugin/src/lua.h diff --git a/PluginDevFolder/SMLuaReaderPlugin/SMLuaReaderPlugin.vcxproj b/PluginDevFolder/SMLuaReaderPlugin/SMLuaReaderPlugin.vcxproj index ab501cc..ef294b4 100644 --- a/PluginDevFolder/SMLuaReaderPlugin/SMLuaReaderPlugin.vcxproj +++ b/PluginDevFolder/SMLuaReaderPlugin/SMLuaReaderPlugin.vcxproj @@ -15,7 +15,9 @@ - + + + 16.0 @@ -118,5 +120,12 @@ copy /B "$(LocalDebuggerCommand)" "$(OutputPath)plugins\$(TargetFileName)" + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + \ No newline at end of file diff --git a/PluginDevFolder/SMLuaReaderPlugin/SMLuaReaderPlugin.vcxproj.filters b/PluginDevFolder/SMLuaReaderPlugin/SMLuaReaderPlugin.vcxproj.filters index abc8bae..f362751 100644 --- a/PluginDevFolder/SMLuaReaderPlugin/SMLuaReaderPlugin.vcxproj.filters +++ b/PluginDevFolder/SMLuaReaderPlugin/SMLuaReaderPlugin.vcxproj.filters @@ -17,8 +17,8 @@ Header Files - - Header Files - + + + \ No newline at end of file diff --git a/PluginDevFolder/SMLuaReaderPlugin/packages.config b/PluginDevFolder/SMLuaReaderPlugin/packages.config new file mode 100644 index 0000000..8226e66 --- /dev/null +++ b/PluginDevFolder/SMLuaReaderPlugin/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/PluginDevFolder/SMLuaReaderPlugin/src/hooks.h b/PluginDevFolder/SMLuaReaderPlugin/src/hooks.h index 6681f9e..916561b 100644 --- a/PluginDevFolder/SMLuaReaderPlugin/src/hooks.h +++ b/PluginDevFolder/SMLuaReaderPlugin/src/hooks.h @@ -1,6 +1,7 @@ +#pragma once #include #include -#include "lua.h" +#include #include using Console::Color; @@ -12,35 +13,42 @@ GameHook* hck_luaL_register; // LUAL_LOADSTRING typedef int (*pluaL_loadstring)(lua_State*, const char*); -GameHook *hck_luaL_loadstring; +GameHook* hck_luaL_loadstring; // LUA_NEWSTATE -typedef lua_State *(*plua_newstate)(lua_Alloc, void*); -GameHook *hck_lua_newstate; +typedef lua_State* (*plua_newstate)(lua_Alloc, void*); +GameHook* hck_lua_newstate; // LUAL_LOADBUFFER typedef int (*pluaL_loadbuffer)(lua_State*, const char*, size_t, const char*); -GameHook *hck_luaL_loadbuffer; +GameHook* hck_luaL_loadbuffer; // ============= namespace Hooks { - void hook_luaL_register(lua_State *L, const char *libname, const luaL_Reg *l) { + void hook_luaL_register(lua_State* L, const char* libname, const luaL_Reg* l) { Console::log(Color::Aqua, "hook_luaL_register: libname=[%s]", libname); + + const luaL_Reg* ptr = l; + + for (int i = 0; ptr->name != NULL; i++, ptr++) { + Console::log(Color::Aqua, "hook_luaL_register: luaL_Reg[%d] name=[%s] func=[%p]", i, ptr->name, (void*)ptr->func); + } + return ((pluaL_register)*hck_luaL_register)(L, libname, l); } - int hook_luaL_loadstring(lua_State *L, const char *s) { + int hook_luaL_loadstring(lua_State* L, const char* s) { Console::log(Color::Aqua, "hook_luaL_loadstring: s=[ ... ]"); return ((pluaL_loadstring)*hck_luaL_loadstring)(L, s); } - lua_State *hook_lua_newstate(lua_Alloc f, void* ud) { + lua_State* hook_lua_newstate(lua_Alloc f, void* ud) { Console::log(Color::Aqua, "hck_lua_newstate: ud=[%p]", ud); return ((plua_newstate)*hck_lua_newstate)(f, ud); } - int hook_luaL_loadbuffer(lua_State *L, const char *buff, size_t sz, const char *name) { + int hook_luaL_loadbuffer(lua_State* L, const char* buff, size_t sz, const char* name) { Console::log(Color::Aqua, "hck_luaL_loadbuffer: buff=[ ... ], sz=[%zu], name=[%s]", sz, name); return ((pluaL_loadbuffer)*hck_luaL_loadbuffer)(L, buff, sz, name); } diff --git a/PluginDevFolder/SMLuaReaderPlugin/src/lua.h b/PluginDevFolder/SMLuaReaderPlugin/src/lua.h deleted file mode 100644 index f0113d9..0000000 --- a/PluginDevFolder/SMLuaReaderPlugin/src/lua.h +++ /dev/null @@ -1,7 +0,0 @@ -typedef void *(*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); -typedef struct lua_State lua_State; -typedef int (*lua_CFunction) (lua_State *L); -typedef struct luaL_Reg { - const char *name; - lua_CFunction func; -} luaL_Reg; From c6b7c7fde72afa63ce1262f744cdcd441152cffd Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Mon, 4 Oct 2021 15:23:38 +0200 Subject: [PATCH 14/29] Add SMLuaHook lua hook config system --- PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj | 1 + .../SMLuaHook/SMLuaHook.vcxproj.filters | 3 + PluginDevFolder/SMLuaHook/hooks.h | 2 +- PluginDevFolder/SMLuaHook/lua_hook_config.h | 139 ++++++++++++++++++ PluginDevFolder/SMLuaHook/main.cpp | 24 ++- SMLibrary/include/plugin_config.h | 1 + 6 files changed, 165 insertions(+), 5 deletions(-) create mode 100644 PluginDevFolder/SMLuaHook/lua_hook_config.h diff --git a/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj b/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj index 70b0110..08df75f 100644 --- a/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj +++ b/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj @@ -15,6 +15,7 @@ + diff --git a/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj.filters b/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj.filters index 74a3413..127eef9 100644 --- a/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj.filters +++ b/PluginDevFolder/SMLuaHook/SMLuaHook.vcxproj.filters @@ -23,6 +23,9 @@ Header Files + + Header Files + diff --git a/PluginDevFolder/SMLuaHook/hooks.h b/PluginDevFolder/SMLuaHook/hooks.h index 23ac071..cfe08b0 100644 --- a/PluginDevFolder/SMLuaHook/hooks.h +++ b/PluginDevFolder/SMLuaHook/hooks.h @@ -25,7 +25,7 @@ GameHook* hck_luaL_loadbuffer; // ============= -namespace Hooks { +namespace LuaHook::Hooks { void hook_luaL_register(lua_State* L, const char* libname, const luaL_Reg* l) { Console::log(Color::Aqua, "hook_luaL_register: libname=[%s]", libname); diff --git a/PluginDevFolder/SMLuaHook/lua_hook_config.h b/PluginDevFolder/SMLuaHook/lua_hook_config.h new file mode 100644 index 0000000..821556f --- /dev/null +++ b/PluginDevFolder/SMLuaHook/lua_hook_config.h @@ -0,0 +1,139 @@ +#pragma once +#pragma warning(push) +#pragma warning(disable : 26819 28020) +#include +#pragma warning(pop) +#include +#include +#include +#include + +using json = nlohmann::json; + +namespace LuaHook { + + typedef std::function fields, json j_hook, json j_selector)> selectorFunction; + + std::map selectorFunctions = { + { + "CONTAINS", [](std::map fields, json j_hook, json j_selector) { + //assert(j_selector["field"], "selector.field not found!"); + std::string fieldName = j_selector["field"]; + + //assert(fields.find(fieldName) != fields.end(), "this field does not exist for this hook!"); + std::string input = std::any_cast(fields[j_selector["field"]]); + + //assert(j_selector["value"], "selector.value not found!"); + std::string value = j_selector["value"]; + + return input.find(value) != std::string::npos; + } + } + }; + + struct selector { + selectorFunction* func; + }; + + void from_json(const json& j, selector& s) { + s.func = &selectorFunctions.at(j.at("operator").get()); + } + + + + struct hookItem { + float priority = 1; + std::vector selector; + std::vector execute; + }; + + void from_json(const json& j, hookItem& hi) { + j.at("priority").get_to(hi.priority); + j.at("selector").get_to(hi.selector); + j.at("execute").get_to(hi.execute); + } + + + + class HookConfig { + public: + inline static std::vector enabledConfigs; + + private: + json root; + std::map> hooks; + bool enabled = false; + + public: + HookConfig(json root) { + this->root = root; + + //assert(this->root["hooks"], "lua hook config has no \"hooks\" object"); + + for (auto& [key, value] : this->root.at("hooks").items()) { + this->hooks[key] = value.get>(); + } + } + + ~HookConfig() { + if (this->enabled) { + Console::log(Color::LightYellow, "Warning: Deconstructing HookConfig while enabled!"); + } + } + + void setEnabled(bool enabled) { + if (enabled == this->enabled) { + return; + } + + if (enabled) { + // Add this + HookConfig::enabledConfigs.push_back(this); + } + else { + // Remove this + HookConfig::enabledConfigs.erase(std::remove(HookConfig::enabledConfigs.begin(), HookConfig::enabledConfigs.end(), this), HookConfig::enabledConfigs.end()); + } + } + + static std::vector getHookItems(std::string name) { + size_t totalSize = 0; + + // Calculate the total size + for (auto& hookConfig : HookConfig::enabledConfigs) { + if (hookConfig->hooks.find(name) == hookConfig->hooks.end()) + continue; + + totalSize += hookConfig->hooks[name].size(); + } + + std::vector items; + items.reserve(totalSize); + + // Insert all hookItems into items + for (auto& hookConfig : HookConfig::enabledConfigs) { + if (hookConfig->hooks.find(name) == hookConfig->hooks.end()) + continue; + + items.insert(items.end(), hookConfig->hooks[name].begin(), hookConfig->hooks[name].end()); + } + + return items; + } + + static std::set getHookNames() { + std::set names; + + // Insert all hookItems into items + for (auto& hookConfig : HookConfig::enabledConfigs) { + for (auto& [hookName, hookItems] : hookConfig->hooks) { + names.insert(hookName); + } + } + + return names; + } + + }; + +} \ No newline at end of file diff --git a/PluginDevFolder/SMLuaHook/main.cpp b/PluginDevFolder/SMLuaHook/main.cpp index f0b7434..0052123 100644 --- a/PluginDevFolder/SMLuaHook/main.cpp +++ b/PluginDevFolder/SMLuaHook/main.cpp @@ -9,6 +9,7 @@ using Console::Color; #include "hooks.h" +#include "lua_hook_config.h" bool InjectLua(); LIB_RESULT PluginLoad() { @@ -57,10 +58,10 @@ const char* defaultConfig = R"(// Configuration file for hooking the Lua C API bool InjectLua() { Console::log(Color::Aqua, "Installing lua hooks"); - hck_luaL_register = GameHooks::InjectFromName("lua51.dll", "luaL_register", &Hooks::hook_luaL_register, 15); - hck_luaL_loadstring = GameHooks::InjectFromName("lua51.dll", "luaL_loadstring", &Hooks::hook_luaL_loadstring, 16); - hck_lua_newstate = GameHooks::InjectFromName("lua51.dll", "lua_newstate", &Hooks::hook_lua_newstate, 6); - hck_luaL_loadbuffer = GameHooks::InjectFromName("lua51.dll", "luaL_loadbuffer", &Hooks::hook_luaL_loadbuffer, 13); + hck_luaL_register = GameHooks::InjectFromName("lua51.dll", "luaL_register", &LuaHook::Hooks::hook_luaL_register, 15); + hck_luaL_loadstring = GameHooks::InjectFromName("lua51.dll", "luaL_loadstring", &LuaHook::Hooks::hook_luaL_loadstring, 16); + hck_lua_newstate = GameHooks::InjectFromName("lua51.dll", "lua_newstate", &LuaHook::Hooks::hook_lua_newstate, 6); + hck_luaL_loadbuffer = GameHooks::InjectFromName("lua51.dll", "luaL_loadbuffer", &LuaHook::Hooks::hook_luaL_loadbuffer, 13); if (!hck_luaL_register) { Console::log(Color::Red, "Failed to inject 'luaL_register'"); @@ -87,6 +88,21 @@ bool InjectLua() { config.createIfNotExists(); config.load(); + try { + Console::log(Color::Aqua, "Loading Lua C API hook config files..."); + LuaHook::HookConfig *hookConfig = new LuaHook::HookConfig(config.root); + hookConfig->setEnabled(true); + } + catch (const json::exception& e) { + Console::log(Color::LightRed, "Failed initialising HookConfig: %s", e.what()); + } + + Console::log(Color::Aqua, "Loaded %llu Lua C API hook config files", LuaHook::HookConfig::enabledConfigs.size()); + for (auto& hookName : LuaHook::HookConfig::getHookNames()) { + Console::log(Color::Aqua, " %s (%llu)", hookName.c_str(), LuaHook::HookConfig::getHookItems(hookName).size()); + } + + return true; } diff --git a/SMLibrary/include/plugin_config.h b/SMLibrary/include/plugin_config.h index ec56e58..7c25e03 100644 --- a/SMLibrary/include/plugin_config.h +++ b/SMLibrary/include/plugin_config.h @@ -5,6 +5,7 @@ #include #pragma warning(push) #pragma warning(disable : 26819 28020) +#define JSON_DIAGNOSTICS 1 #include #pragma warning(pop) #include "console.h" From fce3abf95bb5735df0e6df4a259b7583e29b00be Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Mon, 4 Oct 2021 19:39:22 +0200 Subject: [PATCH 15/29] Implement EXISTS selector --- PluginDevFolder/SMLuaHook/hooks.h | 14 ++++ PluginDevFolder/SMLuaHook/lua_hook_config.h | 92 ++++++++++++++++----- 2 files changed, 85 insertions(+), 21 deletions(-) diff --git a/PluginDevFolder/SMLuaHook/hooks.h b/PluginDevFolder/SMLuaHook/hooks.h index cfe08b0..50f6fe3 100644 --- a/PluginDevFolder/SMLuaHook/hooks.h +++ b/PluginDevFolder/SMLuaHook/hooks.h @@ -6,6 +6,8 @@ #include using Console::Color; +#include "lua_hook_config.h" + // LUAL_REGISTER typedef void (*pluaL_register)(lua_State*, const char*, const luaL_Reg*); @@ -43,6 +45,18 @@ namespace LuaHook::Hooks { int hook_luaL_loadstring(lua_State* L, const char* s) { Console::log(Color::Aqua, "hook_luaL_loadstring: s=[ ... ]"); + + std::map fields = { + {"s", &s} + }; + + for (LuaHook::hookItem& hookItem : LuaHook::HookConfig::getHookItems("luaL_loadstring")) { + for (LuaHook::selector& selector : hookItem.selector) { + bool selected = (*selector.func)(fields, hookItem, selector); + Console::log(selected ? Color::LightPurple : Color::Purple, selected ? "selected" : "not selected"); + } + } + return ((pluaL_loadstring)*hck_luaL_loadstring)(L, s); } diff --git a/PluginDevFolder/SMLuaHook/lua_hook_config.h b/PluginDevFolder/SMLuaHook/lua_hook_config.h index 821556f..3e80ff0 100644 --- a/PluginDevFolder/SMLuaHook/lua_hook_config.h +++ b/PluginDevFolder/SMLuaHook/lua_hook_config.h @@ -1,6 +1,7 @@ #pragma once #pragma warning(push) #pragma warning(disable : 26819 28020) +#define JSON_DIAGNOSTICS 1 #include #pragma warning(pop) #include @@ -12,45 +13,92 @@ using json = nlohmann::json; namespace LuaHook { - typedef std::function fields, json j_hook, json j_selector)> selectorFunction; + struct selector; + struct hookItem; - std::map selectorFunctions = { - { - "CONTAINS", [](std::map fields, json j_hook, json j_selector) { - //assert(j_selector["field"], "selector.field not found!"); - std::string fieldName = j_selector["field"]; + typedef std::function fields, hookItem hookItem, selector selector)> selectorFunction; - //assert(fields.find(fieldName) != fields.end(), "this field does not exist for this hook!"); - std::string input = std::any_cast(fields[j_selector["field"]]); + struct selector { + selectorFunction* func; + + json j_selector; + }; + + struct hookItem { + float priority = 1; + std::vector selector; + std::vector execute; + + json j_hook; + + bool operator<(const hookItem& other) const { + return this->priority < other.priority; + } + }; + + namespace SelectorHelper { + + std::any getInput(std::map& fields, hookItem& hookItem, selector& selector) { + if (selector.j_selector.contains("field")) { + std::string fieldName = selector.j_selector.at("field"); + + if (fields.find(fieldName) == fields.end()) { + throw new std::invalid_argument("Field not found"); + } + + return fields[fieldName]; + } + else { + if (fields.size() == 1) { + return fields.begin()->second; + } + else { + // Throw an exception + selector.j_selector.at("field"); + return NULL; + } + } + } - //assert(j_selector["value"], "selector.value not found!"); - std::string value = j_selector["value"]; + std::string getInputConstCharPtr(std::map& fields, hookItem& hookItem, selector& selector) { + std::any input = SelectorHelper::getInput(fields, hookItem, selector); + + if (const char*** str = std::any_cast(&input)) { + return std::string(**str); + } + else { + throw new std::invalid_argument(std::string("Field type not castable to const char**: ") + input.type().name()); + } + } + + } + + std::map selectorFunctions = { + { + "CONTAINS", [](std::map fields, hookItem hookItem, selector selector) { + std::string input = SelectorHelper::getInputConstCharPtr(fields, hookItem, selector); + + std::string value = selector.j_selector.at("value"); return input.find(value) != std::string::npos; } } }; - struct selector { - selectorFunction* func; - }; + void from_json(const json& j, selector& s) { s.func = &selectorFunctions.at(j.at("operator").get()); - } - - - struct hookItem { - float priority = 1; - std::vector selector; - std::vector execute; - }; + j.get_to(s.j_selector); + } void from_json(const json& j, hookItem& hi) { j.at("priority").get_to(hi.priority); j.at("selector").get_to(hi.selector); j.at("execute").get_to(hi.execute); + + j.get_to(hi.j_hook); } @@ -118,6 +166,8 @@ namespace LuaHook { items.insert(items.end(), hookConfig->hooks[name].begin(), hookConfig->hooks[name].end()); } + std::sort(items.begin(), items.end()); + return items; } From 502953e2185fad90946f07a1cd9850c8434d108e Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Mon, 4 Oct 2021 21:58:02 +0200 Subject: [PATCH 16/29] Add luaL_loadbuffer hook and EQUALS selector --- PluginDevFolder/SMLuaHook/hooks.h | 13 +++++++++++++ PluginDevFolder/SMLuaHook/lua_hook_config.h | 9 +++++++++ 2 files changed, 22 insertions(+) diff --git a/PluginDevFolder/SMLuaHook/hooks.h b/PluginDevFolder/SMLuaHook/hooks.h index 50f6fe3..c1d1abf 100644 --- a/PluginDevFolder/SMLuaHook/hooks.h +++ b/PluginDevFolder/SMLuaHook/hooks.h @@ -67,6 +67,19 @@ namespace LuaHook::Hooks { int hook_luaL_loadbuffer(lua_State* L, const char* buff, size_t sz, const char* name) { Console::log(Color::Aqua, "hck_luaL_loadbuffer: buff=[ ... ], sz=[%zu], name=[%s]", sz, name); + + std::map fields = { + {"buff", &buff}, + {"name", &name} + }; + + for (LuaHook::hookItem& hookItem : LuaHook::HookConfig::getHookItems("luaL_loadbuffer")) { + for (LuaHook::selector& selector : hookItem.selector) { + bool selected = (*selector.func)(fields, hookItem, selector); + Console::log(selected ? Color::LightPurple : Color::Purple, selected ? "selected" : "not selected"); + } + } + return ((pluaL_loadbuffer)*hck_luaL_loadbuffer)(L, buff, sz, name); } } diff --git a/PluginDevFolder/SMLuaHook/lua_hook_config.h b/PluginDevFolder/SMLuaHook/lua_hook_config.h index 3e80ff0..b3ee096 100644 --- a/PluginDevFolder/SMLuaHook/lua_hook_config.h +++ b/PluginDevFolder/SMLuaHook/lua_hook_config.h @@ -82,6 +82,15 @@ namespace LuaHook { return input.find(value) != std::string::npos; } + }, + { + "EQUALS", [](std::map fields, hookItem hookItem, selector selector) { + std::string input = SelectorHelper::getInputConstCharPtr(fields, hookItem, selector); + + std::string value = selector.j_selector.at("value"); + + return input.compare(value) == 0; + } } }; From 0a128a13fc5a0d2333beba0060a236d50be09724 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Fri, 8 Oct 2021 22:19:37 +0200 Subject: [PATCH 17/29] Add PathHelper --- SMLibrary/SMLibrary.vcxproj | 1 + SMLibrary/SMLibrary.vcxproj.filters | 3 +++ SMLibrary/include/path_helper.h | 42 +++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 SMLibrary/include/path_helper.h diff --git a/SMLibrary/SMLibrary.vcxproj b/SMLibrary/SMLibrary.vcxproj index ae6f85d..5503edf 100644 --- a/SMLibrary/SMLibrary.vcxproj +++ b/SMLibrary/SMLibrary.vcxproj @@ -92,6 +92,7 @@ + diff --git a/SMLibrary/SMLibrary.vcxproj.filters b/SMLibrary/SMLibrary.vcxproj.filters index a44d82a..556726b 100644 --- a/SMLibrary/SMLibrary.vcxproj.filters +++ b/SMLibrary/SMLibrary.vcxproj.filters @@ -47,6 +47,9 @@ Header Files + + Header Files + diff --git a/SMLibrary/include/path_helper.h b/SMLibrary/include/path_helper.h new file mode 100644 index 0000000..7a21e49 --- /dev/null +++ b/SMLibrary/include/path_helper.h @@ -0,0 +1,42 @@ +#pragma once +#include +#include + +#include "plugin_config.h" + +namespace fs = std::filesystem; + +namespace PathHelper { + + fs::path getInstallationPath() { + TCHAR dir[MAX_PATH] = { 0 }; + DWORD length = GetModuleFileName(NULL, dir, _countof(dir)); + return fs::path(dir).parent_path(); + } + + fs::path resolvePath(std::string path) { + +#ifdef _LIB_PLUGIN_NAME_STR + if (path.rfind("$PLUGIN_CONFIG", 0) == 0) { + return PluginConfig::getConfigDirectory() / fs::path(_LIB_PLUGIN_NAME_STR) / path.substr(path.find_first_of("/") + 1); + } +#endif + + if (path.rfind("$GAME_DATA", 0) == 0) { + return PathHelper::getInstallationPath() / fs::path("Data") / path.substr(path.find_first_of("/") + 1); + } + + if (path.rfind("$SURVIVAL_DATA", 0) == 0) { + return PathHelper::getInstallationPath() / fs::path("Survival") / path.substr(path.find_first_of("/") + 1); + } + + if (path.rfind("$CHALLENGE_DATA", 0) == 0) { + return PathHelper::getInstallationPath() / fs::path("ChallengeData") / path.substr(path.find_first_of("/") + 1); + } + + // TODO: Call the funtion in the game to do this + + return path; + } + +} From b96ae12f0b4b702d7b4a69097bbb13827e4d2baf Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Fri, 8 Oct 2021 22:26:49 +0200 Subject: [PATCH 18/29] Implement REPLACE_CONTENT_WITH_FILE executor for luaL_loadstring --- PluginDevFolder/SMLuaHook/hooks.h | 28 ++++++++++++++- PluginDevFolder/SMLuaHook/lua_hook_config.h | 39 ++++++++++++++++++++- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/PluginDevFolder/SMLuaHook/hooks.h b/PluginDevFolder/SMLuaHook/hooks.h index c1d1abf..356037e 100644 --- a/PluginDevFolder/SMLuaHook/hooks.h +++ b/PluginDevFolder/SMLuaHook/hooks.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include #include @@ -51,9 +52,34 @@ namespace LuaHook::Hooks { }; for (LuaHook::hookItem& hookItem : LuaHook::HookConfig::getHookItems("luaL_loadstring")) { + bool selected = true; + for (LuaHook::selector& selector : hookItem.selector) { - bool selected = (*selector.func)(fields, hookItem, selector); + selected &= (*selector.func)(fields, hookItem, selector); + Console::log(selected ? Color::LightPurple : Color::Purple, selected ? "selected" : "not selected"); + + if (!selected) { + break; + } + } + + if (selected) { + std::string sStr(s); + + for (LuaHook::executor& executor : hookItem.execute) { + try { + if (executor.command == "REPLACE_CONTENT_WITH_FILE") { + sStr = LuaHook::ExecutorHelper::readFile(PathHelper::resolvePath(executor.j_executor.at("file"))); + } + } + catch (std::exception& e) { + Console::log(Color::LightRed, "Failed executing executor %s: %s", executor.j_executor.dump(4).c_str(), e.what()); + } + } + + Console::log(Color::Green, "Set contents to:\n%s", sStr.c_str()); + return ((pluaL_loadstring)*hck_luaL_loadstring)(L, sStr.c_str()); } } diff --git a/PluginDevFolder/SMLuaHook/lua_hook_config.h b/PluginDevFolder/SMLuaHook/lua_hook_config.h index b3ee096..5b8ece2 100644 --- a/PluginDevFolder/SMLuaHook/lua_hook_config.h +++ b/PluginDevFolder/SMLuaHook/lua_hook_config.h @@ -8,6 +8,12 @@ #include #include #include +#include +#include +#include +#include + +namespace fs = std::filesystem; using json = nlohmann::json; @@ -23,11 +29,17 @@ namespace LuaHook { json j_selector; }; + + struct executor { + std::string command; + + json j_executor; + }; struct hookItem { float priority = 1; std::vector selector; - std::vector execute; + std::vector execute; json j_hook; @@ -96,12 +108,37 @@ namespace LuaHook { + namespace ExecutorHelper { + + std::string readFile(fs::path path) { + std::ifstream in(path); + + if (in.fail()) { +#pragma warning(suppress : 4996) + throw std::exception((std::string() + "Failed to open file \"" + path.string() + "\": " + strerror(errno)).c_str()); + } + + std::ostringstream sstr; + sstr << in.rdbuf(); + return sstr.str(); + } + + } + + + void from_json(const json& j, selector& s) { s.func = &selectorFunctions.at(j.at("operator").get()); j.get_to(s.j_selector); } + void from_json(const json& j, executor& e) { + j.at("command").get_to(e.command); + + j.get_to(e.j_executor); + } + void from_json(const json& j, hookItem& hi) { j.at("priority").get_to(hi.priority); j.at("selector").get_to(hi.selector); From b3204735bb120b4e326e27986094c90abce876d4 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Fri, 8 Oct 2021 23:54:14 +0200 Subject: [PATCH 19/29] Use map for executor functions --- PluginDevFolder/SMLuaHook/hooks.h | 33 ++---------- PluginDevFolder/SMLuaHook/lua_hook_config.h | 57 +++++++++++++++++++-- 2 files changed, 56 insertions(+), 34 deletions(-) diff --git a/PluginDevFolder/SMLuaHook/hooks.h b/PluginDevFolder/SMLuaHook/hooks.h index 356037e..18445b2 100644 --- a/PluginDevFolder/SMLuaHook/hooks.h +++ b/PluginDevFolder/SMLuaHook/hooks.h @@ -51,36 +51,11 @@ namespace LuaHook::Hooks { {"s", &s} }; - for (LuaHook::hookItem& hookItem : LuaHook::HookConfig::getHookItems("luaL_loadstring")) { - bool selected = true; + std::string input(s); - for (LuaHook::selector& selector : hookItem.selector) { - selected &= (*selector.func)(fields, hookItem, selector); - - Console::log(selected ? Color::LightPurple : Color::Purple, selected ? "selected" : "not selected"); - - if (!selected) { - break; - } - } - - if (selected) { - std::string sStr(s); - - for (LuaHook::executor& executor : hookItem.execute) { - try { - if (executor.command == "REPLACE_CONTENT_WITH_FILE") { - sStr = LuaHook::ExecutorHelper::readFile(PathHelper::resolvePath(executor.j_executor.at("file"))); - } - } - catch (std::exception& e) { - Console::log(Color::LightRed, "Failed executing executor %s: %s", executor.j_executor.dump(4).c_str(), e.what()); - } - } - - Console::log(Color::Green, "Set contents to:\n%s", sStr.c_str()); - return ((pluaL_loadstring)*hck_luaL_loadstring)(L, sStr.c_str()); - } + if (LuaHook::runLuaHook("luaL_loadstring", &input, fields)) { + Console::log(Color::Green, "Set contents to:\n%s", input.c_str()); + return ((pluaL_loadstring)*hck_luaL_loadstring)(L, input.c_str()); } return ((pluaL_loadstring)*hck_luaL_loadstring)(L, s); diff --git a/PluginDevFolder/SMLuaHook/lua_hook_config.h b/PluginDevFolder/SMLuaHook/lua_hook_config.h index 5b8ece2..716a112 100644 --- a/PluginDevFolder/SMLuaHook/lua_hook_config.h +++ b/PluginDevFolder/SMLuaHook/lua_hook_config.h @@ -20,9 +20,11 @@ using json = nlohmann::json; namespace LuaHook { struct selector; + struct executor; struct hookItem; - typedef std::function fields, hookItem hookItem, selector selector)> selectorFunction; + typedef std::function& fields, hookItem& hookItem, selector& selector)> selectorFunction; + typedef std::function executorFunction; struct selector { selectorFunction* func; @@ -31,7 +33,7 @@ namespace LuaHook { }; struct executor { - std::string command; + executorFunction* func; json j_executor; }; @@ -87,7 +89,7 @@ namespace LuaHook { std::map selectorFunctions = { { - "CONTAINS", [](std::map fields, hookItem hookItem, selector selector) { + "CONTAINS", [](std::map& fields, hookItem& hookItem, selector& selector) { std::string input = SelectorHelper::getInputConstCharPtr(fields, hookItem, selector); std::string value = selector.j_selector.at("value"); @@ -96,7 +98,7 @@ namespace LuaHook { } }, { - "EQUALS", [](std::map fields, hookItem hookItem, selector selector) { + "EQUALS", [](std::map& fields, hookItem& hookItem, selector& selector) { std::string input = SelectorHelper::getInputConstCharPtr(fields, hookItem, selector); std::string value = selector.j_selector.at("value"); @@ -125,6 +127,14 @@ namespace LuaHook { } + std::map executorFunctions = { + { + "REPLACE_CONTENT_WITH_FILE", [](std::string* input, hookItem& hookItem, executor& executor) { + return input->assign(LuaHook::ExecutorHelper::readFile(PathHelper::resolvePath(executor.j_executor.at("file")))); + } + } + }; + void from_json(const json& j, selector& s) { @@ -134,7 +144,7 @@ namespace LuaHook { } void from_json(const json& j, executor& e) { - j.at("command").get_to(e.command); + e.func = &executorFunctions.at(j.at("command").get()); j.get_to(e.j_executor); } @@ -232,4 +242,41 @@ namespace LuaHook { }; + + + bool runLuaHook(std::string name, std::string* input, std::map& fields) { + bool hasDoneSomething = false; + + for (hookItem& hookItem : HookConfig::getHookItems(name)) { + bool selected = true; + + for (selector& selector : hookItem.selector) { + selected &= (*selector.func)(fields, hookItem, selector); + + Console::log(selected ? Color::LightPurple : Color::Purple, selected ? "selected" : "not selected"); + + if (!selected) { + break; + } + } + + if (selected) { + + for (executor& executor : hookItem.execute) { + try { + (*executor.func)(input, hookItem, executor); + + hasDoneSomething = true; + } + catch (std::exception& e) { + Console::log(Color::LightRed, "Failed executing executor %s: %s", executor.j_executor.dump(4).c_str(), e.what()); + } + } + + } + } + + return hasDoneSomething; + } + } \ No newline at end of file From f0b401204a638d6897fc1607ad4aacef015875eb Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Sat, 9 Oct 2021 00:53:11 +0200 Subject: [PATCH 20/29] Add error handling to HookConfig --- PluginDevFolder/SMLuaHook/lua_hook_config.h | 38 ++++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/PluginDevFolder/SMLuaHook/lua_hook_config.h b/PluginDevFolder/SMLuaHook/lua_hook_config.h index 716a112..791c748 100644 --- a/PluginDevFolder/SMLuaHook/lua_hook_config.h +++ b/PluginDevFolder/SMLuaHook/lua_hook_config.h @@ -138,13 +138,35 @@ namespace LuaHook { void from_json(const json& j, selector& s) { - s.func = &selectorFunctions.at(j.at("operator").get()); + std::string op = j.at("operator").get(); + + if (selectorFunctions.find(op) == selectorFunctions.end()) { + std::vector opList; + for (auto const& opFunc : selectorFunctions) { + opList.push_back(opFunc.first); + } + + throw std::exception((std::string() + "Unknown operator \"" + op + "\". Possible operators: " + json(opList).dump()).c_str()); + } + + s.func = &selectorFunctions.at(op); j.get_to(s.j_selector); } void from_json(const json& j, executor& e) { - e.func = &executorFunctions.at(j.at("command").get()); + std::string command = j.at("command").get(); + + if (executorFunctions.find(command) == executorFunctions.end()) { + std::vector commandList; + for (auto const& cmdFunc : executorFunctions) { + commandList.push_back(cmdFunc.first); + } + + throw std::exception((std::string() + "Unknown command \"" + command + "\". Possible commands: " + json(commandList).dump()).c_str()); + } + + e.func = &executorFunctions.at(command); j.get_to(e.j_executor); } @@ -172,10 +194,16 @@ namespace LuaHook { HookConfig(json root) { this->root = root; - //assert(this->root["hooks"], "lua hook config has no \"hooks\" object"); - for (auto& [key, value] : this->root.at("hooks").items()) { - this->hooks[key] = value.get>(); + try { + this->hooks[key] = value.get>(); + } + catch (json::exception e) { + Console::log(Color::LightRed, "Failed parsing %s hooks: %s", key.c_str(), e.what()); + } + catch (std::exception e) { + Console::log(Color::LightRed, "Failed processing %s hooks: %s", key.c_str(), e.what()); + } } } From fb2d52e1cc79f0c7b87c44adbca91d62cc930642 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Sat, 9 Oct 2021 00:53:39 +0200 Subject: [PATCH 21/29] Add APPEND_FILE executor --- PluginDevFolder/SMLuaHook/lua_hook_config.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/PluginDevFolder/SMLuaHook/lua_hook_config.h b/PluginDevFolder/SMLuaHook/lua_hook_config.h index 791c748..ceff4c2 100644 --- a/PluginDevFolder/SMLuaHook/lua_hook_config.h +++ b/PluginDevFolder/SMLuaHook/lua_hook_config.h @@ -132,6 +132,11 @@ namespace LuaHook { "REPLACE_CONTENT_WITH_FILE", [](std::string* input, hookItem& hookItem, executor& executor) { return input->assign(LuaHook::ExecutorHelper::readFile(PathHelper::resolvePath(executor.j_executor.at("file")))); } + }, + { + "APPEND_FILE", [](std::string* input, hookItem& hookItem, executor& executor) { + return input->append("\n").append(LuaHook::ExecutorHelper::readFile(PathHelper::resolvePath(executor.j_executor.at("file")))); + } } }; From 3b4cb238500dee1087229b4a06f3ac731c2cc9cb Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Sat, 9 Oct 2021 23:55:18 +0200 Subject: [PATCH 22/29] Pass fields to executor --- PluginDevFolder/SMLuaHook/lua_hook_config.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PluginDevFolder/SMLuaHook/lua_hook_config.h b/PluginDevFolder/SMLuaHook/lua_hook_config.h index ceff4c2..1282e68 100644 --- a/PluginDevFolder/SMLuaHook/lua_hook_config.h +++ b/PluginDevFolder/SMLuaHook/lua_hook_config.h @@ -24,7 +24,7 @@ namespace LuaHook { struct hookItem; typedef std::function& fields, hookItem& hookItem, selector& selector)> selectorFunction; - typedef std::function executorFunction; + typedef std::function& fields, hookItem& hookItem, executor& executor)> executorFunction; struct selector { selectorFunction* func; @@ -129,12 +129,12 @@ namespace LuaHook { std::map executorFunctions = { { - "REPLACE_CONTENT_WITH_FILE", [](std::string* input, hookItem& hookItem, executor& executor) { + "REPLACE_CONTENT_WITH_FILE", [](std::string* input, std::map& fields, hookItem& hookItem, executor& executor) { return input->assign(LuaHook::ExecutorHelper::readFile(PathHelper::resolvePath(executor.j_executor.at("file")))); } }, { - "APPEND_FILE", [](std::string* input, hookItem& hookItem, executor& executor) { + "APPEND_FILE", [](std::string* input, std::map& fields, hookItem& hookItem, executor& executor) { return input->append("\n").append(LuaHook::ExecutorHelper::readFile(PathHelper::resolvePath(executor.j_executor.at("file")))); } } @@ -297,7 +297,7 @@ namespace LuaHook { for (executor& executor : hookItem.execute) { try { - (*executor.func)(input, hookItem, executor); + (*executor.func)(input, fields, hookItem, executor); hasDoneSomething = true; } From b8cb446310af7bf6fdce7481803898858edc8aa6 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Sun, 10 Oct 2021 00:43:33 +0200 Subject: [PATCH 23/29] Return execute count in runLuaHook --- PluginDevFolder/SMLuaHook/lua_hook_config.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PluginDevFolder/SMLuaHook/lua_hook_config.h b/PluginDevFolder/SMLuaHook/lua_hook_config.h index 1282e68..9decf72 100644 --- a/PluginDevFolder/SMLuaHook/lua_hook_config.h +++ b/PluginDevFolder/SMLuaHook/lua_hook_config.h @@ -277,8 +277,8 @@ namespace LuaHook { - bool runLuaHook(std::string name, std::string* input, std::map& fields) { - bool hasDoneSomething = false; + size_t runLuaHook(std::string name, std::string* input, std::map& fields) { + size_t executeCount = 0; for (hookItem& hookItem : HookConfig::getHookItems(name)) { bool selected = true; @@ -299,7 +299,7 @@ namespace LuaHook { try { (*executor.func)(input, fields, hookItem, executor); - hasDoneSomething = true; + executeCount++; } catch (std::exception& e) { Console::log(Color::LightRed, "Failed executing executor %s: %s", executor.j_executor.dump(4).c_str(), e.what()); @@ -309,7 +309,7 @@ namespace LuaHook { } } - return hasDoneSomething; + return executeCount; } } \ No newline at end of file From 6c236b9db0db23e98eef46af28c9c5fb6e8a233f Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Sun, 10 Oct 2021 00:44:15 +0200 Subject: [PATCH 24/29] Add luaL_loadbuffer hook --- PluginDevFolder/SMLuaHook/hooks.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/PluginDevFolder/SMLuaHook/hooks.h b/PluginDevFolder/SMLuaHook/hooks.h index 18445b2..c01b763 100644 --- a/PluginDevFolder/SMLuaHook/hooks.h +++ b/PluginDevFolder/SMLuaHook/hooks.h @@ -74,11 +74,11 @@ namespace LuaHook::Hooks { {"name", &name} }; - for (LuaHook::hookItem& hookItem : LuaHook::HookConfig::getHookItems("luaL_loadbuffer")) { - for (LuaHook::selector& selector : hookItem.selector) { - bool selected = (*selector.func)(fields, hookItem, selector); - Console::log(selected ? Color::LightPurple : Color::Purple, selected ? "selected" : "not selected"); - } + std::string input(buff, sz); + + if (size_t executeCount = LuaHook::runLuaHook("luaL_loadbuffer", &input, fields)) { + Console::log(Color::Green, "Set contents to:\n%s", input.c_str()); + return ((pluaL_loadbuffer)*hck_luaL_loadbuffer)(L, input.c_str(), input.size(), name); } return ((pluaL_loadbuffer)*hck_luaL_loadbuffer)(L, buff, sz, name); From a7cdc23496735fdfc14243d59c9362a3c0b44cda Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Sun, 10 Oct 2021 21:11:38 +0200 Subject: [PATCH 25/29] Add PREPEND_FILE executor --- PluginDevFolder/SMLuaHook/lua_hook_config.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/PluginDevFolder/SMLuaHook/lua_hook_config.h b/PluginDevFolder/SMLuaHook/lua_hook_config.h index 9decf72..07ffc8e 100644 --- a/PluginDevFolder/SMLuaHook/lua_hook_config.h +++ b/PluginDevFolder/SMLuaHook/lua_hook_config.h @@ -133,6 +133,11 @@ namespace LuaHook { return input->assign(LuaHook::ExecutorHelper::readFile(PathHelper::resolvePath(executor.j_executor.at("file")))); } }, + { + "PREPEND_FILE", [](std::string* input, std::map& fields, hookItem& hookItem, executor& executor) { + return input->insert(0, LuaHook::ExecutorHelper::readFile(PathHelper::resolvePath(executor.j_executor.at("file"))).append("\n")); + } + }, { "APPEND_FILE", [](std::string* input, std::map& fields, hookItem& hookItem, executor& executor) { return input->append("\n").append(LuaHook::ExecutorHelper::readFile(PathHelper::resolvePath(executor.j_executor.at("file")))); From 7b8e384ed33f1f1932201159a35fc485d152b214 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Sun, 10 Oct 2021 22:49:32 +0200 Subject: [PATCH 26/29] Add PREPEND_STRING and APPEND_STRING executors --- PluginDevFolder/SMLuaHook/lua_hook_config.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/PluginDevFolder/SMLuaHook/lua_hook_config.h b/PluginDevFolder/SMLuaHook/lua_hook_config.h index 07ffc8e..0b78206 100644 --- a/PluginDevFolder/SMLuaHook/lua_hook_config.h +++ b/PluginDevFolder/SMLuaHook/lua_hook_config.h @@ -142,6 +142,16 @@ namespace LuaHook { "APPEND_FILE", [](std::string* input, std::map& fields, hookItem& hookItem, executor& executor) { return input->append("\n").append(LuaHook::ExecutorHelper::readFile(PathHelper::resolvePath(executor.j_executor.at("file")))); } + }, + { + "PREPEND_STRING", [](std::string* input, std::map& fields, hookItem& hookItem, executor& executor) { + return input->insert(0, executor.j_executor.at("string").get().append("\n")); + } + }, + { + "APPEND_STRING", [](std::string* input, std::map& fields, hookItem& hookItem, executor& executor) { + return input->append("\n").append(executor.j_executor.at("string")); + } } }; From 53073763a2dcd78a81443142f0d2fe6cfb1a7cfc Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Sun, 10 Oct 2021 23:12:48 +0200 Subject: [PATCH 27/29] Update default lua_hooks.json --- PluginDevFolder/SMLuaHook/main.cpp | 61 +++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/PluginDevFolder/SMLuaHook/main.cpp b/PluginDevFolder/SMLuaHook/main.cpp index 0052123..7ec6e06 100644 --- a/PluginDevFolder/SMLuaHook/main.cpp +++ b/PluginDevFolder/SMLuaHook/main.cpp @@ -27,29 +27,56 @@ const char* defaultConfig = R"(// Configuration file for hooking the Lua C API { "hooks": { "luaL_loadstring": [ + /* { - "selector": { - "operator": "contains", - "value": "unsafe_env" - }, - "file": { - "option": "replace_content", - "name": "$PLUGIN_CONFIG/override/unsafe_env.lua" - } + // Replace the environment table (the functions accessible inside + // the lua sandbox) with an environment table loaded from a file + + // Hooks are ran from high to low priority + "priority": 1, + + // All selectors must result in true for commands to be ran + "selector": [ + { + // The "name" field can be omitted if the hooked function has + // at most one string field (check the (Lua/Luajit) source code) + + // "name": "s", + "operator": "CONTAINS", + "value": "unsafe_env" + } + ], + + "execute": [ + { + "command": "REPLACE_CONTENT_WITH_FILE", + "file": "$PLUGIN_CONFIG/override/unsafe_env.lua" + } + ] } + */ ], "luaL_loadbuffer": [ + /* { - "selector": { - "field": "name", - "operator": "equals", - "value": "Survival/Scripts/game/SurvivalGame.lua" - }, - "file": { - "option": "replace_content", - "name": "$PLUGIN_CONFIG/override/files/SurvivalGame.lua" - } + // Enable survival dev mode + + "priority": 1, + "selector": [ + { + "field": "name", + "operator": "EQUALS", + "value": "Survival/Scripts/game/SurvivalGame.lua" + } + ], + "execute": [ + { + "command": "PREPEND_STRING", + "string": "g_survivalDev = true" + } + ] } + */ ] } } From 9c4b54d9eefad79b91fb1e61016a056f5cb82771 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Sun, 10 Oct 2021 23:24:25 +0200 Subject: [PATCH 28/29] Add more comments to the default lua_hooks.json --- PluginDevFolder/SMLuaHook/main.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/PluginDevFolder/SMLuaHook/main.cpp b/PluginDevFolder/SMLuaHook/main.cpp index 7ec6e06..d855217 100644 --- a/PluginDevFolder/SMLuaHook/main.cpp +++ b/PluginDevFolder/SMLuaHook/main.cpp @@ -26,6 +26,8 @@ LIB_RESULT PluginLoad() { const char* defaultConfig = R"(// Configuration file for hooking the Lua C API { "hooks": { + + // This function is used for setting up the Lua environment "luaL_loadstring": [ /* { @@ -56,6 +58,8 @@ const char* defaultConfig = R"(// Configuration file for hooking the Lua C API } */ ], + + // All files the game tries to load pass through here "luaL_loadbuffer": [ /* { @@ -78,6 +82,7 @@ const char* defaultConfig = R"(// Configuration file for hooking the Lua C API } */ ] + } } )"; From 8f58ccdf91f814034d140384a779e057a033b7b4 Mon Sep 17 00:00:00 2001 From: TechnologicNick Date: Sun, 10 Oct 2021 23:38:33 +0200 Subject: [PATCH 29/29] Add TechnologicNick to LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index aae4ee8..d05522f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 HardCoded +Copyright (c) 2021 HardCoded and TechnologicNick Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal