[core] Fix sandhook
This commit is contained in:
parent
b5305e8621
commit
aae69dcf5c
|
|
@ -87,9 +87,9 @@ public class MainActivity extends BaseActivity {
|
|||
Glide.with(binding.appIcon)
|
||||
.load(GlideHelper.wrapApplicationInfoForIconLoader(getApplicationInfo()))
|
||||
.into(binding.appIcon);
|
||||
String installedXposedVersion = ConfigManager.getXposedVersionName();
|
||||
String installXposedVersion = ConfigManager.getXposedVersionName();
|
||||
int cardBackgroundColor;
|
||||
if (installedXposedVersion != null) {
|
||||
if (installXposedVersion != null) {
|
||||
binding.statusTitle.setText(String.format(Locale.US, "%s %s", getString(R.string.Activated), ConfigManager.getVariantString()));
|
||||
if (!ConfigManager.isPermissive()) {
|
||||
if (Helpers.currentHoliday == Helpers.Holidays.LUNARNEWYEAR) {
|
||||
|
|
@ -98,7 +98,7 @@ public class MainActivity extends BaseActivity {
|
|||
cardBackgroundColor = ResourcesKt.resolveColor(getTheme(), R.attr.colorNormal);
|
||||
}
|
||||
binding.statusIcon.setImageResource(R.drawable.ic_check_circle);
|
||||
binding.statusSummary.setText(String.format(Locale.US, "%s (%d)", installedXposedVersion, ConfigManager.getXposedVersionCode()));
|
||||
binding.statusSummary.setText(String.format(Locale.US, "%s (%d)", installXposedVersion, ConfigManager.getXposedVersionCode()));
|
||||
} else {
|
||||
cardBackgroundColor = ResourcesKt.resolveColor(getTheme(), R.attr.colorError);
|
||||
binding.statusIcon.setImageResource(R.drawable.ic_warning);
|
||||
|
|
|
|||
|
|
@ -66,13 +66,13 @@ public class StatusDialogBuilder extends AlertDialog.Builder {
|
|||
super(context);
|
||||
StatusInstallerBinding binding = StatusInstallerBinding.inflate(LayoutInflater.from(context), null, false);
|
||||
|
||||
String installedXposedVersion = ConfigManager.getXposedVersionName();
|
||||
String installXposedVersion = ConfigManager.getXposedVersionName();
|
||||
String mAppVer = String.format("%s (%s)", BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE);
|
||||
binding.manager.setText(mAppVer);
|
||||
|
||||
if (installedXposedVersion != null) {
|
||||
if (installXposedVersion != null) {
|
||||
binding.api.setText(String.format(Locale.US, "%s.0", ConfigManager.getXposedApiVersion()));
|
||||
binding.framework.setText(String.format(Locale.US, "%s (%s)", installedXposedVersion, ConfigManager.getXposedVersionCode()));
|
||||
binding.framework.setText(String.format(Locale.US, "%s (%s)", installXposedVersion, ConfigManager.getXposedVersionCode()));
|
||||
}
|
||||
|
||||
binding.androidVersion.setText(context.getString(R.string.android_sdk, getAndroidVersion(), Build.VERSION.RELEASE, Build.VERSION.SDK_INT));
|
||||
|
|
|
|||
|
|
@ -52,8 +52,6 @@ inline constexpr bool is64 = Is64();
|
|||
static const auto kClassLinkerClassName = "io.github.lsposed.lspd.nativebridge.ClassLinker"s;
|
||||
static const auto kBridgeServiceClassName = "io.github.lsposed.lspd.service.BridgeService"s;
|
||||
static const auto kDexPath = "/data/adb/lspd/framework/lspd.dex"s;
|
||||
static const auto kSandHookClassName = "com.swift.sandhook.SandHook"s;
|
||||
static const auto kSandHookNeverCallClassName = "com.swift.sandhook.ClassNeverCall"s;
|
||||
|
||||
static const auto kLibArtName = "libart.so"s;
|
||||
static const auto kLibFwName = "libandroidfw.so"s;
|
||||
|
|
|
|||
|
|
@ -23,12 +23,12 @@
|
|||
#include "JNIHelper.h"
|
||||
#include "jni/art_class_linker.h"
|
||||
#include "jni/yahfa.h"
|
||||
#include "jni/sandhook.h"
|
||||
#include "jni/resources_hook.h"
|
||||
#include <dl_util.h>
|
||||
#include <art/runtime/jni_env_ext.h>
|
||||
#include <android-base/strings.h>
|
||||
#include "jni/pending_hooks.h"
|
||||
#include <sandhook.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <nativehelper/scoped_local_ref.h>
|
||||
|
|
@ -122,30 +122,12 @@ namespace lspd {
|
|||
FindClassFromLoader(env, GetCurrentClassLoader(), kEntryClassName)));
|
||||
|
||||
RegisterLogger(env);
|
||||
RegisterEdxpResourcesHook(env);
|
||||
RegisterResourcesHook(env);
|
||||
RegisterArtClassLinker(env);
|
||||
RegisterEdxpYahfa(env);
|
||||
RegisterYahfa(env);
|
||||
RegisterPendingHooks(env);
|
||||
RegisterNativeAPI(env);
|
||||
// TODO: Recover this
|
||||
|
||||
// variant_ = Variant(ConfigManager::GetInstance()->GetVariant());
|
||||
// LOGI("LSP Variant: %d", variant_);
|
||||
//
|
||||
// if (variant_ == SANDHOOK) {
|
||||
// //for SandHook variant
|
||||
// ScopedLocalRef sandhook_class(env, FindClassFromCurrentLoader(env, kSandHookClassName));
|
||||
// ScopedLocalRef nevercall_class(env,
|
||||
// FindClassFromCurrentLoader(env,
|
||||
// kSandHookNeverCallClassName));
|
||||
// if (sandhook_class == nullptr || nevercall_class == nullptr) { // fail-fast
|
||||
// return;
|
||||
// }
|
||||
// if (!JNI_Load_Ex(env, sandhook_class.get(), nevercall_class.get())) {
|
||||
// LOGE("SandHook: HookEntry class error. %d", getpid());
|
||||
// }
|
||||
//
|
||||
// }
|
||||
RegisterSandHook(env);
|
||||
}
|
||||
|
||||
jclass
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
namespace lspd {
|
||||
LSP_DEF_NATIVE_METHOD(void, ModuleLogger, nativeLog, int fd, jstring jstr) {
|
||||
if (fd < 0) {
|
||||
if (UNLIKELY(fd < 0)) {
|
||||
LOGE("fd is -1");
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ namespace lspd {
|
|||
LSP_NATIVE_METHOD(ResourcesHook, removeFinalFlagNative, "(Ljava/lang/Class;)Z"),
|
||||
};
|
||||
|
||||
void RegisterEdxpResourcesHook(JNIEnv *env) {
|
||||
void RegisterResourcesHook(JNIEnv *env) {
|
||||
REGISTER_LSP_NATIVE_METHODS(ResourcesHook);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,6 @@ namespace lspd {
|
|||
|
||||
static constexpr uint32_t kAccFinal = 0x0010;
|
||||
|
||||
void RegisterEdxpResourcesHook(JNIEnv *);
|
||||
void RegisterResourcesHook(JNIEnv *);
|
||||
|
||||
} // namespace lspd
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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) 2021 LSPosed Contributors
|
||||
*/
|
||||
|
||||
#include <sandhook.h>
|
||||
#include "sandhook.h"
|
||||
#include "native_util.h"
|
||||
#include "nativehelper/jni_macros.h"
|
||||
|
||||
namespace lspd {
|
||||
LSP_DEF_NATIVE_METHOD(bool, SandHook, init, jclass classSandHook, jclass classNeverCall) {
|
||||
return JNI_Load_Ex(env, classSandHook, classNeverCall);
|
||||
}
|
||||
|
||||
static JNINativeMethod gMethods[] = {
|
||||
LSP_NATIVE_METHOD(SandHook, init,
|
||||
"(Ljava/lang/Class;Ljava/lang/Class;)Z"),
|
||||
};
|
||||
|
||||
void RegisterSandHook(JNIEnv *env) {
|
||||
REGISTER_LSP_NATIVE_METHODS(SandHook);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
//
|
||||
// Created by loves on 2/18/2021.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
namespace lspd {
|
||||
void RegisterSandHook(JNIEnv *env);
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ namespace lspd {
|
|||
LSP_NATIVE_METHOD(Yahfa, isHooked, "(Ljava/lang/reflect/Member;)Z")
|
||||
};
|
||||
|
||||
void RegisterEdxpYahfa(JNIEnv *env) {
|
||||
void RegisterYahfa(JNIEnv *env) {
|
||||
REGISTER_LSP_NATIVE_METHODS(Yahfa);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,6 @@
|
|||
|
||||
namespace lspd {
|
||||
|
||||
void RegisterEdxpYahfa(JNIEnv *);
|
||||
void RegisterYahfa(JNIEnv *);
|
||||
|
||||
} // namespace lspd
|
||||
|
|
|
|||
|
|
@ -1,24 +1,15 @@
|
|||
package com.swift.sandhook.xposedcompat;
|
||||
|
||||
import android.os.Process;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import io.github.lsposed.lspd.util.FileUtils;
|
||||
import io.github.lsposed.lspd.util.ProcessUtils;
|
||||
import io.github.lsposed.lspd.util.ProxyClassLoader;
|
||||
import com.swift.sandhook.wrapper.HookWrapper;
|
||||
import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge;
|
||||
import com.swift.sandhook.xposedcompat.utils.ApplicationUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Member;
|
||||
|
||||
import de.robv.android.xposed.XposedBridge;
|
||||
|
||||
public class XposedCompat {
|
||||
|
||||
// TODO initialize these variables
|
||||
public static volatile File cacheDir;
|
||||
public static volatile ClassLoader classLoader;
|
||||
|
||||
//try to use internal stub hooker & backup method to speed up hook
|
||||
|
|
@ -40,21 +31,10 @@ public class XposedCompat {
|
|||
}
|
||||
|
||||
public static void onForkProcess() {
|
||||
cacheDir = null;
|
||||
classLoader = null;
|
||||
sandHookXposedClassLoader = null;
|
||||
}
|
||||
|
||||
public static File getCacheDir() {
|
||||
// TODO: cache path?
|
||||
// if (cacheDir == null) {
|
||||
// String fixedAppDataDir = getDataPathPrefix() + getPackageName(ConfigManager.appDataDir) + "/";
|
||||
// cacheDir = new File(fixedAppDataDir, "/cache/sandhook/"
|
||||
// + ProcessUtils.getProcessName(Process.myPid()).replace(":", "_") + "/");
|
||||
// }
|
||||
return cacheDir;
|
||||
}
|
||||
|
||||
public static ClassLoader getClassLoader() {
|
||||
if (classLoader == null) {
|
||||
classLoader = getSandHookXposedClassLoader(ApplicationUtils.currentApplication().getClassLoader(), XposedCompat.class.getClassLoader());
|
||||
|
|
@ -74,30 +54,4 @@ public class XposedCompat {
|
|||
return sandHookXposedClassLoader;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean clearCache() {
|
||||
try {
|
||||
FileUtils.delete(getCacheDir());
|
||||
getCacheDir().mkdirs();
|
||||
return true;
|
||||
} catch (Throwable throwable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearOatCache() {
|
||||
SandHookXposedBridge.clearOatFile();
|
||||
}
|
||||
|
||||
public static String getPackageName(String dataDir) {
|
||||
if (TextUtils.isEmpty(dataDir)) {
|
||||
return "";
|
||||
}
|
||||
int lastIndex = dataDir.lastIndexOf("/");
|
||||
if (lastIndex < 0) {
|
||||
return dataDir;
|
||||
}
|
||||
return dataDir.substring(lastIndex + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,18 +83,6 @@ public final class SandHookXposedBridge {
|
|||
}
|
||||
}
|
||||
|
||||
public static void clearOatFile() {
|
||||
String fixedAppDataDir = XposedCompat.getCacheDir().getAbsolutePath();
|
||||
File dexOatDir = new File(fixedAppDataDir, "/hookers/oat/");
|
||||
if (!dexOatDir.exists())
|
||||
return;
|
||||
try {
|
||||
FileUtils.delete(dexOatDir);
|
||||
dexOatDir.mkdirs();
|
||||
} catch (Throwable throwable) {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkMember(Member member) {
|
||||
|
||||
if (member instanceof Method) {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import androidx.annotation.NonNull;
|
|||
import io.github.lsposed.lspd.proxy.NormalProxy;
|
||||
import io.github.lsposed.lspd.proxy.Router;
|
||||
|
||||
public abstract class BaseEdxpImpl implements EdxpImpl {
|
||||
public abstract class BaseImpl implements Impl {
|
||||
|
||||
protected Proxy mNormalProxy;
|
||||
protected Router mRouter;
|
||||
|
|
@ -30,7 +30,7 @@ import java.lang.annotation.Retention;
|
|||
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
||||
public interface EdxpImpl extends KeepAll {
|
||||
public interface Impl extends KeepAll {
|
||||
|
||||
int NONE = 0;
|
||||
int YAHFA = 1;
|
||||
|
|
@ -21,34 +21,29 @@
|
|||
package io.github.lsposed.lspd.core;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.ddm.DdmHandleAppName;
|
||||
|
||||
import io.github.lsposed.common.KeepAll;
|
||||
import io.github.lsposed.lspd.config.LSPApplicationServiceClient;
|
||||
import io.github.lsposed.lspd.service.ILSPApplicationService;
|
||||
import io.github.lsposed.lspd.service.ServiceManager;
|
||||
import io.github.lsposed.lspd.util.Utils;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static io.github.lsposed.lspd.config.LSPApplicationServiceClient.serviceClient;
|
||||
import static io.github.lsposed.lspd.service.ServiceManager.TAG;
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
public class Main implements KeepAll {
|
||||
private static final AtomicReference<EdxpImpl> lspdImplRef = new AtomicReference<>(null);
|
||||
private static final AtomicReference<Impl> lspdImplRef = new AtomicReference<>(null);
|
||||
private static final Binder heartBeatBinder = new Binder();
|
||||
|
||||
public static void forkAndSpecializePost(String appDataDir, String niceName, IBinder binder) {
|
||||
LSPApplicationServiceClient.Init(binder);
|
||||
serviceClient.registerHeartBeat(heartBeatBinder);
|
||||
final int variant = serviceClient.getVariant();
|
||||
EdxpImpl lspd = getEdxpImpl(variant);
|
||||
Impl lspd = getEdxpImpl(variant);
|
||||
if (lspd == null || !lspd.isInitialized()) {
|
||||
Utils.logE("Not started up");
|
||||
return;
|
||||
|
|
@ -60,30 +55,30 @@ public class Main implements KeepAll {
|
|||
LSPApplicationServiceClient.Init(binder);
|
||||
serviceClient.registerHeartBeat(heartBeatBinder);
|
||||
final int variant = serviceClient.getVariant();
|
||||
EdxpImpl lspd = getEdxpImpl(variant);
|
||||
Impl lspd = getEdxpImpl(variant);
|
||||
if (lspd == null || !lspd.isInitialized()) {
|
||||
return;
|
||||
}
|
||||
lspd.getNormalProxy().forkSystemServerPost();
|
||||
}
|
||||
|
||||
public static synchronized boolean setEdxpImpl(EdxpImpl lspd) {
|
||||
public static synchronized boolean setEdxpImpl(Impl lspd) {
|
||||
return lspdImplRef.compareAndSet(null, lspd);
|
||||
}
|
||||
|
||||
public static synchronized EdxpImpl getEdxpImpl(int variant) {
|
||||
EdxpImpl lspd = lspdImplRef.get();
|
||||
public static synchronized Impl getEdxpImpl(int variant) {
|
||||
Impl lspd = lspdImplRef.get();
|
||||
if (lspd != null) {
|
||||
return lspd;
|
||||
}
|
||||
Utils.logD("Loading variant " + variant);
|
||||
try {
|
||||
switch (variant) {
|
||||
case EdxpImpl.YAHFA:
|
||||
Class.forName("io.github.lsposed.lspd.yahfa.core.YahfaEdxpImpl");
|
||||
case Impl.YAHFA:
|
||||
Class.forName("io.github.lsposed.lspd.yahfa.core.YahfaImpl");
|
||||
break;
|
||||
case EdxpImpl.SANDHOOK:
|
||||
Class.forName("io.github.lsposed.lspd.sandhook.core.SandHookEdxpImpl");
|
||||
case Impl.SANDHOOK:
|
||||
Class.forName("io.github.lsposed.lspd.sandhook.core.SandHookImpl");
|
||||
break;
|
||||
default:
|
||||
Utils.logE("Unsupported variant " + variant);
|
||||
|
|
@ -95,11 +90,11 @@ public class Main implements KeepAll {
|
|||
return lspdImplRef.get();
|
||||
}
|
||||
|
||||
public static synchronized EdxpImpl getEdxpImpl() {
|
||||
public static synchronized Impl getEdxpImpl() {
|
||||
return lspdImplRef.get();
|
||||
}
|
||||
|
||||
@EdxpImpl.Variant
|
||||
@Impl.Variant
|
||||
public static synchronized int getEdxpVariant() {
|
||||
return getEdxpImpl().getVariant();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
package io.github.lsposed.lspd.nativebridge;
|
||||
|
||||
public class SandHook {
|
||||
public static native boolean init(Class<?> ClassNeverCall, Class<?> ClassSandHook);
|
||||
}
|
||||
|
|
@ -22,16 +22,19 @@ package io.github.lsposed.lspd.sandhook.core;
|
|||
|
||||
import android.os.Build;
|
||||
|
||||
import io.github.lsposed.lspd.core.BaseEdxpImpl;
|
||||
import io.github.lsposed.lspd.core.EdxpImpl;
|
||||
import io.github.lsposed.lspd.core.BaseImpl;
|
||||
import io.github.lsposed.lspd.core.Impl;
|
||||
import io.github.lsposed.lspd.core.Main;
|
||||
import io.github.lsposed.lspd.nativebridge.SandHook;
|
||||
import io.github.lsposed.lspd.nativebridge.Yahfa;
|
||||
|
||||
import com.swift.sandhook.ClassNeverCall;
|
||||
import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge;
|
||||
|
||||
public class SandHookEdxpImpl extends BaseEdxpImpl {
|
||||
public class SandHookImpl extends BaseImpl {
|
||||
|
||||
static {
|
||||
final EdxpImpl lspdImpl = new SandHookEdxpImpl();
|
||||
final Impl lspdImpl = new SandHookImpl();
|
||||
if (Main.setEdxpImpl(lspdImpl)) {
|
||||
lspdImpl.init();
|
||||
}
|
||||
|
|
@ -50,6 +53,7 @@ public class SandHookEdxpImpl extends BaseEdxpImpl {
|
|||
|
||||
@Override
|
||||
public void init() {
|
||||
SandHook.init(ClassNeverCall.class, com.swift.sandhook.SandHook.class);
|
||||
Yahfa.init(Build.VERSION.SDK_INT);
|
||||
getRouter().injectConfig();
|
||||
SandHookXposedBridge.init();
|
||||
|
|
@ -22,18 +22,18 @@ package io.github.lsposed.lspd.yahfa.core;
|
|||
|
||||
import android.os.Build;
|
||||
|
||||
import io.github.lsposed.lspd.core.BaseEdxpImpl;
|
||||
import io.github.lsposed.lspd.core.EdxpImpl;
|
||||
import io.github.lsposed.lspd.core.BaseImpl;
|
||||
import io.github.lsposed.lspd.core.Impl;
|
||||
import io.github.lsposed.lspd.core.Main;
|
||||
import io.github.lsposed.lspd.core.Proxy;
|
||||
import io.github.lsposed.lspd.nativebridge.Yahfa;
|
||||
import io.github.lsposed.lspd.proxy.NormalProxy;
|
||||
import io.github.lsposed.lspd.proxy.Router;
|
||||
|
||||
public class YahfaEdxpImpl extends BaseEdxpImpl {
|
||||
public class YahfaImpl extends BaseImpl {
|
||||
|
||||
static {
|
||||
final EdxpImpl lspdImpl = new YahfaEdxpImpl();
|
||||
final Impl lspdImpl = new YahfaImpl();
|
||||
if (Main.setEdxpImpl(lspdImpl)) {
|
||||
lspdImpl.init();
|
||||
}
|
||||
|
|
@ -34,8 +34,8 @@ RIRU_PATH="/data/adb/riru"
|
|||
RIRU_PROP="$(magisk --path)/.magisk/modules/riru-core/module.prop"
|
||||
TARGET="${RIRU_PATH}/modules"
|
||||
|
||||
EDXP_VERSION=$(grep_prop version "${MODDIR}/module.prop")
|
||||
EDXP_APICODE=$(grep_prop api "${MODDIR}/module.prop")
|
||||
LSPD_VERSION=$(grep_prop version "${MODDIR}/module.prop")
|
||||
LSPD_APICODE=$(grep_prop api "${MODDIR}/module.prop")
|
||||
|
||||
ANDROID_SDK=$(getprop ro.build.version.sdk)
|
||||
BUILD_DESC=$(getprop ro.build.description)
|
||||
|
|
@ -103,8 +103,9 @@ print_log_head() {
|
|||
echo "Android build: ${BUILD}">>"${LOG_FILE}"
|
||||
echo "Android version: ${ANDROID}">>"${LOG_FILE}"
|
||||
echo "Android sdk: ${ANDROID_SDK}">>"${LOG_FILE}"
|
||||
echo "LSPosed version: ${EDXP_VERSION}">>"${LOG_FILE}"
|
||||
echo "LSPosed api: ${EDXP_APICODE}">>"${LOG_FILE}"
|
||||
echo "LSPosed version: ${
|
||||
LSPD_VERSION}">>"${LOG_FILE}"
|
||||
echo "LSPosed api: ${LSPD_APICODE}">>"${LOG_FILE}"
|
||||
echo "Riru version: ${RIRU_VERSION} (${RIRU_VERCODE})">>"${LOG_FILE}"
|
||||
echo "Riru api: ${RIRU_APICODE}">>"${LOG_FILE}"
|
||||
echo "Magisk: ${MAGISK_VERSION%:*} (${MAGISK_VERCODE})">>"${LOG_FILE}"
|
||||
|
|
|
|||
Loading…
Reference in New Issue