mirror of
https://github.com/LSPosed/DisableFlagSecure.git
synced 2025-05-05 01:59:43 +08:00
switch to new bypass method (A12+)
This commit is contained in:
parent
465cb2ed9b
commit
ced188ff61
@ -3,11 +3,15 @@ package io.github.lsposed.disableflagsecure;
|
|||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.hardware.display.DisplayManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.SurfaceControl;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
@ -21,8 +25,11 @@ import io.github.libxposed.api.annotations.XposedHooker;
|
|||||||
@SuppressLint({"PrivateApi", "BlockedPrivateApi"})
|
@SuppressLint({"PrivateApi", "BlockedPrivateApi"})
|
||||||
public class DisableFlagSecure extends XposedModule {
|
public class DisableFlagSecure extends XposedModule {
|
||||||
|
|
||||||
|
private static XposedModule module;
|
||||||
|
|
||||||
public DisableFlagSecure(XposedInterface base, ModuleLoadedParam param) {
|
public DisableFlagSecure(XposedInterface base, ModuleLoadedParam param) {
|
||||||
super(base, param);
|
super(base, param);
|
||||||
|
module = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -34,7 +41,38 @@ public class DisableFlagSecure extends XposedModule {
|
|||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
log("deoptimize system server failed", t);
|
log("deoptimize system server failed", t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||||
|
try {
|
||||||
|
// Screenshot
|
||||||
|
hookScreenCapture(classLoader);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
log("hook ScreenCapture failed", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
try {
|
||||||
|
// Blackout permission check
|
||||||
|
hookActivityManagerService(classLoader);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
log("hook ActivityManagerService failed", t);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// WifiDisplay
|
||||||
|
hookDisplayControl(classLoader);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
log("hook DisplayControl failed", t);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// MediaProjection
|
||||||
|
hookVirtualDisplayAdapter(classLoader);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
log("hook VirtualDisplayAdapter failed", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Screenshot
|
||||||
hookWindowState(classLoader);
|
hookWindowState(classLoader);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
log("hook WindowState failed", t);
|
log("hook WindowState failed", t);
|
||||||
@ -84,6 +122,18 @@ public class DisableFlagSecure extends XposedModule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "com.android.systemui":
|
||||||
|
case "com.miui.screenshot":
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
|
||||||
|
Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||||
|
try {
|
||||||
|
// Screenshot
|
||||||
|
hookScreenCapture(classLoader);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
log("hook ScreenCapture failed", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
try {
|
try {
|
||||||
hookOnResume();
|
hookOnResume();
|
||||||
@ -135,7 +185,42 @@ public class DisableFlagSecure extends XposedModule {
|
|||||||
var windowManagerServiceClazz = classLoader.loadClass("com.android.server.wm.WindowManagerService");
|
var windowManagerServiceClazz = classLoader.loadClass("com.android.server.wm.WindowManagerService");
|
||||||
isSecureLockedMethod = windowManagerServiceClazz.getDeclaredMethod("isSecureLocked", windowStateClazz);
|
isSecureLockedMethod = windowManagerServiceClazz.getDeclaredMethod("isSecureLocked", windowStateClazz);
|
||||||
}
|
}
|
||||||
hook(isSecureLockedMethod, ReturnFalseHooker.class);
|
hook(isSecureLockedMethod, SecureLockedHooker.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Class<?> captureArgsClazz;
|
||||||
|
private static Field captureSecureLayersField;
|
||||||
|
private static Field allowProtectedField;
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.S)
|
||||||
|
private void hookScreenCapture(ClassLoader classLoader) throws ClassNotFoundException, NoSuchFieldException {
|
||||||
|
var screenCaptureClazz = Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE ?
|
||||||
|
classLoader.loadClass("android.window.ScreenCapture") :
|
||||||
|
SurfaceControl.class;
|
||||||
|
captureArgsClazz = classLoader.loadClass(Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE ?
|
||||||
|
"android.window.ScreenCapture$CaptureArgs" :
|
||||||
|
"android.view.SurfaceControl$CaptureArgs");
|
||||||
|
captureSecureLayersField = captureArgsClazz.getDeclaredField("mCaptureSecureLayers");
|
||||||
|
captureSecureLayersField.setAccessible(true);
|
||||||
|
allowProtectedField = captureArgsClazz.getDeclaredField("mAllowProtected");
|
||||||
|
allowProtectedField.setAccessible(true);
|
||||||
|
hookMethods(screenCaptureClazz, ScreenCaptureHooker.class, "captureDisplay");
|
||||||
|
hookMethods(screenCaptureClazz, ScreenCaptureHooker.class, "captureLayers");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.S)
|
||||||
|
private void hookDisplayControl(ClassLoader classLoader) throws ClassNotFoundException, NoSuchMethodException {
|
||||||
|
var displayControlClazz = Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE ?
|
||||||
|
classLoader.loadClass("com.android.server.display.DisplayControl") :
|
||||||
|
SurfaceControl.class;
|
||||||
|
var method = displayControlClazz.getDeclaredMethod("createDisplay", String.class, boolean.class);
|
||||||
|
hook(method, CreateDisplayHooker.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.S)
|
||||||
|
private void hookVirtualDisplayAdapter(ClassLoader classLoader) throws ClassNotFoundException {
|
||||||
|
var displayControlClazz = classLoader.loadClass("com.android.server.display.VirtualDisplayAdapter");
|
||||||
|
hookMethods(displayControlClazz, CreateVirtualDisplayLockedHooker.class, "createVirtualDisplayLocked");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
@TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||||
@ -147,6 +232,13 @@ public class DisableFlagSecure extends XposedModule {
|
|||||||
hook(method, ReturnNullHooker.class);
|
hook(method, ReturnNullHooker.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.S)
|
||||||
|
private void hookActivityManagerService(ClassLoader classLoader) throws ClassNotFoundException, NoSuchMethodException {
|
||||||
|
var activityTaskManagerServiceClazz = classLoader.loadClass("com.android.server.am.ActivityManagerService");
|
||||||
|
var method = activityTaskManagerServiceClazz.getDeclaredMethod("checkPermission", String.class, int.class, int.class);
|
||||||
|
hook(method, CheckPermissionHooker.class);
|
||||||
|
}
|
||||||
|
|
||||||
private void hookHyperOS(ClassLoader classLoader) throws ClassNotFoundException {
|
private void hookHyperOS(ClassLoader classLoader) throws ClassNotFoundException {
|
||||||
var windowManagerServiceImplClazz = classLoader.loadClass("com.android.server.wm.WindowManagerServiceImpl");
|
var windowManagerServiceImplClazz = classLoader.loadClass("com.android.server.wm.WindowManagerServiceImpl");
|
||||||
hookMethods(windowManagerServiceImplClazz, ReturnFalseHooker.class, "notAllowCaptureDisplay");
|
hookMethods(windowManagerServiceImplClazz, ReturnFalseHooker.class, "notAllowCaptureDisplay");
|
||||||
@ -180,6 +272,85 @@ public class DisableFlagSecure extends XposedModule {
|
|||||||
hook(method, ToastHooker.class);
|
hook(method, ToastHooker.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@XposedHooker
|
||||||
|
private static class CreateDisplayHooker implements Hooker {
|
||||||
|
|
||||||
|
@BeforeInvocation
|
||||||
|
public static void before(@NonNull BeforeHookCallback callback) {
|
||||||
|
callback.getArgs()[1] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@XposedHooker
|
||||||
|
private static class CheckPermissionHooker implements Hooker {
|
||||||
|
|
||||||
|
@BeforeInvocation
|
||||||
|
public static void before(@NonNull BeforeHookCallback callback) {
|
||||||
|
var permission = callback.getArgs()[0];
|
||||||
|
if ("android.permission.CAPTURE_BLACKOUT_CONTENT".equals(permission)) {
|
||||||
|
callback.getArgs()[0] = "android.permission.READ_FRAME_BUFFER";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@XposedHooker
|
||||||
|
private static class ScreenCaptureHooker implements Hooker {
|
||||||
|
|
||||||
|
@BeforeInvocation
|
||||||
|
public static void before(@NonNull BeforeHookCallback callback) {
|
||||||
|
var captureArgs = callback.getArgs()[0];
|
||||||
|
if (!captureArgsClazz.isInstance(captureArgs)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
captureSecureLayersField.set(captureArgs, true);
|
||||||
|
allowProtectedField.set(captureArgs, true);
|
||||||
|
} catch (IllegalAccessException t) {
|
||||||
|
module.log("ScreenCaptureHooker failed", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@XposedHooker
|
||||||
|
private static class CreateVirtualDisplayLockedHooker implements Hooker {
|
||||||
|
|
||||||
|
@BeforeInvocation
|
||||||
|
public static void before(@NonNull BeforeHookCallback callback) {
|
||||||
|
var caller = (int) callback.getArgs()[2];
|
||||||
|
if (caller != 1000 && callback.getArgs()[1] == null) {
|
||||||
|
// not os and not media projection
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 3; i < callback.getArgs().length; i++) {
|
||||||
|
var arg = callback.getArgs()[i];
|
||||||
|
if (arg instanceof Integer) {
|
||||||
|
var flags = (int) arg;
|
||||||
|
flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
|
||||||
|
callback.getArgs()[i] = flags;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.log("flag not found in CreateVirtualDisplayLockedHooker");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@XposedHooker
|
||||||
|
private static class SecureLockedHooker implements Hooker {
|
||||||
|
|
||||||
|
@BeforeInvocation
|
||||||
|
public static void before(@NonNull BeforeHookCallback callback) {
|
||||||
|
String stack = Log.getStackTraceString(new Throwable());
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
// don't change surface flags, but passing other checks
|
||||||
|
if (stack.contains("setInitialSurfaceControlProperties")
|
||||||
|
|| stack.contains("createSurfaceLocked")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback.returnAndSkip(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@XposedHooker
|
@XposedHooker
|
||||||
private static class ReturnFalseHooker implements Hooker {
|
private static class ReturnFalseHooker implements Hooker {
|
||||||
@BeforeInvocation
|
@BeforeInvocation
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
system
|
system
|
||||||
|
com.android.systemui
|
||||||
com.flyme.systemuiex
|
com.flyme.systemuiex
|
||||||
com.oplus.screenshot
|
com.oplus.screenshot
|
||||||
|
com.miui.screenshot
|
Loading…
x
Reference in New Issue
Block a user