diff --git a/core/src/main/java/org/lsposed/lspd/service/ConfigFileManager.java b/core/src/main/java/org/lsposed/lspd/service/ConfigFileManager.java index 2c0b226b..0f18b3df 100644 --- a/core/src/main/java/org/lsposed/lspd/service/ConfigFileManager.java +++ b/core/src/main/java/org/lsposed/lspd/service/ConfigFileManager.java @@ -6,6 +6,7 @@ import static org.lsposed.lspd.service.ServiceManager.toGlobalNamespace; import android.content.res.AssetManager; import android.content.res.Resources; import android.os.ParcelFileDescriptor; +import android.os.Process; import android.os.SELinux; import android.os.SharedMemory; import android.system.ErrnoException; @@ -149,8 +150,8 @@ public class ConfigFileManager { public static boolean chattr0(Path path) { try { - var dir = Os.open(path.toAbsolutePath().toString(), OsConstants.O_RDONLY, 0); - HiddenApiBridge.Os_ioctlInt(dir, HiddenApiBridge.VMRuntime_is64Bit() ? 0x40086602 : 0x40046602, 0); + var dir = Os.open(path.toString(), OsConstants.O_RDONLY, 0); + HiddenApiBridge.Os_ioctlInt(dir, Process.is64Bit() ? 0x40086602 : 0x40046602, 0); Os.close(dir); return true; } catch (Throwable e) { @@ -189,7 +190,7 @@ public class ConfigFileManager { static File getpropsLogPath() throws IOException { createLogDirPath(); - return logDirPath.resolve("props.log").toFile(); + return logDirPath.resolve("props.txt").toFile(); } static Map getLogs() { diff --git a/core/src/main/java/org/lsposed/lspd/service/LogcatService.java b/core/src/main/java/org/lsposed/lspd/service/LogcatService.java index 1b2a55f8..5f02de0d 100644 --- a/core/src/main/java/org/lsposed/lspd/service/LogcatService.java +++ b/core/src/main/java/org/lsposed/lspd/service/LogcatService.java @@ -2,20 +2,14 @@ package org.lsposed.lspd.service; import android.annotation.SuppressLint; import android.os.ParcelFileDescriptor; +import android.os.SELinux; import android.os.SystemProperties; import android.system.Os; import android.util.Log; -import org.lsposed.lspd.BuildConfig; - -import java.io.BufferedReader; -import java.io.BufferedWriter; import java.io.File; import java.io.FileDescriptor; -import java.io.FileOutputStream; -import java.io.FileWriter; import java.io.IOException; -import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.Path; @@ -36,6 +30,29 @@ public class LogcatService implements Runnable { String libraryPath = System.getProperty("lsp.library.path"); System.load(libraryPath + "/" + System.mapLibraryName("daemon")); ConfigFileManager.moveLogDir(); + + // Meizu devices set this prop and prevent debug logs from being recorded + if (SystemProperties.getInt("persist.sys.log_reject_level", 0) > 0) { + SystemProperties.set("persist.sys.log_reject_level", "0"); + } + + getprop(); + } + + private static void getprop() { + // multithreaded process can not change their context type, + // start a new process to set restricted context to filter privacy props + var cmd = "echo -n u:r:untrusted_app:s0 > /proc/thread-self/attr/current; getprop"; + try { + SELinux.setFSCreateContext("u:object_r:app_data_file:s0"); + new ProcessBuilder("sh", "-c", cmd) + .redirectOutput(ConfigFileManager.getpropsLogPath()) + .start(); + } catch (IOException e) { + Log.e(TAG, "getprop: ", e); + } finally { + SELinux.setFSCreateContext(null); + } } private native void runLogcat(); @@ -43,10 +60,6 @@ public class LogcatService implements Runnable { @Override public void run() { Log.i(TAG, "start running"); - // Meizu devices set this prop and prevent debug logs from being recorded - if (BuildConfig.DEBUG && SystemProperties.getInt("persist.sys.log_reject_level", 0) > 0) { - SystemProperties.set("persist.sys.log_reject_level", "0"); - } runLogcat(); Log.i(TAG, "stopped"); } @@ -80,6 +93,7 @@ public class LogcatService implements Runnable { if (fd == -1) return; try { var jfd = new FileDescriptor(); + //noinspection JavaReflectionMemberAccess DiscouragedPrivateApi jfd.getClass().getDeclaredMethod("setInt$", int.class).invoke(jfd, fd); var stat = Os.fstat(jfd); if (stat.st_nlink == 0) { @@ -112,42 +126,6 @@ public class LogcatService implements Runnable { start(); }); thread.start(); - getprop(); - } - - private void getprop() { - try { - var sb = new StringBuilder(); - var t = new Thread(() -> { - try (var magiskPathReader = new BufferedReader(new InputStreamReader(new ProcessBuilder("magisk", "--path").start().getInputStream()))) { - var magiskPath = magiskPathReader.readLine(); - var sh = magiskPath + "/.magisk/busybox/sh"; - var pid = Os.getpid(); - var tid = Os.gettid(); - try (var exec = new FileOutputStream("/proc/" + pid + "/task/" + tid + "/attr/exec")) { - var untrusted = "u:r:untrusted_app:s0"; - exec.write(untrusted.getBytes()); - } - try (var rd = new BufferedReader(new InputStreamReader(new ProcessBuilder(sh, "-c", "getprop").start().getInputStream()))) { - String line; - while ((line = rd.readLine()) != null) { - sb.append(line); - sb.append(System.lineSeparator()); - } - } - } catch (IOException e) { - Log.e(TAG, "GetProp: ", e); - } - }); - t.start(); - t.join(); - var propsLogPath = ConfigFileManager.getpropsLogPath(); - try (var writer = new BufferedWriter(new FileWriter(propsLogPath))) { - writer.append(sb); - } - } catch (IOException | InterruptedException | NullPointerException e) { - Log.e(TAG, "GetProp: ", e); - } } public void startVerbose() { @@ -166,7 +144,7 @@ public class LogcatService implements Runnable { } } - static private Path fdToPath(int fd) { + private static Path fdToPath(int fd) { if (fd == -1) return null; else return Paths.get("/proc/self/fd", String.valueOf(fd)); } diff --git a/hiddenapi-bridge/src/main/java/hidden/HiddenApiBridge.java b/hiddenapi-bridge/src/main/java/hidden/HiddenApiBridge.java index f0ee0f76..31489fdb 100644 --- a/hiddenapi-bridge/src/main/java/hidden/HiddenApiBridge.java +++ b/hiddenapi-bridge/src/main/java/hidden/HiddenApiBridge.java @@ -109,8 +109,4 @@ public class HiddenApiBridge { return Os.ioctlInt(fd, cmd); } } - - public static boolean VMRuntime_is64Bit() { - return VMRuntime.getRuntime().is64Bit(); - } } diff --git a/hiddenapi-stubs/src/main/java/android/os/SELinux.java b/hiddenapi-stubs/src/main/java/android/os/SELinux.java index 4dfe1de7..991a84fe 100644 --- a/hiddenapi-stubs/src/main/java/android/os/SELinux.java +++ b/hiddenapi-stubs/src/main/java/android/os/SELinux.java @@ -8,4 +8,8 @@ public class SELinux { public static boolean setFileContext(String path, String context) { throw new UnsupportedOperationException("Stub"); } + + public static boolean setFSCreateContext(String context){ + throw new UnsupportedOperationException("Stub"); + } } diff --git a/hiddenapi-stubs/src/main/java/dalvik/system/VMRuntime.java b/hiddenapi-stubs/src/main/java/dalvik/system/VMRuntime.java index 2d953c32..e578e8c4 100644 --- a/hiddenapi-stubs/src/main/java/dalvik/system/VMRuntime.java +++ b/hiddenapi-stubs/src/main/java/dalvik/system/VMRuntime.java @@ -6,7 +6,8 @@ public class VMRuntime { throw new RuntimeException("Stub!"); } + // Use `Process.is64Bit()` instead public native boolean is64Bit(); - + public native String vmInstructionSet(); }