#include "utils.hpp" #include #include #include #include #include #include "il2cpp.hpp" struct enum_so_info { const char* name; void* base_addr; }; static int get_so_base_callback(struct dl_phdr_info *info, size_t size, void *data) { auto* enum_info = (enum_so_info *)data; if (info->dlpi_name && strstr(info->dlpi_name, enum_info->name)) { enum_info->base_addr = (void*)info->dlpi_addr; } return 0; } void* Utils::get_so_base_address(const std::string& name) { enum_so_info so_info = {name.c_str(), nullptr}; dl_iterate_phdr(get_so_base_callback, &so_info); if (so_info.base_addr) { SPDLOG_INFO("Found {} at {}", name.c_str(), so_info.base_addr); return so_info.base_addr; } // TODO: throw exception instead of returning nullptr return nullptr; } lua_State* Utils::get_lua_state() { void* il2cpp_base_addr = get_so_base_address("libil2cpp.so"); LuaScriptMgr_get_Inst get_instance = reinterpret_cast(PTR_ADD(il2cpp_base_addr, LuaScriptMgr_get_Inst_OFFSET)); struct LuaScriptMgr_o* lua_script_mgr = get_instance(); LuaInterface_LuaState_o* luaState = nullptr; while (luaState == nullptr) { luaState = lua_script_mgr->fields.luaState; std::this_thread::sleep_for(std::chrono::seconds(1)); } SPDLOG_INFO("lua_State: {}", (void*)luaState->fields.L); // std::this_thread::sleep_for(std::chrono::seconds(10)); return (lua_State*)luaState->fields.L; } std::string Utils::Lua::get_type_name(sol::type t) { switch (t) { case sol::type::nil: return "nil"; case sol::type::boolean: return "boolean"; case sol::type::lightuserdata: return "lightuserdata"; case sol::type::number: return "number"; case sol::type::string: return "string"; case sol::type::table: return "table"; case sol::type::function: return "function"; case sol::type::userdata: return "userdata"; case sol::type::thread: return "thread"; case sol::type::poly: return "poly"; default: return "unknown"; } } std::string Utils::Lua::get_type_name(sol::object& o) { return get_type_name(o.get_type()); } void Utils::Lua::print_table_fields_type(sol::table& t) { for (auto& [k, v] : t) { SPDLOG_INFO("key: {}, type: {}", k.as(), get_type_name(v)); } } void Utils::Lua::print_traceback(sol::this_state& L) { sol::state_view state(L); sol::function trace = state["debug"]["traceback"]; std::string trace_str = trace(); SPDLOG_INFO("trace: {}", trace_str); }