Remove Riru support

The repository RikkaApps/Riru is archived since Jan 8, 2024, which
recommends Zygisk as its alternative.
This commit is contained in:
JingMatrix 2024-09-23 07:29:11 +02:00
parent ea2e1c8518
commit 4d8e01176f
9 changed files with 95 additions and 533 deletions

View File

@ -104,27 +104,11 @@ jobs:
if: success() if: success()
id: prepareArtifact id: prepareArtifact
run: | run: |
riruReleaseName=`ls magisk-loader/release/LSPosed-v*-riru-release.zip | awk -F '(/|.zip)' '{print $3}'` && echo "riruReleaseName=$riruReleaseName" >> $GITHUB_OUTPUT
riruDebugName=`ls magisk-loader/release/LSPosed-v*-riru-debug.zip | awk -F '(/|.zip)' '{print $3}'` && echo "riruDebugName=$riruDebugName" >> $GITHUB_OUTPUT
zygiskReleaseName=`ls magisk-loader/release/LSPosed-v*-zygisk-release.zip | awk -F '(/|.zip)' '{print $3}'` && echo "zygiskReleaseName=$zygiskReleaseName" >> $GITHUB_OUTPUT zygiskReleaseName=`ls magisk-loader/release/LSPosed-v*-zygisk-release.zip | awk -F '(/|.zip)' '{print $3}'` && echo "zygiskReleaseName=$zygiskReleaseName" >> $GITHUB_OUTPUT
zygiskDebugName=`ls magisk-loader/release/LSPosed-v*-zygisk-debug.zip | awk -F '(/|.zip)' '{print $3}'` && echo "zygiskDebugName=$zygiskDebugName" >> $GITHUB_OUTPUT zygiskDebugName=`ls magisk-loader/release/LSPosed-v*-zygisk-debug.zip | awk -F '(/|.zip)' '{print $3}'` && echo "zygiskDebugName=$zygiskDebugName" >> $GITHUB_OUTPUT
unzip magisk-loader/release/LSPosed-v*-riru-release.zip -d LSPosed-riru-release
unzip magisk-loader/release/LSPosed-v*-riru-debug.zip -d LSPosed-riru-debug
unzip magisk-loader/release/LSPosed-v*-zygisk-release.zip -d LSPosed-zygisk-release unzip magisk-loader/release/LSPosed-v*-zygisk-release.zip -d LSPosed-zygisk-release
unzip magisk-loader/release/LSPosed-v*-zygisk-debug.zip -d LSPosed-zygisk-debug unzip magisk-loader/release/LSPosed-v*-zygisk-debug.zip -d LSPosed-zygisk-debug
- name: Upload riru release
uses: actions/upload-artifact@v4
with:
name: ${{ steps.prepareArtifact.outputs.riruReleaseName }}
path: "./LSPosed-riru-release/*"
- name: Upload riru debug
uses: actions/upload-artifact@v4
with:
name: ${{ steps.prepareArtifact.outputs.riruDebugName }}
path: "./LSPosed-riru-debug/*"
- name: Upload zygisk release - name: Upload zygisk release
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:

View File

@ -4,7 +4,7 @@
## Introduction ## Introduction
A Riru / Zygisk module trying to provide an ART hooking framework which delivers consistent APIs with the OG Xposed, leveraging LSPlant hooking framework. A Zygisk module trying to provide an ART hooking framework which delivers consistent APIs with the OG Xposed, leveraging LSPlant hooking framework.
> Xposed is a framework for modules that can change the behavior of the system and apps without touching any APKs. That's great because it means that modules can work for different versions and even ROMs without any changes (as long as the original code was not changed too much). It's also easy to undo. As all changes are done in the memory, you just need to deactivate the module and reboot to get your original system back. There are many other advantages, but here is just one more: multiple modules can do changes to the same part of the system or app. With modified APKs, you have to choose one. No way to combine them, unless the author builds multiple APKs with different combinations. > Xposed is a framework for modules that can change the behavior of the system and apps without touching any APKs. That's great because it means that modules can work for different versions and even ROMs without any changes (as long as the original code was not changed too much). It's also easy to undo. As all changes are done in the memory, you just need to deactivate the module and reboot to get your original system back. There are many other advantages, but here is just one more: multiple modules can do changes to the same part of the system or app. With modified APKs, you have to choose one. No way to combine them, unless the author builds multiple APKs with different combinations.
@ -55,13 +55,13 @@ You can contribute translation [here](https://crowdin.com/project/lsposed_jingma
## Credits ## Credits
- [Magisk](https://github.com/topjohnwu/Magisk/): makes all these possible - [Magisk](https://github.com/topjohnwu/Magisk/): makes all these possible
- [Riru](https://github.com/RikkaApps/Riru): provides a way to inject code into zygote process
- [XposedBridge](https://github.com/rovo89/XposedBridge): the OG Xposed framework APIs - [XposedBridge](https://github.com/rovo89/XposedBridge): the OG Xposed framework APIs
- [LSPlt](https://github.com/LSPosed/LSPlt): used for (Android 15) `libart` inline hooking - [LSPlt](https://github.com/LSPosed/LSPlt): used for (Android 15) `libart` inline hooking
- [Dobby](https://github.com/JingMatrix/Dobby): used for fallback and `native_api` inline hooking - [Dobby](https://github.com/JingMatrix/Dobby): used for fallback and `native_api` inline hooking
- [LSPlant](https://github.com/JingMatrix/LSPlant): the core ART hooking framework - [LSPlant](https://github.com/JingMatrix/LSPlant): the core ART hooking framework
- [EdXposed](https://github.com/ElderDrivers/EdXposed): fork source - [EdXposed](https://github.com/ElderDrivers/EdXposed): fork source
- [xz-embedded](https://github.com/tukaani-project/xz-embedded): decompress `.gnu_debugdata` header section of stripped `libart.so` - [xz-embedded](https://github.com/tukaani-project/xz-embedded): decompress `.gnu_debugdata` header section of stripped `libart.so`
- ~~[Riru](https://github.com/RikkaApps/Riru): provides a way to inject code into zygote process~~
- ~[SandHook](https://github.com/ganyao114/SandHook/): ART hooking framework for SandHook variant~ - ~[SandHook](https://github.com/ganyao114/SandHook/): ART hooking framework for SandHook variant~
- ~[YAHFA](https://github.com/rk700/YAHFA): previous ART hooking framework~ - ~[YAHFA](https://github.com/rk700/YAHFA): previous ART hooking framework~
- ~[dexmaker](https://github.com/linkedin/dexmaker) and [dalvikdx](https://github.com/JakeWharton/dalvik-dx): to dynamically generate YAHFA hooker classes~ - ~[dexmaker](https://github.com/linkedin/dexmaker) and [dalvikdx](https://github.com/JakeWharton/dalvik-dx): to dynamically generate YAHFA hooker classes~

View File

@ -1,16 +1,17 @@
#include "logcat.h" #include "logcat.h"
#include <jni.h>
#include <unistd.h>
#include <string>
#include <android/log.h> #include <android/log.h>
#include <jni.h>
#include <sys/system_properties.h>
#include <unistd.h>
#include <array> #include <array>
#include <atomic> #include <atomic>
#include <cinttypes>
#include <chrono> #include <chrono>
#include <thread> #include <cinttypes>
#include <functional> #include <functional>
#include <sys/system_properties.h> #include <string>
#include <thread>
using namespace std::string_view_literals; using namespace std::string_view_literals;
using namespace std::chrono_literals; using namespace std::chrono_literals;
@ -19,74 +20,75 @@ constexpr size_t kMaxLogSize = 4 * 1024 * 1024;
constexpr size_t kLogBufferSize = 64 * 1024; constexpr size_t kLogBufferSize = 64 * 1024;
namespace { namespace {
constexpr std::array<char, ANDROID_LOG_SILENT + 1> kLogChar = { constexpr std::array<char, ANDROID_LOG_SILENT + 1> kLogChar = {
/*ANDROID_LOG_UNKNOWN*/'?', /*ANDROID_LOG_UNKNOWN*/ '?',
/*ANDROID_LOG_DEFAULT*/ '?', /*ANDROID_LOG_DEFAULT*/ '?',
/*ANDROID_LOG_VERBOSE*/ 'V', /*ANDROID_LOG_VERBOSE*/ 'V',
/*ANDROID_LOG_DEBUG*/ 'D', /*ANDROID_LOG_DEBUG*/ 'D',
/*ANDROID_LOG_INFO*/'I', /*ANDROID_LOG_INFO*/ 'I',
/*ANDROID_LOG_WARN*/'W', /*ANDROID_LOG_WARN*/ 'W',
/*ANDROID_LOG_ERROR*/ 'E', /*ANDROID_LOG_ERROR*/ 'E',
/*ANDROID_LOG_FATAL*/ 'F', /*ANDROID_LOG_FATAL*/ 'F',
/*ANDROID_LOG_SILENT*/ 'S', /*ANDROID_LOG_SILENT*/ 'S',
}; };
size_t ParseUint(const char *s) { size_t ParseUint(const char *s) {
if (s[0] == '\0') return -1; if (s[0] == '\0') return -1;
while (isspace(*s)) { while (isspace(*s)) {
s++; s++;
} }
if (s[0] == '-') { if (s[0] == '-') {
return -1;
}
int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10;
char *end;
auto result = strtoull(s, &end, base);
if (end == s) {
return -1;
}
if (*end != '\0') {
const char *suffixes = "bkmgtpe";
const char *suffix;
if ((suffix = strchr(suffixes, tolower(*end))) == nullptr ||
__builtin_mul_overflow(result, 1ULL << (10 * (suffix - suffixes)), &result)) {
return -1; return -1;
} }
int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10;
char *end;
auto result = strtoull(s, &end, base);
if (end == s) {
return -1;
}
if (*end != '\0') {
const char *suffixes = "bkmgtpe";
const char *suffix;
if ((suffix = strchr(suffixes, tolower(*end))) == nullptr ||
__builtin_mul_overflow(result, 1ULL << (10 * (suffix - suffixes)), &result)) {
return -1;
}
}
if (std::numeric_limits<size_t>::max() < result) {
return -1;
}
return static_cast<size_t>(result);
} }
if (std::numeric_limits<size_t>::max() < result) {
inline size_t GetByteProp(std::string_view prop, size_t def = -1) { return -1;
std::array<char, PROP_VALUE_MAX> buf{};
if (__system_property_get(prop.data(), buf.data()) < 0) return def;
return ParseUint(buf.data());
} }
return static_cast<size_t>(result);
}
inline std::string GetStrProp(std::string_view prop, std::string def = {}) { inline size_t GetByteProp(std::string_view prop, size_t def = -1) {
std::array<char, PROP_VALUE_MAX> buf{}; std::array<char, PROP_VALUE_MAX> buf{};
if (__system_property_get(prop.data(), buf.data()) < 0) return def; if (__system_property_get(prop.data(), buf.data()) < 0) return def;
return {buf.data()}; return ParseUint(buf.data());
} }
inline bool SetIntProp(std::string_view prop, int val) { inline std::string GetStrProp(std::string_view prop, std::string def = {}) {
auto buf = std::to_string(val); std::array<char, PROP_VALUE_MAX> buf{};
return __system_property_set(prop.data(), buf.data()) >= 0; if (__system_property_get(prop.data(), buf.data()) < 0) return def;
} return {buf.data()};
}
inline bool SetStrProp(std::string_view prop, std::string_view val) { inline bool SetIntProp(std::string_view prop, int val) {
return __system_property_set(prop.data(), val.data()) >= 0; auto buf = std::to_string(val);
} return __system_property_set(prop.data(), buf.data()) >= 0;
}
inline bool SetStrProp(std::string_view prop, std::string_view val) {
return __system_property_set(prop.data(), val.data()) >= 0;
}
} // namespace } // namespace
class UniqueFile : public std::unique_ptr<FILE, std::function<void(FILE *)>> { class UniqueFile : public std::unique_ptr<FILE, std::function<void(FILE *)>> {
inline static deleter_type deleter = [](auto f) { f && f != stdout && fclose(f); }; inline static deleter_type deleter = [](auto f) { f &&f != stdout &&fclose(f); };
public: public:
explicit UniqueFile(FILE *f) : std::unique_ptr<FILE, std::function<void(FILE *)>>(f, deleter) {} explicit UniqueFile(FILE *f) : std::unique_ptr<FILE, std::function<void(FILE *)>>(f, deleter) {}
@ -97,8 +99,8 @@ public:
class Logcat { class Logcat {
public: public:
explicit Logcat(JNIEnv *env, jobject thiz, jmethodID method) : explicit Logcat(JNIEnv *env, jobject thiz, jmethodID method)
env_(env), thiz_(thiz), refresh_fd_method_(method) {} : env_(env), thiz_(thiz), refresh_fd_method_(method) {}
[[noreturn]] void Run(); [[noreturn]] void Run();
@ -136,7 +138,7 @@ private:
size_t Logcat::PrintLogLine(const AndroidLogEntry &entry, FILE *out) { size_t Logcat::PrintLogLine(const AndroidLogEntry &entry, FILE *out) {
if (!out) return 0; if (!out) return 0;
constexpr static size_t kMaxTimeBuff = 64; constexpr static size_t kMaxTimeBuff = 64;
struct tm tm{}; struct tm tm {};
std::array<char, kMaxTimeBuff> time_buff{}; std::array<char, kMaxTimeBuff> time_buff{};
auto now = entry.tv_sec; auto now = entry.tv_sec;
@ -151,12 +153,10 @@ size_t Logcat::PrintLogLine(const AndroidLogEntry &entry, FILE *out) {
} }
localtime_r(&now, &tm); localtime_r(&now, &tm);
strftime(time_buff.data(), time_buff.size(), "%Y-%m-%dT%H:%M:%S", &tm); strftime(time_buff.data(), time_buff.size(), "%Y-%m-%dT%H:%M:%S", &tm);
int len = fprintf(out, "[ %s.%03ld %8d:%6d:%6d %c/%-15.*s ] %.*s\n", int len =
time_buff.data(), fprintf(out, "[ %s.%03ld %8d:%6d:%6d %c/%-15.*s ] %.*s\n", time_buff.data(),
nsec / MS_PER_NSEC, nsec / MS_PER_NSEC, entry.uid, entry.pid, entry.tid, kLogChar[entry.priority],
entry.uid, entry.pid, entry.tid, static_cast<int>(entry.tagLen), entry.tag, static_cast<int>(message_len), message);
kLogChar[entry.priority], static_cast<int>(entry.tagLen),
entry.tag, static_cast<int>(message_len), message);
fflush(out); fflush(out);
// trigger overflow when failed to generate a new fd // trigger overflow when failed to generate a new fd
if (len <= 0) len = kMaxLogSize; if (len <= 0) len = kMaxLogSize;
@ -222,13 +222,13 @@ void Logcat::ProcessBuffer(struct log_msg *buf) {
std::string_view tag(entry.tag, entry.tagLen); std::string_view tag(entry.tag, entry.tagLen);
bool shortcut = false; bool shortcut = false;
if (tag == "LSPosed-Bridge"sv || tag == "XSharedPreferences"sv || tag == "LSPosedContext") [[unlikely]] { if (tag == "LSPosed-Bridge"sv || tag == "XSharedPreferences"sv || tag == "LSPosedContext")
[[unlikely]] {
modules_print_count_ += PrintLogLine(entry, modules_file_.get()); modules_print_count_ += PrintLogLine(entry, modules_file_.get());
shortcut = true; shortcut = true;
} }
if (verbose_ && (shortcut || buf->id() == log_id::LOG_ID_CRASH || if (verbose_ && (shortcut || buf->id() == log_id::LOG_ID_CRASH || entry.pid == my_pid_ ||
entry.pid == my_pid_ || tag == "Magisk"sv || tag == "LSPlt"sv || tag == "Magisk"sv || tag == "LSPlt"sv || tag.starts_with("zygisk"sv) ||
tag.starts_with("Riru"sv) || tag.starts_with("zygisk"sv) ||
tag == "LSPlant"sv || tag.starts_with("LSPosed"sv))) [[unlikely]] { tag == "LSPlant"sv || tag.starts_with("LSPosed"sv))) [[unlikely]] {
verbose_print_count_ += PrintLogLine(entry, verbose_file_.get()); verbose_print_count_ += PrintLogLine(entry, verbose_file_.get());
} }
@ -270,8 +270,7 @@ void Logcat::EnsureLogWatchDog() {
!((logd_main_size == kErr && logd_crash_size == kErr && logd_size != kErr && !((logd_main_size == kErr && logd_crash_size == kErr && logd_size != kErr &&
logd_size >= kLogBufferSize) || logd_size >= kLogBufferSize) ||
(logd_main_size != kErr && logd_main_size >= kLogBufferSize && (logd_main_size != kErr && logd_main_size >= kLogBufferSize &&
logd_crash_size != kErr && logd_crash_size != kErr && logd_crash_size >= kLogBufferSize))) {
logd_crash_size >= kLogBufferSize))) {
SetIntProp(kLogdSizeProp, std::max(kLogBufferSize, logd_size)); SetIntProp(kLogdSizeProp, std::max(kLogBufferSize, logd_size));
SetIntProp(kLogdMainSizeProp, std::max(kLogBufferSize, logd_main_size)); SetIntProp(kLogdMainSizeProp, std::max(kLogBufferSize, logd_main_size));
SetIntProp(kLogdCrashSizeProp, std::max(kLogBufferSize, logd_crash_size)); SetIntProp(kLogdCrashSizeProp, std::max(kLogBufferSize, logd_crash_size));
@ -281,14 +280,15 @@ void Logcat::EnsureLogWatchDog() {
const auto *pi = __system_property_find(kLogdTagProp.data()); const auto *pi = __system_property_find(kLogdTagProp.data());
uint32_t serial = 0; uint32_t serial = 0;
if (pi != nullptr) { if (pi != nullptr) {
__system_property_read_callback(pi, [](auto *c, auto, auto, auto s) { __system_property_read_callback(
*reinterpret_cast<uint32_t *>(c) = s; pi, [](auto *c, auto, auto, auto s) { *reinterpret_cast<uint32_t *>(c) = s; },
}, &serial); &serial);
} }
if (!__system_property_wait(pi, serial, &serial, nullptr)) break; if (!__system_property_wait(pi, serial, &serial, nullptr)) break;
if (pi != nullptr) { if (pi != nullptr) {
if (enable_watchdog) Log("\nResetting log settings\n"); if (enable_watchdog) Log("\nResetting log settings\n");
} else std::this_thread::sleep_for(1s); } else
std::this_thread::sleep_for(1s);
// log tag prop was not found; to avoid frequently trigger wait, sleep for a while // log tag prop was not found; to avoid frequently trigger wait, sleep for a while
} }
}); });
@ -306,35 +306,37 @@ void Logcat::Run() {
while (true) { while (true) {
std::unique_ptr<logger_list, decltype(&android_logger_list_free)> logger_list{ std::unique_ptr<logger_list, decltype(&android_logger_list_free)> logger_list{
android_logger_list_alloc(0, tail, 0), &android_logger_list_free}; android_logger_list_alloc(0, tail, 0), &android_logger_list_free};
tail = tail_after_crash; tail = tail_after_crash;
for (log_id id:{LOG_ID_MAIN, LOG_ID_CRASH}) { for (log_id id : {LOG_ID_MAIN, LOG_ID_CRASH}) {
auto *logger = android_logger_open(logger_list.get(), id); auto *logger = android_logger_open(logger_list.get(), id);
if (logger == nullptr) continue; if (logger == nullptr) continue;
if (auto size = android_logger_get_log_size(logger); if (auto size = android_logger_get_log_size(logger);
size >= 0 && static_cast<size_t>(size) < kLogBufferSize) { size >= 0 && static_cast<size_t>(size) < kLogBufferSize) {
android_logger_set_log_size(logger, kLogBufferSize); android_logger_set_log_size(logger, kLogBufferSize);
} }
} }
struct log_msg msg{}; struct log_msg msg {};
while (true) { while (true) {
if (android_logger_list_read(logger_list.get(), &msg) <= 0) [[unlikely]] break; if (android_logger_list_read(logger_list.get(), &msg) <= 0) [[unlikely]]
break;
ProcessBuffer(&msg); ProcessBuffer(&msg);
if (verbose_print_count_ >= kMaxLogSize) [[unlikely]] RefreshFd(true); if (verbose_print_count_ >= kMaxLogSize) [[unlikely]]
if (modules_print_count_ >= kMaxLogSize) [[unlikely]] RefreshFd(false); RefreshFd(true);
if (modules_print_count_ >= kMaxLogSize) [[unlikely]]
RefreshFd(false);
} }
OnCrash(errno); OnCrash(errno);
} }
} }
extern "C" extern "C" JNIEXPORT void JNICALL
JNIEXPORT void JNICALL
// NOLINTNEXTLINE // NOLINTNEXTLINE
Java_org_lsposed_lspd_service_LogcatService_runLogcat(JNIEnv *env, jobject thiz) { Java_org_lsposed_lspd_service_LogcatService_runLogcat(JNIEnv *env, jobject thiz) {
jclass clazz = env->GetObjectClass(thiz); jclass clazz = env->GetObjectClass(thiz);

View File

@ -32,11 +32,6 @@ val moduleName = "LSPosed"
val moduleBaseId = "lsposed" val moduleBaseId = "lsposed"
val authors = "Jing Matrix & LSPosed Developers" val authors = "Jing Matrix & LSPosed Developers"
val riruModuleId = "lsposed"
val moduleMinRiruApiVersion = 26
val moduleMinRiruVersionName = "26.1.7"
val moduleMaxRiruApiVersion = 26
val injectedPackageName: String by rootProject.extra val injectedPackageName: String by rootProject.extra
val injectedPackageUid: Int by rootProject.extra val injectedPackageUid: Int by rootProject.extra
@ -88,15 +83,6 @@ android {
} }
} }
create("Riru") {
dimension = "api"
externalNativeBuild {
cmake {
arguments += "-DAPI_VERSION=$moduleMaxRiruApiVersion"
}
}
}
create("Zygisk") { create("Zygisk") {
dimension = "api" dimension = "api"
externalNativeBuild { externalNativeBuild {
@ -191,7 +177,7 @@ fun afterEval() = android.applicationVariants.forEach { variant ->
into(magiskDir) into(magiskDir)
from("${rootProject.projectDir}/README.md") from("${rootProject.projectDir}/README.md")
from("$projectDir/magisk_module") { from("$projectDir/magisk_module") {
exclude("riru.sh", "module.prop", "customize.sh", "daemon") exclude("module.prop", "customize.sh", "daemon")
} }
from("$projectDir/magisk_module") { from("$projectDir/magisk_module") {
include("module.prop") include("module.prop")
@ -202,7 +188,6 @@ fun afterEval() = android.applicationVariants.forEach { variant ->
"authorList" to authors, "authorList" to authors,
"updateJson" to "https://raw.githubusercontent.com/JingMatrix/LSPosed/master/magisk-loader/update/${flavorLowered}.json", "updateJson" to "https://raw.githubusercontent.com/JingMatrix/LSPosed/master/magisk-loader/update/${flavorLowered}.json",
"requirement" to when (flavorLowered) { "requirement" to when (flavorLowered) {
"riru" -> "Requires Riru $moduleMinRiruVersionName or above installed"
"zygisk" -> "Requires Magisk 26.0+ and Zygisk enabled" "zygisk" -> "Requires Magisk 26.0+ and Zygisk enabled"
else -> "No further requirements" else -> "No further requirements"
}, },
@ -219,19 +204,6 @@ fun afterEval() = android.applicationVariants.forEach { variant ->
filter<ReplaceTokens>("tokens" to tokens) filter<ReplaceTokens>("tokens" to tokens)
filter<FixCrLfFilter>("eol" to FixCrLfFilter.CrLf.newInstance("lf")) filter<FixCrLfFilter>("eol" to FixCrLfFilter.CrLf.newInstance("lf"))
} }
if (flavorLowered == "riru") {
from("${projectDir}/magisk_module") {
include("riru.sh")
val tokens = mapOf(
"RIRU_MODULE_LIB_NAME" to "lspd",
"RIRU_MODULE_API_VERSION" to moduleMaxRiruApiVersion.toString(),
"RIRU_MODULE_MIN_API_VERSION" to moduleMinRiruApiVersion.toString(),
"RIRU_MODULE_MIN_RIRU_VERSION_NAME" to moduleMinRiruVersionName,
)
filter<ReplaceTokens>("tokens" to tokens)
filter<FixCrLfFilter>("eol" to FixCrLfFilter.CrLf.newInstance("lf"))
}
}
from(project(":app").tasks.getByName("package$buildTypeCapped").outputs) { from(project(":app").tasks.getByName("package$buildTypeCapped").outputs) {
include("*.apk") include("*.apk")
rename(".*\\.apk", "manager.apk") rename(".*\\.apk", "manager.apk")

View File

@ -29,8 +29,7 @@ enforce_install_from_magisk_app() {
else else
ui_print "*********************************************************" ui_print "*********************************************************"
ui_print "! Install from recovery is NOT supported" ui_print "! Install from recovery is NOT supported"
ui_print "! Some recovery has broken implementations, install with such recovery will finally cause Riru or Riru modules not working" ui_print "! Some recovery has broken implementations, please thus install from Magisk app"
ui_print "! Please install from Magisk app"
abort "*********************************************************" abort "*********************************************************"
fi fi
} }
@ -60,14 +59,6 @@ if [ -z "$KSU" ] && [ -z "$APATCH" ]; then
fi fi
check_incompatible_module check_incompatible_module
if [ "$FLAVOR" == "riru" ]; then
# Extract riru.sh
extract "$ZIPFILE" 'riru.sh' "$TMPDIR"
. "$TMPDIR/riru.sh"
# Functions from riru.sh
check_riru_version
fi
enforce_install_from_magisk_app enforce_install_from_magisk_app
# Check architecture # Check architecture
@ -123,43 +114,6 @@ if [ "$FLAVOR" == "zygisk" ]; then
mv "$MODPATH/zygisk/liblspd.so" "$MODPATH/zygisk/x86_64.so" mv "$MODPATH/zygisk/liblspd.so" "$MODPATH/zygisk/x86_64.so"
fi fi
fi fi
elif [ "$FLAVOR" == "riru" ]; then
mkdir "$MODPATH/riru"
mkdir "$MODPATH/riru/lib"
mkdir "$MODPATH/riru/lib64"
if [ "$ARCH" = "arm" ] || [ "$ARCH" = "arm64" ]; then
ui_print "- Extracting arm libraries"
extract "$ZIPFILE" "lib/armeabi-v7a/lib$RIRU_MODULE_LIB_NAME.so" "$MODPATH/riru/lib" true
if [ "$IS64BIT" = true ]; then
ui_print "- Extracting arm64 libraries"
extract "$ZIPFILE" "lib/arm64-v8a/lib$RIRU_MODULE_LIB_NAME.so" "$MODPATH/riru/lib64" true
fi
fi
if [ "$ARCH" = "x86" ] || [ "$ARCH" = "x64" ]; then
ui_print "- Extracting x86 libraries"
extract "$ZIPFILE" "lib/x86/lib$RIRU_MODULE_LIB_NAME.so" "$MODPATH/riru/lib" true
if [ "$IS64BIT" = true ]; then
ui_print "- Extracting x64 libraries"
extract "$ZIPFILE" "lib/x86_64/lib$RIRU_MODULE_LIB_NAME.so" "$MODPATH/riru/lib64" true
fi
fi
if [ "$RIRU_MODULE_DEBUG" = true ]; then
mv "$MODPATH/riru" "$MODPATH/system"
mv "$MODPATH/system/lib/lib$RIRU_MODULE_LIB_NAME.so" "$MODPATH/system/lib/libriru_$RIRU_MODULE_LIB_NAME.so"
mv "$MODPATH/system/lib64/lib$RIRU_MODULE_LIB_NAME.so" "$MODPATH/system/lib64/libriru_$RIRU_MODULE_LIB_NAME.so"
if [ "$RIRU_API" -ge 26 ]; then
mkdir -p "$MODPATH/riru/lib"
mkdir -p "$MODPATH/riru/lib64"
touch "$MODPATH/riru/lib/libriru_$RIRU_MODULE_LIB_NAME"
touch "$MODPATH/riru/lib64/libriru_$RIRU_MODULE_LIB_NAME"
else
mkdir -p "/data/adb/riru/modules/$RIRU_MODULE_LIB_NAME"
fi
fi
fi fi
if [ "$API" -ge 29 ]; then if [ "$API" -ge 29 ]; then

View File

@ -1,86 +0,0 @@
#!/sbin/sh
RIRU_MODULE_LIB_NAME="@RIRU_MODULE_LIB_NAME@"
# Variables for customize.sh
RIRU_API=0
RIRU_MIN_COMPATIBLE_API=0
RIRU_VERSION_CODE=0
RIRU_VERSION_NAME=""
# Used by /data/adb/riru/util_functions.sh
RIRU_MODULE_API_VERSION=@RIRU_MODULE_API_VERSION@
RIRU_MODULE_MIN_API_VERSION=@RIRU_MODULE_MIN_API_VERSION@
RIRU_MODULE_MIN_RIRU_VERSION_NAME="@RIRU_MODULE_MIN_RIRU_VERSION_NAME@"
RIRU_MODULE_DEBUG=@RIRU_MODULE_DEBUG@
if [ "$MAGISK_VER_CODE" -ge 21000 ]; then
MAGISK_CURRENT_RIRU_MODULE_PATH=$(magisk --path)/.magisk/modules/riru-core
else
MAGISK_CURRENT_RIRU_MODULE_PATH=/sbin/.magisk/modules/riru-core
fi
# This function will be used when util_functions.sh not exists
check_riru_version() {
if [ ! -f "$MAGISK_CURRENT_RIRU_MODULE_PATH/api_version" ] && [ ! -f "/data/adb/riru/api_version" ] && [ ! -f "/data/adb/riru/api_version.new" ]; then
ui_print "*********************************************************"
ui_print "! Riru $RIRU_MODULE_MIN_RIRU_VERSION_NAME or above is required"
ui_print "! Please install Riru from Magisk Manager or https://github.com/RikkaApps/Riru/releases"
abort "*********************************************************"
fi
RIRU_API=$(cat "$MAGISK_CURRENT_RIRU_MODULE_PATH/api_version") || RIRU_API=$(cat "/data/adb/riru/api_version.new") || RIRU_API=$(cat "/data/adb/riru/api_version") || RIRU_API=0
[ "$RIRU_API" -eq "$RIRU_API" ] || RIRU_API=0
ui_print "- Riru API version: $RIRU_API"
if [ "$RIRU_API" -lt $RIRU_MODULE_MIN_API_VERSION ]; then
ui_print "*********************************************************"
ui_print "! Riru $RIRU_MODULE_MIN_RIRU_VERSION_NAME or above is required"
ui_print "! Please upgrade Riru from Magisk Manager or https://github.com/RikkaApps/Riru/releases"
abort "*********************************************************"
fi
}
# This function will be used when util_functions.sh not exists
enforce_install_from_magisk_app() {
if $BOOTMODE; then
ui_print "- Installing from Magisk app"
else
ui_print "*********************************************************"
ui_print "! Install from recovery is NOT supported"
ui_print "! Some recovery has broken implementations, install with such recovery will finally cause Riru or Riru modules not working"
ui_print "! Please install from Magisk app"
abort "*********************************************************"
fi
}
if [ ! -d $MAGISK_CURRENT_RIRU_MODULE_PATH ]; then
ui_print "*********************************************************"
ui_print "! Riru is not installed"
ui_print "! Please install Riru from Magisk Manager or https://github.com/RikkaApps/Riru/releases"
abort "*********************************************************"
fi
if [ -f "$MAGISK_CURRENT_RIRU_MODULE_PATH/disable" ] || [ -f "$MAGISK_CURRENT_RIRU_MODULE_PATH/remove" ]; then
ui_print "*********************************************************"
ui_print "! Riru is not enabled or will be removed"
ui_print "! Please enable Riru in Magisk first"
abort "*********************************************************"
fi
if [ -f $MAGISK_CURRENT_RIRU_MODULE_PATH/util_functions.sh ]; then
ui_print "- Load $MAGISK_CURRENT_RIRU_MODULE_PATH/util_functions.sh"
# shellcheck disable=SC1090
. $MAGISK_CURRENT_RIRU_MODULE_PATH/util_functions.sh
else
if [ "$RIRU_MODULE_MIN_API_VERSION" -ge 11 ]; then
ui_print "*********************************************************"
ui_print "! Riru $RIRU_MODULE_MIN_RIRU_VERSION_NAME or above is required"
ui_print "! Please upgrade Riru from Magisk Manager or https://github.com/RikkaApps/Riru/releases"
abort "*********************************************************"
fi
if [ -f /data/adb/riru/util_functions.sh ]; then
ui_print "- Load /data/adb/riru/util_functions.sh"
. /data/adb/riru/util_functions.sh
else
ui_print "- Can't find /data/adb/riru/util_functions.sh"
fi
fi

View File

@ -6,9 +6,7 @@ add_subdirectory(${CORE_ROOT} core)
configure_file(template/loader.cpp src/loader.cpp) configure_file(template/loader.cpp src/loader.cpp)
aux_source_directory(src SRC_LIST) aux_source_directory(src SRC_LIST)
if (${API} STREQUAL "riru") if (${API} STREQUAL "zygisk")
set(SRC_LIST ${SRC_LIST} api/riru_main.cpp)
elseif (${API} STREQUAL "zygisk")
set(SRC_LIST ${SRC_LIST} api/zygisk_main.cpp) set(SRC_LIST ${SRC_LIST} api/zygisk_main.cpp)
endif() endif()

View File

@ -1,125 +0,0 @@
#ifndef RIRU_H
#define RIRU_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <jni.h>
#include <sys/types.h>
#include <stddef.h>
// ---------------------------------------------------------
typedef void(onModuleLoaded_v9)();
#ifndef RIRU_MODULE
typedef int(shouldSkipUid_v9)(int uid);
#endif
typedef void(nativeForkAndSpecializePre_v9)(
JNIEnv *env, jclass cls, jint *uid, jint *gid, jintArray *gids, jint *runtimeFlags,
jobjectArray *rlimits, jint *mountExternal, jstring *seInfo, jstring *niceName,
jintArray *fdsToClose, jintArray *fdsToIgnore, jboolean *is_child_zygote,
jstring *instructionSet, jstring *appDataDir, jboolean *isTopApp,
jobjectArray *pkgDataInfoList,
jobjectArray *whitelistedDataInfoList, jboolean *bindMountAppDataDirs,
jboolean *bindMountAppStorageDirs);
typedef void(nativeForkAndSpecializePost_v9)(JNIEnv *env, jclass cls, jint res);
typedef void(nativeForkSystemServerPre_v9)(
JNIEnv *env, jclass cls, uid_t *uid, gid_t *gid, jintArray *gids, jint *runtimeFlags,
jobjectArray *rlimits, jlong *permittedCapabilities, jlong *effectiveCapabilities);
typedef void(nativeForkSystemServerPost_v9)(JNIEnv *env, jclass cls, jint res);
typedef void(nativeSpecializeAppProcessPre_v9)(
JNIEnv *env, jclass cls, jint *uid, jint *gid, jintArray *gids, jint *runtimeFlags,
jobjectArray *rlimits, jint *mountExternal, jstring *seInfo, jstring *niceName,
jboolean *startChildZygote, jstring *instructionSet, jstring *appDataDir,
jboolean *isTopApp, jobjectArray *pkgDataInfoList, jobjectArray *whitelistedDataInfoList,
jboolean *bindMountAppDataDirs, jboolean *bindMountAppStorageDirs);
typedef void(nativeSpecializeAppProcessPost_v9)(JNIEnv *env, jclass cls);
typedef struct {
int supportHide;
int version;
const char *versionName;
onModuleLoaded_v9 *onModuleLoaded;
#ifndef RIRU_MODULE
shouldSkipUid_v9 *shouldSkipUid;
#else
void *unused;
#endif
nativeForkAndSpecializePre_v9 *forkAndSpecializePre;
nativeForkAndSpecializePost_v9 *forkAndSpecializePost;
nativeForkSystemServerPre_v9 *forkSystemServerPre;
nativeForkSystemServerPost_v9 *forkSystemServerPost;
nativeSpecializeAppProcessPre_v9 *specializeAppProcessPre;
nativeSpecializeAppProcessPost_v9 *specializeAppProcessPost;
} RiruModuleInfo;
typedef struct {
int moduleApiVersion;
RiruModuleInfo moduleInfo;
} RiruVersionedModuleInfo;
// ---------------------------------------------------------
typedef struct {
int riruApiVersion;
void *unused;
const char *magiskModulePath;
int *allowUnload;
} Riru;
typedef RiruVersionedModuleInfo *(RiruInit_t)(Riru *);
#ifdef RIRU_MODULE
#define RIRUD_ADDRESS "rirud"
#if __cplusplus < 201103L
#define RIRU_EXPORT __attribute__((visibility("default"))) __attribute__((used))
#else
#define RIRU_EXPORT [[gnu::visibility("default")]] [[gnu::used]]
#endif
RIRU_EXPORT RiruVersionedModuleInfo *init(Riru *riru) ;
extern int riru_api_version;
extern const char *riru_magisk_module_path;
extern int *riru_allow_unload;
#if !__cplusplus && __STDC_VERSION__ < 199409L
#define RIRU_INLINE __attribute__((weak)) __inline__
#elif !__cplusplus
#define RIRU_INLINE __attribute__((weak)) inline extern
#else
#define RIRU_INLINE inline
#endif
RIRU_INLINE const char *riru_get_magisk_module_path() {
if (riru_api_version >= 24) {
return riru_magisk_module_path;
}
return NULL;
}
RIRU_INLINE void riru_set_unload_allowed(int allowed) {
if (riru_api_version >= 25 && riru_allow_unload) {
*riru_allow_unload = allowed;
}
}
#undef RIRU_INLINE
#endif
#ifdef __cplusplus
}
#endif
#endif //RIRU_H

View File

@ -1,137 +0,0 @@
/*
* This file is part of LSPosed.
*
* LSPosed is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LSPosed is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
*
* Copyright (C) 2020 EdXposed Contributors
* Copyright (C) 2021 - 2022 LSPosed Contributors
*/
#include <jni.h>
#include <cstring>
#include <cstdlib>
#include <array>
#include "logging.h"
#include "loader.h"
#include "config_impl.h"
#include "magisk_loader.h"
#include "symbol_cache.h"
#define RIRU_MODULE
#include "riru.h"
namespace lspd {
int *allowUnload = nullptr;
namespace {
std::string magiskPath;
jstring nice_name = nullptr;
jstring app_dir = nullptr;
void onModuleLoaded() {
LOGI("onModuleLoaded: welcome to LSPosed!");
LOGI("onModuleLoaded: version v{} ({})", versionName, versionCode);
MagiskLoader::Init();
ConfigImpl::Init();
}
void nativeForkAndSpecializePre(JNIEnv *env, jclass, jint *_uid, jint *,
jintArray *gids, jint *,
jobjectArray *, jint *,
jstring *, jstring *_nice_name,
jintArray *, jintArray *,
jboolean *start_child_zygote, jstring *,
jstring *_app_data_dir, jboolean *,
jobjectArray *,
jobjectArray *,
jboolean *,
jboolean *) {
nice_name = *_nice_name;
app_dir = *_app_data_dir;
MagiskLoader::GetInstance()->OnNativeForkAndSpecializePre(env, *_uid, *gids,
nice_name,
*start_child_zygote,
*_app_data_dir);
*_nice_name = nice_name;
}
void nativeForkAndSpecializePost(JNIEnv *env, jclass, jint res) {
if (res == 0)
MagiskLoader::GetInstance()->OnNativeForkAndSpecializePost(env, nice_name, app_dir);
}
void nativeForkSystemServerPre(JNIEnv *env, jclass, uid_t *, gid_t *,
jintArray *, jint *,
jobjectArray *, jlong *,
jlong *) {
MagiskLoader::GetInstance()->OnNativeForkSystemServerPre(env);
}
void nativeForkSystemServerPost(JNIEnv *env, jclass, jint res) {
if (res == 0)
MagiskLoader::GetInstance()->OnNativeForkSystemServerPost(env);
}
/* method added in Android Q */
void specializeAppProcessPre(JNIEnv *env, jclass, jint *_uid, jint *,
jintArray *gids, jint *,
jobjectArray *, jint *,
jstring *, jstring *_nice_name,
jboolean *start_child_zygote, jstring *,
jstring *_app_data_dir, jboolean *,
jobjectArray *,
jobjectArray *,
jboolean *,
jboolean *) {
nice_name = *_nice_name;
app_dir = *_app_data_dir;
MagiskLoader::GetInstance()->OnNativeForkAndSpecializePre(env, *_uid, *gids,
nice_name,
*start_child_zygote,
*_app_data_dir);
}
void specializeAppProcessPost(JNIEnv *env, jclass) {
MagiskLoader::GetInstance()->OnNativeForkAndSpecializePost(env, nice_name, app_dir);
}
}
RiruVersionedModuleInfo module{
.moduleApiVersion = apiVersion,
.moduleInfo = RiruModuleInfo{
.supportHide = !isDebug,
.version = versionCode,
.versionName = versionName,
.onModuleLoaded = lspd::onModuleLoaded,
.forkAndSpecializePre = lspd::nativeForkAndSpecializePre,
.forkAndSpecializePost = lspd::nativeForkAndSpecializePost,
.forkSystemServerPre = lspd::nativeForkSystemServerPre,
.forkSystemServerPost = lspd::nativeForkSystemServerPost,
.specializeAppProcessPre = lspd::specializeAppProcessPre,
.specializeAppProcessPost = lspd::specializeAppProcessPost,
}
};
}
RIRU_EXPORT RiruVersionedModuleInfo *init(Riru *riru) {
LOGD("using riru {}", riru->riruApiVersion);
LOGD("module path: {}", riru->magiskModulePath);
lspd::magiskPath = riru->magiskModulePath;
if (!lspd::isDebug && lspd::magiskPath.find(lspd::moduleName) == std::string::npos) {
LOGE("who am i");
return nullptr;
}
lspd::allowUnload = riru->allowUnload;
return &lspd::module;
}