diff --git a/app/src/main/java/org/lsposed/manager/ConfigManager.java b/app/src/main/java/org/lsposed/manager/ConfigManager.java
index 22dfca14..983c76fb 100644
--- a/app/src/main/java/org/lsposed/manager/ConfigManager.java
+++ b/app/src/main/java/org/lsposed/manager/ConfigManager.java
@@ -178,6 +178,25 @@ public class ConfigManager {
}
}
+ public static boolean isLogWatchdogEnabled() {
+ try {
+ return LSPManagerServiceHolder.getService().isLogWatchdogEnabled();
+ } catch (RemoteException e) {
+ Log.e(App.TAG, Log.getStackTraceString(e));
+ return false;
+ }
+ }
+
+ public static boolean setLogWatchdog(boolean enabled) {
+ try {
+ LSPManagerServiceHolder.getService().setLogWatchdog(enabled);
+ return true;
+ } catch (RemoteException e) {
+ Log.e(App.TAG, Log.getStackTraceString(e));
+ return false;
+ }
+ }
+
public static ParcelFileDescriptor getLog(boolean verbose) {
try {
return verbose ? LSPManagerServiceHolder.getService().getVerboseLog() : LSPManagerServiceHolder.getService().getModulesLog();
diff --git a/app/src/main/java/org/lsposed/manager/ui/fragment/SettingsFragment.java b/app/src/main/java/org/lsposed/manager/ui/fragment/SettingsFragment.java
index 2d06c1e5..dc7b5b91 100644
--- a/app/src/main/java/org/lsposed/manager/ui/fragment/SettingsFragment.java
+++ b/app/src/main/java/org/lsposed/manager/ui/fragment/SettingsFragment.java
@@ -160,6 +160,13 @@ public class SettingsFragment extends BaseFragment {
prefVerboseLogs.setOnPreferenceChangeListener((preference, newValue) -> ConfigManager.setVerboseLogEnabled(!(boolean) newValue));
}
+ MaterialSwitchPreference prefEnableLog = findPreference("enable_log_watchdog");
+ if (prefEnableLog != null) {
+ prefEnableLog.setEnabled(!BuildConfig.DEBUG && installed);
+ prefEnableLog.setChecked(!installed || ConfigManager.isLogWatchdogEnabled());
+ prefEnableLog.setOnPreferenceChangeListener((preference, newValue) -> ConfigManager.setLogWatchdog((boolean) newValue));
+ }
+
MaterialSwitchPreference prefDexObfuscate = findPreference("enable_dex_obfuscate");
if (prefDexObfuscate != null) {
prefDexObfuscate.setEnabled(installed);
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 1ad115ea..f17fca6f 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -175,6 +175,8 @@
Framework
Disable verbose logs
Report issues request to include verbose logs
+ Enable log watchdog
+ Log watchdog of LSPosed modifies system properties, which could be exploited to detect LSPosed
Black dark theme
Use the pure black theme if dark theme is enabled
Theme
diff --git a/app/src/main/res/xml/prefs.xml b/app/src/main/res/xml/prefs.xml
index f7219288..6b9d8691 100644
--- a/app/src/main/res/xml/prefs.xml
+++ b/app/src/main/res/xml/prefs.xml
@@ -91,6 +91,14 @@
android:summary="@string/settings_disable_verbose_log_summary"
android:title="@string/settings_disable_verbose_log" />
+
+
= Build.VERSION_CODES.R)
permissionManagerWorkaround();
@@ -133,11 +142,6 @@ public class ServiceManager {
systemServerService.putBinderForSystemServer();
- // get config before package service is started
- // otherwise getInstance will trigger module/scope cache
- var configManager = ConfigManager.getInstance();
- // --- DO NOT call ConfigManager.getInstance later!!! ---
-
ActivityThread.systemMain();
DdmHandleAppName.setAppName("org.lsposed.daemon", 0);
diff --git a/daemon/src/main/jni/logcat.cpp b/daemon/src/main/jni/logcat.cpp
index af5aeb73..3f0ec340 100644
--- a/daemon/src/main/jni/logcat.cpp
+++ b/daemon/src/main/jni/logcat.cpp
@@ -5,6 +5,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -129,6 +130,7 @@ private:
pid_t my_pid_ = getpid();
bool verbose_ = true;
+ std::atomic enable_watchdog = std::atomic(false);
};
size_t Logcat::PrintLogLine(const AndroidLogEntry &entry, FILE *out) {
@@ -241,6 +243,12 @@ void Logcat::ProcessBuffer(struct log_msg *buf) {
RefreshFd(false);
} else if (msg == "!!refresh_verbose!!"sv) {
RefreshFd(true);
+ } else if (msg == "!!start_watchdog!!"sv) {
+ enable_watchdog = true;
+ enable_watchdog.notify_one();
+ } else if (msg == "!!stop_watchdog!!"sv) {
+ enable_watchdog = false;
+ enable_watchdog.notify_one();
}
}
}
@@ -253,6 +261,7 @@ void Logcat::EnsureLogWatchDog() {
constexpr static size_t kErr = -1;
std::thread watch_dog([this] {
while (true) {
+ enable_watchdog.wait(false);
auto logd_size = GetByteProp(kLogdSizeProp);
auto logd_tag = GetStrProp(kLogdTagProp);
auto logd_main_size = GetByteProp(kLogdMainSizeProp);
@@ -277,8 +286,9 @@ void Logcat::EnsureLogWatchDog() {
}, &serial);
}
if (!__system_property_wait(pi, serial, &serial, nullptr)) break;
- if (pi != nullptr) Log("\nResetting log settings\n");
- else std::this_thread::sleep_for(1s);
+ if (pi != nullptr) {
+ if (enable_watchdog) Log("\nResetting log settings\n");
+ } else std::this_thread::sleep_for(1s);
// log tag prop was not found; to avoid frequently trigger wait, sleep for a while
}
});
diff --git a/services/manager-service/src/main/aidl/org/lsposed/lspd/ILSPManagerService.aidl b/services/manager-service/src/main/aidl/org/lsposed/lspd/ILSPManagerService.aidl
index ca1c0488..ea82be2f 100644
--- a/services/manager-service/src/main/aidl/org/lsposed/lspd/ILSPManagerService.aidl
+++ b/services/manager-service/src/main/aidl/org/lsposed/lspd/ILSPManagerService.aidl
@@ -87,4 +87,8 @@ interface ILSPManagerService {
boolean enableStatusNotification() = 47;
void setEnableStatusNotification(boolean enable) = 48;
+
+ void setLogWatchdog(boolean enable) = 49;
+
+ boolean isLogWatchdogEnabled() = 50;
}