Skip to content

Commit

Permalink
switch to new bypass method (A12+)
Browse files Browse the repository at this point in the history
  • Loading branch information
tehcneko committed May 27, 2024
1 parent 465cb2e commit ced188f
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.hardware.display.DisplayManager;
import android.os.Build;
import android.util.Log;
import android.view.SurfaceControl;
import android.widget.Toast;

import androidx.annotation.NonNull;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.function.BiConsumer;
Expand All @@ -21,8 +25,11 @@
@SuppressLint({"PrivateApi", "BlockedPrivateApi"})
public class DisableFlagSecure extends XposedModule {

private static XposedModule module;

public DisableFlagSecure(XposedInterface base, ModuleLoadedParam param) {
super(base, param);
module = this;
}

@Override
Expand All @@ -34,7 +41,38 @@ public void onSystemServerLoaded(@NonNull SystemServerLoadedParam param) {
} catch (Throwable 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 {
// Screenshot
hookWindowState(classLoader);
} catch (Throwable t) {
log("hook WindowState failed", t);
Expand Down Expand Up @@ -84,6 +122,18 @@ public void onPackageLoaded(@NonNull PackageLoadedParam param) {
}
}
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:
try {
hookOnResume();
Expand Down Expand Up @@ -135,7 +185,42 @@ private void hookWindowState(ClassLoader classLoader) throws ClassNotFoundExcept
var windowManagerServiceClazz = classLoader.loadClass("com.android.server.wm.WindowManagerService");
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)
Expand All @@ -147,6 +232,13 @@ private void hookActivityTaskManagerService(ClassLoader classLoader) throws Clas
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 {
var windowManagerServiceImplClazz = classLoader.loadClass("com.android.server.wm.WindowManagerServiceImpl");
hookMethods(windowManagerServiceImplClazz, ReturnFalseHooker.class, "notAllowCaptureDisplay");
Expand Down Expand Up @@ -180,6 +272,85 @@ private void hookOnResume() throws NoSuchMethodException {
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
private static class ReturnFalseHooker implements Hooker {
@BeforeInvocation
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/resources/META-INF/xposed/scope.list
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
system
com.android.systemui
com.flyme.systemuiex
com.oplus.screenshot
com.oplus.screenshot
com.miui.screenshot

0 comments on commit ced188f

Please sign in to comment.