From 2731a441050ae237f1331ae5131257ed28786417 Mon Sep 17 00:00:00 2001 From: fesily Date: Wed, 15 Mar 2023 15:47:51 +0800 Subject: [PATCH 01/69] add config --- src/launcher/autoattach/autoattach.cpp | 7 ++ src/launcher/autoattach/lua_module.cpp | 71 ++++++++++--- src/launcher/config/config.cpp | 136 +++++++++++++++++++++++++ src/launcher/config/config.h | 29 ++++++ src/launcher/resolver/lua_signature.h | 11 ++ 5 files changed, 240 insertions(+), 14 deletions(-) create mode 100644 src/launcher/config/config.cpp create mode 100644 src/launcher/config/config.h create mode 100644 src/launcher/resolver/lua_signature.h diff --git a/src/launcher/autoattach/autoattach.cpp b/src/launcher/autoattach/autoattach.cpp index af3d197c9..db9add529 100644 --- a/src/launcher/autoattach/autoattach.cpp +++ b/src/launcher/autoattach/autoattach.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -16,6 +17,8 @@ namespace luadebug::autoattach { constexpr auto find_lua_module_key = "lua_newstate"; static bool is_lua_module(const char* module_path) { + if (config.get_lua_module() == module_path) + return true; if (Gum::Process::module_find_export_by_name(module_path, find_lua_module_key)) return true; return Gum::Process::module_find_symbol_by_name(module_path, find_lua_module_key) != nullptr; @@ -36,6 +39,10 @@ namespace luadebug::autoattach { } void start() { + if (!Config::init_from_file()){ + log::info("can't load config"); + return; + } bool found = false; lua_module rm = {}; Gum::Process::enumerate_modules([&rm, &found](const Gum::ModuleDetails& details)->bool{ diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index 917cf04b5..47a293e6a 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -1,26 +1,16 @@ #include #include #include +#include #include +#include #include #include -namespace luadebug::autoattach { - static lua_version lua_version_from_string[[maybe_unused]](const std::string_view& v) { - if (v == "luajit") - return lua_version::luajit; - if (v == "lua51") - return lua_version::lua51; - if (v == "lua52") - return lua_version::lua52; - if (v == "lua53") - return lua_version::lua53; - if (v == "lua54") - return lua_version::lua54; - return lua_version::unknown; - } +#include +namespace luadebug::autoattach { static const char* lua_version_to_string(lua_version v) { switch (v) { case lua_version::lua51: @@ -43,6 +33,9 @@ namespace luadebug::autoattach { } static lua_version get_lua_version(const lua_module& m) { + auto version = config.get_lua_version(); + if (version != lua_version::unknown) + return version; /* luaJIT_version_2_1_0_beta3 luaJIT_version_2_1_0_beta2 @@ -85,8 +78,54 @@ namespace luadebug::autoattach { default: return lua_version::unknown; } + //TODO: from signature } + bool load_remotedebug_dll(lua_version version) { + if (version != lua_version::unknown) + return false; + + auto dllpath = bee::path_helper::dll_path(); + if (!dllpath) { + return false; + } + auto os = +#if defined(_WIN32) + "windows" +#elif defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) + "darwin" +#else + ;return false; +#endif + ; + auto arch = +#if defined(_M_ARM64) || defined(__aarch64__) + "arm64" +#elif defined(_M_IX86) || defined(__i386__) + "x86" +#elif defined(_M_X64) || defined(__x86_64__) + "x86_64" +#elif defined(__arm__) + "arm" +#elif defined(__riscv) + "riscv" +#else + ;return false; +#endif + ; + auto platform = std::format("{}-{}", os, arch); + auto path = dllpath.value().parent_path().parent_path() / "runtime" / platform /lua_version_to_string(version); + + dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL); + + module_enumerate_import(path.c_str(), [](const Gum::ImportDetails& details)->bool { + if (std::string_view (details.name).find_first_of("lua") != 0){ + return true; + } + return true; + }); + } + bool lua_module::initialize(fn_attach attach_lua_vm) { resolver.module_name = path; auto error_msg = lua::initialize(resolver); @@ -97,6 +136,10 @@ namespace luadebug::autoattach { version = get_lua_version(*this); log::info("current lua version: {}", lua_version_to_string(version)); + if (config.is_remotedebug_by_signature()) { + load_remotedebug_dll(version); + } + watchdog = create_watchdog(attach_lua_vm, version, resolver); if (!watchdog) { //TODO: more errmsg diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp new file mode 100644 index 000000000..ffea2c5b9 --- /dev/null +++ b/src/launcher/config/config.cpp @@ -0,0 +1,136 @@ +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#if !defined(_WIN32) +#include +#else +#include +#include "config.h" +#endif + +namespace luadebug::autoattach { + static lua_version lua_version_from_string[[maybe_unused]](const std::string_view& v) { + if (v == "luajit") + return lua_version::luajit; + if (v == "lua51") + return lua_version::lua51; + if (v == "lua52") + return lua_version::lua52; + if (v == "lua53") + return lua_version::lua53; + if (v == "lua54") + return lua_version::lua54; + return lua_version::unknown; + } + + Config config; + std::string Config::get(const std::string &key) const { + auto it = values.find(key); + if (it == values.end()) { + return {}; + } + return it->second; + } + + bool Config::contains(const std::string &key) const { + return values.find(key) != values.end(); + } + + lua_version Config::get_lua_version() const { + std::string key = "lua_version"; + + if (!contains(key)) { + return lua_version::unknown; + } + + return lua_version_from_string(get(key)); + } + + std::optional Config::get_lua_signature(const std::string &key) const { + if (!contains(key)) + return std::nullopt; + const auto& value = get(key); + if (value.empty()) + return std::nullopt; + // value string match regex + std::regex re(R"re((?:\[([-+]?\d+)(?::([-+]?\d+)\])?)?([ \da-fA-F]+)([-+]\d+)?)re"); + std::smatch match; + if (!std::regex_match(value, match, re)) + return std::nullopt; + + signture res = {}; + if (match[1].matched) + res.start_offset = std::atoi(match[1].str().c_str()); + + if (match[2].matched) + res.end_offset = std::atoi(match[2].str().c_str()); + + res.pattern = match[3].str(); + + if (match[4].matched) + res.pattern_offset = std::atoi(match[4].str().c_str()); + + return res; + } + + std::string Config::get_lua_module() const { + std::string key = "lua_module"; + + if (!contains(key)) + return {}; + + const auto& value = get(key); + if (!fs::exists(value)) + return {}; + + return value; + } + + bool Config::is_remotedebug_by_signature() const { + std::string key = "remotedebug_by_signature"; + return contains(key); + } + + bool Config::init_from_file() { + config.values.clear(); + auto dllpath = bee::path_helper::dll_path(); + if (!dllpath) { + return false; + } + + auto filename = std::format("{}/tmp/pid_{}_config", dllpath.value().parent_path().parent_path().generic_string(), +#if defined(_WIN32) + GetCurrentProcessId() +#else + getpid() +#endif + ); + + std::ifstream s(filename, s.in); + if (!s.is_open()) + return false; + + for (std::string line; std::getline(s, line);) { + auto pos = line.find(':'); + if (pos == std::string::npos) { + continue; + } + auto iter = config.values.insert_or_assign(line.substr(0, pos), line.substr(pos + 1)).first; + + log::info("load config {}={}", iter->first, iter->second); + } + return true; + } + +}// namespace luadebug::autoattach \ No newline at end of file diff --git a/src/launcher/config/config.h b/src/launcher/config/config.h new file mode 100644 index 000000000..cefc3ede5 --- /dev/null +++ b/src/launcher/config/config.h @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +namespace luadebug::autoattach { + + enum class lua_version; + struct signture; + + class Config { + std::unordered_map values; + public: + std::string get(const std::string& key) const; + + bool contains(const std::string& key) const; + + lua_version get_lua_version() const; + + std::optional get_lua_signature(const std::string& key) const; + + std::string get_lua_module() const; + + bool is_remotedebug_by_signature() const; + + static bool init_from_file(); + }; + extern Config config; +} \ No newline at end of file diff --git a/src/launcher/resolver/lua_signature.h b/src/launcher/resolver/lua_signature.h new file mode 100644 index 000000000..778e177c8 --- /dev/null +++ b/src/launcher/resolver/lua_signature.h @@ -0,0 +1,11 @@ +#include + +namespace luadebug::autoattach { + struct signture { + std::string name; + int32_t start_offset; + int32_t end_offset; + std::string pattern; + int32_t pattern_offset; + }; +} \ No newline at end of file From cff99ef7d525304110a95a99f4bab391a73c569f Mon Sep 17 00:00:00 2001 From: fesily Date: Wed, 15 Mar 2023 16:44:33 +0800 Subject: [PATCH 02/69] remove config api --- src/launcher/config/config.cpp | 107 +++++++++++++++------------------ src/launcher/config/config.h | 29 ++++----- 2 files changed, 63 insertions(+), 73 deletions(-) diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index ffea2c5b9..ad581f29f 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -20,7 +20,7 @@ #endif namespace luadebug::autoattach { - static lua_version lua_version_from_string[[maybe_unused]](const std::string_view& v) { + static lua_version lua_version_from_string [[maybe_unused]] (const std::string_view& v) { if (v == "luajit") return lua_version::luajit; if (v == "lua51") @@ -34,88 +34,81 @@ namespace luadebug::autoattach { return lua_version::unknown; } - Config config; - std::string Config::get(const std::string &key) const { + Config config; + + lua_version Config::get_lua_version() const { + std::string key = "lua_version"; + auto it = values.find(key); if (it == values.end()) { - return {}; + return lua_version::unknown; } - return it->second; - } - bool Config::contains(const std::string &key) const { - return values.find(key) != values.end(); + return lua_version_from_string(it->second); } - lua_version Config::get_lua_version() const { - std::string key = "lua_version"; - - if (!contains(key)) { - return lua_version::unknown; - } - - return lua_version_from_string(get(key)); - } - - std::optional Config::get_lua_signature(const std::string &key) const { - if (!contains(key)) - return std::nullopt; - const auto& value = get(key); - if (value.empty()) - return std::nullopt; - // value string match regex - std::regex re(R"re((?:\[([-+]?\d+)(?::([-+]?\d+)\])?)?([ \da-fA-F]+)([-+]\d+)?)re"); - std::smatch match; - if (!std::regex_match(value, match, re)) - return std::nullopt; + std::optional Config::get_lua_signature(const std::string& key) const { + auto it = values.find(key); + if (it == values.end()) { + return std::nullopt; + } + const auto& value = it->second; + if (value.empty()) + return std::nullopt; + // value string match regex + std::regex re(R"re((?:\[([-+]?\d+)(?::([-+]?\d+)\])?)?([ \da-fA-F]+)([-+]\d+)?)re"); + std::smatch match; + if (!std::regex_match(value, match, re)) + return std::nullopt; - signture res = {}; - if (match[1].matched) - res.start_offset = std::atoi(match[1].str().c_str()); + signture res = {}; + if (match[1].matched) + res.start_offset = std::atoi(match[1].str().c_str()); - if (match[2].matched) - res.end_offset = std::atoi(match[2].str().c_str()); + if (match[2].matched) + res.end_offset = std::atoi(match[2].str().c_str()); - res.pattern = match[3].str(); + res.pattern = match[3].str(); - if (match[4].matched) - res.pattern_offset = std::atoi(match[4].str().c_str()); + if (match[4].matched) + res.pattern_offset = std::atoi(match[4].str().c_str()); - return res; + return res; } std::string Config::get_lua_module() const { - std::string key = "lua_module"; - - if (!contains(key)) - return {}; + std::string key = "lua_module"; - const auto& value = get(key); - if (!fs::exists(value)) - return {}; + auto it = values.find(key); + if (it == values.end()) { + return {}; + } + const auto& value = it->second; + if (!fs::exists(value)) + return {}; return value; } bool Config::is_remotedebug_by_signature() const { - std::string key = "remotedebug_by_signature"; - return contains(key); + std::string key = "remotedebug_by_signature"; + return values.find(key) != values.end(); } bool Config::init_from_file() { - config.values.clear(); - auto dllpath = bee::path_helper::dll_path(); - if (!dllpath) { - return false; - } + config.values.clear(); + auto dllpath = bee::path_helper::dll_path(); + if (!dllpath) { + return false; + } - auto filename = std::format("{}/tmp/pid_{}_config", dllpath.value().parent_path().parent_path().generic_string(), + auto filename = std::format("{}/tmp/pid_{}_config", dllpath.value().parent_path().parent_path().generic_string(), #if defined(_WIN32) - GetCurrentProcessId() + GetCurrentProcessId() #else - getpid() + getpid() #endif - ); + ); std::ifstream s(filename, s.in); if (!s.is_open()) @@ -128,7 +121,7 @@ namespace luadebug::autoattach { } auto iter = config.values.insert_or_assign(line.substr(0, pos), line.substr(pos + 1)).first; - log::info("load config {}={}", iter->first, iter->second); + log::info("load config {}={}", iter->first, iter->second); } return true; } diff --git a/src/launcher/config/config.h b/src/launcher/config/config.h index cefc3ede5..913921431 100644 --- a/src/launcher/config/config.h +++ b/src/launcher/config/config.h @@ -5,25 +5,22 @@ namespace luadebug::autoattach { - enum class lua_version; - struct signture; + enum class lua_version; + struct signture; - class Config { - std::unordered_map values; - public: - std::string get(const std::string& key) const; + class Config { + std::unordered_map values; - bool contains(const std::string& key) const; + public: + lua_version get_lua_version() const; - lua_version get_lua_version() const; + std::optional get_lua_signature(const std::string& key) const; - std::optional get_lua_signature(const std::string& key) const; + std::string get_lua_module() const; - std::string get_lua_module() const; + bool is_remotedebug_by_signature() const; - bool is_remotedebug_by_signature() const; - - static bool init_from_file(); - }; - extern Config config; -} \ No newline at end of file + static bool init_from_file(); + }; + extern Config config; +}// namespace luadebug::autoattach \ No newline at end of file From 815d2ed6dcbaca1eb9104cd053bca204f97f2951 Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 16 Mar 2023 09:43:48 +0800 Subject: [PATCH 03/69] config chang to json --- .gitmodules | 3 ++ 3rd/frida_gum/gumpp | 2 +- 3rd/json | 1 + compile/macos/runtime.lua | 1 + src/launcher/autoattach/lua_module.cpp | 3 +- src/launcher/config/config.cpp | 50 +++++++++----------------- src/launcher/config/config.h | 4 ++- 7 files changed, 27 insertions(+), 37 deletions(-) create mode 160000 3rd/json diff --git a/.gitmodules b/.gitmodules index 3f804f6b7..dccdcea3a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -11,3 +11,6 @@ path = 3rd/frida_gum/gumpp url = https://github.com/fesily/gumpp +[submodule "3rd/json"] + path = 3rd/json + url = https://github.com/nlohmann/json diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index 41bee742d..cef50b378 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit 41bee742d0176aaf569a2513464339543e63c2de +Subproject commit cef50b3781bc01b5dd2757e3f66f2fb797b85f86 diff --git a/3rd/json b/3rd/json new file mode 160000 index 000000000..546370c9e --- /dev/null +++ b/3rd/json @@ -0,0 +1 @@ +Subproject commit 546370c9e778d99e7176641123e5cc1d0b62acab diff --git a/compile/macos/runtime.lua b/compile/macos/runtime.lua index a4f5bb81a..3b4d642e7 100644 --- a/compile/macos/runtime.lua +++ b/compile/macos/runtime.lua @@ -22,6 +22,7 @@ lm:lua_library 'launcher' { "3rd/bee.lua", "3rd/frida_gum/gumpp", "3rd/lua/lua54", + "3rd/json/single_include", "src/launcher", }, sources = { diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index 47a293e6a..ad2126007 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -118,12 +118,13 @@ namespace luadebug::autoattach { dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL); - module_enumerate_import(path.c_str(), [](const Gum::ImportDetails& details)->bool { + Gum::Process::module_enumerate_import(path.c_str(), [](const Gum::ImportDetails& details)->bool { if (std::string_view (details.name).find_first_of("lua") != 0){ return true; } return true; }); + return true; } bool lua_module::initialize(fn_attach attach_lua_vm) { diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index ad581f29f..8aeba492a 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -5,19 +5,15 @@ #include #include +#include #include #include #include -#include +#include -#if !defined(_WIN32) -#include -#else -#include -#include "config.h" -#endif +#include namespace luadebug::autoattach { static lua_version lua_version_from_string [[maybe_unused]] (const std::string_view& v) { @@ -39,20 +35,20 @@ namespace luadebug::autoattach { lua_version Config::get_lua_version() const { std::string key = "lua_version"; - auto it = values.find(key); - if (it == values.end()) { + auto it = values->find(key); + if (!values || it == values->end()) { return lua_version::unknown; } - return lua_version_from_string(it->second); + return lua_version_from_string(it->get()); } std::optional Config::get_lua_signature(const std::string& key) const { - auto it = values.find(key); - if (it == values.end()) { + auto it = values->find(key); + if (it == values->end()) { return std::nullopt; } - const auto& value = it->second; + const auto& value = it->get(); if (value.empty()) return std::nullopt; // value string match regex @@ -79,11 +75,11 @@ namespace luadebug::autoattach { std::string Config::get_lua_module() const { std::string key = "lua_module"; - auto it = values.find(key); - if (it == values.end()) { + auto it = values->find(key); + if (it == values->end()) { return {}; } - const auto& value = it->second; + const auto& value = it->get(); if (!fs::exists(value)) return {}; @@ -92,37 +88,23 @@ namespace luadebug::autoattach { bool Config::is_remotedebug_by_signature() const { std::string key = "remotedebug_by_signature"; - return values.find(key) != values.end(); + return values->find(key) != values->end(); } bool Config::init_from_file() { - config.values.clear(); + config.values = std::make_unique(); auto dllpath = bee::path_helper::dll_path(); if (!dllpath) { return false; } - auto filename = std::format("{}/tmp/pid_{}_config", dllpath.value().parent_path().parent_path().generic_string(), -#if defined(_WIN32) - GetCurrentProcessId() -#else - getpid() -#endif - ); + auto filename = std::format("{}/tmp/pid_{}_config", dllpath.value().parent_path().parent_path().generic_string(), Gum::Process::get_id()); std::ifstream s(filename, s.in); if (!s.is_open()) return false; - for (std::string line; std::getline(s, line);) { - auto pos = line.find(':'); - if (pos == std::string::npos) { - continue; - } - auto iter = config.values.insert_or_assign(line.substr(0, pos), line.substr(pos + 1)).first; - - log::info("load config {}={}", iter->first, iter->second); - } + s >> *config.values; return true; } diff --git a/src/launcher/config/config.h b/src/launcher/config/config.h index 913921431..7345d78e7 100644 --- a/src/launcher/config/config.h +++ b/src/launcher/config/config.h @@ -2,6 +2,7 @@ #include #include #include +#include namespace luadebug::autoattach { @@ -9,7 +10,7 @@ namespace luadebug::autoattach { struct signture; class Config { - std::unordered_map values; + std::unique_ptr values; public: lua_version get_lua_version() const; @@ -22,5 +23,6 @@ namespace luadebug::autoattach { static bool init_from_file(); }; + extern Config config; }// namespace luadebug::autoattach \ No newline at end of file From 158be30f85675293723f361d3086cb4010b6e650 Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 16 Mar 2023 09:44:49 +0800 Subject: [PATCH 04/69] update gumpp --- 3rd/frida_gum/gumpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index cef50b378..016103822 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit cef50b3781bc01b5dd2757e3f66f2fb797b85f86 +Subproject commit 016103822ce0a86764f8d1c22a93a7dfd205ba73 From 05e158c94a9961c147488837e307f3d8d1f6a215 Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 16 Mar 2023 09:47:54 +0800 Subject: [PATCH 05/69] chang lua_version string --- src/launcher/autoattach/lua_module.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index 949d3796b..26ace88b3 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -14,15 +14,15 @@ namespace luadebug::autoattach { static const char* lua_version_to_string(lua_version v) { switch (v) { case lua_version::lua51: - return "lua51"; + return "5.1"; case lua_version::lua52: - return "lua52"; + return "5.2"; case lua_version::lua53: - return "lua53"; + return "5.3"; case lua_version::lua54: - return "lua54"; + return "5.4"; case lua_version::luajit: - return "luajit"; + return "jit"; default: return "unknown"; } From 87b395abdfdbcdc368ffcb886384601f71b21c04 Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 16 Mar 2023 10:24:39 +0800 Subject: [PATCH 06/69] config signature from json --- src/launcher/config/config.cpp | 56 +++++++++++++++------------ src/launcher/resolver/lua_signature.h | 15 +++---- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index 8aeba492a..1b85e0b36 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include @@ -15,6 +15,7 @@ #include +using namespace std::string_view_literals; namespace luadebug::autoattach { static lua_version lua_version_from_string [[maybe_unused]] (const std::string_view& v) { if (v == "luajit") @@ -33,7 +34,7 @@ namespace luadebug::autoattach { Config config; lua_version Config::get_lua_version() const { - std::string key = "lua_version"; + const auto key = "lua_version"sv; auto it = values->find(key); if (!values || it == values->end()) { @@ -44,36 +45,43 @@ namespace luadebug::autoattach { } std::optional Config::get_lua_signature(const std::string& key) const { - auto it = values->find(key); + const auto signture_key = "signture"sv; + auto it = values->find(signture_key); if (it == values->end()) { return std::nullopt; } - const auto& value = it->get(); - if (value.empty()) - return std::nullopt; - // value string match regex - std::regex re(R"re((?:\[([-+]?\d+)(?::([-+]?\d+)\])?)?([ \da-fA-F]+)([-+]\d+)?)re"); - std::smatch match; - if (!std::regex_match(value, match, re)) - return std::nullopt; - - signture res = {}; - if (match[1].matched) - res.start_offset = std::atoi(match[1].str().c_str()); - - if (match[2].matched) - res.end_offset = std::atoi(match[2].str().c_str()); - res.pattern = match[3].str(); + //split key by . + std::vector keys; + std::string_view key_view = key; + while (!key_view.empty()) { + auto pos = key_view.find('.'); + if (pos == std::string_view::npos) { + keys.push_back(key_view); + break; + } + keys.push_back(key_view.substr(0, pos)); + key_view = key_view.substr(pos + 1); + } - if (match[4].matched) - res.pattern_offset = std::atoi(match[4].str().c_str()); + nlohmann::json& json = *it; + for (const auto& key: keys) { + json = json[key]; + } + // searilize json to signture + signture res = {}; + json["name"].get_to(res.name); + json["start_offset"].get_to(res.start_offset); + json["end_offset"].get_to(res.end_offset); + json["pattern"].get_to(res.pattern); + json["pattern_offset"].get_to(res.pattern_offset); + json["hit_offset"].get_to(res.hit_offset); return res; } std::string Config::get_lua_module() const { - std::string key = "lua_module"; + const auto key = "lua_module"sv; auto it = values->find(key); if (it == values->end()) { @@ -87,7 +95,7 @@ namespace luadebug::autoattach { } bool Config::is_remotedebug_by_signature() const { - std::string key = "remotedebug_by_signature"; + const auto key = "remotedebug_by_signature"sv; return values->find(key) != values->end(); } @@ -108,4 +116,4 @@ namespace luadebug::autoattach { return true; } -}// namespace luadebug::autoattach \ No newline at end of file +} // namespace luadebug::autoattach \ No newline at end of file diff --git a/src/launcher/resolver/lua_signature.h b/src/launcher/resolver/lua_signature.h index 778e177c8..f39c5f6ae 100644 --- a/src/launcher/resolver/lua_signature.h +++ b/src/launcher/resolver/lua_signature.h @@ -1,11 +1,12 @@ #include namespace luadebug::autoattach { - struct signture { - std::string name; - int32_t start_offset; - int32_t end_offset; - std::string pattern; - int32_t pattern_offset; - }; + struct signture { + std::string name; + int32_t start_offset = 0; + int32_t end_offset = 0; + std::string pattern; + int32_t pattern_offset = 0; + uint8_t hit_offset = 0; + }; } \ No newline at end of file From 128eb77e57d2826d5c4327777645eca6ddb159bb Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 16 Mar 2023 10:25:01 +0800 Subject: [PATCH 07/69] include add once --- src/launcher/resolver/lua_signature.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/launcher/resolver/lua_signature.h b/src/launcher/resolver/lua_signature.h index f39c5f6ae..bb81c0559 100644 --- a/src/launcher/resolver/lua_signature.h +++ b/src/launcher/resolver/lua_signature.h @@ -1,3 +1,4 @@ +#pragma once #include namespace luadebug::autoattach { From 53dd01ddd7b5f67acf04a1c4da770fbaf3aa0803 Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 16 Mar 2023 14:02:50 +0800 Subject: [PATCH 08/69] signature mode --- 3rd/frida_gum/gumpp | 2 +- src/launcher/autoattach/lua_module.cpp | 21 +++++++--- src/launcher/config/config.cpp | 51 ++++++++++--------------- src/launcher/config/config.h | 4 +- src/launcher/resolver/lua_resolver.cpp | 17 ++++++++- src/launcher/resolver/lua_resolver.h | 3 ++ src/launcher/resolver/lua_signature.cpp | 38 ++++++++++++++++++ src/launcher/resolver/lua_signature.h | 2 + 8 files changed, 98 insertions(+), 40 deletions(-) create mode 100644 src/launcher/resolver/lua_signature.cpp diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index 016103822..c2e93b74e 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit 016103822ce0a86764f8d1c22a93a7dfd205ba73 +Subproject commit c2e93b74eeb6b5463d37abc0683c63f49882e4a2 diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index 26ace88b3..1accf4d65 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -8,6 +8,7 @@ #include #include + #include namespace luadebug::autoattach { @@ -29,7 +30,7 @@ namespace luadebug::autoattach { } static bool in_module(const lua_module& m, void* addr) { - return addr > m.memory_address && addr <= (void*)((intptr_t)m.memory_address + m.memory_size); + return addr >= m.memory_address && addr <= (void*)((intptr_t)m.memory_address + m.memory_size); } static lua_version get_lua_version(const lua_module& m) { @@ -82,7 +83,7 @@ namespace luadebug::autoattach { //TODO: from signature } - bool load_remotedebug_dll(lua_version version) { + bool load_remotedebug_dll(lua_version version, const lua_resolver& resolver) { if (version != lua_version::unknown) return false; @@ -118,13 +119,19 @@ namespace luadebug::autoattach { ; auto platform = std::format("{}-{}", os, arch); auto path = dllpath.value().parent_path().parent_path() / "runtime" / platform / lua_version_to_string(version); +#ifdef _WIN32 +#else dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL); - - Gum::Process::module_enumerate_import(path.c_str(), [](const Gum::ImportDetails& details) -> bool { +#endif + Gum::Process::module_enumerate_import(path.c_str(), [&](const Gum::ImportDetails& details) -> bool { if (std::string_view(details.name).find_first_of("lua") != 0) { return true; } + if (auto address = (void*)resolver.find_signture(details.name)) { + *(void**)details.slot = address; + log::info("find signture {} to {}", details.name, address); + } return true; }); return true; @@ -139,9 +146,11 @@ namespace luadebug::autoattach { } version = get_lua_version(*this); log::info("current lua version: {}", lua_version_to_string(version)); + if (version != lua_version::unknown) + resolver.version = lua_version_to_string(version); - if (config.is_remotedebug_by_signature()) { - load_remotedebug_dll(version); + if (config.is_signature_mode()) { + load_remotedebug_dll(version, resolver); } watchdog = create_watchdog(attach_lua_vm, version, resolver); diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index 1b85e0b36..364ad6397 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -50,34 +50,21 @@ namespace luadebug::autoattach { if (it == values->end()) { return std::nullopt; } - - //split key by . - std::vector keys; - std::string_view key_view = key; - while (!key_view.empty()) { - auto pos = key_view.find('.'); - if (pos == std::string_view::npos) { - keys.push_back(key_view); - break; - } - keys.push_back(key_view.substr(0, pos)); - key_view = key_view.substr(pos + 1); - } - - nlohmann::json& json = *it; - for (const auto& key: keys) { - json = json[key]; + try { + const auto& json = (*it)[key]; + // searilize json to signture + signture res = {}; + json["name"].get_to(res.name); + json["start_offset"].get_to(res.start_offset); + json["end_offset"].get_to(res.end_offset); + json["pattern"].get_to(res.pattern); + json["pattern_offset"].get_to(res.pattern_offset); + json["hit_offset"].get_to(res.hit_offset); + return res; + } catch (const nlohmann::json::exception& e) { + std::cerr << e.what() << '\n'; } - - // searilize json to signture - signture res = {}; - json["name"].get_to(res.name); - json["start_offset"].get_to(res.start_offset); - json["end_offset"].get_to(res.end_offset); - json["pattern"].get_to(res.pattern); - json["pattern_offset"].get_to(res.pattern_offset); - json["hit_offset"].get_to(res.hit_offset); - return res; + return std::nullopt; } std::string Config::get_lua_module() const { @@ -94,8 +81,8 @@ namespace luadebug::autoattach { return value; } - bool Config::is_remotedebug_by_signature() const { - const auto key = "remotedebug_by_signature"sv; + bool Config::is_signature_mode() const { + const auto key = "signature_mode"sv; return values->find(key) != values->end(); } @@ -111,8 +98,12 @@ namespace luadebug::autoattach { std::ifstream s(filename, s.in); if (!s.is_open()) return false; + try { + s >> *config.values; + } catch (const nlohmann::json::exception& e) { + std::cerr << e.what() << '\n'; + } - s >> *config.values; return true; } diff --git a/src/launcher/config/config.h b/src/launcher/config/config.h index 7345d78e7..df3335cde 100644 --- a/src/launcher/config/config.h +++ b/src/launcher/config/config.h @@ -19,10 +19,10 @@ namespace luadebug::autoattach { std::string get_lua_module() const; - bool is_remotedebug_by_signature() const; + bool is_signature_mode() const; static bool init_from_file(); }; extern Config config; -}// namespace luadebug::autoattach \ No newline at end of file +} // namespace luadebug::autoattach \ No newline at end of file diff --git a/src/launcher/resolver/lua_resolver.cpp b/src/launcher/resolver/lua_resolver.cpp index a7359b617..106048fd0 100644 --- a/src/launcher/resolver/lua_resolver.cpp +++ b/src/launcher/resolver/lua_resolver.cpp @@ -1,6 +1,8 @@ #include #include #include +#include +#include namespace luadebug { static int (*_lua_pcall)(intptr_t L, int nargs, int nresults, int errfunc); @@ -20,9 +22,22 @@ namespace luadebug { return (intptr_t)Gum::Process::module_find_symbol_by_name(module_name.data(), name.data()); } + intptr_t lua_resolver::find_signture(std::string_view name) const { + if (!version.empty()) { + if (auto signature = autoattach::config.get_lua_signature(version + "." + std::string(name))) { + return signature->find(module_name.data()); + } + } + + if (auto signature = autoattach::config.get_lua_signature(std::string(name))) { + return signature->find(module_name.data()); + } + return 0; + } + intptr_t lua_resolver::find(std::string_view name) const { using namespace std::string_view_literals; - for (auto& finder: { &lua_resolver::find_export, &lua_resolver::find_symbol }) { + for (auto& finder: { &lua_resolver::find_export, &lua_resolver::find_symbol, &lua_resolver::find_signture }) { if (auto result = (this->*finder)(name)) { return result; } diff --git a/src/launcher/resolver/lua_resolver.h b/src/launcher/resolver/lua_resolver.h index 907b1a8dc..94529e6ba 100644 --- a/src/launcher/resolver/lua_resolver.h +++ b/src/launcher/resolver/lua_resolver.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace luadebug { @@ -8,6 +9,8 @@ namespace luadebug { intptr_t find(std::string_view name) const override; intptr_t find_export(std::string_view name) const; intptr_t find_symbol(std::string_view name) const; + intptr_t find_signture(std::string_view name) const; std::string_view module_name; + std::string version; }; } \ No newline at end of file diff --git a/src/launcher/resolver/lua_signature.cpp b/src/launcher/resolver/lua_signature.cpp new file mode 100644 index 000000000..eb6340cad --- /dev/null +++ b/src/launcher/resolver/lua_signature.cpp @@ -0,0 +1,38 @@ +#include + +#include + +namespace luadebug::autoattach { + intptr_t signture::find(const char* module_name) const { + auto all_address = Gum::search_module_function(module_name, pattern.c_str()); + if (all_address.empty()) + return 0; + + if (all_address.size() == 1) + return (uintptr_t)all_address[0]; + + Gum::MemoryRange range; + Gum::Process::enumerate_modules([&](const Gum::ModuleDetails& details) { + if (details.name() == std::string_view(module_name) || details.path() == std::string_view(module_name)) { + range = details.range(); + return false; + } + return true; + }); + + range.size -= end_offset + start_offset; + range.base_address = (void*)((uintptr_t)range.base_address + start_offset); + + if (hit_offset != 0 && all_address.size() > hit_offset) { + return (uintptr_t)all_address[hit_offset]; + } + + for (auto address: all_address) { + if (range.contains(address)) { + return (uintptr_t)address; + } + } + + return (uintptr_t)all_address[0]; + } +} \ No newline at end of file diff --git a/src/launcher/resolver/lua_signature.h b/src/launcher/resolver/lua_signature.h index bb81c0559..48e438bfd 100644 --- a/src/launcher/resolver/lua_signature.h +++ b/src/launcher/resolver/lua_signature.h @@ -1,5 +1,6 @@ #pragma once #include +#include namespace luadebug::autoattach { struct signture { @@ -9,5 +10,6 @@ namespace luadebug::autoattach { std::string pattern; int32_t pattern_offset = 0; uint8_t hit_offset = 0; + intptr_t find(const char* module_name) const; }; } \ No newline at end of file From 5673a68040f12aaf2e18d443d0a8941da123e300 Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 16 Mar 2023 14:38:18 +0800 Subject: [PATCH 09/69] fix signture --- src/launcher/autoattach/autoattach.cpp | 12 +++--- src/launcher/config/config.cpp | 3 +- src/launcher/resolver/lua_signature.cpp | 49 +++++++++++++------------ src/launcher/resolver/lua_signature.h | 1 - 4 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/launcher/autoattach/autoattach.cpp b/src/launcher/autoattach/autoattach.cpp index 7914f51a0..91eeaaf95 100644 --- a/src/launcher/autoattach/autoattach.cpp +++ b/src/launcher/autoattach/autoattach.cpp @@ -17,8 +17,8 @@ namespace luadebug::autoattach { constexpr auto find_lua_module_key = "lua_newstate"; static bool is_lua_module(const char* module_path) { - if (config.get_lua_module() == module_path) - return true; + if (std::string_view(module_path).find(config.get_lua_module()) != std::string_view::npos) + return true; if (Gum::Process::module_find_export_by_name(module_path, find_lua_module_key)) return true; return Gum::Process::module_find_symbol_by_name(module_path, find_lua_module_key) != nullptr; @@ -39,10 +39,10 @@ namespace luadebug::autoattach { } void start() { - if (!Config::init_from_file()){ - log::info("can't load config"); - return; - } + if (!Config::init_from_file()) { + log::info("can't load config"); + return; + } bool found = false; lua_module rm = {}; Gum::Process::enumerate_modules([&rm, &found](const Gum::ModuleDetails& details) -> bool { diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index 364ad6397..64dfa43ac 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -54,7 +54,6 @@ namespace luadebug::autoattach { const auto& json = (*it)[key]; // searilize json to signture signture res = {}; - json["name"].get_to(res.name); json["start_offset"].get_to(res.start_offset); json["end_offset"].get_to(res.end_offset); json["pattern"].get_to(res.pattern); @@ -107,4 +106,4 @@ namespace luadebug::autoattach { return true; } -} // namespace luadebug::autoattach \ No newline at end of file +} // namespace luadebug::autoattach \ No newline at end of file diff --git a/src/launcher/resolver/lua_signature.cpp b/src/launcher/resolver/lua_signature.cpp index eb6340cad..f7b808e72 100644 --- a/src/launcher/resolver/lua_signature.cpp +++ b/src/launcher/resolver/lua_signature.cpp @@ -8,31 +8,32 @@ namespace luadebug::autoattach { if (all_address.empty()) return 0; + void* find_address = nullptr; if (all_address.size() == 1) - return (uintptr_t)all_address[0]; - - Gum::MemoryRange range; - Gum::Process::enumerate_modules([&](const Gum::ModuleDetails& details) { - if (details.name() == std::string_view(module_name) || details.path() == std::string_view(module_name)) { - range = details.range(); - return false; - } - return true; - }); - - range.size -= end_offset + start_offset; - range.base_address = (void*)((uintptr_t)range.base_address + start_offset); - - if (hit_offset != 0 && all_address.size() > hit_offset) { - return (uintptr_t)all_address[hit_offset]; + find_address = all_address[0]; + else { + Gum::MemoryRange range; + Gum::Process::enumerate_modules([&](const Gum::ModuleDetails& details) { + if (details.name() == std::string_view(module_name) || details.path() == std::string_view(module_name)) { + range = details.range(); + return false; + } + return true; + }); + + range.size -= end_offset * sizeof(void*); + range.base_address = (void*)((uint8_t*)range.base_address + start_offset); + + // 限定匹配地址范围 + std::remove_if(all_address.begin(), all_address.end(), [&](void* address) { + return !range.contains(address); + }); + + auto hit_index = all_address.size() > hit_offset ? hit_offset : 0; + find_address = all_address[hit_index]; } - - for (auto address: all_address) { - if (range.contains(address)) { - return (uintptr_t)address; - } - } - - return (uintptr_t)all_address[0]; + if (find_address != 0) + return (uintptr_t)((uint8_t*)find_address + pattern_offset); + return 0; } } \ No newline at end of file diff --git a/src/launcher/resolver/lua_signature.h b/src/launcher/resolver/lua_signature.h index 48e438bfd..371619eac 100644 --- a/src/launcher/resolver/lua_signature.h +++ b/src/launcher/resolver/lua_signature.h @@ -4,7 +4,6 @@ namespace luadebug::autoattach { struct signture { - std::string name; int32_t start_offset = 0; int32_t end_offset = 0; std::string pattern; From 61bd751027587a845c808ae45c9f88dd78fef22a Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 16 Mar 2023 14:44:50 +0800 Subject: [PATCH 10/69] changed lua_version string --- src/launcher/autoattach/lua_module.cpp | 13 ++++++------- src/launcher/config/config.cpp | 14 +++++++------- src/launcher/config/config.h | 2 +- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index f757e40c8..755d805c3 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -8,22 +8,21 @@ #include #include - #include namespace luadebug::autoattach { static const char* lua_version_to_string(lua_version v) { switch (v) { case lua_version::lua51: - return "5.1"; + return "lua51"; case lua_version::lua52: - return "5.2"; + return "lua52"; case lua_version::lua53: - return "5.3"; + return "lua53"; case lua_version::lua54: - return "5.4"; + return "lua54"; case lua_version::luajit: - return "jit"; + return "luajit"; default: return "unknown"; } @@ -80,7 +79,7 @@ namespace luadebug::autoattach { default: return lua_version::unknown; } - //TODO: from signature + // TODO: from signature } bool load_remotedebug_dll(lua_version version, const lua_resolver& resolver) { diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index 64dfa43ac..639e5e99b 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -18,15 +18,15 @@ using namespace std::string_view_literals; namespace luadebug::autoattach { static lua_version lua_version_from_string [[maybe_unused]] (const std::string_view& v) { - if (v == "luajit") + if (v == "jit" || v == "luajit") return lua_version::luajit; - if (v == "lua51") + else if (v == "5.1" || v == "lua51") return lua_version::lua51; - if (v == "lua52") + else if (v == "5.2" || v == "lua52") return lua_version::lua52; - if (v == "lua53") + else if (v == "5.3" || v == "lua53") return lua_version::lua53; - if (v == "lua54") + else if (v == "5.4" || v == "lua54") return lua_version::lua54; return lua_version::unknown; } @@ -61,7 +61,7 @@ namespace luadebug::autoattach { json["hit_offset"].get_to(res.hit_offset); return res; } catch (const nlohmann::json::exception& e) { - std::cerr << e.what() << '\n'; + log::info("get_lua_signature {} error: {}", key, e.what()); } return std::nullopt; } @@ -100,7 +100,7 @@ namespace luadebug::autoattach { try { s >> *config.values; } catch (const nlohmann::json::exception& e) { - std::cerr << e.what() << '\n'; + log::info("init_from_file error: {}", e.what()); } return true; diff --git a/src/launcher/config/config.h b/src/launcher/config/config.h index df3335cde..968b35ab7 100644 --- a/src/launcher/config/config.h +++ b/src/launcher/config/config.h @@ -25,4 +25,4 @@ namespace luadebug::autoattach { }; extern Config config; -} // namespace luadebug::autoattach \ No newline at end of file +} // namespace luadebug::autoattach \ No newline at end of file From 3aec1e077d800f18744883fac752bbb404375f2d Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 16 Mar 2023 15:45:25 +0800 Subject: [PATCH 11/69] front write config file --- compile/common/package_json.lua | 1022 +++++++++++++------------ extension/js/configurationProvider.js | 3 + extension/script/frontend/proxy.lua | 32 +- src/launcher/config/config.cpp | 5 +- 4 files changed, 558 insertions(+), 504 deletions(-) diff --git a/compile/common/package_json.lua b/compile/common/package_json.lua index bf9d79e7b..cd2678e05 100644 --- a/compile/common/package_json.lua +++ b/compile/common/package_json.lua @@ -1,492 +1,530 @@ -local platform = ... -platform = platform or "unknown-unknown" - -local OS, ARCH = platform:match "^([^-]+)-([^-]+)$" - -local json = { - name = "lua-debug", - version = "1.61.0", - publisher = "actboy168", - displayName = "Lua Debug", - description = "VSCode debugger extension for Lua", - icon = "images/logo.png", - private = true, - author = { - name = "actboy168", - }, - bugs = { - url = "https://github.com/actboy168/lua-debug/issues", - }, - repository = { - type = "git", - url = "https://github.com/actboy168/lua-debug", - }, - keywords = { - "lua", - "debug", - "debuggers", - }, - categories = { - "Debuggers", - }, - engines = { - vscode = "^1.61.0", - }, - extensionKind = { - "workspace", - }, - main = "./js/extension.js", - activationEvents = { - "onCommand:extension.lua-debug.runEditorContents", - "onCommand:extension.lua-debug.debugEditorContents", - "onDebugInitialConfigurations", - "onDebugDynamicConfigurations", - "onDebugResolve:lua", - }, - capabilities = { - untrustedWorkspaces = { - description = "Debugging is disabled in Restricted Mode.", - supported = false, - }, - }, - contributes = { - breakpoints = { - { - language = "lua", - }, - { - language = "html", - }, - }, - commands = { - { - command = "extension.lua-debug.runEditorContents", - icon = "$(play)", - title = "Run File", - }, - { - command = "extension.lua-debug.debugEditorContents", - icon = "$(debug-alt-small)", - title = "Debug File", - }, - { - command = "extension.lua-debug.showIntegerAsDec", - title = "Show as Dec", - }, - { - command = "extension.lua-debug.showIntegerAsHex", - title = "Show as Hex", - }, - }, - configuration = { - properties = { - ["lua.debug.variables.showIntegerAsHex"] = { - default = false, - description = "Show integer as hex.", - type = "boolean", - }, - }, - }, - debuggers = { - { - type = "lua", - languages = { - "lua", - }, - label = "Lua Debug", - configurationSnippets = { - { - label = "Lua Debug: Launch Script", - description = "A new configuration for launching a lua debug program", - body = { - type = "lua", - request = "launch", - name = "${1:launch}", - stopOnEntry = true, - program = "^\"\\${workspaceFolder}/${2:main.lua}\"", - arg = { - }, - }, - }, - { - label = "Lua Debug: Attach", - description = "A new configuration for attaching a lua debug program", - body = { - type = "lua", - request = "attach", - name = "${1:attach}", - stopOnEntry = true, - address = "127.0.0.1:4278", - } - } - } - } - }, - menus = { - ["debug/variables/context"] = { - { - command = "extension.lua-debug.showIntegerAsDec", - group = "1_view", - when = "debugConfigurationType == 'lua' && debugProtocolVariableMenuContext == 'integer/hex'", - }, - { - command = "extension.lua-debug.showIntegerAsHex", - group = "1_view", - when = "debugConfigurationType == 'lua' && debugProtocolVariableMenuContext == 'integer/dec'", - }, - }, - ["editor/title/run"] = { - { - command = "extension.lua-debug.runEditorContents", - when = "resourceLangId == lua", - }, - { - command = "extension.lua-debug.debugEditorContents", - when = "resourceLangId == lua", - }, - }, - }, - }, -} - -local attributes = {} - -attributes.common = { - luaVersion = { - default = "5.4", - enum = { - "5.1", - "5.2", - "5.3", - "5.4", - "latest", - "jit", - }, - markdownDescription = "%lua.debug.launch.luaVersion.description%", - type = "string", - }, - outputCapture = { - default = { - }, - items = { - enum = { - "print", - "io.write", - "stdout", - "stderr", - }, - }, - markdownDescription = "From where to capture output messages: print or stdout/stderr streams.", - type = "array", - }, - pathFormat = { - default = "path", - enum = { - "path", - "linuxpath", - }, - markdownDescription = "Path format", - type = "string", - }, - sourceFormat = { - default = "path", - enum = { - "path", - "string", - "linuxpath", - }, - markdownDescription = "Source format", - type = "string", - }, - sourceMaps = { - default = { - { - "./*", - "${workspaceFolder}/*", - }, - }, - markdownDescription = "The source path of the remote host and the source path of local.", - type = "array", - }, - skipFiles = { - default = { - }, - items = { - type = "string", - }, - markdownDescription = "An array of glob patterns for files to skip when debugging.", - type = "array", - }, - stopOnEntry = { - default = false, - markdownDescription = "Automatically stop after entry.", - type = "boolean", - }, - stopOnThreadEntry = { - default = true, - markdownDescription = "Automatically stop after thread entry.", - type = "boolean", - }, - address = { - default = "127.0.0.1:4278", - markdownDescription = [[ -Debugger address. -1. IPv4 e.g. `127.0.0.1:4278` -2. IPv6 e.g. `[::1]:4278` -3. Unix domain socket e.g. `@c:\\unix.sock`]], - type = { - "string", - "null", - }, - }, - client = { - default = true, - markdownDescription = "Choose whether to `connect` or `listen`.", - type = "boolean", - }, - inject = { - default = "none", - markdownDescription = "How to inject debugger.", - enum = { - "none", - }, - type = "string", - }, -} - -if OS == "win32" then - attributes.common.inject.default = "hook" - table.insert(attributes.common.inject.enum, "hook") -elseif OS == "darwin" then - attributes.common.inject.default = "lldb" - table.insert(attributes.common.inject.enum, "hook") - table.insert(attributes.common.inject.enum, "lldb") - attributes.common.inject_executable = { - markdownDescription = "inject executable path", - type = { - "string", - "null", - }, - } -end - -attributes.attach = { -} - -if OS == "win32" or OS == "darwin" then - attributes.attach.processId = { - default = "${command:pickProcess}", - markdownDescription = "Id of process to attach to.", - type = "string", - } - attributes.attach.processName = { - default = "lua.exe", - markdownDescription = "Name of process to attach to.", - type = "string", - } - json.activationEvents[#json.activationEvents+1] = "onCommand:extension.lua-debug.pickProcess" - json.contributes.debuggers[1].variables = { - pickProcess = "extension.lua-debug.pickProcess", - } -end - -attributes.launch = { - luaexe = { - markdownDescription = "Absolute path to the lua exe.", - type = "string", - }, - program = { - default = "${workspaceFolder}/main.lua", - markdownDescription = "Lua program to debug - set this to the path of the script", - type = "string", - }, - arg = { - default = { - }, - markdownDescription = "Command line argument, arg[1] ... arg[n]", - type = "array", - }, - arg0 = { - default = { - }, - markdownDescription = "Command line argument, arg[-n] ... arg[0]", - type = { - "string", - "array", - }, - }, - path = { - default = "${workspaceFolder}/?.lua", - markdownDescription = "%lua.debug.launch.path.description%", - type = { - "string", - "array", - "null", - }, - }, - cpath = { - markdownDescription = "%lua.debug.launch.cpath.description%", - type = { - "string", - "array", - "null", - }, - }, - luaArch = { - markdownDescription = "%lua.debug.launch.luaArch.description%", - type = "string", - }, - cwd = { - default = "${workspaceFolder}", - markdownDescription = "Working directory at program startup", - type = { - "string", - "null", - }, - }, - env = { - additionalProperties = { - type = { - "string", - "null", - }, - }, - default = { - PATH = "${workspaceFolder}", - }, - markdownDescription = "Environment variables passed to the program. The value `null` removes thevariable from the environment.", - type = "object", - }, - console = { - default = "integratedTerminal", - enum = { - "internalConsole", - "integratedTerminal", - "externalTerminal", - }, - enummarkdownDescriptions = { - "%lua.debug.launch.console.internalConsole.description%", - "%lua.debug.launch.console.integratedTerminal.description%", - "%lua.debug.launch.console.externalTerminal.description%", - }, - markdownDescription = "%lua.debug.launch.console.description%", - type = "string", - }, - runtimeExecutable = { - default = OS == "win32" and "${workspaceFolder}/lua.exe" or "${workspaceFolder}/lua", - markdownDescription = "Runtime to use. Either an absolute path or the name of a runtime availableon the PATH.", - type = { - "string", - "null", - }, - }, - runtimeArgs = { - default = "${workspaceFolder}/main.lua", - markdownDescription = "Arguments passed to the runtime executable.", - type = { - "string", - "array", - "null", - }, - }, -} - -if OS == "win32" or OS == "darwin" then - local snippets = json.contributes.debuggers[1].configurationSnippets - snippets[#snippets+1] = { - label = "Lua Debug: Launch Process", - description = "A new configuration for launching a lua process", - body = { - type = "lua", - request = "launch", - name = "${1:launch process}", - stopOnEntry = true, - runtimeExecutable = "^\"\\${workspaceFolder}/lua.exe\"", - runtimeArgs = "^\"\\${workspaceFolder}/${2:main.lua}\"", - } - } - snippets[#snippets+1] = { - label = "Lua Debug: Attach Process", - description = "A new configuration for attaching a lua debug program", - body = { - type = "lua", - request = "attach", - name = "${1:attach}", - stopOnEntry = true, - processId = "^\"\\${command:pickProcess}\"", - } - } -end - -if OS == "win32" then - attributes.common.sourceCoding = { - default = "utf8", - enum = { - "utf8", - "ansi", - }, - markdownDescription = "%lua.debug.launch.sourceCoding.description%", - type = "string", - } - attributes.common.useWSL = { - default = true, - description = "Use Windows Subsystem for Linux.", - type = "boolean", - } - attributes.launch.luaexe.default = "${workspaceFolder}/lua.exe" - attributes.launch.cpath.default = "${workspaceFolder}/?.dll" -else - attributes.launch.luaexe.default = "${workspaceFolder}/lua" - attributes.launch.cpath.default = "${workspaceFolder}/?.so" -end - -local function SupportedArchs() - if OS == "win32" then - return "x86_64", "x86" - elseif OS == "darwin" then - if ARCH == "arm64" then - return "arm64", "x86_64" - else - return "x86_64" - end - elseif OS == "linux" then - if ARCH == "arm64" then - return "arm64" - else - return "x86_64" - end - end -end - -local Archs = {SupportedArchs()} -attributes.launch.luaArch.default = Archs[1] -attributes.launch.luaArch.enum = Archs - -for k, v in pairs(attributes.common) do - attributes.attach[k] = v - attributes.launch[k] = v -end -json.contributes.debuggers[1].configurationAttributes = { - launch = {properties=attributes.launch}, - attach = {properties=attributes.attach}, -} - -local configuration = json.contributes.configuration.properties -for _, name in ipairs {"luaArch", "luaVersion", "sourceCoding", "path", "cpath","console"} do - local attr = attributes.launch[name] or attributes.attach[name] - if attr then - local cfg = {} - for k, v in pairs(attr) do - if k == 'markdownDescription' then - k = 'description' - end - if k == 'enummarkdownDescriptions' then - k = 'enumDescriptions' - end - cfg[k] = v - end - configuration["lua.debug.settings."..name] = cfg - end -end - -return json +local platform = ... +platform = platform or "unknown-unknown" + +local OS, ARCH = platform:match "^([^-]+)-([^-]+)$" + +local json = { + name = "lua-debug", + version = "1.61.0", + publisher = "actboy168", + displayName = "Lua Debug", + description = "VSCode debugger extension for Lua", + icon = "images/logo.png", + private = true, + author = { + name = "actboy168", + }, + bugs = { + url = "https://github.com/actboy168/lua-debug/issues", + }, + repository = { + type = "git", + url = "https://github.com/actboy168/lua-debug", + }, + keywords = { + "lua", + "debug", + "debuggers", + }, + categories = { + "Debuggers", + }, + engines = { + vscode = "^1.61.0", + }, + extensionKind = { + "workspace", + }, + main = "./js/extension.js", + activationEvents = { + "onCommand:extension.lua-debug.runEditorContents", + "onCommand:extension.lua-debug.debugEditorContents", + "onDebugInitialConfigurations", + "onDebugDynamicConfigurations", + "onDebugResolve:lua", + }, + capabilities = { + untrustedWorkspaces = { + description = "Debugging is disabled in Restricted Mode.", + supported = false, + }, + }, + contributes = { + breakpoints = { + { + language = "lua", + }, + { + language = "html", + }, + }, + commands = { + { + command = "extension.lua-debug.runEditorContents", + icon = "$(play)", + title = "Run File", + }, + { + command = "extension.lua-debug.debugEditorContents", + icon = "$(debug-alt-small)", + title = "Debug File", + }, + { + command = "extension.lua-debug.showIntegerAsDec", + title = "Show as Dec", + }, + { + command = "extension.lua-debug.showIntegerAsHex", + title = "Show as Hex", + }, + }, + configuration = { + properties = { + ["lua.debug.variables.showIntegerAsHex"] = { + default = false, + description = "Show integer as hex.", + type = "boolean", + }, + }, + }, + debuggers = { + { + type = "lua", + languages = { + "lua", + }, + label = "Lua Debug", + configurationSnippets = { + { + label = "Lua Debug: Launch Script", + description = "A new configuration for launching a lua debug program", + body = { + type = "lua", + request = "launch", + name = "${1:launch}", + stopOnEntry = true, + program = "^\"\\${workspaceFolder}/${2:main.lua}\"", + arg = { + }, + }, + }, + { + label = "Lua Debug: Attach", + description = "A new configuration for attaching a lua debug program", + body = { + type = "lua", + request = "attach", + name = "${1:attach}", + stopOnEntry = true, + address = "127.0.0.1:4278", + } + } + } + } + }, + menus = { + ["debug/variables/context"] = { + { + command = "extension.lua-debug.showIntegerAsDec", + group = "1_view", + when = "debugConfigurationType == 'lua' && debugProtocolVariableMenuContext == 'integer/hex'", + }, + { + command = "extension.lua-debug.showIntegerAsHex", + group = "1_view", + when = "debugConfigurationType == 'lua' && debugProtocolVariableMenuContext == 'integer/dec'", + }, + }, + ["editor/title/run"] = { + { + command = "extension.lua-debug.runEditorContents", + when = "resourceLangId == lua", + }, + { + command = "extension.lua-debug.debugEditorContents", + when = "resourceLangId == lua", + }, + }, + }, + }, +} + +local attributes = {} + +attributes.common = { + luaVersion = { + default = "5.4", + enum = { + "5.1", + "5.2", + "5.3", + "5.4", + "latest", + "jit", + }, + markdownDescription = "%lua.debug.launch.luaVersion.description%", + type = "string", + }, + outputCapture = { + default = { + }, + items = { + enum = { + "print", + "io.write", + "stdout", + "stderr", + }, + }, + markdownDescription = "From where to capture output messages: print or stdout/stderr streams.", + type = "array", + }, + pathFormat = { + default = "path", + enum = { + "path", + "linuxpath", + }, + markdownDescription = "Path format", + type = "string", + }, + sourceFormat = { + default = "path", + enum = { + "path", + "string", + "linuxpath", + }, + markdownDescription = "Source format", + type = "string", + }, + sourceMaps = { + default = { + { + "./*", + "${workspaceFolder}/*", + }, + }, + markdownDescription = "The source path of the remote host and the source path of local.", + type = "array", + }, + skipFiles = { + default = { + }, + items = { + type = "string", + }, + markdownDescription = "An array of glob patterns for files to skip when debugging.", + type = "array", + }, + stopOnEntry = { + default = false, + markdownDescription = "Automatically stop after entry.", + type = "boolean", + }, + stopOnThreadEntry = { + default = true, + markdownDescription = "Automatically stop after thread entry.", + type = "boolean", + }, + address = { + default = "127.0.0.1:4278", + markdownDescription = [[ +Debugger address. +1. IPv4 e.g. `127.0.0.1:4278` +2. IPv6 e.g. `[::1]:4278` +3. Unix domain socket e.g. `@c:\\unix.sock`]], + type = { + "string", + "null", + }, + }, + client = { + default = true, + markdownDescription = "Choose whether to `connect` or `listen`.", + type = "boolean", + }, + inject = { + default = "none", + markdownDescription = "How to inject debugger.", + enum = { + "none", + }, + type = "string", + }, + signature = { + default = "null", + type = "object", + markdownDescription = "signature info", + properties = { + lua_module = { + default = "null", + type = "string", + markdownDescription = "lua module path or name", + }, + functions = { + default = "null", + type = "object", + additionalProperties = { + type = "object", + properties = { + start_offset = { + type = "integer" + }, + end_offset = { + type = "integer" + }, + pattern = { + type = "string" + }, + pattern_offset = { + type = "integer" + }, + hit_offset = { + type = "integer", + } + }, + required = { "pattern" } + } + } + }, + required = { "functions" } + } +} + +if OS == "win32" then + attributes.common.inject.default = "hook" + table.insert(attributes.common.inject.enum, "hook") +elseif OS == "darwin" then + attributes.common.inject.default = "lldb" + table.insert(attributes.common.inject.enum, "hook") + table.insert(attributes.common.inject.enum, "lldb") + attributes.common.inject_executable = { + markdownDescription = "inject executable path", + type = { + "string", + "null", + }, + } +end + +attributes.attach = { +} + +if OS == "win32" or OS == "darwin" then + attributes.attach.processId = { + default = "${command:pickProcess}", + markdownDescription = "Id of process to attach to.", + type = "string", + } + attributes.attach.processName = { + default = "lua.exe", + markdownDescription = "Name of process to attach to.", + type = "string", + } + json.activationEvents[#json.activationEvents+1] = "onCommand:extension.lua-debug.pickProcess" + json.contributes.debuggers[1].variables = { + pickProcess = "extension.lua-debug.pickProcess", + } +end + +attributes.launch = { + luaexe = { + markdownDescription = "Absolute path to the lua exe.", + type = "string", + }, + program = { + default = "${workspaceFolder}/main.lua", + markdownDescription = "Lua program to debug - set this to the path of the script", + type = "string", + }, + arg = { + default = { + }, + markdownDescription = "Command line argument, arg[1] ... arg[n]", + type = "array", + }, + arg0 = { + default = { + }, + markdownDescription = "Command line argument, arg[-n] ... arg[0]", + type = { + "string", + "array", + }, + }, + path = { + default = "${workspaceFolder}/?.lua", + markdownDescription = "%lua.debug.launch.path.description%", + type = { + "string", + "array", + "null", + }, + }, + cpath = { + markdownDescription = "%lua.debug.launch.cpath.description%", + type = { + "string", + "array", + "null", + }, + }, + luaArch = { + markdownDescription = "%lua.debug.launch.luaArch.description%", + type = "string", + }, + cwd = { + default = "${workspaceFolder}", + markdownDescription = "Working directory at program startup", + type = { + "string", + "null", + }, + }, + env = { + additionalProperties = { + type = { + "string", + "null", + }, + }, + default = { + PATH = "${workspaceFolder}", + }, + markdownDescription = "Environment variables passed to the program. The value `null` removes thevariable from the environment.", + type = "object", + }, + console = { + default = "integratedTerminal", + enum = { + "internalConsole", + "integratedTerminal", + "externalTerminal", + }, + enummarkdownDescriptions = { + "%lua.debug.launch.console.internalConsole.description%", + "%lua.debug.launch.console.integratedTerminal.description%", + "%lua.debug.launch.console.externalTerminal.description%", + }, + markdownDescription = "%lua.debug.launch.console.description%", + type = "string", + }, + runtimeExecutable = { + default = OS == "win32" and "${workspaceFolder}/lua.exe" or "${workspaceFolder}/lua", + markdownDescription = "Runtime to use. Either an absolute path or the name of a runtime availableon the PATH.", + type = { + "string", + "null", + }, + }, + runtimeArgs = { + default = "${workspaceFolder}/main.lua", + markdownDescription = "Arguments passed to the runtime executable.", + type = { + "string", + "array", + "null", + }, + }, +} + +if OS == "win32" or OS == "darwin" then + local snippets = json.contributes.debuggers[1].configurationSnippets + snippets[#snippets+1] = { + label = "Lua Debug: Launch Process", + description = "A new configuration for launching a lua process", + body = { + type = "lua", + request = "launch", + name = "${1:launch process}", + stopOnEntry = true, + runtimeExecutable = "^\"\\${workspaceFolder}/lua.exe\"", + runtimeArgs = "^\"\\${workspaceFolder}/${2:main.lua}\"", + } + } + snippets[#snippets+1] = { + label = "Lua Debug: Attach Process", + description = "A new configuration for attaching a lua debug program", + body = { + type = "lua", + request = "attach", + name = "${1:attach}", + stopOnEntry = true, + processId = "^\"\\${command:pickProcess}\"", + } + } +end + +if OS == "win32" then + attributes.common.sourceCoding = { + default = "utf8", + enum = { + "utf8", + "ansi", + }, + markdownDescription = "%lua.debug.launch.sourceCoding.description%", + type = "string", + } + attributes.common.useWSL = { + default = true, + description = "Use Windows Subsystem for Linux.", + type = "boolean", + } + attributes.launch.luaexe.default = "${workspaceFolder}/lua.exe" + attributes.launch.cpath.default = "${workspaceFolder}/?.dll" +else + attributes.launch.luaexe.default = "${workspaceFolder}/lua" + attributes.launch.cpath.default = "${workspaceFolder}/?.so" +end + +local function SupportedArchs() + if OS == "win32" then + return "x86_64", "x86" + elseif OS == "darwin" then + if ARCH == "arm64" then + return "arm64", "x86_64" + else + return "x86_64" + end + elseif OS == "linux" then + if ARCH == "arm64" then + return "arm64" + else + return "x86_64" + end + end +end + +local Archs = {SupportedArchs()} +attributes.launch.luaArch.default = Archs[1] +attributes.launch.luaArch.enum = Archs + +for k, v in pairs(attributes.common) do + attributes.attach[k] = v + attributes.launch[k] = v +end +json.contributes.debuggers[1].configurationAttributes = { + launch = {properties=attributes.launch}, + attach = {properties=attributes.attach}, +} + +local configuration = json.contributes.configuration.properties +for _, name in ipairs {"luaArch", "luaVersion", "sourceCoding", "path", "cpath","console"} do + local attr = attributes.launch[name] or attributes.attach[name] + if attr then + local cfg = {} + for k, v in pairs(attr) do + if k == 'markdownDescription' then + k = 'description' + end + if k == 'enummarkdownDescriptions' then + k = 'enumDescriptions' + end + cfg[k] = v + end + configuration["lua.debug.settings."..name] = cfg + end +end + +return json diff --git a/extension/js/configurationProvider.js b/extension/js/configurationProvider.js index d5a6b5e87..05078ddab 100644 --- a/extension/js/configurationProvider.js +++ b/extension/js/configurationProvider.js @@ -243,6 +243,9 @@ function resolveConfig(folder, config) { throw new Error('Missing `address` to debug'); } } + if (config.signature != null) { + config.signature.lua_version = config.lua_version + } config.configuration = { variables: vscode.workspace.getConfiguration("lua.debug.variables") } diff --git a/extension/script/frontend/proxy.lua b/extension/script/frontend/proxy.lua index f31cfb89b..df4f48fce 100644 --- a/extension/script/frontend/proxy.lua +++ b/extension/script/frontend/proxy.lua @@ -4,6 +4,7 @@ local fs = require 'bee.filesystem' local sp = require 'bee.subprocess' local platform_os = require 'frontend.platform_os' local process_inject = require 'frontend.process_inject' +local json = require 'common.json' local server local client local initReq @@ -23,6 +24,14 @@ local function ipc_send_latest(pid) fd:close() end +local function ipc_send_config(pid, config) + fs.create_directories(WORKDIR / "tmp") + local ipc = require "common.ipc" + local fd = assert(ipc(WORKDIR, pid, "config", "w")) + fd:write(json.encode(config)) + fd:close() +end + local function response_initialize(req) client.sendmsg { type = 'response', @@ -59,10 +68,11 @@ local function attach_process(pkg, pid) if args.luaVersion == "latest" then ipc_send_latest(pid) end + ipc_send_config(pid, args.signature) local ok, errmsg = process_inject.inject(pid, "attach", args) if not ok then - return false, errmsg - end + return false, errmsg + end server = network(getUnixAddress(pid), true) server.sendmsg(initReq) @@ -80,8 +90,8 @@ local function proxy_attach(pkg) local args = pkg.arguments platform_os.init(args) if platform_os() ~= "Windows" and platform_os() ~= "macOS" then - attach_tcp(pkg, args) - return + attach_tcp(pkg, args) + return end if args.processId then local processId = tonumber(args.processId) @@ -92,7 +102,7 @@ local function proxy_attach(pkg) return end if args.processName then - local pids = require "frontend.query_process"(args.processName) + local pids = require "frontend.query_process" (args.processName) if #pids == 0 then response_error(pkg, ('Cannot found process `%s`.'):format(args.processName)) return @@ -113,7 +123,7 @@ local function create_server(args, pid) local s, address if args.address ~= nil then s = network(args.address, args.client) - address = (args.client and "s:" or "c:") .. args.address + address = (args.client and "s:" or "c:")..args.address else pid = pid or sp.get_id() s = network(getUnixAddress(pid), true) @@ -158,11 +168,15 @@ local function proxy_launch_console(pkg) response_error(pkg, "`runtimeExecutable` need specify `inject` or `address`.") return end - local process, err = debuger_factory.create_process_in_console(args, function (process) + local process, err = debuger_factory.create_process_in_console(args, function(process) local address server, address = create_server(args, process:get_id()) - if args.luaVersion == "latest" and type(address) == "number" then - ipc_send_latest(address) + + if type(address) == "number" then + if args.luaVersion == "latest" then + ipc_send_latest(address) + end + ipc_send_config(address, args.signature) end end) if not process then diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index 639e5e99b..69445acbe 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -45,7 +45,7 @@ namespace luadebug::autoattach { } std::optional Config::get_lua_signature(const std::string& key) const { - const auto signture_key = "signture"sv; + const auto signture_key = "functions"sv; auto it = values->find(signture_key); if (it == values->end()) { return std::nullopt; @@ -81,8 +81,7 @@ namespace luadebug::autoattach { } bool Config::is_signature_mode() const { - const auto key = "signature_mode"sv; - return values->find(key) != values->end(); + return !values->is_null(); } bool Config::init_from_file() { From d494069822f0f080d4086ac99c8b9b35a38f88a1 Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 16 Mar 2023 16:02:37 +0800 Subject: [PATCH 12/69] remove signature.functions default --- compile/common/package_json.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/compile/common/package_json.lua b/compile/common/package_json.lua index cd2678e05..78f3a3bf9 100644 --- a/compile/common/package_json.lua +++ b/compile/common/package_json.lua @@ -263,7 +263,6 @@ Debugger address. markdownDescription = "lua module path or name", }, functions = { - default = "null", type = "object", additionalProperties = { type = "object", From 2f3987dda74e4a7fa6c2352069b3439937b5567c Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 16 Mar 2023 16:09:51 +0800 Subject: [PATCH 13/69] fix end_offset error --- src/launcher/resolver/lua_signature.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/launcher/resolver/lua_signature.cpp b/src/launcher/resolver/lua_signature.cpp index f7b808e72..f644e5d44 100644 --- a/src/launcher/resolver/lua_signature.cpp +++ b/src/launcher/resolver/lua_signature.cpp @@ -21,7 +21,7 @@ namespace luadebug::autoattach { return true; }); - range.size -= end_offset * sizeof(void*); + range.size -= end_offset; range.base_address = (void*)((uint8_t*)range.base_address + start_offset); // 限定匹配地址范围 From 84a73b1413ba170b1a8440a116ad5e734b1cde2f Mon Sep 17 00:00:00 2001 From: fesily Date: Fri, 17 Mar 2023 09:35:06 +0800 Subject: [PATCH 14/69] add compiler_signature --- 3rd/frida_gum/gumpp | 2 +- compile/common/package_json.lua | 2 +- compile/macos/compiler_signature.lua | 9 ++ compile/macos/make.lua | 11 +- compile/macos/runtime.lua | 1 + extension/js/configurationProvider.js | 2 +- src/launcher/config/config.cpp | 4 +- src/launcher/tools/signature_compiler.cpp | 159 ++++++++++++++++++++++ 8 files changed, 180 insertions(+), 10 deletions(-) create mode 100644 compile/macos/compiler_signature.lua create mode 100644 src/launcher/tools/signature_compiler.cpp diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index c2e93b74e..764a33a48 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit c2e93b74eeb6b5463d37abc0683c63f49882e4a2 +Subproject commit 764a33a48e20224833cb8f8b8e3e842de1c77ac6 diff --git a/compile/common/package_json.lua b/compile/common/package_json.lua index 78f3a3bf9..61b5b4639 100644 --- a/compile/common/package_json.lua +++ b/compile/common/package_json.lua @@ -257,7 +257,7 @@ Debugger address. type = "object", markdownDescription = "signature info", properties = { - lua_module = { + module = { default = "null", type = "string", markdownDescription = "lua module path or name", diff --git a/compile/macos/compiler_signature.lua b/compile/macos/compiler_signature.lua new file mode 100644 index 000000000..86aacb3d0 --- /dev/null +++ b/compile/macos/compiler_signature.lua @@ -0,0 +1,9 @@ +local lm = require "luamake" + +require "compile.common.frida" + +lm:executable("signature_compiler") { + deps = { "frida" }, + includes = { "3rd/frida_gum/gumpp", "3rd/bee.lua" }, + sources = { "src/launcher/tools/signature_compiler.cpp" }, +} diff --git a/compile/macos/make.lua b/compile/macos/make.lua index e90d5bdf0..f2f4f4518 100644 --- a/compile/macos/make.lua +++ b/compile/macos/make.lua @@ -3,7 +3,7 @@ local lm = require "luamake" if lm.platform == "darwin-arm64" then lm.target = "arm64-apple-macos11" else - lm.target = "x86_64-apple-macos10.12" + lm.target = "x86_64-apple-macos10.15" end lm.builddir = ("build/%s/%s"):format(lm.platform, lm.mode) @@ -23,7 +23,7 @@ if lm.platform == "darwin-arm64" then args = { "-builddir", "build/darwin-x64/"..lm.mode, "-runtime_platform", "darwin-x64", - "-target", "x86_64-apple-macos10.12", + "-target", "x86_64-apple-macos10.15", }, } end @@ -60,10 +60,10 @@ end if lm.mode == "debug" then lm:executable "test_delayload" { sources = "test/delayload.cpp", - includes = {"src/launcher","3rd/lua/lua54"}, + includes = { "src/launcher", "3rd/lua/lua54" }, } lm:phony "tests" { - deps = {"test_frida", "test_delayload", "test_symbol"} + deps = { "test_frida", "test_delayload", "test_symbol" } } end @@ -74,5 +74,6 @@ lm:default { "process_inject_helper", "merge_launcher", lm.platform == "darwin-arm64" and "x86_64", - lm.mode == "debug" and "tests" + lm.mode == "debug" and "tests", + "signature_compiler" } diff --git a/compile/macos/runtime.lua b/compile/macos/runtime.lua index 3b4d642e7..95685fe50 100644 --- a/compile/macos/runtime.lua +++ b/compile/macos/runtime.lua @@ -2,6 +2,7 @@ local lm = require "luamake" require "compile.common.runtime" require "compile.common.frida" +require "compile.macos.compiler_signature" lm:source_set "launcher_hook_luajit" { includes = { diff --git a/extension/js/configurationProvider.js b/extension/js/configurationProvider.js index 05078ddab..9965f51fc 100644 --- a/extension/js/configurationProvider.js +++ b/extension/js/configurationProvider.js @@ -244,7 +244,7 @@ function resolveConfig(folder, config) { } } if (config.signature != null) { - config.signature.lua_version = config.lua_version + config.signature.version = config.lua_version } config.configuration = { variables: vscode.workspace.getConfiguration("lua.debug.variables") diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index 69445acbe..818ef22f1 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -34,7 +34,7 @@ namespace luadebug::autoattach { Config config; lua_version Config::get_lua_version() const { - const auto key = "lua_version"sv; + const auto key = "version"sv; auto it = values->find(key); if (!values || it == values->end()) { @@ -67,7 +67,7 @@ namespace luadebug::autoattach { } std::string Config::get_lua_module() const { - const auto key = "lua_module"sv; + const auto key = "module"sv; auto it = values->find(key); if (it == values->end()) { diff --git a/src/launcher/tools/signature_compiler.cpp b/src/launcher/tools/signature_compiler.cpp new file mode 100644 index 000000000..cc1a6329b --- /dev/null +++ b/src/launcher/tools/signature_compiler.cpp @@ -0,0 +1,159 @@ +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 + +#else +# include +#endif + +using namespace std::literals; +const char* module_name; +struct Pattern { + std::string name; + std::string pattern; + size_t scan_count; +}; + +int imports(std::string file_path, bool is_string, std::set& imports_names) { +#ifdef _WIN32 + +#else + auto handle = dlopen(file_path.c_str(), RTLD_LAZY | RTLD_LOCAL); + if (!handle) { + std::cerr << "dlopen " << file_path << " failed: " << dlerror() << std::endl; + return 1; + } +#endif + + if (is_string) { + // check address is a string begin + for (auto str : Gum::search_module_string(file_path.c_str(), "lua")) { + std::string_view name(str); + if (str[-1] != 0) { + continue; + } + // check name has '_' and not has ' ' '.' '*' '/' '\\' ':' '<' '>' '|' '"' '?' + if (name.find('_') == std::string_view::npos) { + continue; + } + if (name.find_first_of(" .*/\\:<>|\"?") != std::string_view::npos) { + continue; + } + if (name.find("lua") != 0) { + continue; + } + + imports_names.emplace(name); + } + } + else { + Gum::Process::module_enumerate_import(file_path.c_str(), [&](const Gum::ImportDetails& details) { + auto name = std::string_view(details.name); + if (name.find("lua") == 0) { + imports_names.insert(details.name); + } + return true; + }); + } + for (const auto& name : imports_names) { + std::cerr << name << std::endl; + } + return 0; +} +bool starts_with(std::string_view _this, std::string_view __s) _NOEXCEPT { + return _this.size() >= __s.size() && + _this.compare(0, __s.size(), __s) == + 0; +} + +bool compiler_pattern(const char* name, void* address, std::list& patterns) { + auto pattern = Gum::to_signature_pattern(address, 255); + std::vector find_address = Gum::search_module_function(module_name, pattern.c_str()); + if (find_address.size() != 1) { + std::cerr << name << " address:" << address << " pattern:" << pattern << std::endl; + if (find_address.empty()) { + std::cerr << name << ": invalid pattern[can't search pattern]" << std::endl; + } + else { + if (find_address.size() > 8) { + std::cerr << name << ": invalid pattern[too many matched]:" << find_address.size() + << " hited" << std::endl; + } + else { + for (auto addr : find_address) { + std::cerr << "\taddress:" << addr << std::endl; + } + } + } + } + bool isvalid = false; + for (auto addr : find_address) { + if (addr == address) { + isvalid = true; + break; + } + } + + if (!isvalid) { + std::cerr << name << ": invalid pattern[address not match]:" << address << std::endl; + return false; + } + else { + patterns.emplace_back(Pattern { name, pattern, find_address.size() }); + return true; + } +} + +int main(int narg, const char* argvs[]) { + if (narg != 5) { + std::cerr << "Usage: " + << "signautre import_file is_string target_file is_export" + << std::endl; + return 1; + } + + Gum::runtime_init(); + auto import_file = std::filesystem::absolute(argvs[1]).generic_string(); + auto is_string = argvs[2] == "true"sv ? true : false; + std::set imports_names; + if (auto ec = imports(import_file, is_string, imports_names); ec != 0) { + return ec; + } + auto target_path = std::filesystem::absolute(argvs[3]).generic_string(); + auto is_export = argvs[4] == "true"sv ? true : false; + std::string error; + module_name = target_path.c_str(); + std::cerr << "signature:" << module_name << std::endl; + + if (!Gum::Process::module_load(module_name, &error)) { + std::cerr << "Load " << module_name << " failed: " << error << std::endl; + return 1; + } + + std::list patterns; + if (is_export) { + Gum::Process::module_enumerate_export(module_name, [&](const Gum::ExportDetails& details) { + if (imports_names.find(details.name) != imports_names.end()) + compiler_pattern(details.name, details.address, patterns); + return true; + }); + } + else { + Gum::Process::module_enumerate_symbols(module_name, [&](const Gum::SymbolDetails& details) { + if (imports_names.find(details.name) != imports_names.end()) + compiler_pattern(details.name, details.address, patterns); + return true; + }); + } + + for (const auto& pattern : patterns) { + std::cout << pattern.name << ":" << pattern.pattern << "-" << pattern.scan_count << std::endl; + } + return 0; +} From ffdcb7bcfff03f96ad963f148a8251049feda9f9 Mon Sep 17 00:00:00 2001 From: fesily Date: Fri, 17 Mar 2023 21:34:52 +0800 Subject: [PATCH 15/69] add launcher config --- .gitmodules | 4 +- 3rd/frida_gum/gumpp | 2 +- 3rd/json | 1 + compile/common/package_json.lua | 997 +++++++++++++------------ compile/macos/runtime.lua | 1 + compile/windows/runtime.lua | 1 + extension/js/configurationProvider.js | 3 + extension/script/frontend/proxy.lua | 32 +- src/launcher/autoattach/autoattach.cpp | 10 +- src/launcher/autoattach/lua_module.cpp | 21 +- src/launcher/config/config.cpp | 77 ++ src/launcher/config/config.h | 23 + 12 files changed, 651 insertions(+), 521 deletions(-) create mode 160000 3rd/json create mode 100644 src/launcher/config/config.cpp create mode 100644 src/launcher/config/config.h diff --git a/.gitmodules b/.gitmodules index 3f804f6b7..7c87d52db 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,4 +10,6 @@ [submodule "3rd/frida_gum/gumpp"] path = 3rd/frida_gum/gumpp url = https://github.com/fesily/gumpp - +[submodule "3rd/json"] + path = 3rd/json + url = https://github.com/nlohmann/json diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index 41bee742d..54ad1d5a6 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit 41bee742d0176aaf569a2513464339543e63c2de +Subproject commit 54ad1d5a6c8d4856f1db0a3899625a2370b1ca19 diff --git a/3rd/json b/3rd/json new file mode 160000 index 000000000..546370c9e --- /dev/null +++ b/3rd/json @@ -0,0 +1 @@ +Subproject commit 546370c9e778d99e7176641123e5cc1d0b62acab diff --git a/compile/common/package_json.lua b/compile/common/package_json.lua index bf9d79e7b..275b5af4b 100644 --- a/compile/common/package_json.lua +++ b/compile/common/package_json.lua @@ -1,492 +1,505 @@ -local platform = ... -platform = platform or "unknown-unknown" - -local OS, ARCH = platform:match "^([^-]+)-([^-]+)$" - -local json = { - name = "lua-debug", - version = "1.61.0", - publisher = "actboy168", - displayName = "Lua Debug", - description = "VSCode debugger extension for Lua", - icon = "images/logo.png", - private = true, - author = { - name = "actboy168", - }, - bugs = { - url = "https://github.com/actboy168/lua-debug/issues", - }, - repository = { - type = "git", - url = "https://github.com/actboy168/lua-debug", - }, - keywords = { - "lua", - "debug", - "debuggers", - }, - categories = { - "Debuggers", - }, - engines = { - vscode = "^1.61.0", - }, - extensionKind = { - "workspace", - }, - main = "./js/extension.js", - activationEvents = { - "onCommand:extension.lua-debug.runEditorContents", - "onCommand:extension.lua-debug.debugEditorContents", - "onDebugInitialConfigurations", - "onDebugDynamicConfigurations", - "onDebugResolve:lua", - }, - capabilities = { - untrustedWorkspaces = { - description = "Debugging is disabled in Restricted Mode.", - supported = false, - }, - }, - contributes = { - breakpoints = { - { - language = "lua", - }, - { - language = "html", - }, - }, - commands = { - { - command = "extension.lua-debug.runEditorContents", - icon = "$(play)", - title = "Run File", - }, - { - command = "extension.lua-debug.debugEditorContents", - icon = "$(debug-alt-small)", - title = "Debug File", - }, - { - command = "extension.lua-debug.showIntegerAsDec", - title = "Show as Dec", - }, - { - command = "extension.lua-debug.showIntegerAsHex", - title = "Show as Hex", - }, - }, - configuration = { - properties = { - ["lua.debug.variables.showIntegerAsHex"] = { - default = false, - description = "Show integer as hex.", - type = "boolean", - }, - }, - }, - debuggers = { - { - type = "lua", - languages = { - "lua", - }, - label = "Lua Debug", - configurationSnippets = { - { - label = "Lua Debug: Launch Script", - description = "A new configuration for launching a lua debug program", - body = { - type = "lua", - request = "launch", - name = "${1:launch}", - stopOnEntry = true, - program = "^\"\\${workspaceFolder}/${2:main.lua}\"", - arg = { - }, - }, - }, - { - label = "Lua Debug: Attach", - description = "A new configuration for attaching a lua debug program", - body = { - type = "lua", - request = "attach", - name = "${1:attach}", - stopOnEntry = true, - address = "127.0.0.1:4278", - } - } - } - } - }, - menus = { - ["debug/variables/context"] = { - { - command = "extension.lua-debug.showIntegerAsDec", - group = "1_view", - when = "debugConfigurationType == 'lua' && debugProtocolVariableMenuContext == 'integer/hex'", - }, - { - command = "extension.lua-debug.showIntegerAsHex", - group = "1_view", - when = "debugConfigurationType == 'lua' && debugProtocolVariableMenuContext == 'integer/dec'", - }, - }, - ["editor/title/run"] = { - { - command = "extension.lua-debug.runEditorContents", - when = "resourceLangId == lua", - }, - { - command = "extension.lua-debug.debugEditorContents", - when = "resourceLangId == lua", - }, - }, - }, - }, -} - -local attributes = {} - -attributes.common = { - luaVersion = { - default = "5.4", - enum = { - "5.1", - "5.2", - "5.3", - "5.4", - "latest", - "jit", - }, - markdownDescription = "%lua.debug.launch.luaVersion.description%", - type = "string", - }, - outputCapture = { - default = { - }, - items = { - enum = { - "print", - "io.write", - "stdout", - "stderr", - }, - }, - markdownDescription = "From where to capture output messages: print or stdout/stderr streams.", - type = "array", - }, - pathFormat = { - default = "path", - enum = { - "path", - "linuxpath", - }, - markdownDescription = "Path format", - type = "string", - }, - sourceFormat = { - default = "path", - enum = { - "path", - "string", - "linuxpath", - }, - markdownDescription = "Source format", - type = "string", - }, - sourceMaps = { - default = { - { - "./*", - "${workspaceFolder}/*", - }, - }, - markdownDescription = "The source path of the remote host and the source path of local.", - type = "array", - }, - skipFiles = { - default = { - }, - items = { - type = "string", - }, - markdownDescription = "An array of glob patterns for files to skip when debugging.", - type = "array", - }, - stopOnEntry = { - default = false, - markdownDescription = "Automatically stop after entry.", - type = "boolean", - }, - stopOnThreadEntry = { - default = true, - markdownDescription = "Automatically stop after thread entry.", - type = "boolean", - }, - address = { - default = "127.0.0.1:4278", - markdownDescription = [[ -Debugger address. -1. IPv4 e.g. `127.0.0.1:4278` -2. IPv6 e.g. `[::1]:4278` -3. Unix domain socket e.g. `@c:\\unix.sock`]], - type = { - "string", - "null", - }, - }, - client = { - default = true, - markdownDescription = "Choose whether to `connect` or `listen`.", - type = "boolean", - }, - inject = { - default = "none", - markdownDescription = "How to inject debugger.", - enum = { - "none", - }, - type = "string", - }, -} - -if OS == "win32" then - attributes.common.inject.default = "hook" - table.insert(attributes.common.inject.enum, "hook") -elseif OS == "darwin" then - attributes.common.inject.default = "lldb" - table.insert(attributes.common.inject.enum, "hook") - table.insert(attributes.common.inject.enum, "lldb") - attributes.common.inject_executable = { - markdownDescription = "inject executable path", - type = { - "string", - "null", - }, - } -end - -attributes.attach = { -} - -if OS == "win32" or OS == "darwin" then - attributes.attach.processId = { - default = "${command:pickProcess}", - markdownDescription = "Id of process to attach to.", - type = "string", - } - attributes.attach.processName = { - default = "lua.exe", - markdownDescription = "Name of process to attach to.", - type = "string", - } - json.activationEvents[#json.activationEvents+1] = "onCommand:extension.lua-debug.pickProcess" - json.contributes.debuggers[1].variables = { - pickProcess = "extension.lua-debug.pickProcess", - } -end - -attributes.launch = { - luaexe = { - markdownDescription = "Absolute path to the lua exe.", - type = "string", - }, - program = { - default = "${workspaceFolder}/main.lua", - markdownDescription = "Lua program to debug - set this to the path of the script", - type = "string", - }, - arg = { - default = { - }, - markdownDescription = "Command line argument, arg[1] ... arg[n]", - type = "array", - }, - arg0 = { - default = { - }, - markdownDescription = "Command line argument, arg[-n] ... arg[0]", - type = { - "string", - "array", - }, - }, - path = { - default = "${workspaceFolder}/?.lua", - markdownDescription = "%lua.debug.launch.path.description%", - type = { - "string", - "array", - "null", - }, - }, - cpath = { - markdownDescription = "%lua.debug.launch.cpath.description%", - type = { - "string", - "array", - "null", - }, - }, - luaArch = { - markdownDescription = "%lua.debug.launch.luaArch.description%", - type = "string", - }, - cwd = { - default = "${workspaceFolder}", - markdownDescription = "Working directory at program startup", - type = { - "string", - "null", - }, - }, - env = { - additionalProperties = { - type = { - "string", - "null", - }, - }, - default = { - PATH = "${workspaceFolder}", - }, - markdownDescription = "Environment variables passed to the program. The value `null` removes thevariable from the environment.", - type = "object", - }, - console = { - default = "integratedTerminal", - enum = { - "internalConsole", - "integratedTerminal", - "externalTerminal", - }, - enummarkdownDescriptions = { - "%lua.debug.launch.console.internalConsole.description%", - "%lua.debug.launch.console.integratedTerminal.description%", - "%lua.debug.launch.console.externalTerminal.description%", - }, - markdownDescription = "%lua.debug.launch.console.description%", - type = "string", - }, - runtimeExecutable = { - default = OS == "win32" and "${workspaceFolder}/lua.exe" or "${workspaceFolder}/lua", - markdownDescription = "Runtime to use. Either an absolute path or the name of a runtime availableon the PATH.", - type = { - "string", - "null", - }, - }, - runtimeArgs = { - default = "${workspaceFolder}/main.lua", - markdownDescription = "Arguments passed to the runtime executable.", - type = { - "string", - "array", - "null", - }, - }, -} - -if OS == "win32" or OS == "darwin" then - local snippets = json.contributes.debuggers[1].configurationSnippets - snippets[#snippets+1] = { - label = "Lua Debug: Launch Process", - description = "A new configuration for launching a lua process", - body = { - type = "lua", - request = "launch", - name = "${1:launch process}", - stopOnEntry = true, - runtimeExecutable = "^\"\\${workspaceFolder}/lua.exe\"", - runtimeArgs = "^\"\\${workspaceFolder}/${2:main.lua}\"", - } - } - snippets[#snippets+1] = { - label = "Lua Debug: Attach Process", - description = "A new configuration for attaching a lua debug program", - body = { - type = "lua", - request = "attach", - name = "${1:attach}", - stopOnEntry = true, - processId = "^\"\\${command:pickProcess}\"", - } - } -end - -if OS == "win32" then - attributes.common.sourceCoding = { - default = "utf8", - enum = { - "utf8", - "ansi", - }, - markdownDescription = "%lua.debug.launch.sourceCoding.description%", - type = "string", - } - attributes.common.useWSL = { - default = true, - description = "Use Windows Subsystem for Linux.", - type = "boolean", - } - attributes.launch.luaexe.default = "${workspaceFolder}/lua.exe" - attributes.launch.cpath.default = "${workspaceFolder}/?.dll" -else - attributes.launch.luaexe.default = "${workspaceFolder}/lua" - attributes.launch.cpath.default = "${workspaceFolder}/?.so" -end - -local function SupportedArchs() - if OS == "win32" then - return "x86_64", "x86" - elseif OS == "darwin" then - if ARCH == "arm64" then - return "arm64", "x86_64" - else - return "x86_64" - end - elseif OS == "linux" then - if ARCH == "arm64" then - return "arm64" - else - return "x86_64" - end - end -end - -local Archs = {SupportedArchs()} -attributes.launch.luaArch.default = Archs[1] -attributes.launch.luaArch.enum = Archs - -for k, v in pairs(attributes.common) do - attributes.attach[k] = v - attributes.launch[k] = v -end -json.contributes.debuggers[1].configurationAttributes = { - launch = {properties=attributes.launch}, - attach = {properties=attributes.attach}, -} - -local configuration = json.contributes.configuration.properties -for _, name in ipairs {"luaArch", "luaVersion", "sourceCoding", "path", "cpath","console"} do - local attr = attributes.launch[name] or attributes.attach[name] - if attr then - local cfg = {} - for k, v in pairs(attr) do - if k == 'markdownDescription' then - k = 'description' - end - if k == 'enummarkdownDescriptions' then - k = 'enumDescriptions' - end - cfg[k] = v - end - configuration["lua.debug.settings."..name] = cfg - end -end - -return json +local platform = ... +platform = platform or "unknown-unknown" + +local OS, ARCH = platform:match "^([^-]+)-([^-]+)$" + +local json = { + name = "lua-debug", + version = "1.61.0", + publisher = "actboy168", + displayName = "Lua Debug", + description = "VSCode debugger extension for Lua", + icon = "images/logo.png", + private = true, + author = { + name = "actboy168", + }, + bugs = { + url = "https://github.com/actboy168/lua-debug/issues", + }, + repository = { + type = "git", + url = "https://github.com/actboy168/lua-debug", + }, + keywords = { + "lua", + "debug", + "debuggers", + }, + categories = { + "Debuggers", + }, + engines = { + vscode = "^1.61.0", + }, + extensionKind = { + "workspace", + }, + main = "./js/extension.js", + activationEvents = { + "onCommand:extension.lua-debug.runEditorContents", + "onCommand:extension.lua-debug.debugEditorContents", + "onDebugInitialConfigurations", + "onDebugDynamicConfigurations", + "onDebugResolve:lua", + }, + capabilities = { + untrustedWorkspaces = { + description = "Debugging is disabled in Restricted Mode.", + supported = false, + }, + }, + contributes = { + breakpoints = { + { + language = "lua", + }, + { + language = "html", + }, + }, + commands = { + { + command = "extension.lua-debug.runEditorContents", + icon = "$(play)", + title = "Run File", + }, + { + command = "extension.lua-debug.debugEditorContents", + icon = "$(debug-alt-small)", + title = "Debug File", + }, + { + command = "extension.lua-debug.showIntegerAsDec", + title = "Show as Dec", + }, + { + command = "extension.lua-debug.showIntegerAsHex", + title = "Show as Hex", + }, + }, + configuration = { + properties = { + ["lua.debug.variables.showIntegerAsHex"] = { + default = false, + description = "Show integer as hex.", + type = "boolean", + }, + }, + }, + debuggers = { + { + type = "lua", + languages = { + "lua", + }, + label = "Lua Debug", + configurationSnippets = { + { + label = "Lua Debug: Launch Script", + description = "A new configuration for launching a lua debug program", + body = { + type = "lua", + request = "launch", + name = "${1:launch}", + stopOnEntry = true, + program = "^\"\\${workspaceFolder}/${2:main.lua}\"", + arg = { + }, + }, + }, + { + label = "Lua Debug: Attach", + description = "A new configuration for attaching a lua debug program", + body = { + type = "lua", + request = "attach", + name = "${1:attach}", + stopOnEntry = true, + address = "127.0.0.1:4278", + } + } + } + } + }, + menus = { + ["debug/variables/context"] = { + { + command = "extension.lua-debug.showIntegerAsDec", + group = "1_view", + when = "debugConfigurationType == 'lua' && debugProtocolVariableMenuContext == 'integer/hex'", + }, + { + command = "extension.lua-debug.showIntegerAsHex", + group = "1_view", + when = "debugConfigurationType == 'lua' && debugProtocolVariableMenuContext == 'integer/dec'", + }, + }, + ["editor/title/run"] = { + { + command = "extension.lua-debug.runEditorContents", + when = "resourceLangId == lua", + }, + { + command = "extension.lua-debug.debugEditorContents", + when = "resourceLangId == lua", + }, + }, + }, + }, +} + +local attributes = {} + +attributes.common = { + luaVersion = { + default = "5.4", + enum = { + "5.1", + "5.2", + "5.3", + "5.4", + "latest", + "jit", + }, + markdownDescription = "%lua.debug.launch.luaVersion.description%", + type = "string", + }, + outputCapture = { + default = { + }, + items = { + enum = { + "print", + "io.write", + "stdout", + "stderr", + }, + }, + markdownDescription = "From where to capture output messages: print or stdout/stderr streams.", + type = "array", + }, + pathFormat = { + default = "path", + enum = { + "path", + "linuxpath", + }, + markdownDescription = "Path format", + type = "string", + }, + sourceFormat = { + default = "path", + enum = { + "path", + "string", + "linuxpath", + }, + markdownDescription = "Source format", + type = "string", + }, + sourceMaps = { + default = { + { + "./*", + "${workspaceFolder}/*", + }, + }, + markdownDescription = "The source path of the remote host and the source path of local.", + type = "array", + }, + skipFiles = { + default = { + }, + items = { + type = "string", + }, + markdownDescription = "An array of glob patterns for files to skip when debugging.", + type = "array", + }, + stopOnEntry = { + default = false, + markdownDescription = "Automatically stop after entry.", + type = "boolean", + }, + stopOnThreadEntry = { + default = true, + markdownDescription = "Automatically stop after thread entry.", + type = "boolean", + }, + address = { + default = "127.0.0.1:4278", + markdownDescription = [[ +Debugger address. +1. IPv4 e.g. `127.0.0.1:4278` +2. IPv6 e.g. `[::1]:4278` +3. Unix domain socket e.g. `@c:\\unix.sock`]], + type = { + "string", + "null", + }, + }, + client = { + default = true, + markdownDescription = "Choose whether to `connect` or `listen`.", + type = "boolean", + }, + inject = { + default = "none", + markdownDescription = "How to inject debugger.", + enum = { + "none", + }, + type = "string", + }, + signature = { + default = "null", + type = "object", + markdownDescription = "signature info", + properties = { + module = { + default = "null", + type = "string", + markdownDescription = "lua module path or name", + }, + }, + } +} + +if OS == "win32" then + attributes.common.inject.default = "hook" + table.insert(attributes.common.inject.enum, "hook") +elseif OS == "darwin" then + attributes.common.inject.default = "lldb" + table.insert(attributes.common.inject.enum, "hook") + table.insert(attributes.common.inject.enum, "lldb") + attributes.common.inject_executable = { + markdownDescription = "inject executable path", + type = { + "string", + "null", + }, + } +end + +attributes.attach = { +} + +if OS == "win32" or OS == "darwin" then + attributes.attach.processId = { + default = "${command:pickProcess}", + markdownDescription = "Id of process to attach to.", + type = "string", + } + attributes.attach.processName = { + default = "lua.exe", + markdownDescription = "Name of process to attach to.", + type = "string", + } + json.activationEvents[#json.activationEvents + 1] = "onCommand:extension.lua-debug.pickProcess" + json.contributes.debuggers[1].variables = { + pickProcess = "extension.lua-debug.pickProcess", + } +end + +attributes.launch = { + luaexe = { + markdownDescription = "Absolute path to the lua exe.", + type = "string", + }, + program = { + default = "${workspaceFolder}/main.lua", + markdownDescription = "Lua program to debug - set this to the path of the script", + type = "string", + }, + arg = { + default = { + }, + markdownDescription = "Command line argument, arg[1] ... arg[n]", + type = "array", + }, + arg0 = { + default = { + }, + markdownDescription = "Command line argument, arg[-n] ... arg[0]", + type = { + "string", + "array", + }, + }, + path = { + default = "${workspaceFolder}/?.lua", + markdownDescription = "%lua.debug.launch.path.description%", + type = { + "string", + "array", + "null", + }, + }, + cpath = { + markdownDescription = "%lua.debug.launch.cpath.description%", + type = { + "string", + "array", + "null", + }, + }, + luaArch = { + markdownDescription = "%lua.debug.launch.luaArch.description%", + type = "string", + }, + cwd = { + default = "${workspaceFolder}", + markdownDescription = "Working directory at program startup", + type = { + "string", + "null", + }, + }, + env = { + additionalProperties = { + type = { + "string", + "null", + }, + }, + default = { + PATH = "${workspaceFolder}", + }, + markdownDescription = + "Environment variables passed to the program. The value `null` removes thevariable from the environment.", + type = "object", + }, + console = { + default = "integratedTerminal", + enum = { + "internalConsole", + "integratedTerminal", + "externalTerminal", + }, + enummarkdownDescriptions = { + "%lua.debug.launch.console.internalConsole.description%", + "%lua.debug.launch.console.integratedTerminal.description%", + "%lua.debug.launch.console.externalTerminal.description%", + }, + markdownDescription = "%lua.debug.launch.console.description%", + type = "string", + }, + runtimeExecutable = { + default = OS == "win32" and "${workspaceFolder}/lua.exe" or "${workspaceFolder}/lua", + markdownDescription = "Runtime to use. Either an absolute path or the name of a runtime availableon the PATH.", + type = { + "string", + "null", + }, + }, + runtimeArgs = { + default = "${workspaceFolder}/main.lua", + markdownDescription = "Arguments passed to the runtime executable.", + type = { + "string", + "array", + "null", + }, + }, +} + +if OS == "win32" or OS == "darwin" then + local snippets = json.contributes.debuggers[1].configurationSnippets + snippets[#snippets + 1] = { + label = "Lua Debug: Launch Process", + description = "A new configuration for launching a lua process", + body = { + type = "lua", + request = "launch", + name = "${1:launch process}", + stopOnEntry = true, + runtimeExecutable = "^\"\\${workspaceFolder}/lua.exe\"", + runtimeArgs = "^\"\\${workspaceFolder}/${2:main.lua}\"", + } + } + snippets[#snippets + 1] = { + label = "Lua Debug: Attach Process", + description = "A new configuration for attaching a lua debug program", + body = { + type = "lua", + request = "attach", + name = "${1:attach}", + stopOnEntry = true, + processId = "^\"\\${command:pickProcess}\"", + } + } +end + +if OS == "win32" then + attributes.common.sourceCoding = { + default = "utf8", + enum = { + "utf8", + "ansi", + }, + markdownDescription = "%lua.debug.launch.sourceCoding.description%", + type = "string", + } + attributes.common.useWSL = { + default = true, + description = "Use Windows Subsystem for Linux.", + type = "boolean", + } + attributes.launch.luaexe.default = "${workspaceFolder}/lua.exe" + attributes.launch.cpath.default = "${workspaceFolder}/?.dll" +else + attributes.launch.luaexe.default = "${workspaceFolder}/lua" + attributes.launch.cpath.default = "${workspaceFolder}/?.so" +end + +local function SupportedArchs() + if OS == "win32" then + return "x86_64", "x86" + elseif OS == "darwin" then + if ARCH == "arm64" then + return "arm64", "x86_64" + else + return "x86_64" + end + elseif OS == "linux" then + if ARCH == "arm64" then + return "arm64" + else + return "x86_64" + end + end +end + +local Archs = { SupportedArchs() } +attributes.launch.luaArch.default = Archs[1] +attributes.launch.luaArch.enum = Archs + +for k, v in pairs(attributes.common) do + attributes.attach[k] = v + attributes.launch[k] = v +end +json.contributes.debuggers[1].configurationAttributes = { + launch = { properties = attributes.launch }, + attach = { properties = attributes.attach }, +} + +local configuration = json.contributes.configuration.properties +for _, name in ipairs { "luaArch", "luaVersion", "sourceCoding", "path", "cpath", "console" } do + local attr = attributes.launch[name] or attributes.attach[name] + if attr then + local cfg = {} + for k, v in pairs(attr) do + if k == 'markdownDescription' then + k = 'description' + end + if k == 'enummarkdownDescriptions' then + k = 'enumDescriptions' + end + cfg[k] = v + end + configuration["lua.debug.settings."..name] = cfg + end +end + +return json diff --git a/compile/macos/runtime.lua b/compile/macos/runtime.lua index a4f5bb81a..3b4d642e7 100644 --- a/compile/macos/runtime.lua +++ b/compile/macos/runtime.lua @@ -22,6 +22,7 @@ lm:lua_library 'launcher' { "3rd/bee.lua", "3rd/frida_gum/gumpp", "3rd/lua/lua54", + "3rd/json/single_include", "src/launcher", }, sources = { diff --git a/compile/windows/runtime.lua b/compile/windows/runtime.lua index fdfec993f..b089aba15 100644 --- a/compile/windows/runtime.lua +++ b/compile/windows/runtime.lua @@ -38,6 +38,7 @@ lm:lua_library ('launcher.'..ArchAlias[platform]) { includes = { "3rd/bee.lua", "3rd/frida_gum/gumpp", + "3rd/json/single_include", "src/launcher", }, sources = { diff --git a/extension/js/configurationProvider.js b/extension/js/configurationProvider.js index d5a6b5e87..76601bc44 100644 --- a/extension/js/configurationProvider.js +++ b/extension/js/configurationProvider.js @@ -243,6 +243,9 @@ function resolveConfig(folder, config) { throw new Error('Missing `address` to debug'); } } + if (config.signature != null) { + config.signature.version = config.version + } config.configuration = { variables: vscode.workspace.getConfiguration("lua.debug.variables") } diff --git a/extension/script/frontend/proxy.lua b/extension/script/frontend/proxy.lua index f31cfb89b..df4f48fce 100644 --- a/extension/script/frontend/proxy.lua +++ b/extension/script/frontend/proxy.lua @@ -4,6 +4,7 @@ local fs = require 'bee.filesystem' local sp = require 'bee.subprocess' local platform_os = require 'frontend.platform_os' local process_inject = require 'frontend.process_inject' +local json = require 'common.json' local server local client local initReq @@ -23,6 +24,14 @@ local function ipc_send_latest(pid) fd:close() end +local function ipc_send_config(pid, config) + fs.create_directories(WORKDIR / "tmp") + local ipc = require "common.ipc" + local fd = assert(ipc(WORKDIR, pid, "config", "w")) + fd:write(json.encode(config)) + fd:close() +end + local function response_initialize(req) client.sendmsg { type = 'response', @@ -59,10 +68,11 @@ local function attach_process(pkg, pid) if args.luaVersion == "latest" then ipc_send_latest(pid) end + ipc_send_config(pid, args.signature) local ok, errmsg = process_inject.inject(pid, "attach", args) if not ok then - return false, errmsg - end + return false, errmsg + end server = network(getUnixAddress(pid), true) server.sendmsg(initReq) @@ -80,8 +90,8 @@ local function proxy_attach(pkg) local args = pkg.arguments platform_os.init(args) if platform_os() ~= "Windows" and platform_os() ~= "macOS" then - attach_tcp(pkg, args) - return + attach_tcp(pkg, args) + return end if args.processId then local processId = tonumber(args.processId) @@ -92,7 +102,7 @@ local function proxy_attach(pkg) return end if args.processName then - local pids = require "frontend.query_process"(args.processName) + local pids = require "frontend.query_process" (args.processName) if #pids == 0 then response_error(pkg, ('Cannot found process `%s`.'):format(args.processName)) return @@ -113,7 +123,7 @@ local function create_server(args, pid) local s, address if args.address ~= nil then s = network(args.address, args.client) - address = (args.client and "s:" or "c:") .. args.address + address = (args.client and "s:" or "c:")..args.address else pid = pid or sp.get_id() s = network(getUnixAddress(pid), true) @@ -158,11 +168,15 @@ local function proxy_launch_console(pkg) response_error(pkg, "`runtimeExecutable` need specify `inject` or `address`.") return end - local process, err = debuger_factory.create_process_in_console(args, function (process) + local process, err = debuger_factory.create_process_in_console(args, function(process) local address server, address = create_server(args, process:get_id()) - if args.luaVersion == "latest" and type(address) == "number" then - ipc_send_latest(address) + + if type(address) == "number" then + if args.luaVersion == "latest" then + ipc_send_latest(address) + end + ipc_send_config(address, args.signature) end end) if not process then diff --git a/src/launcher/autoattach/autoattach.cpp b/src/launcher/autoattach/autoattach.cpp index 33ba59e7d..2449d9b87 100644 --- a/src/launcher/autoattach/autoattach.cpp +++ b/src/launcher/autoattach/autoattach.cpp @@ -1,13 +1,11 @@ #include #include #include -#include -#include +#include #include #include #include -#include #include #include @@ -16,6 +14,8 @@ namespace luadebug::autoattach { constexpr auto find_lua_module_key = "lua_newstate"; static bool is_lua_module(const char* module_path) { + if (std::string_view(module_path).find(config.get_lua_module()) != std::string_view::npos) + return true; if (Gum::Process::module_find_export_by_name(module_path, find_lua_module_key)) return true; return Gum::Process::module_find_symbol_by_name(module_path, find_lua_module_key) != nullptr; @@ -36,6 +36,10 @@ namespace luadebug::autoattach { } void start() { + if (!Config::init_from_file()) { + log::info("can't load config"); + return; + } bool found = false; lua_module rm = {}; Gum::Process::enumerate_modules([&rm, &found](const Gum::ModuleDetails& details) -> bool { diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index e5a800cb4..bde7ed96b 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include @@ -7,20 +9,6 @@ #include namespace luadebug::autoattach { - static lua_version lua_version_from_string [[maybe_unused]] (const std::string_view& v) { - if (v == "luajit") - return lua_version::luajit; - if (v == "lua51") - return lua_version::lua51; - if (v == "lua52") - return lua_version::lua52; - if (v == "lua53") - return lua_version::lua53; - if (v == "lua54") - return lua_version::lua54; - return lua_version::unknown; - } - static const char* lua_version_to_string(lua_version v) { switch (v) { case lua_version::lua51: @@ -39,10 +27,13 @@ namespace luadebug::autoattach { } static bool in_module(const lua_module& m, void* addr) { - return addr > m.memory_address && addr <= (void*)((intptr_t)m.memory_address + m.memory_size); + return addr >= m.memory_address && addr <= (void*)((intptr_t)m.memory_address + m.memory_size); } static lua_version get_lua_version(const lua_module& m) { + auto version = config.get_lua_version(); + if (version != lua_version::unknown) + return version; /* luaJIT_version_2_1_0_beta3 luaJIT_version_2_1_0_beta2 diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp new file mode 100644 index 000000000..662d7d410 --- /dev/null +++ b/src/launcher/config/config.cpp @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +using namespace std::string_view_literals; +namespace luadebug::autoattach { + static lua_version lua_version_from_string [[maybe_unused]] (const std::string_view& v) { + if (v == "jit" || v == "luajit") + return lua_version::luajit; + else if (v == "5.1" || v == "lua51") + return lua_version::lua51; + else if (v == "5.2" || v == "lua52") + return lua_version::lua52; + else if (v == "5.3" || v == "lua53") + return lua_version::lua53; + else if (v == "5.4" || v == "lua54") + return lua_version::lua54; + return lua_version::unknown; + } + + Config config; + + lua_version Config::get_lua_version() const { + const auto key = "version"sv; + + auto it = values->find(key); + if (!values || it == values->end()) { + return lua_version::unknown; + } + + return lua_version_from_string(it->get()); + } + + std::string Config::get_lua_module() const { + const auto key = "module"sv; + + auto it = values->find(key); + if (it == values->end()) { + return {}; + } + const auto& value = it->get(); + if (!fs::exists(value)) + return {}; + + return value; + } + + bool Config::init_from_file() { + config.values = std::make_unique(); + auto dllpath = bee::path_helper::dll_path(); + if (!dllpath) { + return false; + } + + auto filename = std::format("{}/tmp/pid_{}_config", dllpath.value().parent_path().parent_path().generic_string(), Gum::Process::get_id()); + + std::ifstream s(filename, s.in); + if (!s.is_open()) + return false; + try { + s >> *config.values; + } catch (const nlohmann::json::exception& e) { + log::info("init_from_file error: {}", e.what()); + } + + return true; + } + +} // namespace luadebug::autoattach \ No newline at end of file diff --git a/src/launcher/config/config.h b/src/launcher/config/config.h new file mode 100644 index 000000000..049df88fd --- /dev/null +++ b/src/launcher/config/config.h @@ -0,0 +1,23 @@ +#include +#include +#include +#include +#include +#include + +namespace luadebug::autoattach { + + enum class lua_version; + class Config { + std::unique_ptr values; + + public: + lua_version get_lua_version() const; + + std::string get_lua_module() const; + + static bool init_from_file(); + }; + + extern Config config; +} // namespace luadebug::autoattach \ No newline at end of file From 65e15599d0e49ef8f9d13c06c830ee7a010edcf3 Mon Sep 17 00:00:00 2001 From: fesily Date: Fri, 17 Mar 2023 21:39:39 +0800 Subject: [PATCH 16/69] fix config lua version --- extension/js/configurationProvider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extension/js/configurationProvider.js b/extension/js/configurationProvider.js index 76601bc44..b6e6cea23 100644 --- a/extension/js/configurationProvider.js +++ b/extension/js/configurationProvider.js @@ -244,7 +244,7 @@ function resolveConfig(folder, config) { } } if (config.signature != null) { - config.signature.version = config.version + config.signature.version = config.luaVersion } config.configuration = { variables: vscode.workspace.getConfiguration("lua.debug.variables") From 61aa43cf7e33f628413e5c8f2e83287e3ba06f1d Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 18 Mar 2023 08:42:43 +0800 Subject: [PATCH 17/69] add auto signature compiler --- 3rd/frida_gum/gumpp | 2 +- compile/common/runtime.lua | 2 + compile/macos/make.lua | 7 +- compile/macos/runtime.lua | 2 +- ...r_signature.lua => signature_compiler.lua} | 0 compile/signature_compiler.lua | 119 ++++++++++++++++++ src/launcher/tools/signature_compiler.cpp | 52 ++++++-- 7 files changed, 170 insertions(+), 14 deletions(-) rename compile/macos/{compiler_signature.lua => signature_compiler.lua} (100%) create mode 100644 compile/signature_compiler.lua diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index 764a33a48..041cd4819 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit 764a33a48e20224833cb8f8b8e3e842de1c77ac6 +Subproject commit 041cd48199564415da68431d83340c6df2f1112f diff --git a/compile/common/runtime.lua b/compile/common/runtime.lua index 0f50b3bd1..5bada7fa3 100644 --- a/compile/common/runtime.lua +++ b/compile/common/runtime.lua @@ -87,6 +87,8 @@ for _, luaver in ipairs { "lua51", "lua52", "lua53", "lua54", "lua-latest", "lua }, visibility = "default", links = "m", + flags = "-g", + ldflags = "-g", linux = { defines = "LUA_USE_LINUX", links = { "pthread", "dl" }, diff --git a/compile/macos/make.lua b/compile/macos/make.lua index f2f4f4518..e30db748f 100644 --- a/compile/macos/make.lua +++ b/compile/macos/make.lua @@ -67,6 +67,11 @@ if lm.mode == "debug" then } end +lm:phony "compile_signature" { + deps = { "signature_compiler", "merge_launcher", "runtime", "lua-debug" }, + "$luamake", "lua", "compile/signature_compiler.lua" +} + lm:default { "common", "lua-debug", @@ -75,5 +80,5 @@ lm:default { "merge_launcher", lm.platform == "darwin-arm64" and "x86_64", lm.mode == "debug" and "tests", - "signature_compiler" + "compile_signature" } diff --git a/compile/macos/runtime.lua b/compile/macos/runtime.lua index 95685fe50..597e0d141 100644 --- a/compile/macos/runtime.lua +++ b/compile/macos/runtime.lua @@ -2,7 +2,7 @@ local lm = require "luamake" require "compile.common.runtime" require "compile.common.frida" -require "compile.macos.compiler_signature" +require "compile.macos.signature_compiler" lm:source_set "launcher_hook_luajit" { includes = { diff --git a/compile/macos/compiler_signature.lua b/compile/macos/signature_compiler.lua similarity index 100% rename from compile/macos/compiler_signature.lua rename to compile/macos/signature_compiler.lua diff --git a/compile/signature_compiler.lua b/compile/signature_compiler.lua new file mode 100644 index 000000000..144375101 --- /dev/null +++ b/compile/signature_compiler.lua @@ -0,0 +1,119 @@ +local fs = require "bee.filesystem" +local sp = require "bee.subprocess" +local platform = require "bee.platform" + +package.path = package.path..";3rd/json.lua/?.lua" + +local json = require "json-beautify" + +local luadebug_files = {} + +local function scan(dir, platform_arch) + for path in fs.pairs(dir) do + if fs.is_directory(path) then + scan(path, platform_arch or path:filename():string()) + else + if path:filename():string():find("luadebug") then + local t = { platform_arch = platform_arch, luadebug = path:string() } + + local dir_path = path:parent_path() + local version = dir_path:filename():string() + t.version = version + + if platform.os == "windows" then + t.lua_modlue = dir_path / version..".dll" + else + t.lua_modlue = dir_path / "lua" + end + luadebug_files[#luadebug_files + 1] = t + end + end + end +end + +scan((fs.path("publish") / "runtime"):string()) + +local option = { + ext = "so", + is_export = false, +} +if platform.os == "windows" then + option = { + ext = "dll", + is_export = true + } +end + +local launcher_path = (fs.path("publish") / "bin" / "launcher."..option.ext):string() + +local function compiler(executable, import_file, is_string, lua_modlue) + print(executable, import_file, is_string, lua_modlue, option.is_export) + local process = assert(sp.spawn { + executable, + import_file, + is_string and "true" or "false", + lua_modlue, + option.is_export and "true" or "false", + stdout = true, + }) + local res = {} + for line in process.stdout:lines() do + local name, pattern, offset, hit_offset = line:match([[(.+):([0-9a-f%?]+)%(([%-%+]?%d+)%)@([%-%+]?%d+)]]) + res[#res + 1] = { + name = name, + pattern = pattern, + offset = offset, + hit_offset = hit_offset, + } + end + process.stdout:close() + + local code = process:wait() + if code ~= 0 then + print("signature_compiler error", code) + os.exit(code, true) + end + + return res +end + +local output_dir = fs.path("publish") / "signature" +fs.create_directories(output_dir) + +local function get_executable(platform_arch) + local bin_dir = fs.path("build") / platform_arch + + local modes = { + "debug", + "release", + } + for _, mode in ipairs(modes) do + local executable = bin_dir / mode / "bin" / "signature_compiler" + if fs.exists(executable) then + return executable:string() + end + end + print("can't find signature_compiler") + os.exit(1, true) +end + +for _, t in ipairs(luadebug_files) do + if t.platform_arch:find("arm64") then + local lua_modlue = t.lua_modlue + local executable = get_executable(t.platform_arch) + local t1 = compiler(executable, launcher_path, true, lua_modlue) + local t2 = compiler(executable, t.luadebug, false, lua_modlue) + local signatures = table.pack(table.unpack(t1), table.unpack(t2)) + local output = {} + for i, signature in ipairs(signatures) do + output[signature.name] = { + pattern = signature.pattern, + offset = signature.offset, + hit_offset = signature.hit_offset, + } + end + local file = io.open((output_dir / (t.version..".json")):string(), "w") + file:write(json.beautify(output)) + file:close() + end +end diff --git a/src/launcher/tools/signature_compiler.cpp b/src/launcher/tools/signature_compiler.cpp index cc1a6329b..b7fa89f91 100644 --- a/src/launcher/tools/signature_compiler.cpp +++ b/src/launcher/tools/signature_compiler.cpp @@ -16,8 +16,8 @@ using namespace std::literals; const char* module_name; struct Pattern { std::string name; - std::string pattern; - size_t scan_count; + Gum::signature signature; + size_t hit_offset; }; int imports(std::string file_path, bool is_string, std::set& imports_names) { @@ -61,9 +61,11 @@ int imports(std::string file_path, bool is_string, std::set& import return true; }); } +#ifndef NDEBUG for (const auto& name : imports_names) { std::cerr << name << std::endl; } +#endif return 0; } bool starts_with(std::string_view _this, std::string_view __s) _NOEXCEPT { @@ -72,8 +74,9 @@ bool starts_with(std::string_view _this, std::string_view __s) _NOEXCEPT { 0; } -bool compiler_pattern(const char* name, void* address, std::list& patterns) { - auto pattern = Gum::to_signature_pattern(address, 255); +bool compiler_signature(const char* name, void* address, std::list& patterns) { + auto signature = Gum::get_function_signature(address, 255); + const auto& pattern = signature.pattern; std::vector find_address = Gum::search_module_function(module_name, pattern.c_str()); if (find_address.size() != 1) { std::cerr << name << " address:" << address << " pattern:" << pattern << std::endl; @@ -93,11 +96,13 @@ bool compiler_pattern(const char* name, void* address, std::list& patte } } bool isvalid = false; + size_t offset = 0; for (auto addr : find_address) { - if (addr == address) { + if ((void*)((uint8_t*)addr + signature.offset) == address) { isvalid = true; break; } + offset++; } if (!isvalid) { @@ -105,7 +110,7 @@ bool compiler_pattern(const char* name, void* address, std::list& patte return false; } else { - patterns.emplace_back(Pattern { name, pattern, find_address.size() }); + patterns.emplace_back(Pattern { name, signature, offset }); return true; } } @@ -136,24 +141,49 @@ int main(int narg, const char* argvs[]) { return 1; } + // imports_names remove lua_ident luaJIT_version_* + { + auto iter = imports_names.begin(); + while (iter != imports_names.end()) { + const auto& name = *iter; + if (name == "lua_ident" || starts_with(name, "luaJIT_version_")) { + iter = imports_names.erase(iter); + } + else { + ++iter; + } + } + } + std::list patterns; if (is_export) { Gum::Process::module_enumerate_export(module_name, [&](const Gum::ExportDetails& details) { - if (imports_names.find(details.name) != imports_names.end()) - compiler_pattern(details.name, details.address, patterns); + if (imports_names.find(details.name) != imports_names.end()) { + if (compiler_signature(details.name, details.address, patterns)) { + imports_names.erase(details.name); + } + } return true; }); } else { Gum::Process::module_enumerate_symbols(module_name, [&](const Gum::SymbolDetails& details) { - if (imports_names.find(details.name) != imports_names.end()) - compiler_pattern(details.name, details.address, patterns); + if (imports_names.find(details.name) != imports_names.end()) { + if (compiler_signature(details.name, details.address, patterns)) { + imports_names.erase(details.name); + } + } return true; }); } for (const auto& pattern : patterns) { - std::cout << pattern.name << ":" << pattern.pattern << "-" << pattern.scan_count << std::endl; + std::cout << pattern.name << ":" << pattern.signature.pattern << "(" << (intptr_t)pattern.signature.offset << ")" + << "@" << pattern.hit_offset << std::endl; + } + for (auto name : imports_names) { + std::cerr << "can't find signature: " << name << std::endl; } + return 0; } From fcd627a094ce40d77d05d687dd57fd2048c50de4 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 18 Mar 2023 12:37:38 +0800 Subject: [PATCH 18/69] reset package_json --- compile/common/package_json.lua | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/compile/common/package_json.lua b/compile/common/package_json.lua index 275b5af4b..8670afe9f 100644 --- a/compile/common/package_json.lua +++ b/compile/common/package_json.lua @@ -296,7 +296,7 @@ if OS == "win32" or OS == "darwin" then markdownDescription = "Name of process to attach to.", type = "string", } - json.activationEvents[#json.activationEvents + 1] = "onCommand:extension.lua-debug.pickProcess" + json.activationEvents[#json.activationEvents+1] = "onCommand:extension.lua-debug.pickProcess" json.contributes.debuggers[1].variables = { pickProcess = "extension.lua-debug.pickProcess", } @@ -366,8 +366,7 @@ attributes.launch = { default = { PATH = "${workspaceFolder}", }, - markdownDescription = - "Environment variables passed to the program. The value `null` removes thevariable from the environment.", + markdownDescription = "Environment variables passed to the program. The value `null` removes thevariable from the environment.", type = "object", }, console = { @@ -406,7 +405,7 @@ attributes.launch = { if OS == "win32" or OS == "darwin" then local snippets = json.contributes.debuggers[1].configurationSnippets - snippets[#snippets + 1] = { + snippets[#snippets+1] = { label = "Lua Debug: Launch Process", description = "A new configuration for launching a lua process", body = { @@ -418,7 +417,7 @@ if OS == "win32" or OS == "darwin" then runtimeArgs = "^\"\\${workspaceFolder}/${2:main.lua}\"", } } - snippets[#snippets + 1] = { + snippets[#snippets+1] = { label = "Lua Debug: Attach Process", description = "A new configuration for attaching a lua debug program", body = { @@ -471,7 +470,7 @@ local function SupportedArchs() end end -local Archs = { SupportedArchs() } +local Archs = {SupportedArchs()} attributes.launch.luaArch.default = Archs[1] attributes.launch.luaArch.enum = Archs @@ -480,12 +479,12 @@ for k, v in pairs(attributes.common) do attributes.launch[k] = v end json.contributes.debuggers[1].configurationAttributes = { - launch = { properties = attributes.launch }, - attach = { properties = attributes.attach }, + launch = {properties=attributes.launch}, + attach = {properties=attributes.attach}, } local configuration = json.contributes.configuration.properties -for _, name in ipairs { "luaArch", "luaVersion", "sourceCoding", "path", "cpath", "console" } do +for _, name in ipairs {"luaArch", "luaVersion", "sourceCoding", "path", "cpath","console"} do local attr = attributes.launch[name] or attributes.attach[name] if attr then local cfg = {} @@ -502,4 +501,4 @@ for _, name in ipairs { "luaArch", "luaVersion", "sourceCoding", "path", "cpath" end end -return json +return json \ No newline at end of file From cea9c3c09b91ce52efce0720ed643d3e540fca28 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 18 Mar 2023 14:12:15 +0800 Subject: [PATCH 19/69] reset packgae_json --- compile/common/package_json.lua | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/compile/common/package_json.lua b/compile/common/package_json.lua index 8670afe9f..1b056f7ef 100644 --- a/compile/common/package_json.lua +++ b/compile/common/package_json.lua @@ -252,18 +252,6 @@ Debugger address. }, type = "string", }, - signature = { - default = "null", - type = "object", - markdownDescription = "signature info", - properties = { - module = { - default = "null", - type = "string", - markdownDescription = "lua module path or name", - }, - }, - } } if OS == "win32" then From c085d01c87f16045650f86a376cde7135de300f8 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 18 Mar 2023 14:15:27 +0800 Subject: [PATCH 20/69] reset --- compile/common/package_json.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compile/common/package_json.lua b/compile/common/package_json.lua index 1b056f7ef..e37139bba 100644 --- a/compile/common/package_json.lua +++ b/compile/common/package_json.lua @@ -489,4 +489,4 @@ for _, name in ipairs {"luaArch", "luaVersion", "sourceCoding", "path", "cpath", end end -return json \ No newline at end of file +return json From 710d3fcd44168a65045c9379ecba936cf14574c0 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 18 Mar 2023 14:21:22 +0800 Subject: [PATCH 21/69] reset --- compile/common/package_json.lua | 984 ++++++++++++++++---------------- 1 file changed, 492 insertions(+), 492 deletions(-) diff --git a/compile/common/package_json.lua b/compile/common/package_json.lua index e37139bba..bf9d79e7b 100644 --- a/compile/common/package_json.lua +++ b/compile/common/package_json.lua @@ -1,492 +1,492 @@ -local platform = ... -platform = platform or "unknown-unknown" - -local OS, ARCH = platform:match "^([^-]+)-([^-]+)$" - -local json = { - name = "lua-debug", - version = "1.61.0", - publisher = "actboy168", - displayName = "Lua Debug", - description = "VSCode debugger extension for Lua", - icon = "images/logo.png", - private = true, - author = { - name = "actboy168", - }, - bugs = { - url = "https://github.com/actboy168/lua-debug/issues", - }, - repository = { - type = "git", - url = "https://github.com/actboy168/lua-debug", - }, - keywords = { - "lua", - "debug", - "debuggers", - }, - categories = { - "Debuggers", - }, - engines = { - vscode = "^1.61.0", - }, - extensionKind = { - "workspace", - }, - main = "./js/extension.js", - activationEvents = { - "onCommand:extension.lua-debug.runEditorContents", - "onCommand:extension.lua-debug.debugEditorContents", - "onDebugInitialConfigurations", - "onDebugDynamicConfigurations", - "onDebugResolve:lua", - }, - capabilities = { - untrustedWorkspaces = { - description = "Debugging is disabled in Restricted Mode.", - supported = false, - }, - }, - contributes = { - breakpoints = { - { - language = "lua", - }, - { - language = "html", - }, - }, - commands = { - { - command = "extension.lua-debug.runEditorContents", - icon = "$(play)", - title = "Run File", - }, - { - command = "extension.lua-debug.debugEditorContents", - icon = "$(debug-alt-small)", - title = "Debug File", - }, - { - command = "extension.lua-debug.showIntegerAsDec", - title = "Show as Dec", - }, - { - command = "extension.lua-debug.showIntegerAsHex", - title = "Show as Hex", - }, - }, - configuration = { - properties = { - ["lua.debug.variables.showIntegerAsHex"] = { - default = false, - description = "Show integer as hex.", - type = "boolean", - }, - }, - }, - debuggers = { - { - type = "lua", - languages = { - "lua", - }, - label = "Lua Debug", - configurationSnippets = { - { - label = "Lua Debug: Launch Script", - description = "A new configuration for launching a lua debug program", - body = { - type = "lua", - request = "launch", - name = "${1:launch}", - stopOnEntry = true, - program = "^\"\\${workspaceFolder}/${2:main.lua}\"", - arg = { - }, - }, - }, - { - label = "Lua Debug: Attach", - description = "A new configuration for attaching a lua debug program", - body = { - type = "lua", - request = "attach", - name = "${1:attach}", - stopOnEntry = true, - address = "127.0.0.1:4278", - } - } - } - } - }, - menus = { - ["debug/variables/context"] = { - { - command = "extension.lua-debug.showIntegerAsDec", - group = "1_view", - when = "debugConfigurationType == 'lua' && debugProtocolVariableMenuContext == 'integer/hex'", - }, - { - command = "extension.lua-debug.showIntegerAsHex", - group = "1_view", - when = "debugConfigurationType == 'lua' && debugProtocolVariableMenuContext == 'integer/dec'", - }, - }, - ["editor/title/run"] = { - { - command = "extension.lua-debug.runEditorContents", - when = "resourceLangId == lua", - }, - { - command = "extension.lua-debug.debugEditorContents", - when = "resourceLangId == lua", - }, - }, - }, - }, -} - -local attributes = {} - -attributes.common = { - luaVersion = { - default = "5.4", - enum = { - "5.1", - "5.2", - "5.3", - "5.4", - "latest", - "jit", - }, - markdownDescription = "%lua.debug.launch.luaVersion.description%", - type = "string", - }, - outputCapture = { - default = { - }, - items = { - enum = { - "print", - "io.write", - "stdout", - "stderr", - }, - }, - markdownDescription = "From where to capture output messages: print or stdout/stderr streams.", - type = "array", - }, - pathFormat = { - default = "path", - enum = { - "path", - "linuxpath", - }, - markdownDescription = "Path format", - type = "string", - }, - sourceFormat = { - default = "path", - enum = { - "path", - "string", - "linuxpath", - }, - markdownDescription = "Source format", - type = "string", - }, - sourceMaps = { - default = { - { - "./*", - "${workspaceFolder}/*", - }, - }, - markdownDescription = "The source path of the remote host and the source path of local.", - type = "array", - }, - skipFiles = { - default = { - }, - items = { - type = "string", - }, - markdownDescription = "An array of glob patterns for files to skip when debugging.", - type = "array", - }, - stopOnEntry = { - default = false, - markdownDescription = "Automatically stop after entry.", - type = "boolean", - }, - stopOnThreadEntry = { - default = true, - markdownDescription = "Automatically stop after thread entry.", - type = "boolean", - }, - address = { - default = "127.0.0.1:4278", - markdownDescription = [[ -Debugger address. -1. IPv4 e.g. `127.0.0.1:4278` -2. IPv6 e.g. `[::1]:4278` -3. Unix domain socket e.g. `@c:\\unix.sock`]], - type = { - "string", - "null", - }, - }, - client = { - default = true, - markdownDescription = "Choose whether to `connect` or `listen`.", - type = "boolean", - }, - inject = { - default = "none", - markdownDescription = "How to inject debugger.", - enum = { - "none", - }, - type = "string", - }, -} - -if OS == "win32" then - attributes.common.inject.default = "hook" - table.insert(attributes.common.inject.enum, "hook") -elseif OS == "darwin" then - attributes.common.inject.default = "lldb" - table.insert(attributes.common.inject.enum, "hook") - table.insert(attributes.common.inject.enum, "lldb") - attributes.common.inject_executable = { - markdownDescription = "inject executable path", - type = { - "string", - "null", - }, - } -end - -attributes.attach = { -} - -if OS == "win32" or OS == "darwin" then - attributes.attach.processId = { - default = "${command:pickProcess}", - markdownDescription = "Id of process to attach to.", - type = "string", - } - attributes.attach.processName = { - default = "lua.exe", - markdownDescription = "Name of process to attach to.", - type = "string", - } - json.activationEvents[#json.activationEvents+1] = "onCommand:extension.lua-debug.pickProcess" - json.contributes.debuggers[1].variables = { - pickProcess = "extension.lua-debug.pickProcess", - } -end - -attributes.launch = { - luaexe = { - markdownDescription = "Absolute path to the lua exe.", - type = "string", - }, - program = { - default = "${workspaceFolder}/main.lua", - markdownDescription = "Lua program to debug - set this to the path of the script", - type = "string", - }, - arg = { - default = { - }, - markdownDescription = "Command line argument, arg[1] ... arg[n]", - type = "array", - }, - arg0 = { - default = { - }, - markdownDescription = "Command line argument, arg[-n] ... arg[0]", - type = { - "string", - "array", - }, - }, - path = { - default = "${workspaceFolder}/?.lua", - markdownDescription = "%lua.debug.launch.path.description%", - type = { - "string", - "array", - "null", - }, - }, - cpath = { - markdownDescription = "%lua.debug.launch.cpath.description%", - type = { - "string", - "array", - "null", - }, - }, - luaArch = { - markdownDescription = "%lua.debug.launch.luaArch.description%", - type = "string", - }, - cwd = { - default = "${workspaceFolder}", - markdownDescription = "Working directory at program startup", - type = { - "string", - "null", - }, - }, - env = { - additionalProperties = { - type = { - "string", - "null", - }, - }, - default = { - PATH = "${workspaceFolder}", - }, - markdownDescription = "Environment variables passed to the program. The value `null` removes thevariable from the environment.", - type = "object", - }, - console = { - default = "integratedTerminal", - enum = { - "internalConsole", - "integratedTerminal", - "externalTerminal", - }, - enummarkdownDescriptions = { - "%lua.debug.launch.console.internalConsole.description%", - "%lua.debug.launch.console.integratedTerminal.description%", - "%lua.debug.launch.console.externalTerminal.description%", - }, - markdownDescription = "%lua.debug.launch.console.description%", - type = "string", - }, - runtimeExecutable = { - default = OS == "win32" and "${workspaceFolder}/lua.exe" or "${workspaceFolder}/lua", - markdownDescription = "Runtime to use. Either an absolute path or the name of a runtime availableon the PATH.", - type = { - "string", - "null", - }, - }, - runtimeArgs = { - default = "${workspaceFolder}/main.lua", - markdownDescription = "Arguments passed to the runtime executable.", - type = { - "string", - "array", - "null", - }, - }, -} - -if OS == "win32" or OS == "darwin" then - local snippets = json.contributes.debuggers[1].configurationSnippets - snippets[#snippets+1] = { - label = "Lua Debug: Launch Process", - description = "A new configuration for launching a lua process", - body = { - type = "lua", - request = "launch", - name = "${1:launch process}", - stopOnEntry = true, - runtimeExecutable = "^\"\\${workspaceFolder}/lua.exe\"", - runtimeArgs = "^\"\\${workspaceFolder}/${2:main.lua}\"", - } - } - snippets[#snippets+1] = { - label = "Lua Debug: Attach Process", - description = "A new configuration for attaching a lua debug program", - body = { - type = "lua", - request = "attach", - name = "${1:attach}", - stopOnEntry = true, - processId = "^\"\\${command:pickProcess}\"", - } - } -end - -if OS == "win32" then - attributes.common.sourceCoding = { - default = "utf8", - enum = { - "utf8", - "ansi", - }, - markdownDescription = "%lua.debug.launch.sourceCoding.description%", - type = "string", - } - attributes.common.useWSL = { - default = true, - description = "Use Windows Subsystem for Linux.", - type = "boolean", - } - attributes.launch.luaexe.default = "${workspaceFolder}/lua.exe" - attributes.launch.cpath.default = "${workspaceFolder}/?.dll" -else - attributes.launch.luaexe.default = "${workspaceFolder}/lua" - attributes.launch.cpath.default = "${workspaceFolder}/?.so" -end - -local function SupportedArchs() - if OS == "win32" then - return "x86_64", "x86" - elseif OS == "darwin" then - if ARCH == "arm64" then - return "arm64", "x86_64" - else - return "x86_64" - end - elseif OS == "linux" then - if ARCH == "arm64" then - return "arm64" - else - return "x86_64" - end - end -end - -local Archs = {SupportedArchs()} -attributes.launch.luaArch.default = Archs[1] -attributes.launch.luaArch.enum = Archs - -for k, v in pairs(attributes.common) do - attributes.attach[k] = v - attributes.launch[k] = v -end -json.contributes.debuggers[1].configurationAttributes = { - launch = {properties=attributes.launch}, - attach = {properties=attributes.attach}, -} - -local configuration = json.contributes.configuration.properties -for _, name in ipairs {"luaArch", "luaVersion", "sourceCoding", "path", "cpath","console"} do - local attr = attributes.launch[name] or attributes.attach[name] - if attr then - local cfg = {} - for k, v in pairs(attr) do - if k == 'markdownDescription' then - k = 'description' - end - if k == 'enummarkdownDescriptions' then - k = 'enumDescriptions' - end - cfg[k] = v - end - configuration["lua.debug.settings."..name] = cfg - end -end - -return json +local platform = ... +platform = platform or "unknown-unknown" + +local OS, ARCH = platform:match "^([^-]+)-([^-]+)$" + +local json = { + name = "lua-debug", + version = "1.61.0", + publisher = "actboy168", + displayName = "Lua Debug", + description = "VSCode debugger extension for Lua", + icon = "images/logo.png", + private = true, + author = { + name = "actboy168", + }, + bugs = { + url = "https://github.com/actboy168/lua-debug/issues", + }, + repository = { + type = "git", + url = "https://github.com/actboy168/lua-debug", + }, + keywords = { + "lua", + "debug", + "debuggers", + }, + categories = { + "Debuggers", + }, + engines = { + vscode = "^1.61.0", + }, + extensionKind = { + "workspace", + }, + main = "./js/extension.js", + activationEvents = { + "onCommand:extension.lua-debug.runEditorContents", + "onCommand:extension.lua-debug.debugEditorContents", + "onDebugInitialConfigurations", + "onDebugDynamicConfigurations", + "onDebugResolve:lua", + }, + capabilities = { + untrustedWorkspaces = { + description = "Debugging is disabled in Restricted Mode.", + supported = false, + }, + }, + contributes = { + breakpoints = { + { + language = "lua", + }, + { + language = "html", + }, + }, + commands = { + { + command = "extension.lua-debug.runEditorContents", + icon = "$(play)", + title = "Run File", + }, + { + command = "extension.lua-debug.debugEditorContents", + icon = "$(debug-alt-small)", + title = "Debug File", + }, + { + command = "extension.lua-debug.showIntegerAsDec", + title = "Show as Dec", + }, + { + command = "extension.lua-debug.showIntegerAsHex", + title = "Show as Hex", + }, + }, + configuration = { + properties = { + ["lua.debug.variables.showIntegerAsHex"] = { + default = false, + description = "Show integer as hex.", + type = "boolean", + }, + }, + }, + debuggers = { + { + type = "lua", + languages = { + "lua", + }, + label = "Lua Debug", + configurationSnippets = { + { + label = "Lua Debug: Launch Script", + description = "A new configuration for launching a lua debug program", + body = { + type = "lua", + request = "launch", + name = "${1:launch}", + stopOnEntry = true, + program = "^\"\\${workspaceFolder}/${2:main.lua}\"", + arg = { + }, + }, + }, + { + label = "Lua Debug: Attach", + description = "A new configuration for attaching a lua debug program", + body = { + type = "lua", + request = "attach", + name = "${1:attach}", + stopOnEntry = true, + address = "127.0.0.1:4278", + } + } + } + } + }, + menus = { + ["debug/variables/context"] = { + { + command = "extension.lua-debug.showIntegerAsDec", + group = "1_view", + when = "debugConfigurationType == 'lua' && debugProtocolVariableMenuContext == 'integer/hex'", + }, + { + command = "extension.lua-debug.showIntegerAsHex", + group = "1_view", + when = "debugConfigurationType == 'lua' && debugProtocolVariableMenuContext == 'integer/dec'", + }, + }, + ["editor/title/run"] = { + { + command = "extension.lua-debug.runEditorContents", + when = "resourceLangId == lua", + }, + { + command = "extension.lua-debug.debugEditorContents", + when = "resourceLangId == lua", + }, + }, + }, + }, +} + +local attributes = {} + +attributes.common = { + luaVersion = { + default = "5.4", + enum = { + "5.1", + "5.2", + "5.3", + "5.4", + "latest", + "jit", + }, + markdownDescription = "%lua.debug.launch.luaVersion.description%", + type = "string", + }, + outputCapture = { + default = { + }, + items = { + enum = { + "print", + "io.write", + "stdout", + "stderr", + }, + }, + markdownDescription = "From where to capture output messages: print or stdout/stderr streams.", + type = "array", + }, + pathFormat = { + default = "path", + enum = { + "path", + "linuxpath", + }, + markdownDescription = "Path format", + type = "string", + }, + sourceFormat = { + default = "path", + enum = { + "path", + "string", + "linuxpath", + }, + markdownDescription = "Source format", + type = "string", + }, + sourceMaps = { + default = { + { + "./*", + "${workspaceFolder}/*", + }, + }, + markdownDescription = "The source path of the remote host and the source path of local.", + type = "array", + }, + skipFiles = { + default = { + }, + items = { + type = "string", + }, + markdownDescription = "An array of glob patterns for files to skip when debugging.", + type = "array", + }, + stopOnEntry = { + default = false, + markdownDescription = "Automatically stop after entry.", + type = "boolean", + }, + stopOnThreadEntry = { + default = true, + markdownDescription = "Automatically stop after thread entry.", + type = "boolean", + }, + address = { + default = "127.0.0.1:4278", + markdownDescription = [[ +Debugger address. +1. IPv4 e.g. `127.0.0.1:4278` +2. IPv6 e.g. `[::1]:4278` +3. Unix domain socket e.g. `@c:\\unix.sock`]], + type = { + "string", + "null", + }, + }, + client = { + default = true, + markdownDescription = "Choose whether to `connect` or `listen`.", + type = "boolean", + }, + inject = { + default = "none", + markdownDescription = "How to inject debugger.", + enum = { + "none", + }, + type = "string", + }, +} + +if OS == "win32" then + attributes.common.inject.default = "hook" + table.insert(attributes.common.inject.enum, "hook") +elseif OS == "darwin" then + attributes.common.inject.default = "lldb" + table.insert(attributes.common.inject.enum, "hook") + table.insert(attributes.common.inject.enum, "lldb") + attributes.common.inject_executable = { + markdownDescription = "inject executable path", + type = { + "string", + "null", + }, + } +end + +attributes.attach = { +} + +if OS == "win32" or OS == "darwin" then + attributes.attach.processId = { + default = "${command:pickProcess}", + markdownDescription = "Id of process to attach to.", + type = "string", + } + attributes.attach.processName = { + default = "lua.exe", + markdownDescription = "Name of process to attach to.", + type = "string", + } + json.activationEvents[#json.activationEvents+1] = "onCommand:extension.lua-debug.pickProcess" + json.contributes.debuggers[1].variables = { + pickProcess = "extension.lua-debug.pickProcess", + } +end + +attributes.launch = { + luaexe = { + markdownDescription = "Absolute path to the lua exe.", + type = "string", + }, + program = { + default = "${workspaceFolder}/main.lua", + markdownDescription = "Lua program to debug - set this to the path of the script", + type = "string", + }, + arg = { + default = { + }, + markdownDescription = "Command line argument, arg[1] ... arg[n]", + type = "array", + }, + arg0 = { + default = { + }, + markdownDescription = "Command line argument, arg[-n] ... arg[0]", + type = { + "string", + "array", + }, + }, + path = { + default = "${workspaceFolder}/?.lua", + markdownDescription = "%lua.debug.launch.path.description%", + type = { + "string", + "array", + "null", + }, + }, + cpath = { + markdownDescription = "%lua.debug.launch.cpath.description%", + type = { + "string", + "array", + "null", + }, + }, + luaArch = { + markdownDescription = "%lua.debug.launch.luaArch.description%", + type = "string", + }, + cwd = { + default = "${workspaceFolder}", + markdownDescription = "Working directory at program startup", + type = { + "string", + "null", + }, + }, + env = { + additionalProperties = { + type = { + "string", + "null", + }, + }, + default = { + PATH = "${workspaceFolder}", + }, + markdownDescription = "Environment variables passed to the program. The value `null` removes thevariable from the environment.", + type = "object", + }, + console = { + default = "integratedTerminal", + enum = { + "internalConsole", + "integratedTerminal", + "externalTerminal", + }, + enummarkdownDescriptions = { + "%lua.debug.launch.console.internalConsole.description%", + "%lua.debug.launch.console.integratedTerminal.description%", + "%lua.debug.launch.console.externalTerminal.description%", + }, + markdownDescription = "%lua.debug.launch.console.description%", + type = "string", + }, + runtimeExecutable = { + default = OS == "win32" and "${workspaceFolder}/lua.exe" or "${workspaceFolder}/lua", + markdownDescription = "Runtime to use. Either an absolute path or the name of a runtime availableon the PATH.", + type = { + "string", + "null", + }, + }, + runtimeArgs = { + default = "${workspaceFolder}/main.lua", + markdownDescription = "Arguments passed to the runtime executable.", + type = { + "string", + "array", + "null", + }, + }, +} + +if OS == "win32" or OS == "darwin" then + local snippets = json.contributes.debuggers[1].configurationSnippets + snippets[#snippets+1] = { + label = "Lua Debug: Launch Process", + description = "A new configuration for launching a lua process", + body = { + type = "lua", + request = "launch", + name = "${1:launch process}", + stopOnEntry = true, + runtimeExecutable = "^\"\\${workspaceFolder}/lua.exe\"", + runtimeArgs = "^\"\\${workspaceFolder}/${2:main.lua}\"", + } + } + snippets[#snippets+1] = { + label = "Lua Debug: Attach Process", + description = "A new configuration for attaching a lua debug program", + body = { + type = "lua", + request = "attach", + name = "${1:attach}", + stopOnEntry = true, + processId = "^\"\\${command:pickProcess}\"", + } + } +end + +if OS == "win32" then + attributes.common.sourceCoding = { + default = "utf8", + enum = { + "utf8", + "ansi", + }, + markdownDescription = "%lua.debug.launch.sourceCoding.description%", + type = "string", + } + attributes.common.useWSL = { + default = true, + description = "Use Windows Subsystem for Linux.", + type = "boolean", + } + attributes.launch.luaexe.default = "${workspaceFolder}/lua.exe" + attributes.launch.cpath.default = "${workspaceFolder}/?.dll" +else + attributes.launch.luaexe.default = "${workspaceFolder}/lua" + attributes.launch.cpath.default = "${workspaceFolder}/?.so" +end + +local function SupportedArchs() + if OS == "win32" then + return "x86_64", "x86" + elseif OS == "darwin" then + if ARCH == "arm64" then + return "arm64", "x86_64" + else + return "x86_64" + end + elseif OS == "linux" then + if ARCH == "arm64" then + return "arm64" + else + return "x86_64" + end + end +end + +local Archs = {SupportedArchs()} +attributes.launch.luaArch.default = Archs[1] +attributes.launch.luaArch.enum = Archs + +for k, v in pairs(attributes.common) do + attributes.attach[k] = v + attributes.launch[k] = v +end +json.contributes.debuggers[1].configurationAttributes = { + launch = {properties=attributes.launch}, + attach = {properties=attributes.attach}, +} + +local configuration = json.contributes.configuration.properties +for _, name in ipairs {"luaArch", "luaVersion", "sourceCoding", "path", "cpath","console"} do + local attr = attributes.launch[name] or attributes.attach[name] + if attr then + local cfg = {} + for k, v in pairs(attr) do + if k == 'markdownDescription' then + k = 'description' + end + if k == 'enummarkdownDescriptions' then + k = 'enumDescriptions' + end + cfg[k] = v + end + configuration["lua.debug.settings."..name] = cfg + end +end + +return json From 56628cc4d2dc589bf52e38b95c4beaec0b6da7f7 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 18 Mar 2023 14:54:35 +0800 Subject: [PATCH 22/69] add module --- compile/common/package_json.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compile/common/package_json.lua b/compile/common/package_json.lua index bf9d79e7b..50eb10215 100644 --- a/compile/common/package_json.lua +++ b/compile/common/package_json.lua @@ -252,6 +252,11 @@ Debugger address. }, type = "string", }, + module = { + defualt = "null", + markdownDescription = "specify lua module path/name", + type = "string", + } } if OS == "win32" then From e2fa78d1ef28d3c56f48e5aa368ad4a80e078c44 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 18 Mar 2023 14:54:51 +0800 Subject: [PATCH 23/69] update gumpp --- 3rd/frida_gum/gumpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index 54ad1d5a6..041cd4819 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit 54ad1d5a6c8d4856f1db0a3899625a2370b1ca19 +Subproject commit 041cd48199564415da68431d83340c6df2f1112f From ca1fcc06ef108449ca5246e54abe1eefb36b07f4 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 18 Mar 2023 14:55:32 +0800 Subject: [PATCH 24/69] remove signature --- extension/js/configurationProvider.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/extension/js/configurationProvider.js b/extension/js/configurationProvider.js index b6e6cea23..d5a6b5e87 100644 --- a/extension/js/configurationProvider.js +++ b/extension/js/configurationProvider.js @@ -243,9 +243,6 @@ function resolveConfig(folder, config) { throw new Error('Missing `address` to debug'); } } - if (config.signature != null) { - config.signature.version = config.luaVersion - } config.configuration = { variables: vscode.workspace.getConfiguration("lua.debug.variables") } From 1968158af01089cedb702e7d99bb407ed6b7ab86 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 18 Mar 2023 14:58:34 +0800 Subject: [PATCH 25/69] remove ipc_send_latest --- extension/script/frontend/proxy.lua | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/extension/script/frontend/proxy.lua b/extension/script/frontend/proxy.lua index df4f48fce..e098be924 100644 --- a/extension/script/frontend/proxy.lua +++ b/extension/script/frontend/proxy.lua @@ -16,18 +16,14 @@ local function getUnixAddress(pid) return "@"..(path / ("pid_%d"):format(pid)):string() end -local function ipc_send_latest(pid) - fs.create_directories(WORKDIR / "tmp") - local ipc = require "common.ipc" - local fd = assert(ipc(WORKDIR, pid, "luaVersion", "w")) - fd:write("latest") - fd:close() -end - -local function ipc_send_config(pid, config) +local function ipc_send_config(pid, args) fs.create_directories(WORKDIR / "tmp") local ipc = require "common.ipc" local fd = assert(ipc(WORKDIR, pid, "config", "w")) + local config = { + version = args.luaVersion, + module = args.module + } fd:write(json.encode(config)) fd:close() end @@ -65,10 +61,7 @@ end local function attach_process(pkg, pid) local args = pkg.arguments - if args.luaVersion == "latest" then - ipc_send_latest(pid) - end - ipc_send_config(pid, args.signature) + ipc_send_config(pid, args) local ok, errmsg = process_inject.inject(pid, "attach", args) if not ok then return false, errmsg @@ -173,10 +166,7 @@ local function proxy_launch_console(pkg) server, address = create_server(args, process:get_id()) if type(address) == "number" then - if args.luaVersion == "latest" then - ipc_send_latest(address) - end - ipc_send_config(address, args.signature) + ipc_send_config(address, args) end end) if not process then From 2c569d218dfb1de6fe249746a1d72837ec9b9491 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 18 Mar 2023 15:23:21 +0800 Subject: [PATCH 26/69] pass version to luadebug --- extension/script/attach.lua | 21 +++++------- extension/script/debugger.lua | 45 +++++++++++++++---------- src/launcher/autoattach/autoattach.cpp | 4 +-- src/launcher/autoattach/autoattach.h | 3 +- src/launcher/autoattach/lua_module.cpp | 17 ---------- src/launcher/autoattach/lua_module.h | 8 ----- src/launcher/autoattach/lua_version.cpp | 33 ++++++++++++++++++ src/launcher/autoattach/lua_version.h | 14 ++++++++ src/launcher/config/config.cpp | 14 -------- src/launcher/hook/create_watchdog.cpp | 2 ++ src/launcher/hook/watchdog.cpp | 2 +- src/launcher/hook/watchdog.h | 2 ++ src/launcher/main.cpp | 13 ++++--- 13 files changed, 98 insertions(+), 80 deletions(-) create mode 100644 src/launcher/autoattach/lua_version.cpp create mode 100644 src/launcher/autoattach/lua_version.h diff --git a/extension/script/attach.lua b/extension/script/attach.lua index da30f4935..7f85417ff 100644 --- a/extension/script/attach.lua +++ b/extension/script/attach.lua @@ -1,4 +1,4 @@ -local path, pid = ... +local path, pid, version = ... if _VERSION == nil or type == nil or assert == nil @@ -19,6 +19,10 @@ if is_luajit and jit == nil then return "wait initialized" end +if version == "" then + version = nil +end + local function dofile(filename, ...) local load = _VERSION == "Lua 5.1" and loadstring or load local f = assert(io.open(filename)) @@ -26,20 +30,11 @@ local function dofile(filename, ...) f:close() return assert(load(str, "=(debugger.lua)"))(...) end -local function isLatest() - local ipc = dofile(path.."/script/common/ipc.lua") - local fd = ipc(path, pid, "luaVersion") - local result = false - if fd then - result = "latest" == fd:read "a" - fd:close() - end - return result -end + local dbg = dofile(path.."/script/debugger.lua", path) dbg:start { address = ("@%s/tmp/pid_%s"):format(path, pid), - latest = isLatest(), + version = version, } dbg:event "wait" -return "ok" \ No newline at end of file +return "ok" diff --git a/extension/script/debugger.lua b/extension/script/debugger.lua index b3b495ee2..5b264026e 100644 --- a/extension/script/debugger.lua +++ b/extension/script/debugger.lua @@ -101,26 +101,37 @@ local function detectLuaDebugPath(cfg) end end - local rt = "/runtime/"..PLATFORM - if cfg.latest then - rt = rt.."/lua-latest" - elseif _VERSION == "Lua 5.4" then - rt = rt.."/lua54" - elseif _VERSION == "Lua 5.3" then - rt = rt.."/lua53" - elseif _VERSION == "Lua 5.2" then - rt = rt.."/lua52" - elseif _VERSION == "Lua 5.1" then - if (tostring(assert):match('builtin') ~= nil) then - rt = rt.."/luajit" - jit.off() - else - rt = rt.."/lua51" + local function get_luadebug_dir() + local version = cfg.version + if not version then + if tostring(assert):match('builtin') ~= nil then + version = "jit" + jit.off() + else + version = _VERSION + end end - else - error(_VERSION.." is not supported.") + + local t = { + ["Lua 5.4"] = "lua54", + ["Lua 5.3"] = "lua53", + ["Lua 5.2"] = "lua52", + ["Lua 5.1"] = "lua51", + latest = "lua-latest", + ["5.4"] = "lua54", + ["5.3"] = "lua53", + ["5.2"] = "lua52", + ["5.1"] = "lua51", + ["jit"] = "luajit", + } + if not t[version] then + error(_VERSION.." is not supported.") + end + return t[version] end + local rt = "/runtime/"..PLATFORM.."/"..get_luadebug_dir() + local ext = isWindows() and "dll" or "so" return root..rt..'/luadebug.'..ext end diff --git a/src/launcher/autoattach/autoattach.cpp b/src/launcher/autoattach/autoattach.cpp index 2449d9b87..5ff873517 100644 --- a/src/launcher/autoattach/autoattach.cpp +++ b/src/launcher/autoattach/autoattach.cpp @@ -31,8 +31,8 @@ namespace luadebug::autoattach { return false; } - attach_status attach_lua_vm(lua::state L) { - return debuggerAttach(L); + attach_status attach_lua_vm(lua::state L, lua_version version) { + return debuggerAttach(L, version); } void start() { diff --git a/src/launcher/autoattach/autoattach.h b/src/launcher/autoattach/autoattach.h index 05df43ef8..184a349f4 100644 --- a/src/launcher/autoattach/autoattach.h +++ b/src/launcher/autoattach/autoattach.h @@ -1,5 +1,6 @@ #pragma once +#include #include namespace luadebug::autoattach { @@ -8,6 +9,6 @@ namespace luadebug::autoattach { fatal, wait, }; - typedef attach_status (*fn_attach)(lua::state L); + typedef attach_status (*fn_attach)(lua::state L, lua_version verison); void initialize(fn_attach attach, bool ap); } diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index bde7ed96b..f8e0e7609 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -9,23 +9,6 @@ #include namespace luadebug::autoattach { - static const char* lua_version_to_string(lua_version v) { - switch (v) { - case lua_version::lua51: - return "lua51"; - case lua_version::lua52: - return "lua52"; - case lua_version::lua53: - return "lua53"; - case lua_version::lua54: - return "lua54"; - case lua_version::luajit: - return "luajit"; - default: - return "unknown"; - } - } - static bool in_module(const lua_module& m, void* addr) { return addr >= m.memory_address && addr <= (void*)((intptr_t)m.memory_address + m.memory_size); } diff --git a/src/launcher/autoattach/lua_module.h b/src/launcher/autoattach/lua_module.h index 23397c3c4..317379cde 100644 --- a/src/launcher/autoattach/lua_module.h +++ b/src/launcher/autoattach/lua_module.h @@ -7,14 +7,6 @@ namespace luadebug::autoattach { struct watchdog; - enum class lua_version { - unknown, - luajit, - lua51, - lua52, - lua53, - lua54, - }; struct lua_module { std::string path; std::string name; diff --git a/src/launcher/autoattach/lua_version.cpp b/src/launcher/autoattach/lua_version.cpp new file mode 100644 index 000000000..d6d12ba0e --- /dev/null +++ b/src/launcher/autoattach/lua_version.cpp @@ -0,0 +1,33 @@ +#include + +namespace luadebug::autoattach { + const char* lua_version_to_string(lua_version v) { + switch (v) { + case lua_version::lua51: + return "lua51"; + case lua_version::lua52: + return "lua52"; + case lua_version::lua53: + return "lua53"; + case lua_version::lua54: + return "lua54"; + case lua_version::luajit: + return "luajit"; + default: + return "unknown"; + } + } + lua_version lua_version_from_string(const std::string_view& v) { + if (v == "jit" || v == "luajit") + return lua_version::luajit; + else if (v == "5.1" || v == "lua51") + return lua_version::lua51; + else if (v == "5.2" || v == "lua52") + return lua_version::lua52; + else if (v == "5.3" || v == "lua53") + return lua_version::lua53; + else if (v == "5.4" || v == "lua54") + return lua_version::lua54; + return lua_version::unknown; + } +} \ No newline at end of file diff --git a/src/launcher/autoattach/lua_version.h b/src/launcher/autoattach/lua_version.h new file mode 100644 index 000000000..1797b3338 --- /dev/null +++ b/src/launcher/autoattach/lua_version.h @@ -0,0 +1,14 @@ +#pragma once +#include +namespace luadebug::autoattach { + enum class lua_version { + unknown, + luajit, + lua51, + lua52, + lua53, + lua54, + }; + const char* lua_version_to_string(lua_version v); + lua_version lua_version_from_string(const std::string_view& v); +} \ No newline at end of file diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index 662d7d410..ccad7baa2 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -12,20 +12,6 @@ using namespace std::string_view_literals; namespace luadebug::autoattach { - static lua_version lua_version_from_string [[maybe_unused]] (const std::string_view& v) { - if (v == "jit" || v == "luajit") - return lua_version::luajit; - else if (v == "5.1" || v == "lua51") - return lua_version::lua51; - else if (v == "5.2" || v == "lua52") - return lua_version::lua52; - else if (v == "5.3" || v == "lua53") - return lua_version::lua53; - else if (v == "5.4" || v == "lua54") - return lua_version::lua54; - return lua_version::unknown; - } - Config config; lua_version Config::get_lua_version() const { diff --git a/src/launcher/hook/create_watchdog.cpp b/src/launcher/hook/create_watchdog.cpp index e62dcef1c..d0a2ed1e8 100644 --- a/src/launcher/hook/create_watchdog.cpp +++ b/src/launcher/hook/create_watchdog.cpp @@ -53,6 +53,7 @@ namespace luadebug::autoattach { if (context->init(resolver, get_watch_points(version))) { // TODO: fix other thread pc context->hook(); + context->version = version; return context; } if (version == lua_version::unknown) { @@ -61,6 +62,7 @@ namespace luadebug::autoattach { if (context->init(resolver, get_watch_points(lua_version::unknown))) { // TODO: fix other thread pc context->hook(); + context->version = version; return context; } return nullptr; diff --git a/src/launcher/hook/watchdog.cpp b/src/launcher/hook/watchdog.cpp index 83271c52f..d84ae0e5e 100644 --- a/src/launcher/hook/watchdog.cpp +++ b/src/launcher/hook/watchdog.cpp @@ -116,7 +116,7 @@ namespace luadebug::autoattach { void watchdog::attach_lua(lua::state L, lua::debug ar, lua::hook fn) { reset_luahook(L, ar); - switch (attach_lua_vm(L)) { + switch (attach_lua_vm(L, version)) { case attach_status::fatal: case attach_status::success: // TODO: how to free so diff --git a/src/launcher/hook/watchdog.h b/src/launcher/hook/watchdog.h index dbc8cf71f..11d984b99 100644 --- a/src/launcher/hook/watchdog.h +++ b/src/launcher/hook/watchdog.h @@ -38,5 +38,7 @@ namespace luadebug::autoattach { int origin_hookmask; int origin_hookcount; fn_attach attach_lua_vm; + public: + lua_version version; }; } diff --git a/src/launcher/main.cpp b/src/launcher/main.cpp index b99d9342e..e05430696 100644 --- a/src/launcher/main.cpp +++ b/src/launcher/main.cpp @@ -11,6 +11,7 @@ # define DLLEXPORT __declspec(dllexport) # define DLLEXPORT_DECLARATION __cdecl #endif +#include #include #include @@ -34,7 +35,7 @@ namespace luadebug::autoattach { return tmp; } - static attach_status attach(lua::state L) { + static attach_status attach(lua::state L, lua_version verison) { log::info("attach lua vm entry"); auto r = bee::path_helper::dll_path(); if (!r) { @@ -49,12 +50,10 @@ namespace luadebug::autoattach { return attach_status::fatal; } lua::call(L, root.generic_u8string().c_str()); -#ifdef _WIN32 - lua::call(L, std::to_string(GetCurrentProcessId()).c_str()); -#else - lua::call(L, std::to_string(getpid()).c_str()); -#endif - if (lua::pcall(L, 2, 1, 0)) { + lua::call(L, std::to_string(Gum::Process::get_id()).c_str()); + lua::call(L, verison == lua_version::unknown ? "" : lua_version_to_string(verison)); + + if (lua::pcall(L, 3, 1, 0)) { /* 这里失败无法调用log::fatal,因为无法知道调试器已经加载到哪一步才失败的。 所以调试器不应该把错误抛到这里。 From 6dccc088a683b76887638a643cb202a971a1a9b4 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 18 Mar 2023 15:26:53 +0800 Subject: [PATCH 27/69] fix format --- src/launcher/hook/watchdog.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/launcher/hook/watchdog.h b/src/launcher/hook/watchdog.h index 11d984b99..986df44d5 100644 --- a/src/launcher/hook/watchdog.h +++ b/src/launcher/hook/watchdog.h @@ -38,6 +38,7 @@ namespace luadebug::autoattach { int origin_hookmask; int origin_hookcount; fn_attach attach_lua_vm; + public: lua_version version; }; From 5738af299e237c4f041f83e0bdb4d20f40ea1c89 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 18 Mar 2023 16:04:06 +0800 Subject: [PATCH 28/69] force load_luadebug_dll --- src/launcher/autoattach/lua_module.cpp | 42 ++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index f8e0e7609..f37d1135a 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -62,6 +62,45 @@ namespace luadebug::autoattach { } } + bool load_luadebug_dll(lua_version version) { + if (version != lua_version::unknown) + return false; + + auto dllpath = bee::path_helper::dll_path(); + if (!dllpath) { + return false; + } + auto os = +#if defined(_WIN32) + "windows" +#elif defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) + "darwin" +#else + ; + return false; +#endif + ; + auto arch = +#if defined(_M_ARM64) || defined(__aarch64__) + "arm64" +#elif defined(_M_IX86) || defined(__i386__) + "x86" +#elif defined(_M_X64) || defined(__x86_64__) + "x86_64" +#else + ; + return false; +#endif + ; + auto platform = std::format("{}-{}", os, arch); + auto path = dllpath.value().parent_path().parent_path() / "runtime" / platform / lua_version_to_string(version); + std::string error; + if (!Gum::Process::module_load(path.c_str(), &error)) { + log::fatal("load remotedebug dll failed: {}", error); + } + return true; + } + bool lua_module::initialize(fn_attach attach_lua_vm) { resolver.module_name = path; auto error_msg = lua::initialize(resolver); @@ -72,6 +111,9 @@ namespace luadebug::autoattach { version = get_lua_version(*this); log::info("current lua version: {}", lua_version_to_string(version)); + if (!load_luadebug_dll(version)) { + return false; + } watchdog = create_watchdog(attach_lua_vm, version, resolver); if (!watchdog) { // TODO: more errmsg From fb0659f5c10b92a4fd9e0f8e6cb380c5b3ca3d12 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 18 Mar 2023 20:30:34 +0800 Subject: [PATCH 29/69] fix build error --- src/launcher/autoattach/lua_module.cpp | 2 +- src/launcher/main.cpp | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index f37d1135a..54abbe6a9 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -93,7 +93,7 @@ namespace luadebug::autoattach { #endif ; auto platform = std::format("{}-{}", os, arch); - auto path = dllpath.value().parent_path().parent_path() / "runtime" / platform / lua_version_to_string(version); + auto path = (dllpath.value().parent_path().parent_path() / "runtime" / platform / lua_version_to_string(version)).string(); std::string error; if (!Gum::Process::module_load(path.c_str(), &error)) { log::fatal("load remotedebug dll failed: {}", error); diff --git a/src/launcher/main.cpp b/src/launcher/main.cpp index e05430696..67aa0a502 100644 --- a/src/launcher/main.cpp +++ b/src/launcher/main.cpp @@ -3,11 +3,9 @@ #include #include #ifndef _WIN32 -# include # define DLLEXPORT __attribute__((visibility("default"))) # define DLLEXPORT_DECLARATION #else -# include # define DLLEXPORT __declspec(dllexport) # define DLLEXPORT_DECLARATION __cdecl #endif @@ -16,9 +14,9 @@ #include namespace luadebug::autoattach { - static std::string readfile(const fs::path& filename) { + static std::string readfile(const fs::path &filename) { #ifdef _WIN32 - FILE* f = _wfopen(filename.c_str(), L"rb"); + FILE *f = _wfopen(filename.c_str(), L"rb"); #else FILE* f = fopen(filename.c_str(), "rb"); #endif @@ -43,7 +41,7 @@ namespace luadebug::autoattach { return attach_status::fatal; } auto root = r.value().parent_path().parent_path(); - auto buf = readfile(root / "script" / "attach.lua"); + auto buf = readfile(root / "script" / "attach.lua"); if (lua::loadbuffer(L, buf.data(), buf.size(), "=(attach.lua)")) { log::fatal("load attach.lua error: {}", lua::tostring(L, -1)); lua::pop(L, 1); From 9054deee1f08af58c6cf4fd252fb55f2e917d8ea Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 18 Mar 2023 21:16:11 +0800 Subject: [PATCH 30/69] format --- src/launcher/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/launcher/main.cpp b/src/launcher/main.cpp index 67aa0a502..f57e82920 100644 --- a/src/launcher/main.cpp +++ b/src/launcher/main.cpp @@ -2,6 +2,7 @@ #include #include #include + #ifndef _WIN32 # define DLLEXPORT __attribute__((visibility("default"))) # define DLLEXPORT_DECLARATION @@ -9,6 +10,7 @@ # define DLLEXPORT __declspec(dllexport) # define DLLEXPORT_DECLARATION __cdecl #endif + #include #include #include From e728a3b4857f14807e2cf0670dfe331cdc873db0 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 18 Mar 2023 21:22:47 +0800 Subject: [PATCH 31/69] format --- src/launcher/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/launcher/main.cpp b/src/launcher/main.cpp index f57e82920..a2aba6ea8 100644 --- a/src/launcher/main.cpp +++ b/src/launcher/main.cpp @@ -43,7 +43,7 @@ namespace luadebug::autoattach { return attach_status::fatal; } auto root = r.value().parent_path().parent_path(); - auto buf = readfile(root / "script" / "attach.lua"); + auto buf = readfile(root / "script" / "attach.lua"); if (lua::loadbuffer(L, buf.data(), buf.size(), "=(attach.lua)")) { log::fatal("load attach.lua error: {}", lua::tostring(L, -1)); lua::pop(L, 1); From 91cd5d288982a7e8bba7b9f4781bb544b2a7a47f Mon Sep 17 00:00:00 2001 From: fesily Date: Mon, 20 Mar 2023 14:36:45 +0800 Subject: [PATCH 32/69] smaller signature --- 3rd/frida_gum/gumpp | 2 +- compile/common/frida.lua | 5 ++++ src/launcher/tools/signature_compiler.cpp | 31 ++++++++++++++++------- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index 041cd4819..925aa41ce 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit 041cd48199564415da68431d83340c6df2f1112f +Subproject commit 925aa41ce799de81536550ad3228670b7f00f818 diff --git a/compile/common/frida.lua b/compile/common/frida.lua index 7780779df..588cfc763 100644 --- a/compile/common/frida.lua +++ b/compile/common/frida.lua @@ -24,6 +24,11 @@ lm:source_set "frida" { '/wd5051', } }, + macos = { + frameworks = { + "CoreFoundation", + } + }, sources = { "3rd/frida_gum/gumpp/src/*.cpp", }, diff --git a/src/launcher/tools/signature_compiler.cpp b/src/launcher/tools/signature_compiler.cpp index b7fa89f91..0b72e6c16 100644 --- a/src/launcher/tools/signature_compiler.cpp +++ b/src/launcher/tools/signature_compiler.cpp @@ -1,10 +1,11 @@ +#include + #include #include #include +#include #include #include -#include -#include #ifdef _WIN32 @@ -73,15 +74,27 @@ bool starts_with(std::string_view _this, std::string_view __s) _NOEXCEPT { _this.compare(0, __s.size(), __s) == 0; } +constexpr auto insn_max_limit = 100; +constexpr auto insn_min_limit = 4; -bool compiler_signature(const char* name, void* address, std::list& patterns) { - auto signature = Gum::get_function_signature(address, 255); - const auto& pattern = signature.pattern; +bool compiler_signature(const char* name, void* address, std::list& patterns, int limit = insn_min_limit) { + auto signature = Gum::get_function_signature(address, limit); + auto& pattern = signature.pattern; std::vector find_address = Gum::search_module_function(module_name, pattern.c_str()); + if (find_address.size() > 1 && limit <= insn_max_limit) { + return compiler_signature(name, address, patterns, limit + 1); + } if (find_address.size() != 1) { std::cerr << name << " address:" << address << " pattern:" << pattern << std::endl; if (find_address.empty()) { - std::cerr << name << ": invalid pattern[can't search pattern]" << std::endl; + for (size_t i = 0; i < pattern.size(); i += 9) { + if (i + 8 < pattern.size()) { + pattern.insert(i + 8, "\n"); + } + } + std::cerr << name << ": invalid pattern[can't search pattern]\n" + << pattern << std::endl; + exit(1); } else { if (find_address.size() > 8) { @@ -95,7 +108,7 @@ bool compiler_signature(const char* name, void* address, std::list& pat } } } - bool isvalid = false; + bool isvalid = false; size_t offset = 0; for (auto addr : find_address) { if ((void*)((uint8_t*)addr + signature.offset) == address) { @@ -125,13 +138,13 @@ int main(int narg, const char* argvs[]) { Gum::runtime_init(); auto import_file = std::filesystem::absolute(argvs[1]).generic_string(); - auto is_string = argvs[2] == "true"sv ? true : false; + auto is_string = argvs[2] == "true"sv ? true : false; std::set imports_names; if (auto ec = imports(import_file, is_string, imports_names); ec != 0) { return ec; } auto target_path = std::filesystem::absolute(argvs[3]).generic_string(); - auto is_export = argvs[4] == "true"sv ? true : false; + auto is_export = argvs[4] == "true"sv ? true : false; std::string error; module_name = target_path.c_str(); std::cerr << "signature:" << module_name << std::endl; From 8bb60fea74e1cf03d6e98aac4a4d56d04f87b004 Mon Sep 17 00:00:00 2001 From: fesily Date: Mon, 20 Mar 2023 14:44:35 +0800 Subject: [PATCH 33/69] Update package_json.lua fix grammar error --- compile/common/package_json.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compile/common/package_json.lua b/compile/common/package_json.lua index 11d859bd5..6ea0f9768 100644 --- a/compile/common/package_json.lua +++ b/compile/common/package_json.lua @@ -253,7 +253,7 @@ Debugger address. type = "string", }, module = { - defualt = "null", + default = "null", markdownDescription = "specify lua module path/name", type = "string", } From 8483e4a89ed4f539692e64fe6c00eff092657fbb Mon Sep 17 00:00:00 2001 From: fesily Date: Mon, 20 Mar 2023 15:01:06 +0800 Subject: [PATCH 34/69] fix some error --- compile/common/package_json.lua | 10 ++-- src/launcher/autoattach/autoattach.cpp | 12 ++-- src/launcher/autoattach/lua_module.cpp | 83 ++++---------------------- src/launcher/config/config.cpp | 18 +----- src/launcher/resolver/lua_resolver.cpp | 4 +- src/launcher/resolver/lua_resolver.h | 2 +- 6 files changed, 27 insertions(+), 102 deletions(-) diff --git a/compile/common/package_json.lua b/compile/common/package_json.lua index 2bd5ca332..2faaed32b 100644 --- a/compile/common/package_json.lua +++ b/compile/common/package_json.lua @@ -252,16 +252,16 @@ Debugger address. }, type = "string", }, + module = { + default = "null", + markdownDescription = "specify lua module path/name", + type = "string", + }, signature = { default = "null", type = "object", markdownDescription = "signature info", properties = { - lua_module = { - default = "null", - type = "string", - markdownDescription = "lua module path or name", - }, functions = { type = "object", additionalProperties = { diff --git a/src/launcher/autoattach/autoattach.cpp b/src/launcher/autoattach/autoattach.cpp index 144c371c0..8ee6c0d82 100644 --- a/src/launcher/autoattach/autoattach.cpp +++ b/src/launcher/autoattach/autoattach.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include @@ -46,12 +46,12 @@ namespace luadebug::autoattach { lua_module rm = {}; Gum::Process::enumerate_modules([&rm, &found](const Gum::ModuleDetails& details) -> bool { if (is_lua_module(details.path())) { - auto range = details.range(); + auto range = details.range(); rm.memory_address = range.base_address; - rm.memory_size = range.size; - rm.path = details.path(); - rm.name = details.name(); - found = true; + rm.memory_size = range.size; + rm.path = details.path(); + rm.name = details.name(); + found = true; return false; } return true; diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index 8ae396d65..806f89196 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -1,32 +1,15 @@ #include +#include +#include +#include +#include #include #include -#include -#include -#include #include #include -#include - namespace luadebug::autoattach { - static const char* lua_version_to_string(lua_version v) { - switch (v) { - case lua_version::lua51: - return "lua51"; - case lua_version::lua52: - return "lua52"; - case lua_version::lua53: - return "lua53"; - case lua_version::lua54: - return "lua54"; - case lua_version::luajit: - return "luajit"; - default: - return "unknown"; - } - } static bool in_module(const lua_module& m, void* addr) { return addr >= m.memory_address && addr <= (void*)((intptr_t)m.memory_address + m.memory_size); @@ -82,7 +65,7 @@ namespace luadebug::autoattach { // TODO: from signature } - bool load_remotedebug_dll(lua_version version, const lua_resolver& resolver) { + bool load_luadebug_dll(lua_version version, lua_resolver& resolver) { if (version != lua_version::unknown) return false; @@ -107,17 +90,13 @@ namespace luadebug::autoattach { "x86" #elif defined(_M_X64) || defined(__x86_64__) "x86_64" -#elif defined(__arm__) - "arm" -#elif defined(__riscv) - "riscv" #else ; return false; #endif ; auto platform = std::format("{}-{}", os, arch); - auto path = dllpath.value().parent_path().parent_path() / "runtime" / platform / lua_version_to_string(version); + auto path = (dllpath.value().parent_path().parent_path() / "runtime" / platform / lua_version_to_string(version)).string(); #ifdef _WIN32 #else @@ -127,7 +106,7 @@ namespace luadebug::autoattach { if (std::string_view(details.name).find_first_of("lua") != 0) { return true; } - if (auto address = (void*)resolver.find_signture(details.name)) { + if (auto address = (void*)resolver.find_signature(details.name)) { *(void**)details.slot = address; log::info("find signture {} to {}", details.name, address); } @@ -136,48 +115,9 @@ namespace luadebug::autoattach { return true; } - bool load_luadebug_dll(lua_version version) { - if (version != lua_version::unknown) - return false; - - auto dllpath = bee::path_helper::dll_path(); - if (!dllpath) { - return false; - } - auto os = -#if defined(_WIN32) - "windows" -#elif defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) - "darwin" -#else - ; - return false; -#endif - ; - auto arch = -#if defined(_M_ARM64) || defined(__aarch64__) - "arm64" -#elif defined(_M_IX86) || defined(__i386__) - "x86" -#elif defined(_M_X64) || defined(__x86_64__) - "x86_64" -#else - ; - return false; -#endif - ; - auto platform = std::format("{}-{}", os, arch); - auto path = (dllpath.value().parent_path().parent_path() / "runtime" / platform / lua_version_to_string(version)).string(); - std::string error; - if (!Gum::Process::module_load(path.c_str(), &error)) { - log::fatal("load remotedebug dll failed: {}", error); - } - return true; - } - bool lua_module::initialize(fn_attach attach_lua_vm) { resolver.module_name = path; - auto error_msg = lua::initialize(resolver); + auto error_msg = lua::initialize(resolver); if (error_msg) { log::fatal("lua initialize failed, can't find {}", error_msg); return false; @@ -188,12 +128,11 @@ namespace luadebug::autoattach { resolver.version = lua_version_to_string(version); if (config.is_signature_mode()) { - load_remotedebug_dll(version, resolver); + if (!load_luadebug_dll(version, resolver)) { + return false; + } } - if (!load_luadebug_dll(version)) { - return false; - } watchdog = create_watchdog(attach_lua_vm, version, resolver); if (!watchdog) { // TODO: more errmsg diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index 69445acbe..e5da38be1 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -17,24 +17,10 @@ using namespace std::string_view_literals; namespace luadebug::autoattach { - static lua_version lua_version_from_string [[maybe_unused]] (const std::string_view& v) { - if (v == "jit" || v == "luajit") - return lua_version::luajit; - else if (v == "5.1" || v == "lua51") - return lua_version::lua51; - else if (v == "5.2" || v == "lua52") - return lua_version::lua52; - else if (v == "5.3" || v == "lua53") - return lua_version::lua53; - else if (v == "5.4" || v == "lua54") - return lua_version::lua54; - return lua_version::unknown; - } - Config config; lua_version Config::get_lua_version() const { - const auto key = "lua_version"sv; + const auto key = "version"sv; auto it = values->find(key); if (!values || it == values->end()) { @@ -67,7 +53,7 @@ namespace luadebug::autoattach { } std::string Config::get_lua_module() const { - const auto key = "lua_module"sv; + const auto key = "module"sv; auto it = values->find(key); if (it == values->end()) { diff --git a/src/launcher/resolver/lua_resolver.cpp b/src/launcher/resolver/lua_resolver.cpp index e4e60b0d1..83dc012c4 100644 --- a/src/launcher/resolver/lua_resolver.cpp +++ b/src/launcher/resolver/lua_resolver.cpp @@ -23,7 +23,7 @@ namespace luadebug { return (intptr_t)Gum::Process::module_find_symbol_by_name(module_name.data(), name.data()); } - intptr_t lua_resolver::find_signture(std::string_view name) const { + intptr_t lua_resolver::find_signature(std::string_view name) const { if (!version.empty()) { if (auto signature = autoattach::config.get_lua_signature(version + "." + std::string(name))) { return signature->find(module_name.data()); @@ -38,7 +38,7 @@ namespace luadebug { intptr_t lua_resolver::find(std::string_view name) const { using namespace std::string_view_literals; - for (auto& finder : { &lua_resolver::find_export, &lua_resolver::find_symbol, &lua_resolver::find_signture }) { + for (auto& finder : { &lua_resolver::find_export, &lua_resolver::find_symbol, &lua_resolver::find_signature }) { if (auto result = (this->*finder)(name)) { return result; } diff --git a/src/launcher/resolver/lua_resolver.h b/src/launcher/resolver/lua_resolver.h index 94529e6ba..0e3a1708d 100644 --- a/src/launcher/resolver/lua_resolver.h +++ b/src/launcher/resolver/lua_resolver.h @@ -9,7 +9,7 @@ namespace luadebug { intptr_t find(std::string_view name) const override; intptr_t find_export(std::string_view name) const; intptr_t find_symbol(std::string_view name) const; - intptr_t find_signture(std::string_view name) const; + intptr_t find_signature(std::string_view name) const; std::string_view module_name; std::string version; }; From 9daadc5405073a0aa04463c83e371903fc4691cf Mon Sep 17 00:00:00 2001 From: fesily Date: Mon, 20 Mar 2023 15:27:23 +0800 Subject: [PATCH 35/69] format code --- compile/signature_compiler.lua | 41 +++++++++++++------------ src/launcher/config/config.cpp | 19 +++++------- src/launcher/config/config.h | 6 ++-- src/launcher/resolver/lua_resolver.cpp | 4 +-- src/launcher/resolver/lua_resolver.h | 1 + src/launcher/resolver/lua_signature.cpp | 2 +- src/launcher/resolver/lua_signature.h | 4 +-- 7 files changed, 38 insertions(+), 39 deletions(-) diff --git a/compile/signature_compiler.lua b/compile/signature_compiler.lua index 144375101..6d9a80426 100644 --- a/compile/signature_compiler.lua +++ b/compile/signature_compiler.lua @@ -25,7 +25,7 @@ local function scan(dir, platform_arch) else t.lua_modlue = dir_path / "lua" end - luadebug_files[#luadebug_files + 1] = t + luadebug_files[#luadebug_files+1] = t end end end @@ -59,7 +59,9 @@ local function compiler(executable, import_file, is_string, lua_modlue) local res = {} for line in process.stdout:lines() do local name, pattern, offset, hit_offset = line:match([[(.+):([0-9a-f%?]+)%(([%-%+]?%d+)%)@([%-%+]?%d+)]]) - res[#res + 1] = { + offset = offset ~= "0" and tonumber(offset) or nil + hit_offset = hit_offset ~= "0" and tonumber(hit_offset) or nil + res[#res+1] = { name = name, pattern = pattern, offset = offset, @@ -78,7 +80,6 @@ local function compiler(executable, import_file, is_string, lua_modlue) end local output_dir = fs.path("publish") / "signature" -fs.create_directories(output_dir) local function get_executable(platform_arch) local bin_dir = fs.path("build") / platform_arch @@ -98,22 +99,22 @@ local function get_executable(platform_arch) end for _, t in ipairs(luadebug_files) do - if t.platform_arch:find("arm64") then - local lua_modlue = t.lua_modlue - local executable = get_executable(t.platform_arch) - local t1 = compiler(executable, launcher_path, true, lua_modlue) - local t2 = compiler(executable, t.luadebug, false, lua_modlue) - local signatures = table.pack(table.unpack(t1), table.unpack(t2)) - local output = {} - for i, signature in ipairs(signatures) do - output[signature.name] = { - pattern = signature.pattern, - offset = signature.offset, - hit_offset = signature.hit_offset, - } - end - local file = io.open((output_dir / (t.version..".json")):string(), "w") - file:write(json.beautify(output)) - file:close() + local output_dir = output_dir / t.platform_arch + fs.create_directories(output_dir) + local lua_modlue = t.lua_modlue + local executable = get_executable(t.platform_arch) + local t1 = compiler(executable, launcher_path, true, lua_modlue) + local t2 = compiler(executable, t.luadebug, false, lua_modlue) + local signatures = table.pack(table.unpack(t1), table.unpack(t2)) + local output = {} + for _, signature in ipairs(signatures) do + output[signature.name] = { + pattern = signature.pattern, + offset = signature.offset, + hit_offset = signature.hit_offset, + } end + local file = io.open((output_dir / (t.version..".json")):string(), "w") + file:write(json.beautify(output)) + file:close() end diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index e5da38be1..433b076e1 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -1,19 +1,16 @@ -#include #include -#include -#include - -#include -#include -#include - #include #include #include +#include +#include +#include +#include #include - +#include #include +#include using namespace std::string_view_literals; namespace luadebug::autoattach { @@ -32,7 +29,7 @@ namespace luadebug::autoattach { std::optional Config::get_lua_signature(const std::string& key) const { const auto signture_key = "functions"sv; - auto it = values->find(signture_key); + auto it = values->find(signture_key); if (it == values->end()) { return std::nullopt; } @@ -72,7 +69,7 @@ namespace luadebug::autoattach { bool Config::init_from_file() { config.values = std::make_unique(); - auto dllpath = bee::path_helper::dll_path(); + auto dllpath = bee::path_helper::dll_path(); if (!dllpath) { return false; } diff --git a/src/launcher/config/config.h b/src/launcher/config/config.h index 968b35ab7..ee4f10ce4 100644 --- a/src/launcher/config/config.h +++ b/src/launcher/config/config.h @@ -1,8 +1,8 @@ -#include +#include +#include #include #include -#include -#include +#include namespace luadebug::autoattach { diff --git a/src/launcher/resolver/lua_resolver.cpp b/src/launcher/resolver/lua_resolver.cpp index 83dc012c4..11e4626d8 100644 --- a/src/launcher/resolver/lua_resolver.cpp +++ b/src/launcher/resolver/lua_resolver.cpp @@ -1,9 +1,9 @@ +#include #include +#include #include #include -#include -#include namespace luadebug { static int (*_lua_pcall)(intptr_t L, int nargs, int nresults, int errfunc); diff --git a/src/launcher/resolver/lua_resolver.h b/src/launcher/resolver/lua_resolver.h index 0e3a1708d..fc0220c5e 100644 --- a/src/launcher/resolver/lua_resolver.h +++ b/src/launcher/resolver/lua_resolver.h @@ -1,6 +1,7 @@ #pragma once #include + #include #include diff --git a/src/launcher/resolver/lua_signature.cpp b/src/launcher/resolver/lua_signature.cpp index f644e5d44..4c2a08989 100644 --- a/src/launcher/resolver/lua_signature.cpp +++ b/src/launcher/resolver/lua_signature.cpp @@ -30,7 +30,7 @@ namespace luadebug::autoattach { }); auto hit_index = all_address.size() > hit_offset ? hit_offset : 0; - find_address = all_address[hit_index]; + find_address = all_address[hit_index]; } if (find_address != 0) return (uintptr_t)((uint8_t*)find_address + pattern_offset); diff --git a/src/launcher/resolver/lua_signature.h b/src/launcher/resolver/lua_signature.h index 371619eac..610a86a6f 100644 --- a/src/launcher/resolver/lua_signature.h +++ b/src/launcher/resolver/lua_signature.h @@ -5,10 +5,10 @@ namespace luadebug::autoattach { struct signture { int32_t start_offset = 0; - int32_t end_offset = 0; + int32_t end_offset = 0; std::string pattern; int32_t pattern_offset = 0; - uint8_t hit_offset = 0; + uint8_t hit_offset = 0; intptr_t find(const char* module_name) const; }; } \ No newline at end of file From 11fca9c7e512beb95a419056d1204fb34ed3a573 Mon Sep 17 00:00:00 2001 From: fesily Date: Mon, 20 Mar 2023 15:31:03 +0800 Subject: [PATCH 36/69] version add latest --- src/launcher/autoattach/lua_version.cpp | 4 ++++ src/launcher/autoattach/lua_version.h | 1 + src/launcher/hook/create_watchdog.cpp | 1 + 3 files changed, 6 insertions(+) diff --git a/src/launcher/autoattach/lua_version.cpp b/src/launcher/autoattach/lua_version.cpp index d6d12ba0e..c1cdba2b5 100644 --- a/src/launcher/autoattach/lua_version.cpp +++ b/src/launcher/autoattach/lua_version.cpp @@ -13,6 +13,8 @@ namespace luadebug::autoattach { return "lua54"; case lua_version::luajit: return "luajit"; + case lua_version::latest: + return "lua-latest"; default: return "unknown"; } @@ -28,6 +30,8 @@ namespace luadebug::autoattach { return lua_version::lua53; else if (v == "5.4" || v == "lua54") return lua_version::lua54; + else if (v == "latest" || v == "lua-latest") + return lua_version::latest; return lua_version::unknown; } } \ No newline at end of file diff --git a/src/launcher/autoattach/lua_version.h b/src/launcher/autoattach/lua_version.h index 1797b3338..406009d70 100644 --- a/src/launcher/autoattach/lua_version.h +++ b/src/launcher/autoattach/lua_version.h @@ -8,6 +8,7 @@ namespace luadebug::autoattach { lua52, lua53, lua54, + latest, }; const char* lua_version_to_string(lua_version v); lua_version lua_version_from_string(const std::string_view& v); diff --git a/src/launcher/hook/create_watchdog.cpp b/src/launcher/hook/create_watchdog.cpp index d0a2ed1e8..09696d83f 100644 --- a/src/launcher/hook/create_watchdog.cpp +++ b/src/launcher/hook/create_watchdog.cpp @@ -27,6 +27,7 @@ namespace luadebug::autoattach { { watch_point::type::common, "luaV_gettable" }, { watch_point::type::common, "luaV_settable" }, }; + case lua_version::latest: case lua_version::lua54: return { { watch_point::type::common, "luaD_poscall" }, From 0dafaffa54a5ca0795007f685607e4b216f22c2e Mon Sep 17 00:00:00 2001 From: fesily Date: Mon, 20 Mar 2023 16:58:45 +0800 Subject: [PATCH 37/69] update gumpp --- 3rd/frida_gum/gumpp | 2 +- compile/signature_compiler.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index 925aa41ce..6e9c08fdc 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit 925aa41ce799de81536550ad3228670b7f00f818 +Subproject commit 6e9c08fdcb265aa7690973c5c7659b8b79fc106e diff --git a/compile/signature_compiler.lua b/compile/signature_compiler.lua index 6d9a80426..0f9d210df 100644 --- a/compile/signature_compiler.lua +++ b/compile/signature_compiler.lua @@ -85,8 +85,8 @@ local function get_executable(platform_arch) local bin_dir = fs.path("build") / platform_arch local modes = { - "debug", "release", + "debug", } for _, mode in ipairs(modes) do local executable = bin_dir / mode / "bin" / "signature_compiler" From 39575ac92b751cb510e156efd018963795c0d9ce Mon Sep 17 00:00:00 2001 From: fesily Date: Mon, 20 Mar 2023 21:27:17 +0800 Subject: [PATCH 38/69] fix build --- 3rd/frida_gum/gumpp | 2 +- src/launcher/tools/signature_compiler.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index 6e9c08fdc..f71f6f5f6 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit 6e9c08fdcb265aa7690973c5c7659b8b79fc106e +Subproject commit f71f6f5f6036bd132c0492863052cef8b3714c5f diff --git a/src/launcher/tools/signature_compiler.cpp b/src/launcher/tools/signature_compiler.cpp index 0b72e6c16..1677cc172 100644 --- a/src/launcher/tools/signature_compiler.cpp +++ b/src/launcher/tools/signature_compiler.cpp @@ -69,7 +69,7 @@ int imports(std::string file_path, bool is_string, std::set& import #endif return 0; } -bool starts_with(std::string_view _this, std::string_view __s) _NOEXCEPT { +bool starts_with(std::string_view _this, std::string_view __s) noexcept { return _this.size() >= __s.size() && _this.compare(0, __s.size(), __s) == 0; From 34577b5be00183de9beb855c401e5553a52ac030 Mon Sep 17 00:00:00 2001 From: fesily Date: Tue, 21 Mar 2023 09:44:28 +0800 Subject: [PATCH 39/69] fix windows err --- src/launcher/autoattach/lua_module.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index 806f89196..00c867b1c 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include #include @@ -97,18 +96,18 @@ namespace luadebug::autoattach { ; auto platform = std::format("{}-{}", os, arch); auto path = (dllpath.value().parent_path().parent_path() / "runtime" / platform / lua_version_to_string(version)).string(); -#ifdef _WIN32 - -#else - dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL); -#endif + std::string error; + if (Gum::Process::module_load(path.c_str(), &error)) { + log::fatal("load luadebug module failed: {}", error); + return false; + } Gum::Process::module_enumerate_import(path.c_str(), [&](const Gum::ImportDetails& details) -> bool { if (std::string_view(details.name).find_first_of("lua") != 0) { return true; } if (auto address = (void*)resolver.find_signature(details.name)) { *(void**)details.slot = address; - log::info("find signture {} to {}", details.name, address); + log::info("find signature {} to {}", details.name, address); } return true; }); From 697a2e5c6b2370cda728c1f37cb766d372250392 Mon Sep 17 00:00:00 2001 From: fesily Date: Tue, 21 Mar 2023 09:50:47 +0800 Subject: [PATCH 40/69] reset target --- compile/macos/make.lua | 4 ++-- src/launcher/tools/signature_compiler.cpp | 21 +++++---------------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/compile/macos/make.lua b/compile/macos/make.lua index 38311f2db..e08526282 100644 --- a/compile/macos/make.lua +++ b/compile/macos/make.lua @@ -3,7 +3,7 @@ local lm = require "luamake" if lm.platform == "darwin-arm64" then lm.target = "arm64-apple-macos11" else - lm.target = "x86_64-apple-macos10.15" + lm.target = "x86_64-apple-macos10.12" end lm.builddir = ("build/%s/%s"):format(lm.platform, lm.mode) @@ -22,7 +22,7 @@ if lm.platform == "darwin-arm64" then args = { "-builddir", "build/darwin-x64/"..lm.mode, "-runtime_platform", "darwin-x64", - "-target", "x86_64-apple-macos10.15", + "-target", "x86_64-apple-macos10.12", }, } end diff --git a/src/launcher/tools/signature_compiler.cpp b/src/launcher/tools/signature_compiler.cpp index 1677cc172..2c392a008 100644 --- a/src/launcher/tools/signature_compiler.cpp +++ b/src/launcher/tools/signature_compiler.cpp @@ -7,12 +7,6 @@ #include #include -#ifdef _WIN32 - -#else -# include -#endif - using namespace std::literals; const char* module_name; struct Pattern { @@ -22,16 +16,11 @@ struct Pattern { }; int imports(std::string file_path, bool is_string, std::set& imports_names) { -#ifdef _WIN32 - -#else - auto handle = dlopen(file_path.c_str(), RTLD_LAZY | RTLD_LOCAL); - if (!handle) { - std::cerr << "dlopen " << file_path << " failed: " << dlerror() << std::endl; + std::string error; + if (Gum::Process::module_load(file_path.c_str(), &error)) { + std::cerr << "module_load " << file_path << " failed: " << error << std::endl; return 1; } -#endif - if (is_string) { // check address is a string begin for (auto str : Gum::search_module_string(file_path.c_str(), "lua")) { @@ -137,13 +126,13 @@ int main(int narg, const char* argvs[]) { } Gum::runtime_init(); - auto import_file = std::filesystem::absolute(argvs[1]).generic_string(); + auto import_file = fs::absolute(argvs[1]).generic_string(); auto is_string = argvs[2] == "true"sv ? true : false; std::set imports_names; if (auto ec = imports(import_file, is_string, imports_names); ec != 0) { return ec; } - auto target_path = std::filesystem::absolute(argvs[3]).generic_string(); + auto target_path = fs::absolute(argvs[3]).generic_string(); auto is_export = argvs[4] == "true"sv ? true : false; std::string error; module_name = target_path.c_str(); From 4fa4d91bc02ef2112287785fecd97132600f6427 Mon Sep 17 00:00:00 2001 From: fesily Date: Wed, 22 Mar 2023 16:39:25 +0800 Subject: [PATCH 41/69] fix build err --- compile/common/launcher.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/compile/common/launcher.lua b/compile/common/launcher.lua index 754a5d065..f1e4831ef 100644 --- a/compile/common/launcher.lua +++ b/compile/common/launcher.lua @@ -20,6 +20,7 @@ lm:lua_source 'launcher_source' { "3rd/bee.lua", "3rd/frida_gum/gumpp", "3rd/lua/lua54", + "3rd/json/single_include", "src/launcher", }, sources = { From 3a7732621a773c8c7201bba3e6dfcaccff123e7b Mon Sep 17 00:00:00 2001 From: fesily Date: Wed, 22 Mar 2023 16:42:10 +0800 Subject: [PATCH 42/69] fix build err --- compile/common/launcher.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/compile/common/launcher.lua b/compile/common/launcher.lua index 754a5d065..f1e4831ef 100644 --- a/compile/common/launcher.lua +++ b/compile/common/launcher.lua @@ -20,6 +20,7 @@ lm:lua_source 'launcher_source' { "3rd/bee.lua", "3rd/frida_gum/gumpp", "3rd/lua/lua54", + "3rd/json/single_include", "src/launcher", }, sources = { From c45e23635b0c6e70881da07b18a47d39e087c5ce Mon Sep 17 00:00:00 2001 From: fesily Date: Wed, 22 Mar 2023 16:45:54 +0800 Subject: [PATCH 43/69] fix build error --- compile/macos/make.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/compile/macos/make.lua b/compile/macos/make.lua index e08526282..264ced58e 100644 --- a/compile/macos/make.lua +++ b/compile/macos/make.lua @@ -13,6 +13,7 @@ require "compile.common.lua-debug" lm.runtime_platform = lm.platform require "compile.macos.runtime" require "compile.macos.shellcode" +require "compile.macos.signature_compiler" if lm.platform == "darwin-arm64" then require "compile.common.run_luamake" From c8bdd8f2afef5ddb4f28f8617b4cd426ca268bd5 Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 23 Mar 2023 10:53:37 +0800 Subject: [PATCH 44/69] fix all error --- extension/script/debugger.lua | 12 ++++++------ extension/script/frontend/proxy.lua | 2 ++ src/launcher/autoattach/lua_module.cpp | 27 ++++++++++++++------------ src/launcher/config/config.cpp | 5 ++--- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/extension/script/debugger.lua b/extension/script/debugger.lua index 5b264026e..b61bcfb82 100644 --- a/extension/script/debugger.lua +++ b/extension/script/debugger.lua @@ -118,14 +118,14 @@ local function detectLuaDebugPath(cfg) ["Lua 5.2"] = "lua52", ["Lua 5.1"] = "lua51", latest = "lua-latest", - ["5.4"] = "lua54", - ["5.3"] = "lua53", - ["5.2"] = "lua52", - ["5.1"] = "lua51", - ["jit"] = "luajit", + lua54 = "lua54", + lua53 = "lua53", + lua52 = "lua52", + lua51 = "lua51", + luajit = "luajit", } if not t[version] then - error(_VERSION.." is not supported.") + error(version.." is not supported.") end return t[version] end diff --git a/extension/script/frontend/proxy.lua b/extension/script/frontend/proxy.lua index e098be924..cb7084c51 100644 --- a/extension/script/frontend/proxy.lua +++ b/extension/script/frontend/proxy.lua @@ -11,12 +11,14 @@ local initReq local m = {} local function getUnixAddress(pid) + --TODO: clear unix file local path = WORKDIR / "tmp" fs.create_directories(path) return "@"..(path / ("pid_%d"):format(pid)):string() end local function ipc_send_config(pid, args) + --TODO: clear config file fs.create_directories(WORKDIR / "tmp") local ipc = require "common.ipc" local fd = assert(ipc(WORKDIR, pid, "config", "w")) diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index 54abbe6a9..9e0ae63ec 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -63,23 +63,25 @@ namespace luadebug::autoattach { } bool load_luadebug_dll(lua_version version) { - if (version != lua_version::unknown) - return false; - auto dllpath = bee::path_helper::dll_path(); if (!dllpath) { return false; } - auto os = +#define LUADEBUG_FILE "luadebug" #if defined(_WIN32) - "windows" + auto os = "windows"; + auto luadebug_name = + LUADEBUG_FILE + ".dll"; #elif defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) - "darwin" + auto os = "darwin"; + auto luadebug_name = + LUADEBUG_FILE + ".so"; #else - ; return false; #endif - ; + ; auto arch = #if defined(_M_ARM64) || defined(__aarch64__) "arm64" @@ -93,10 +95,10 @@ namespace luadebug::autoattach { #endif ; auto platform = std::format("{}-{}", os, arch); - auto path = (dllpath.value().parent_path().parent_path() / "runtime" / platform / lua_version_to_string(version)).string(); + auto path = (dllpath.value().parent_path().parent_path() / "runtime" / platform / lua_version_to_string(version) / luadebug_name).string(); std::string error; if (!Gum::Process::module_load(path.c_str(), &error)) { - log::fatal("load remotedebug dll failed: {}", error); + log::fatal("load debugger [{}] failed: {}", path, error); } return true; } @@ -111,8 +113,9 @@ namespace luadebug::autoattach { version = get_lua_version(*this); log::info("current lua version: {}", lua_version_to_string(version)); - if (!load_luadebug_dll(version)) { - return false; + if (version != lua_version::unknown) { + if (!load_luadebug_dll(version)) + return false; } watchdog = create_watchdog(attach_lua_vm, version, resolver); if (!watchdog) { diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index ccad7baa2..62df63e07 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -45,10 +45,9 @@ namespace luadebug::autoattach { if (!dllpath) { return false; } + auto filename = (dllpath.value().parent_path().parent_path() / "tmp" / std::format("ipc_{}_config", Gum::Process::get_id())).string(); - auto filename = std::format("{}/tmp/pid_{}_config", dllpath.value().parent_path().parent_path().generic_string(), Gum::Process::get_id()); - - std::ifstream s(filename, s.in); + std::ifstream s(filename, s.binary); if (!s.is_open()) return false; try { From 917439bb4aa66efc680e71e70e0da6a62333ce52 Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 23 Mar 2023 13:24:30 +0800 Subject: [PATCH 45/69] fix error --- compile/macos/make.lua | 5 +++++ src/launcher/autoattach/lua_module.cpp | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/compile/macos/make.lua b/compile/macos/make.lua index 01ecbca64..dd7ff72a5 100644 --- a/compile/macos/make.lua +++ b/compile/macos/make.lua @@ -57,6 +57,11 @@ else } end +lm:phony "compile_signature" { + deps = { "signature_compiler", "merge_launcher", "runtime", "lua-debug" }, + "$luamake", "lua", "compile/signature_compiler.lua" +} + lm:default { "common", "lua-debug", diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index d5055f546..7c5bb77f2 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -64,7 +64,7 @@ namespace luadebug::autoattach { // TODO: from signature } - bool load_luadebug_dll(lua_version version) { + bool load_luadebug_dll(lua_version version, lua_resolver& resolver) { auto dllpath = bee::path_helper::dll_path(); if (!dllpath) { return false; @@ -128,7 +128,7 @@ namespace luadebug::autoattach { resolver.version = lua_version_to_string(version); if (version != lua_version::unknown) { - if (!load_luadebug_dll(version)) + if (!load_luadebug_dll(version, resolver)) return false; } From fb1d2d0cfbb7906e24bf5b0a29f37d80d2d65dcc Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 23 Mar 2023 13:37:42 +0800 Subject: [PATCH 46/69] attach luaVersion default unknown --- compile/common/package_json.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compile/common/package_json.lua b/compile/common/package_json.lua index d2d8e4711..bf5d084c1 100644 --- a/compile/common/package_json.lua +++ b/compile/common/package_json.lua @@ -476,6 +476,10 @@ for k, v in pairs(attributes.common) do attributes.attach[k] = v attributes.launch[k] = v end + +table.insert(attributes.attach.luaVersion.enum, "unknown") +attributes.attach.luaVersion.default = "unknown" + json.contributes.debuggers[1].configurationAttributes = { launch = { properties = attributes.launch }, attach = { properties = attributes.attach }, From 7f7e00db06deb49b13b9ccbc2808efe573ff410e Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 23 Mar 2023 14:29:15 +0800 Subject: [PATCH 47/69] fix windows imports --- 3rd/frida_gum/gumpp | 2 +- src/launcher/autoattach/lua_module.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index fdea61ce5..86aca93b2 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit fdea61ce5fa7e11e6e84817ef11a9a44e73d76d5 +Subproject commit 86aca93b2fe5b3a00fd0dafb1f155d597bae4376 diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index 7c5bb77f2..e9b6cc942 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -107,7 +107,7 @@ namespace luadebug::autoattach { return true; } if (auto address = (void*)resolver.find_signature(details.name)) { - *(void**)details.slot = address; + *details.slot = address; log::info("find signature {} to {}", details.name, address); } return true; From 49decb1dee89b5a8286707d73aeaf1c94a4bbb7b Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 23 Mar 2023 16:14:35 +0800 Subject: [PATCH 48/69] fix windows delayload --- 3rd/frida_gum/gumpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index 86aca93b2..4a95cddea 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit 86aca93b2fe5b3a00fd0dafb1f155d597bae4376 +Subproject commit 4a95cddeabd4754386d7837c428059f7f1a24614 From 057c95103291b0fba8f6486fe906abdfe262fe7e Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 23 Mar 2023 16:30:34 +0800 Subject: [PATCH 49/69] update gumpp --- 3rd/frida_gum/gumpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index 4a95cddea..ff3d3c8f0 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit 4a95cddeabd4754386d7837c428059f7f1a24614 +Subproject commit ff3d3c8f063f0c935eb057e364363ceeea0431bf From 0357e25b52d90b5d04d264d555d88e48e705f75f Mon Sep 17 00:00:00 2001 From: fesily Date: Fri, 24 Mar 2023 10:28:04 +0800 Subject: [PATCH 50/69] fix error --- compile/common/launcher.lua | 1 + compile/macos/runtime.lua | 3 ++- src/launcher/tools/signature_compiler.cpp | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compile/common/launcher.lua b/compile/common/launcher.lua index f1e4831ef..4f450f606 100644 --- a/compile/common/launcher.lua +++ b/compile/common/launcher.lua @@ -25,6 +25,7 @@ lm:lua_source 'launcher_source' { }, sources = { "src/launcher/**/*.cpp", + "!src/launcher/tools", "!src/launcher/hook/luajit_listener.cpp", }, defines = { diff --git a/compile/macos/runtime.lua b/compile/macos/runtime.lua index 4e8c1f2e3..a5326fa8a 100644 --- a/compile/macos/runtime.lua +++ b/compile/macos/runtime.lua @@ -3,10 +3,11 @@ local lm = require "luamake" require "compile.common.config" require "compile.common.runtime" require "compile.common.launcher" +require "compile.macos.signature_compiler" lm:lua_library 'launcher' { export_luaopen = "off", deps = { "launcher_source", }, -} +} \ No newline at end of file diff --git a/src/launcher/tools/signature_compiler.cpp b/src/launcher/tools/signature_compiler.cpp index 2c392a008..7eb487707 100644 --- a/src/launcher/tools/signature_compiler.cpp +++ b/src/launcher/tools/signature_compiler.cpp @@ -17,7 +17,7 @@ struct Pattern { int imports(std::string file_path, bool is_string, std::set& imports_names) { std::string error; - if (Gum::Process::module_load(file_path.c_str(), &error)) { + if (!Gum::Process::module_load(file_path.c_str(), &error)) { std::cerr << "module_load " << file_path << " failed: " << error << std::endl; return 1; } From ce666d000a6a05b3898df839db4dd59d05215394 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 25 Mar 2023 13:20:50 +0800 Subject: [PATCH 51/69] add lua_module_backlist --- src/launcher/autoattach/autoattach.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/launcher/autoattach/autoattach.cpp b/src/launcher/autoattach/autoattach.cpp index 2fc8e8434..78ba2ce3e 100644 --- a/src/launcher/autoattach/autoattach.cpp +++ b/src/launcher/autoattach/autoattach.cpp @@ -13,6 +13,17 @@ namespace luadebug::autoattach { fn_attach debuggerAttach; +#ifdef _WIN32 +# define EXT ".dll" +#else +# define EXT ".so" +#endif + + constexpr auto lua_module_backlist[] = { + "launcher" EXT, + "luadebug" EXT, + }; + constexpr auto find_lua_module_key = "lua_newstate"; constexpr auto lua_module_strings = std::array { "luaJIT_BC_%s", // luajit @@ -26,7 +37,12 @@ namespace luadebug::autoattach { " $", // others }; static bool is_lua_module(const char* module_path, bool check_export = true, bool check_strings = false) { - if (std::string_view(module_path).find(config.get_lua_module()) != std::string_view::npos) + auto str = std::string_view(module_path); + for (auto& s : lua_module_backlist) { + if (str.find(s) != std::string_view::npos) + return false; + } + if (str.find(config.get_lua_module()) != std::string_view::npos) return true; if (check_export && Gum::Process::module_find_export_by_name(module_path, find_lua_module_key)) return true; if (Gum::Process::module_find_symbol_by_name(module_path, find_lua_module_key)) return true; From 9d495d60ecd5b86495e09e0ac68d576a960c5850 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 25 Mar 2023 13:32:26 +0800 Subject: [PATCH 52/69] fix build error --- src/launcher/autoattach/autoattach.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/launcher/autoattach/autoattach.cpp b/src/launcher/autoattach/autoattach.cpp index 78ba2ce3e..8dd531b8e 100644 --- a/src/launcher/autoattach/autoattach.cpp +++ b/src/launcher/autoattach/autoattach.cpp @@ -18,8 +18,7 @@ namespace luadebug::autoattach { #else # define EXT ".so" #endif - - constexpr auto lua_module_backlist[] = { + constexpr auto lua_module_backlist = { "launcher" EXT, "luadebug" EXT, }; From ff05aa45cfc98768c4a162f41c34447710399afd Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 25 Mar 2023 13:41:40 +0800 Subject: [PATCH 53/69] update gumpp --- 3rd/frida_gum/gumpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index fdea61ce5..ff3d3c8f0 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit fdea61ce5fa7e11e6e84817ef11a9a44e73d76d5 +Subproject commit ff3d3c8f063f0c935eb057e364363ceeea0431bf From e7d22455a33d64716af98af09acf337cf6f5b026 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 25 Mar 2023 15:47:49 +0800 Subject: [PATCH 54/69] module support symlink --- 3rd/frida_gum/gumpp | 2 +- src/launcher/autoattach/autoattach.cpp | 6 ++++-- src/launcher/config/config.cpp | 14 +++++++++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index ff3d3c8f0..3fcb831c2 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit ff3d3c8f063f0c935eb057e364363ceeea0431bf +Subproject commit 3fcb831c2c6cfc4e8942c31a3dba04095cec55f9 diff --git a/src/launcher/autoattach/autoattach.cpp b/src/launcher/autoattach/autoattach.cpp index 8dd531b8e..269f1d4f7 100644 --- a/src/launcher/autoattach/autoattach.cpp +++ b/src/launcher/autoattach/autoattach.cpp @@ -41,8 +41,10 @@ namespace luadebug::autoattach { if (str.find(s) != std::string_view::npos) return false; } - if (str.find(config.get_lua_module()) != std::string_view::npos) - return true; + + auto target_lua_module = config.get_lua_module(); + if (!target_lua_module.empty() && str.find(config.get_lua_module()) != std::string_view::npos) return true; + if (check_export && Gum::Process::module_find_export_by_name(module_path, find_lua_module_key)) return true; if (Gum::Process::module_find_symbol_by_name(module_path, find_lua_module_key)) return true; // TODO: when signature mode, check strings diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index 62df63e07..56f451248 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -32,11 +32,19 @@ namespace luadebug::autoattach { if (it == values->end()) { return {}; } - const auto& value = it->get(); + auto value = it->get(); if (!fs::exists(value)) - return {}; + return value; - return value; + do { + if (!fs::is_symlink(value)) + return value; + auto link = fs::read_symlink(value); + if (link.is_absolute()) + value = link.string(); + else + value = (fs::path(value).parent_path() / link).lexically_normal().string(); + } while (true); } bool Config::init_from_file() { From d9f53326f77de63a4bce9c672102f32e7d0d64d0 Mon Sep 17 00:00:00 2001 From: fesily Date: Sat, 25 Mar 2023 17:17:14 +0800 Subject: [PATCH 55/69] add signature_resolver --- src/launcher/autoattach/lua_module.cpp | 95 ++++++++++++++++--------- src/launcher/autoattach/lua_module.h | 2 +- src/launcher/config/config.cpp | 6 +- src/launcher/config/config.h | 4 +- src/launcher/resolver/lua_delayload.h | 1 + src/launcher/resolver/lua_resolver.cpp | 23 ++---- src/launcher/resolver/lua_resolver.h | 6 +- src/launcher/resolver/lua_signature.cpp | 21 +++++- src/launcher/resolver/lua_signature.h | 12 +++- 9 files changed, 108 insertions(+), 62 deletions(-) diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index e9b6cc942..9a70d5d9e 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -64,49 +65,56 @@ namespace luadebug::autoattach { // TODO: from signature } - bool load_luadebug_dll(lua_version version, lua_resolver& resolver) { + std::optional get_luadebug_dir(lua_version version) { auto dllpath = bee::path_helper::dll_path(); if (!dllpath) { - return false; + return std::nullopt; } -#define LUADEBUG_FILE "luadebug" + auto os = #if defined(_WIN32) - auto os = "windows"; - auto luadebug_name = - LUADEBUG_FILE - ".dll"; + "windows"; #elif defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) - auto os = "darwin"; - auto luadebug_name = - LUADEBUG_FILE - ".so"; + "darwin"; #else - return false; + "linux"; #endif - ; auto arch = #if defined(_M_ARM64) || defined(__aarch64__) - "arm64" + "arm64"; #elif defined(_M_IX86) || defined(__i386__) - "x86" + "x86"; #elif defined(_M_X64) || defined(__x86_64__) - "x86_64" + "x86_64"; #else - ; - return false; + return std::nullopt; #endif - ; auto platform = std::format("{}-{}", os, arch); - auto path = (dllpath.value().parent_path().parent_path() / "runtime" / platform / lua_version_to_string(version) / luadebug_name).string(); + return dllpath.value().parent_path().parent_path() / "runtime" / platform / lua_version_to_string(version); + } + + bool load_luadebug_dll(lua_version version, lua::resolver& resolver) { +#define LUADEBUG_FILE "luadebug" + +#if defined(_WIN32) +# define EXT ".dll" +#else +# define EXT ".so" +#endif + auto path = get_luadebug_dir(version); + if (!path) { + return false; + } + + auto luadebug = (*path / (LUADEBUG_FILE EXT)).string(); std::string error; - if (!Gum::Process::module_load(path.c_str(), &error)) { - log::fatal("load debugger [{}] failed: {}", path, error); + if (!Gum::Process::module_load(luadebug.c_str(), &error)) { + log::fatal("load debugger [{}] failed: {}", luadebug, error); } - Gum::Process::module_enumerate_import(path.c_str(), [&](const Gum::ImportDetails& details) -> bool { + Gum::Process::module_enumerate_import(luadebug.c_str(), [&](const Gum::ImportDetails& details) -> bool { if (std::string_view(details.name).find_first_of("lua") != 0) { return true; } - if (auto address = (void*)resolver.find_signature(details.name)) { + if (auto address = (void*)resolver.find(details.name)) { *details.slot = address; log::info("find signature {} to {}", details.name, address); } @@ -116,23 +124,46 @@ namespace luadebug::autoattach { } bool lua_module::initialize(fn_attach attach_lua_vm) { - resolver.module_name = path; - auto error_msg = lua::initialize(resolver); + version = get_lua_version(*this); + log::info("current lua version: {}", lua_version_to_string(version)); + + resolver = std::make_unique(path); + if (version != lua_version::unknown && config.is_signature_mode()) { + // 尝试从自带的库里加载函数 + auto dir = get_luadebug_dir(version); + if (dir) { + auto dllpath = +#ifdef _WIN32 + (*dir / lua_version_to_string(version) + std::string(EXT)).string(); +#else + (*dir / "lua" EXT).string(); +#endif + std::string error; + if (!Gum::Process::module_load(dllpath.c_str(), &error)) { + log::info("load lua module {}, failed: {}", dllpath, error); + } + else { + auto signature_resolver_ptr = std::make_unique(); + signature_resolver_ptr->resolver = std::move(resolver); + signature_resolver_ptr->reserve_resolver = + std::make_unique(dllpath); + resolver = std::move(signature_resolver_ptr); + } + } + } + + auto error_msg = lua::initialize(*resolver); if (error_msg) { log::fatal("lua initialize failed, can't find {}", error_msg); return false; } - version = get_lua_version(*this); - log::info("current lua version: {}", lua_version_to_string(version)); - if (version != lua_version::unknown) - resolver.version = lua_version_to_string(version); if (version != lua_version::unknown) { - if (!load_luadebug_dll(version, resolver)) + if (!load_luadebug_dll(version, *resolver)) return false; } - watchdog = create_watchdog(attach_lua_vm, version, resolver); + watchdog = create_watchdog(attach_lua_vm, version, *resolver); if (!watchdog) { // TODO: more errmsg log::fatal("watchdog initialize failed"); diff --git a/src/launcher/autoattach/lua_module.h b/src/launcher/autoattach/lua_module.h index 317379cde..9f9e84812 100644 --- a/src/launcher/autoattach/lua_module.h +++ b/src/launcher/autoattach/lua_module.h @@ -13,7 +13,7 @@ namespace luadebug::autoattach { void* memory_address = 0; size_t memory_size = 0; lua_version version = lua_version::unknown; - lua_resolver resolver; + std::unique_ptr resolver; watchdog* watchdog = nullptr; bool initialize(fn_attach attach_lua_vm); diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index d25afbc3f..76b1fda08 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -27,7 +27,7 @@ namespace luadebug::autoattach { return lua_version_from_string(it->get()); } - std::optional Config::get_lua_signature(const std::string& key) const { + std::optional Config::get_lua_signature(const std::string& key) const { const auto signture_key = "functions"sv; auto it = values->find(signture_key); if (it == values->end()) { @@ -35,8 +35,8 @@ namespace luadebug::autoattach { } try { const auto& json = (*it)[key]; - // searilize json to signture - signture res = {}; + // searilize json to signature + signature res = {}; json["start_offset"].get_to(res.start_offset); json["end_offset"].get_to(res.end_offset); json["pattern"].get_to(res.pattern); diff --git a/src/launcher/config/config.h b/src/launcher/config/config.h index ee4f10ce4..c92644515 100644 --- a/src/launcher/config/config.h +++ b/src/launcher/config/config.h @@ -7,7 +7,7 @@ namespace luadebug::autoattach { enum class lua_version; - struct signture; + struct signature; class Config { std::unique_ptr values; @@ -15,7 +15,7 @@ namespace luadebug::autoattach { public: lua_version get_lua_version() const; - std::optional get_lua_signature(const std::string& key) const; + std::optional get_lua_signature(const std::string& key) const; std::string get_lua_module() const; diff --git a/src/launcher/resolver/lua_delayload.h b/src/launcher/resolver/lua_delayload.h index b1434399b..69d62363d 100644 --- a/src/launcher/resolver/lua_delayload.h +++ b/src/launcher/resolver/lua_delayload.h @@ -18,6 +18,7 @@ namespace luadebug::lua { using hook = void (*)(state, debug); struct resolver { + virtual ~resolver() = default; virtual intptr_t find(std::string_view name) const = 0; }; } diff --git a/src/launcher/resolver/lua_resolver.cpp b/src/launcher/resolver/lua_resolver.cpp index 11e4626d8..a5e4d6504 100644 --- a/src/launcher/resolver/lua_resolver.cpp +++ b/src/launcher/resolver/lua_resolver.cpp @@ -1,4 +1,3 @@ -#include #include #include @@ -16,29 +15,16 @@ namespace luadebug { } intptr_t lua_resolver::find_export(std::string_view name) const { - return (intptr_t)Gum::Process::module_find_export_by_name(module_name.data(), name.data()); + return (intptr_t)Gum::Process::module_find_export_by_name(module_name.c_str(), name.data()); } intptr_t lua_resolver::find_symbol(std::string_view name) const { - return (intptr_t)Gum::Process::module_find_symbol_by_name(module_name.data(), name.data()); - } - - intptr_t lua_resolver::find_signature(std::string_view name) const { - if (!version.empty()) { - if (auto signature = autoattach::config.get_lua_signature(version + "." + std::string(name))) { - return signature->find(module_name.data()); - } - } - - if (auto signature = autoattach::config.get_lua_signature(std::string(name))) { - return signature->find(module_name.data()); - } - return 0; + return (intptr_t)Gum::Process::module_find_symbol_by_name(module_name.c_str(), name.data()); } intptr_t lua_resolver::find(std::string_view name) const { using namespace std::string_view_literals; - for (auto& finder : { &lua_resolver::find_export, &lua_resolver::find_symbol, &lua_resolver::find_signature }) { + for (auto& finder : { &lua_resolver::find_export, &lua_resolver::find_symbol }) { if (auto result = (this->*finder)(name)) { return result; } @@ -57,4 +43,7 @@ namespace luadebug { } return 0; } + lua_resolver::lua_resolver(std::string_view name) + : module_name(std::string(name)) { + } } diff --git a/src/launcher/resolver/lua_resolver.h b/src/launcher/resolver/lua_resolver.h index fc0220c5e..6ca7c98a5 100644 --- a/src/launcher/resolver/lua_resolver.h +++ b/src/launcher/resolver/lua_resolver.h @@ -7,11 +7,11 @@ namespace luadebug { struct lua_resolver : lua::resolver { + lua_resolver(std::string_view name); + ~lua_resolver() = default; intptr_t find(std::string_view name) const override; intptr_t find_export(std::string_view name) const; intptr_t find_symbol(std::string_view name) const; - intptr_t find_signature(std::string_view name) const; - std::string_view module_name; - std::string version; + std::string module_name; }; } \ No newline at end of file diff --git a/src/launcher/resolver/lua_signature.cpp b/src/launcher/resolver/lua_signature.cpp index 4c2a08989..75b0be543 100644 --- a/src/launcher/resolver/lua_signature.cpp +++ b/src/launcher/resolver/lua_signature.cpp @@ -1,9 +1,10 @@ +#include #include +#include #include - namespace luadebug::autoattach { - intptr_t signture::find(const char* module_name) const { + intptr_t signature::find(const char* module_name) const { auto all_address = Gum::search_module_function(module_name, pattern.c_str()); if (all_address.empty()) return 0; @@ -25,9 +26,10 @@ namespace luadebug::autoattach { range.base_address = (void*)((uint8_t*)range.base_address + start_offset); // 限定匹配地址范围 - std::remove_if(all_address.begin(), all_address.end(), [&](void* address) { + auto iter = std::remove_if(all_address.begin(), all_address.end(), [&](void* address) { return !range.contains(address); }); + all_address.erase(iter, all_address.end()); auto hit_index = all_address.size() > hit_offset ? hit_offset : 0; find_address = all_address[hit_index]; @@ -36,4 +38,17 @@ namespace luadebug::autoattach { return (uintptr_t)((uint8_t*)find_address + pattern_offset); return 0; } + + intptr_t signature_resolver::find(std::string_view name) const { + auto addr = resolver->find(name); + if (addr) + return addr; + if (auto signature = config.get_lua_signature(std::string(name))) { + addr = signature->find(module_name.data()); + if (addr) + return addr; + } + log::info("reserve_resolver find: {}", name); + return reserve_resolver->find(name); + } } \ No newline at end of file diff --git a/src/launcher/resolver/lua_signature.h b/src/launcher/resolver/lua_signature.h index 610a86a6f..9d094e0fd 100644 --- a/src/launcher/resolver/lua_signature.h +++ b/src/launcher/resolver/lua_signature.h @@ -1,9 +1,11 @@ #pragma once +#include + #include #include namespace luadebug::autoattach { - struct signture { + struct signature { int32_t start_offset = 0; int32_t end_offset = 0; std::string pattern; @@ -11,4 +13,12 @@ namespace luadebug::autoattach { uint8_t hit_offset = 0; intptr_t find(const char* module_name) const; }; + + struct signature_resolver : lua::resolver { + ~signature_resolver() = default; + intptr_t find(std::string_view name) const override; + std::string module_name; + std::unique_ptr resolver; + std::unique_ptr reserve_resolver; + }; } \ No newline at end of file From 82d832d657b5295946df4116466046b00e1c4609 Mon Sep 17 00:00:00 2001 From: fesily Date: Mon, 27 Mar 2023 10:08:25 +0800 Subject: [PATCH 56/69] Optimize config --- src/launcher/autoattach/autoattach.cpp | 22 +++--- src/launcher/autoattach/lua_module.cpp | 43 ++--------- src/launcher/autoattach/lua_module.h | 2 + src/launcher/autoattach/wait_dll.cpp | 12 +-- src/launcher/autoattach/wait_dll.h | 6 +- src/launcher/config/config.cpp | 103 ++++++++++++++++++++----- src/launcher/config/config.h | 30 +++---- src/launcher/util/log.cpp | 19 ++--- 8 files changed, 140 insertions(+), 97 deletions(-) diff --git a/src/launcher/autoattach/autoattach.cpp b/src/launcher/autoattach/autoattach.cpp index 269f1d4f7..cec38e8e0 100644 --- a/src/launcher/autoattach/autoattach.cpp +++ b/src/launcher/autoattach/autoattach.cpp @@ -35,15 +35,15 @@ namespace luadebug::autoattach { "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" " $", // others }; - static bool is_lua_module(const char* module_path, bool check_export = true, bool check_strings = false) { + static bool is_lua_module(const char* module_path, const config::Config& config, bool check_export = true, bool check_strings = false) { auto str = std::string_view(module_path); for (auto& s : lua_module_backlist) { if (str.find(s) != std::string_view::npos) return false; } - auto target_lua_module = config.get_lua_module(); - if (!target_lua_module.empty() && str.find(config.get_lua_module()) != std::string_view::npos) return true; + auto target_lua_module = config.lua_module; + if (!target_lua_module.empty() && str.find(target_lua_module) != std::string_view::npos) return true; if (check_export && Gum::Process::module_find_export_by_name(module_path, find_lua_module_key)) return true; if (Gum::Process::module_find_symbol_by_name(module_path, find_lua_module_key)) return true; @@ -59,7 +59,7 @@ namespace luadebug::autoattach { } static void start(); - static bool load_lua_module(const std::string& path) { + static bool load_lua_module(const std::string& path, const config::Config& config) { constexpr auto check_export = #ifdef _WIN32 true @@ -67,7 +67,7 @@ namespace luadebug::autoattach { false #endif ; - if (!is_lua_module(path.c_str(), check_export, true)) { + if (!is_lua_module(path.c_str(), config, check_export, true)) { return false; } // find lua module lazy @@ -80,14 +80,15 @@ namespace luadebug::autoattach { } void start() { - if (!Config::init_from_file()) { + auto config = config::init_from_file(); + if (!config) { log::info("can't load config"); return; } bool found = false; lua_module rm = {}; - Gum::Process::enumerate_modules([&rm, &found](const Gum::ModuleDetails& details) -> bool { - if (is_lua_module(details.path())) { + Gum::Process::enumerate_modules([&rm, &found, conf = &(*config)](const Gum::ModuleDetails& details) -> bool { + if (is_lua_module(details.path(), *conf)) { auto range = details.range(); rm.memory_address = range.base_address; rm.memory_size = range.size; @@ -99,12 +100,15 @@ namespace luadebug::autoattach { return true; }); if (!found) { - if (!wait_dll(load_lua_module)) { + if (!wait_dll([conf = std::move(*config)](const std::string& path) { + return load_lua_module(path, conf); + })) { log::fatal("can't find lua module"); } return; } log::info("find lua module path:{}", rm.path); + rm.config = std::move(*config); if (!rm.initialize(attach_lua_vm)) { return; } diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index 9e0ae63ec..77687e0dc 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -14,9 +14,6 @@ namespace luadebug::autoattach { } static lua_version get_lua_version(const lua_module& m) { - auto version = config.get_lua_version(); - if (version != lua_version::unknown) - return version; /* luaJIT_version_2_1_0_beta3 luaJIT_version_2_1_0_beta2 @@ -63,39 +60,10 @@ namespace luadebug::autoattach { } bool load_luadebug_dll(lua_version version) { - auto dllpath = bee::path_helper::dll_path(); - if (!dllpath) { + auto luadebug_path = config::get_luadebug_path(version); + if (!luadebug_path) return false; - } -#define LUADEBUG_FILE "luadebug" -#if defined(_WIN32) - auto os = "windows"; - auto luadebug_name = - LUADEBUG_FILE - ".dll"; -#elif defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) - auto os = "darwin"; - auto luadebug_name = - LUADEBUG_FILE - ".so"; -#else - return false; -#endif - ; - auto arch = -#if defined(_M_ARM64) || defined(__aarch64__) - "arm64" -#elif defined(_M_IX86) || defined(__i386__) - "x86" -#elif defined(_M_X64) || defined(__x86_64__) - "x86_64" -#else - ; - return false; -#endif - ; - auto platform = std::format("{}-{}", os, arch); - auto path = (dllpath.value().parent_path().parent_path() / "runtime" / platform / lua_version_to_string(version) / luadebug_name).string(); + auto path = (*luadebug_path).string(); std::string error; if (!Gum::Process::module_load(path.c_str(), &error)) { log::fatal("load debugger [{}] failed: {}", path, error); @@ -110,7 +78,10 @@ namespace luadebug::autoattach { log::fatal("lua initialize failed, can't find {}", error_msg); return false; } - version = get_lua_version(*this); + version = config.version; + if (version == lua_version::unknown) { + version = get_lua_version(*this); + } log::info("current lua version: {}", lua_version_to_string(version)); if (version != lua_version::unknown) { diff --git a/src/launcher/autoattach/lua_module.h b/src/launcher/autoattach/lua_module.h index 317379cde..f797b74dc 100644 --- a/src/launcher/autoattach/lua_module.h +++ b/src/launcher/autoattach/lua_module.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -15,6 +16,7 @@ namespace luadebug::autoattach { lua_version version = lua_version::unknown; lua_resolver resolver; watchdog* watchdog = nullptr; + config::Config config; bool initialize(fn_attach attach_lua_vm); }; diff --git a/src/launcher/autoattach/wait_dll.cpp b/src/launcher/autoattach/wait_dll.cpp index 5063c7bea..92bd1b4c3 100644 --- a/src/launcher/autoattach/wait_dll.cpp +++ b/src/launcher/autoattach/wait_dll.cpp @@ -32,7 +32,7 @@ extern "C" bool gum_darwin_query_all_image_infos(mach_port_t task, _GumDarwinAll #endif namespace luadebug::autoattach { #ifdef _WIN32 - bool wait_dll(bool (*loaded)(std::string const&)) { + bool wait_dll(WaitDllCallBack_t loaded) { typedef struct _LDR_DLL_UNLOADED_NOTIFICATION_DATA { ULONG Flags; // Reserved. PCUNICODE_STRING FullDllName; // The full path name of the DLL module. @@ -91,19 +91,19 @@ namespace luadebug::autoattach { 0, [](LdrDllNotificationReason NotificationReason, PLDR_DLL_NOTIFICATION_DATA const NotificationData, PVOID Context) { if (NotificationReason == LdrDllNotificationReason::LDR_DLL_NOTIFICATION_REASON_LOADED) { auto path = fs::path(std::wstring(NotificationData->Loaded.FullDllName->Buffer, NotificationData->Loaded.FullDllName->Length)).string(); - auto f = (decltype(loaded))Context; - if (f(path)) { + auto ptr = (decltype(loaded)*)Context; + if ((*ptr)(path)) { if (dllNotification.Cookie) dllNotification.dllUnregisterNotification(dllNotification.Cookie); + delete ptr; } } }, - loaded, &dllNotification.Cookie + (void*)new decltype(loaded)(loaded), &dllNotification.Cookie ); return true; } #elif defined(__APPLE__) - using WaitDllCallBack_t = bool (*)(std::string const&); struct WaitDllListener : Gum::NoLeaveInvocationListener { WaitDllCallBack_t loaded; Gum::RefPtr interceptor; @@ -153,7 +153,7 @@ namespace luadebug::autoattach { // TODO: support linux - bool wait_dll(bool (*loaded)(std::string const&)) { + bool wait_dll(WaitDllCallBack_t loaded) { return false; } #endif diff --git a/src/launcher/autoattach/wait_dll.h b/src/launcher/autoattach/wait_dll.h index 8ace7a505..0c56ef908 100644 --- a/src/launcher/autoattach/wait_dll.h +++ b/src/launcher/autoattach/wait_dll.h @@ -1,7 +1,11 @@ #pragma once +#include + +#include #include namespace luadebug::autoattach { - bool wait_dll(bool (*loaded)(std::string const&)); + using WaitDllCallBack_t = std::function; + bool wait_dll(WaitDllCallBack_t loaded); } diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index 56f451248..eeaafd256 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -11,25 +11,24 @@ #include using namespace std::string_view_literals; -namespace luadebug::autoattach { - Config config; - - lua_version Config::get_lua_version() const { +namespace luadebug::config { + using namespace autoattach; + static lua_version get_lua_version(nlohmann::json& values) { const auto key = "version"sv; - auto it = values->find(key); - if (!values || it == values->end()) { + auto it = values.find(key); + if (!values || it == values.end()) { return lua_version::unknown; } return lua_version_from_string(it->get()); } - std::string Config::get_lua_module() const { + static std::string get_lua_module(nlohmann::json& values) { const auto key = "module"sv; - auto it = values->find(key); - if (it == values->end()) { + auto it = values.find(key); + if (it == values.end()) { return {}; } auto value = it->get(); @@ -47,24 +46,90 @@ namespace luadebug::autoattach { } while (true); } - bool Config::init_from_file() { - config.values = std::make_unique(); - auto dllpath = bee::path_helper::dll_path(); - if (!dllpath) { - return false; - } - auto filename = (dllpath.value().parent_path().parent_path() / "tmp" / std::format("ipc_{}_config", Gum::Process::get_id())).string(); + std::optional init_from_file() { + Config config; + nlohmann::json values; + + auto tmp = get_tmp_dir(); + if (!tmp) + return std::nullopt; + auto filename = ((*tmp) / std::format("ipc_{}_config", Gum::Process::get_id())).string(); std::ifstream s(filename, s.binary); if (!s.is_open()) - return false; + return std::nullopt; try { - s >> *config.values; + s >> values; } catch (const nlohmann::json::exception& e) { log::info("init_from_file error: {}", e.what()); } - return true; + config.version = get_lua_version(values); + config.lua_module = get_lua_module(values); + + return config; + } + + std::optional get_plugin_root() { + auto dllpath = bee::path_helper::dll_path(); + if (!dllpath) { + return std::nullopt; + } + return dllpath.value().parent_path().parent_path(); + } + + std::optional get_tmp_dir() { + auto root = get_plugin_root(); + if (!root) + return std::nullopt; + return (*root) / "tmp"; + } + + std::optional get_runtime_dir() { + auto root = get_plugin_root(); + if (!root) + return std::nullopt; + auto os = +#if defined(_WIN32) + "windows"; +#elif defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) + "darwin"; +#else + "linux"; +#endif + auto arch = +#if defined(_M_ARM64) || defined(__aarch64__) + "arm64"; +#elif defined(_M_IX86) || defined(__i386__) + "x86"; +#elif defined(_M_X64) || defined(__x86_64__) + "x86_64"; +#else +# error "Unknown architecture" +#endif + auto platform = std::format("{}-{}", os, arch); + return (*root) / "runtime" / platform; + } + + std::optional get_lua_runtime_dir(lua_version version) { + auto runtime = get_runtime_dir(); + if (!runtime) + return std::nullopt; + return (*runtime) / lua_version_to_string(version); + } + + std::optional get_luadebug_path(lua_version version) { + auto runtime = get_lua_runtime_dir(version); + if (!runtime) + return std::nullopt; +#define LUADEBUG_FILE "luadebug" + +#if defined(_WIN32) +# define EXT ".dll" +#else +# define EXT ".so" +#endif + return (*runtime) / (LUADEBUG_FILE EXT); } } // namespace luadebug::autoattach \ No newline at end of file diff --git a/src/launcher/config/config.h b/src/launcher/config/config.h index 049df88fd..4d8876e6c 100644 --- a/src/launcher/config/config.h +++ b/src/launcher/config/config.h @@ -1,23 +1,23 @@ +#pragma once +#include +#include + #include -#include #include #include #include #include -namespace luadebug::autoattach { - - enum class lua_version; - class Config { - std::unique_ptr values; - - public: - lua_version get_lua_version() const; - - std::string get_lua_module() const; - - static bool init_from_file(); +namespace luadebug::config { + using lua_version = autoattach::lua_version; + std::optional get_plugin_root(); + std::optional get_tmp_dir(); + std::optional get_runtime_dir(); + std::optional get_lua_runtime_dir(lua_version version); + std::optional get_luadebug_path(lua_version version); + struct Config { + lua_version version = lua_version::unknown; + std::string lua_module; }; - - extern Config config; + std::optional init_from_file(); } // namespace luadebug::autoattach \ No newline at end of file diff --git a/src/launcher/util/log.cpp b/src/launcher/util/log.cpp index afe808782..247dba360 100644 --- a/src/launcher/util/log.cpp +++ b/src/launcher/util/log.cpp @@ -13,6 +13,10 @@ # include #endif +#include + +#include + namespace luadebug::log { static bool attach_mode = false; @@ -55,18 +59,11 @@ namespace luadebug::log { } void notify_frontend(const std::string& msg) { - auto dllpath = bee::path_helper::dll_path(); - if (!dllpath) { + auto tmp = config::get_tmp_dir(); + if (!tmp) return; - } - auto rootpath = dllpath.value().parent_path().parent_path(); - auto path = std::format("{}/tmp/pid_{}", rootpath.generic_u8string(), -#if defined(_WIN32) - GetCurrentProcessId() -#else - getpid() -#endif - ); + auto path = ((*tmp) / std::format("pid_{}", Gum::Process::get_id())).string(); + if (!socket::initialize()) { return; } From b5f9176e8cc316007b1def54d8f925a2fc14703d Mon Sep 17 00:00:00 2001 From: fesily Date: Mon, 27 Mar 2023 10:13:17 +0800 Subject: [PATCH 57/69] fix blacklist --- src/launcher/autoattach/autoattach.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/launcher/autoattach/autoattach.cpp b/src/launcher/autoattach/autoattach.cpp index cec38e8e0..b2cac5aac 100644 --- a/src/launcher/autoattach/autoattach.cpp +++ b/src/launcher/autoattach/autoattach.cpp @@ -13,16 +13,6 @@ namespace luadebug::autoattach { fn_attach debuggerAttach; -#ifdef _WIN32 -# define EXT ".dll" -#else -# define EXT ".so" -#endif - constexpr auto lua_module_backlist = { - "launcher" EXT, - "luadebug" EXT, - }; - constexpr auto find_lua_module_key = "lua_newstate"; constexpr auto lua_module_strings = std::array { "luaJIT_BC_%s", // luajit @@ -37,8 +27,10 @@ namespace luadebug::autoattach { }; static bool is_lua_module(const char* module_path, const config::Config& config, bool check_export = true, bool check_strings = false) { auto str = std::string_view(module_path); - for (auto& s : lua_module_backlist) { - if (str.find(s) != std::string_view::npos) + // black module + auto root = config::get_plugin_root(); + if (root) { + if (str.find((*root).string()) != std::string_view::npos) return false; } From 3e535358090780c5f2173ab6cb7e69ab43819653 Mon Sep 17 00:00:00 2001 From: fesily Date: Mon, 27 Mar 2023 10:17:06 +0800 Subject: [PATCH 58/69] update gumpp --- 3rd/frida_gum/gumpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index 3fcb831c2..c02d1612f 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit 3fcb831c2c6cfc4e8942c31a3dba04095cec55f9 +Subproject commit c02d1612f28263c2cd4e19882c77df496a90d43a From 9c02d9cb9285090ef3c7e5477b97e2918bed4fa5 Mon Sep 17 00:00:00 2001 From: fesily Date: Mon, 27 Mar 2023 10:20:53 +0800 Subject: [PATCH 59/69] optimize wait_dll --- src/launcher/autoattach/wait_dll.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/launcher/autoattach/wait_dll.cpp b/src/launcher/autoattach/wait_dll.cpp index 92bd1b4c3..fa1bc115b 100644 --- a/src/launcher/autoattach/wait_dll.cpp +++ b/src/launcher/autoattach/wait_dll.cpp @@ -91,7 +91,7 @@ namespace luadebug::autoattach { 0, [](LdrDllNotificationReason NotificationReason, PLDR_DLL_NOTIFICATION_DATA const NotificationData, PVOID Context) { if (NotificationReason == LdrDllNotificationReason::LDR_DLL_NOTIFICATION_REASON_LOADED) { auto path = fs::path(std::wstring(NotificationData->Loaded.FullDllName->Buffer, NotificationData->Loaded.FullDllName->Length)).string(); - auto ptr = (decltype(loaded)*)Context; + auto ptr = (WaitDllCallBack_t*)Context; if ((*ptr)(path)) { if (dllNotification.Cookie) dllNotification.dllUnregisterNotification(dllNotification.Cookie); @@ -99,7 +99,7 @@ namespace luadebug::autoattach { } } }, - (void*)new decltype(loaded)(loaded), &dllNotification.Cookie + (void*)new WaitDllCallBack_t(std::move(loaded)), &dllNotification.Cookie ); return true; } @@ -145,7 +145,7 @@ namespace luadebug::autoattach { if (!interceptor) return false; auto listener = new WaitDllListener; - listener->loaded = loaded; + listener->loaded = std::move(loaded); listener->interceptor = interceptor; return interceptor->attach((void*)infos.notification_address, listener, nullptr); } From 6b0fbdb3c7db423e6454ae09365e5759c1da9e34 Mon Sep 17 00:00:00 2001 From: fesily Date: Tue, 28 Mar 2023 09:49:53 +0800 Subject: [PATCH 60/69] fix blacklist --- src/launcher/autoattach/autoattach.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/launcher/autoattach/autoattach.cpp b/src/launcher/autoattach/autoattach.cpp index b2cac5aac..911d327b2 100644 --- a/src/launcher/autoattach/autoattach.cpp +++ b/src/launcher/autoattach/autoattach.cpp @@ -13,6 +13,16 @@ namespace luadebug::autoattach { fn_attach debuggerAttach; +#ifdef _WIN32 +# define EXT ".dll" +#else +# define EXT ".so" +#endif + constexpr auto lua_module_backlist = { + "launcher" EXT, + "luadebug" EXT, + }; + constexpr auto find_lua_module_key = "lua_newstate"; constexpr auto lua_module_strings = std::array { "luaJIT_BC_%s", // luajit @@ -27,11 +37,16 @@ namespace luadebug::autoattach { }; static bool is_lua_module(const char* module_path, const config::Config& config, bool check_export = true, bool check_strings = false) { auto str = std::string_view(module_path); - // black module + // blacklist module auto root = config::get_plugin_root(); if (root) { - if (str.find((*root).string()) != std::string_view::npos) - return false; + if (str.find((*root).string()) != std::string_view::npos) { + // in luadebug root dir + for (auto& s : lua_module_backlist) { + if (str.find(s) != std::string_view::npos) + return false; + } + } } auto target_lua_module = config.lua_module; From a6b082a671effdf9dde955de314f83946694b9f6 Mon Sep 17 00:00:00 2001 From: fesily Date: Tue, 28 Mar 2023 13:24:07 +0800 Subject: [PATCH 61/69] fix miss debugger key --- extension/script/debugger.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/extension/script/debugger.lua b/extension/script/debugger.lua index b61bcfb82..bc1a77787 100644 --- a/extension/script/debugger.lua +++ b/extension/script/debugger.lua @@ -123,6 +123,11 @@ local function detectLuaDebugPath(cfg) lua52 = "lua52", lua51 = "lua51", luajit = "luajit", + ["5.4"] = "lua54", + ["5.3"] = "lua53", + ["5.2"] = "lua52", + ["5.1"] = "lua51", + jit = 'luajit' } if not t[version] then error(version.." is not supported.") From 6a61ba4d4e900da048123ab9fdb040a7a8f717e0 Mon Sep 17 00:00:00 2001 From: fesily Date: Tue, 28 Mar 2023 15:27:25 +0800 Subject: [PATCH 62/69] fix build error --- src/launcher/autoattach/lua_module.cpp | 18 ++++---- src/launcher/config/config.cpp | 56 +++++++++++++------------ src/launcher/config/config.h | 8 ++-- src/launcher/resolver/lua_signature.cpp | 5 ++- src/launcher/resolver/lua_signature.h | 6 ++- 5 files changed, 53 insertions(+), 40 deletions(-) diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index 48c617d4f..86491e638 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -62,11 +62,11 @@ namespace luadebug::autoattach { // TODO: from signature } - bool load_luadebug_dll(lua_version version) { + bool load_luadebug_dll(lua_version version, lua::resolver& resolver) { auto luadebug_path = config::get_luadebug_path(version); if (!luadebug_path) return false; - auto path = (*luadebug_path).string(); + auto luadebug = (*luadebug_path).string(); std::string error; if (!Gum::Process::module_load(luadebug.c_str(), &error)) { log::fatal("load debugger [{}] failed: {}", luadebug, error); @@ -91,21 +91,23 @@ namespace luadebug::autoattach { resolver = std::make_unique(path); if (version != lua_version::unknown && config.is_signature_mode()) { // 尝试从自带的库里加载函数 - auto dir = get_luadebug_dir(version); - if (dir) { + auto runtime_dir = config::get_lua_runtime_dir(version); + if (runtime_dir) { auto dllpath = #ifdef _WIN32 - (*dir / lua_version_to_string(version) + std::string(EXT)).string(); + (*runtime_dir / lua_version_to_string(version) + std::string(".dll")).string(); #else - (*dir / "lua" EXT).string(); + (*runtime_dir / "lua.so").string(); #endif std::string error; if (!Gum::Process::module_load(dllpath.c_str(), &error)) { log::info("load lua module {}, failed: {}", dllpath, error); } else { - auto signature_resolver_ptr = std::make_unique(); - signature_resolver_ptr->resolver = std::move(resolver); + auto signature_resolver_ptr = std::make_unique(); + signature_resolver_ptr->module_name = dllpath; + signature_resolver_ptr->config = &config; + signature_resolver_ptr->resolver = std::move(resolver); signature_resolver_ptr->reserve_resolver = std::make_unique(dllpath); resolver = std::move(signature_resolver_ptr); diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index e37985f80..7459363c3 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -27,29 +27,6 @@ namespace luadebug::config { } static std::string get_lua_module(nlohmann::json& values) { - std::optional Config::get_lua_signature(const std::string& key) const { - const auto signture_key = "functions"sv; - auto it = values->find(signture_key); - if (it == values->end()) { - return std::nullopt; - } - try { - const auto& json = (*it)[key]; - // searilize json to signature - signature res = {}; - json["start_offset"].get_to(res.start_offset); - json["end_offset"].get_to(res.end_offset); - json["pattern"].get_to(res.pattern); - json["pattern_offset"].get_to(res.pattern_offset); - json["hit_offset"].get_to(res.hit_offset); - return res; - } catch (const nlohmann::json::exception& e) { - log::info("get_lua_signature {} error: {}", key, e.what()); - } - return std::nullopt; - } - - std::string Config::get_lua_module() const { const auto key = "module"sv; auto it = values.find(key); @@ -71,12 +48,37 @@ namespace luadebug::config { } while (true); } + static std::map get_lua_signature(const nlohmann::json& values) { + const auto signture_key = "functions"sv; + auto it = values.find(signture_key); + if (it == values.end()) { + return {}; + } + try { + std::map signatures; + for (auto& [key, val] : it->items()) { + // searilize json to signature + signature res = {}; + val["start_offset"].get_to(res.start_offset); + val["end_offset"].get_to(res.end_offset); + val["pattern"].get_to(res.pattern); + val["pattern_offset"].get_to(res.pattern_offset); + val["hit_offset"].get_to(res.hit_offset); + + signatures.emplace(key, res); + } + return signatures; + } catch (const nlohmann::json::exception& e) { + log::info("get_lua_signature error: {}", e.what()); + } + return {}; + } + bool Config::is_signature_mode() const { - return !values->is_null(); + return !signatures.empty(); } std::optional init_from_file() { - Config config; nlohmann::json values; auto tmp = get_tmp_dir(); @@ -93,8 +95,10 @@ namespace luadebug::config { log::info("init_from_file error: {}", e.what()); } + Config config; config.version = get_lua_version(values); config.lua_module = get_lua_module(values); + config.signatures = get_lua_signature(values); return config; } @@ -161,4 +165,4 @@ namespace luadebug::config { return (*runtime) / (LUADEBUG_FILE EXT); } -} // namespace luadebug::autoattach \ No newline at end of file +} // namespace luadebug::config \ No newline at end of file diff --git a/src/launcher/config/config.h b/src/launcher/config/config.h index fb1d710ba..59e5087f6 100644 --- a/src/launcher/config/config.h +++ b/src/launcher/config/config.h @@ -1,15 +1,17 @@ #pragma once #include #include +#include +#include #include #include #include #include -#include namespace luadebug::config { using lua_version = autoattach::lua_version; + using signature = autoattach::signature; std::optional get_plugin_root(); std::optional get_tmp_dir(); std::optional get_runtime_dir(); @@ -18,8 +20,8 @@ namespace luadebug::config { struct Config { lua_version version = lua_version::unknown; std::string lua_module; + std::map signatures; bool is_signature_mode() const; - std::optional get_lua_signature(const std::string& key) const; }; std::optional init_from_file(); -} // namespace luadebug::autoattach \ No newline at end of file +} // namespace luadebug::config \ No newline at end of file diff --git a/src/launcher/resolver/lua_signature.cpp b/src/launcher/resolver/lua_signature.cpp index 75b0be543..9e65189e9 100644 --- a/src/launcher/resolver/lua_signature.cpp +++ b/src/launcher/resolver/lua_signature.cpp @@ -43,8 +43,9 @@ namespace luadebug::autoattach { auto addr = resolver->find(name); if (addr) return addr; - if (auto signature = config.get_lua_signature(std::string(name))) { - addr = signature->find(module_name.data()); + + if (auto it = config->signatures.find(std::string(name)); it != config->signatures.end()) { + addr = it->second.find(module_name.data()); if (addr) return addr; } diff --git a/src/launcher/resolver/lua_signature.h b/src/launcher/resolver/lua_signature.h index 9d094e0fd..528fb8462 100644 --- a/src/launcher/resolver/lua_signature.h +++ b/src/launcher/resolver/lua_signature.h @@ -3,8 +3,11 @@ #include #include - +namespace luadebug::config { + struct Config; +} namespace luadebug::autoattach { + struct signature { int32_t start_offset = 0; int32_t end_offset = 0; @@ -18,6 +21,7 @@ namespace luadebug::autoattach { ~signature_resolver() = default; intptr_t find(std::string_view name) const override; std::string module_name; + config::Config* config; std::unique_ptr resolver; std::unique_ptr reserve_resolver; }; From 4ca910973e100d786ca3586e0dfaca2e0b3cd20c Mon Sep 17 00:00:00 2001 From: fesily Date: Tue, 28 Mar 2023 15:35:59 +0800 Subject: [PATCH 63/69] fix win err --- src/launcher/autoattach/lua_module.cpp | 2 +- src/launcher/resolver/lua_signature.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/launcher/autoattach/lua_module.cpp b/src/launcher/autoattach/lua_module.cpp index 86491e638..d0d5f1507 100644 --- a/src/launcher/autoattach/lua_module.cpp +++ b/src/launcher/autoattach/lua_module.cpp @@ -95,7 +95,7 @@ namespace luadebug::autoattach { if (runtime_dir) { auto dllpath = #ifdef _WIN32 - (*runtime_dir / lua_version_to_string(version) + std::string(".dll")).string(); + (*runtime_dir / (lua_version_to_string(version) + std::string(".dll"))).string(); #else (*runtime_dir / "lua.so").string(); #endif diff --git a/src/launcher/resolver/lua_signature.h b/src/launcher/resolver/lua_signature.h index 528fb8462..379d26779 100644 --- a/src/launcher/resolver/lua_signature.h +++ b/src/launcher/resolver/lua_signature.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include namespace luadebug::config { From 3b18cc6678ed7d581743e75a608ed499389d2d0b Mon Sep 17 00:00:00 2001 From: fesily Date: Wed, 29 Mar 2023 16:56:49 +0800 Subject: [PATCH 64/69] Update config.cpp --- src/launcher/config/config.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index eeaafd256..80ff68577 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -17,7 +17,7 @@ namespace luadebug::config { const auto key = "version"sv; auto it = values.find(key); - if (!values || it == values.end()) { + if (it == values.end()) { return lua_version::unknown; } @@ -132,4 +132,4 @@ namespace luadebug::config { return (*runtime) / (LUADEBUG_FILE EXT); } -} // namespace luadebug::autoattach \ No newline at end of file +} // namespace luadebug::autoattach From 1075d3151ae9477faecc73ea771baa36b6f817a2 Mon Sep 17 00:00:00 2001 From: fesily Date: Wed, 29 Mar 2023 17:10:55 +0800 Subject: [PATCH 65/69] fix err --- 3rd/frida_gum/gumpp | 2 +- compile/common/package_json.lua | 48 ++++++++++------------- compile/signature_compiler.lua | 22 ++++++----- extension/script/frontend/proxy.lua | 3 +- src/launcher/config/config.cpp | 4 +- src/launcher/tools/signature_compiler.cpp | 2 +- 6 files changed, 40 insertions(+), 41 deletions(-) diff --git a/3rd/frida_gum/gumpp b/3rd/frida_gum/gumpp index c02d1612f..757c11c69 160000 --- a/3rd/frida_gum/gumpp +++ b/3rd/frida_gum/gumpp @@ -1 +1 @@ -Subproject commit c02d1612f28263c2cd4e19882c77df496a90d43a +Subproject commit 757c11c69a409c7970016d991f5f513b86a92aa5 diff --git a/compile/common/package_json.lua b/compile/common/package_json.lua index 19390c7c6..e9e4e75db 100644 --- a/compile/common/package_json.lua +++ b/compile/common/package_json.lua @@ -257,37 +257,31 @@ Debugger address. markdownDescription = "specify lua module path/name", type = "string", }, - signature = { + signatures = { default = "null", type = "object", markdownDescription = "signature info", - properties = { - functions = { - type = "object", - additionalProperties = { - type = "object", - properties = { - start_offset = { - type = "integer" - }, - end_offset = { - type = "integer" - }, - pattern = { - type = "string" - }, - pattern_offset = { - type = "integer" - }, - hit_offset = { - type = "integer", - } - }, - required = { "pattern" } + additionalProperties = { + type = "object", + properties = { + start_offset = { + type = "integer" + }, + end_offset = { + type = "integer" + }, + pattern = { + type = "string" + }, + pattern_offset = { + type = "integer" + }, + hit_offset = { + type = "integer", } - } - }, - required = { "functions" } + }, + required = { "pattern" } + } } } diff --git a/compile/signature_compiler.lua b/compile/signature_compiler.lua index 0f9d210df..71f0653f3 100644 --- a/compile/signature_compiler.lua +++ b/compile/signature_compiler.lua @@ -55,6 +55,7 @@ local function compiler(executable, import_file, is_string, lua_modlue) lua_modlue, option.is_export and "true" or "false", stdout = true, + stderr = true, }) local res = {} for line in process.stdout:lines() do @@ -72,10 +73,9 @@ local function compiler(executable, import_file, is_string, lua_modlue) local code = process:wait() if code ~= 0 then - print("signature_compiler error", code) + print("signature_compiler error:\n", process.stderr:read "a") os.exit(code, true) end - return res end @@ -105,15 +105,19 @@ for _, t in ipairs(luadebug_files) do local executable = get_executable(t.platform_arch) local t1 = compiler(executable, launcher_path, true, lua_modlue) local t2 = compiler(executable, t.luadebug, false, lua_modlue) - local signatures = table.pack(table.unpack(t1), table.unpack(t2)) local output = {} - for _, signature in ipairs(signatures) do - output[signature.name] = { - pattern = signature.pattern, - offset = signature.offset, - hit_offset = signature.hit_offset, - } + local function scan_output(signatures) + for _, signature in ipairs(signatures) do + output[signature.name] = { + pattern = signature.pattern, + offset = signature.offset, + hit_offset = signature.hit_offset, + } + end end + scan_output(t1) + scan_output(t2) + local file = io.open((output_dir / (t.version..".json")):string(), "w") file:write(json.beautify(output)) file:close() diff --git a/extension/script/frontend/proxy.lua b/extension/script/frontend/proxy.lua index cb7084c51..5343c47f6 100644 --- a/extension/script/frontend/proxy.lua +++ b/extension/script/frontend/proxy.lua @@ -24,7 +24,8 @@ local function ipc_send_config(pid, args) local fd = assert(ipc(WORKDIR, pid, "config", "w")) local config = { version = args.luaVersion, - module = args.module + module = args.module, + signatures = args.signatures } fd:write(json.encode(config)) fd:close() diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index 7459363c3..bcf53baf6 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -19,7 +19,7 @@ namespace luadebug::config { const auto key = "version"sv; auto it = values.find(key); - if (!values || it == values.end()) { + if (it == values.end()) { return lua_version::unknown; } @@ -49,7 +49,7 @@ namespace luadebug::config { } static std::map get_lua_signature(const nlohmann::json& values) { - const auto signture_key = "functions"sv; + const auto signture_key = "signatures"sv; auto it = values.find(signture_key); if (it == values.end()) { return {}; diff --git a/src/launcher/tools/signature_compiler.cpp b/src/launcher/tools/signature_compiler.cpp index 7eb487707..73cc18fb2 100644 --- a/src/launcher/tools/signature_compiler.cpp +++ b/src/launcher/tools/signature_compiler.cpp @@ -32,7 +32,7 @@ int imports(std::string file_path, bool is_string, std::set& import if (name.find('_') == std::string_view::npos) { continue; } - if (name.find_first_of(" .*/\\:<>|\"?") != std::string_view::npos) { + if (name.find_first_of(" .*/\\:<>|\"?%") != std::string_view::npos) { continue; } if (name.find("lua") != 0) { From b272ecb615face8298ed8cf777121c05976c0d6b Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 30 Mar 2023 13:46:20 +0800 Subject: [PATCH 66/69] fix launch mode --- src/launcher/autoattach/autoattach.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/launcher/autoattach/autoattach.cpp b/src/launcher/autoattach/autoattach.cpp index 911d327b2..1c6be49b3 100644 --- a/src/launcher/autoattach/autoattach.cpp +++ b/src/launcher/autoattach/autoattach.cpp @@ -90,7 +90,6 @@ namespace luadebug::autoattach { auto config = config::init_from_file(); if (!config) { log::info("can't load config"); - return; } bool found = false; lua_module rm = {}; From e2b6068cc3dd4d02f3e1e5b34d14f4a5da30b99c Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 30 Mar 2023 13:49:46 +0800 Subject: [PATCH 67/69] fix launch config --- extension/script/frontend/debuger_factory.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extension/script/frontend/debuger_factory.lua b/extension/script/frontend/debuger_factory.lua index 577738cc4..49f862f93 100644 --- a/extension/script/frontend/debuger_factory.lua +++ b/extension/script/frontend/debuger_factory.lua @@ -221,6 +221,9 @@ local function create_process_in_console(args, callback) if not process then return nil, err end + if callback then + callback(process) + end if args.inject ~= "none" then local ok, errmsg = process_inject.inject(process, "launch", args) if not ok then @@ -231,9 +234,6 @@ local function create_process_in_console(args, callback) end end end - if callback then - callback(process) - end if need_resume then process:resume() end From 30918bc777e95182df784c1e578f9758524a1ef6 Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 30 Mar 2023 15:01:51 +0800 Subject: [PATCH 68/69] fix get_runtime_dir --- src/launcher/config/config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/launcher/config/config.cpp b/src/launcher/config/config.cpp index 56a3b5822..d8d6e5129 100644 --- a/src/launcher/config/config.cpp +++ b/src/launcher/config/config.cpp @@ -136,7 +136,7 @@ namespace luadebug::config { #elif defined(_M_IX86) || defined(__i386__) "x86"; #elif defined(_M_X64) || defined(__x86_64__) - "x86_64"; + "x64"; #else # error "Unknown architecture" #endif From 4590e63b4e6fb0abe2193113b04655f15722878d Mon Sep 17 00:00:00 2001 From: fesily Date: Thu, 30 Mar 2023 16:26:53 +0800 Subject: [PATCH 69/69] watch_point add lua_newstate --- src/launcher/hook/create_watchdog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/launcher/hook/create_watchdog.cpp b/src/launcher/hook/create_watchdog.cpp index 09696d83f..772f915f3 100644 --- a/src/launcher/hook/create_watchdog.cpp +++ b/src/launcher/hook/create_watchdog.cpp @@ -36,6 +36,7 @@ namespace luadebug::autoattach { }; default: return { + { watch_point::type::common, "lua_newstate" }, { watch_point::type::common, "lua_settop" }, { watch_point::type::common, "luaL_openlibs" }, { watch_point::type::common, "lua_newthread" },