Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional root (su, Magisk Zygisk module, etc) for mirroring Android 12+ w/FLAG_SECURE #3049

Open
1 task done
digitalcircuit opened this issue Feb 23, 2022 · 33 comments
Open
1 task done

Comments

@digitalcircuit
Copy link

digitalcircuit commented Feb 23, 2022

I found #2242 but that seemed to focus on non-root options.

Is your feature request related to a problem? Please describe.
In Android 12+, it is no longer possible to mirror the output of apps expecting a FLAG_SECURE display. The non-root fix scrcpy uses now is to no longer capture secure output on Android 12+.

Describe the solution you'd like
For those with root, it'd be nice if scrcpy could optionally make use of root access to enable mirroring apps that require secure display output.

Brainstorming:

Describe alternatives you've considered
Disable FLAG_SECURE for all apps using the LSposed (modern Xposed), or via a Magisk "Zygisk" code injection to the system framework.

This would unfortunately enable every app to have this access instead of just allowing the shell, unless a module could be made to revert specifically the shell UID FLAG_SECURE check.

Additional context
All of this except for maybe using su directly if possible sounds rather complicated for a niche of scrcpy users. I'd understand if the immediate reaction to this feature request is to close it and go "Nope, not touching that." 🙂

@digitalcircuit digitalcircuit changed the title Optional root extension (su, Magisk Zygisk module, etc) for mirroring w/FLAG_SECURE Optional root (su, Magisk Zygisk module, etc) for mirroring Android 12+ w/FLAG_SECURE Feb 23, 2022
@rom1v
Copy link
Collaborator

rom1v commented Feb 23, 2022

I have no experience with Magisk, but if it's possible to only allow shell to enable secure flag permissions, then scrcpy could provide an option --secure-flag, which will cause an exception (like #2129) on non-root devices, but will work for root devices with permissions enabled.

@AndroidDeveloperLB
Copy link

Wait, it's now possible to use ScrCpy to enable mirroring even protected screens (on rooted devices) ?
Is it under development?

@digitalcircuit
Copy link
Author

@AndroidDeveloperLB Not yet, alas. That's why I'm filing this feature request, to prompt discussion about how scrcpy could possibly do this.

@rom1v Noted! Adding a --secure-flag option once a root/Magisk solution is sorted to reverse that permission change sounds like a reasonable low-maintenance approach on scrcpy's side.

Rambling notes

I have much to learn about Magisk's recent Zygisk development and hooking Android functions, but I wanted to jot this down for future reference.

It looks like it'd involve patching the hasCaptureBlackoutContentPermission() function

static bool hasCaptureBlackoutContentPermission() {
    IPCThreadState* ipc = IPCThreadState::self();
    const int pid = ipc->getCallingPid();
    const int uid = ipc->getCallingUid();
    return uid == AID_GRAPHICS || uid == AID_SYSTEM ||
            PermissionCache::checkPermission(sCaptureBlackoutContent, pid, uid);
}

Adding back in a || uid == AID_SHELL like what used to be there.

Alternatively, if there's a way to use root/Magisk/etc to grant android.permission.CAPTURE_BLACKOUT_CONTENT to scrcpy, that would work. It might involve using the Shizuku API within scrcpy itself via Sui, which is… probably lower level than desired?

(I may have gotten the permission name wrong - the system AndroidManifest.xml seems to describe this as capturing secure content, as if a screenshot.)

Regardless, I'd understand wanting to keep the changes to scrcpy itself as minimal (and therefore as maintainable) as possible.

@AndroidDeveloperLB
Copy link

AndroidDeveloperLB commented Feb 23, 2022

@digitalcircuit What's "CAPTURE_BLACKOUT_CONTENT" ? I don't see it on the docs:
https://developer.android.com/reference/android/Manifest.permission
I wonder if a screenshot app could get this permission (via root).

Anyway, I would love to have ScrCpy be able to show this content, even it if requires root. I find it weird that this restriction is applied even via adb.

@digitalcircuit
Copy link
Author

@AndroidDeveloperLB I think it's intentionally not mentioned on that page due to being listed as "Not for use by third-party applications." with an @hide annotation.

frameworks/base/core/res/AndroidManifest.xml found via searching on cs.android.com:

    <!-- Allows an application to take screenshots of layers that normally would be blacked out when
         a screenshot is taken. Specifically, layers that have the flag
         {@link android.view.SurfaceControl#SECURE} will be screenshot if the caller requests to
         capture secure layers. Normally those layers will be rendered black.
         <p>Not for use by third-party applications.
         @hide
    -->
    <permission android:name="android.permission.CAPTURE_BLACKOUT_CONTENT"
        android:protectionLevel="signature" />

As you mentioned, the question I have as well is whether a protection level of signature can be safely granted to just a specific app via root/Sui/Zygisk/etc? And if so, what would be the proper (most maintainable and secure) method of going about it..?

Alternatively, hijacking the hasCaptureBlackoutContentPermission() permission check to allow UID_SHELL (ADB) again might return to pre-Android 12 security level - less specific, but likely an acceptable trade-off.

(It's possible I'm misunderstanding as I'm attempting to make sense of an area of Android that I'm unfamiliar with.)

@AndroidDeveloperLB
Copy link

AndroidDeveloperLB commented Feb 23, 2022

@digitalcircuit According to CommonsWare, it shouldn't allow you to grant it, sadly:
https://stackoverflow.com/questions/29185717/is-there-any-way-to-get-permission-with-protection-level-signature-in-android#comment46586830_29185717

But you can try. Edit some open sourced screenshot app, add the permission, grant it via adb, and see if it helps on protected apps.

He't talking about normal granting of the permission via adb (or root). I don't know the advanced stuff you talk about

@MlgmXyysd
Copy link

It's not a good thing to require root permission. Hook (Zygisk/Xposed) is even worse, especially when Xposed is seriously deprecated and destroying the custom Android community (not modern). Why not try to use the normal application to ask for permission of virtual display?

@AndroidDeveloperLB
Copy link

@MlgmXyysd You'd have to talk with every application that uses this API to block screenshots/screen-capture...
And it's not guaranteed they will do anything about what you write them.
Not practical.

It's better to have some solution than nothing.

I've requested from Google to add some toggle to turn off this kind of protection in next Android version:
https://issuetracker.google.com/issues/225529536
Please consider starring.

@MlgmXyysd
Copy link

I've requested from Google to add some toggle to turn off this kind of protection in next Android version: https://issuetracker.google.com/issues/225529536 Please consider starring.

Starred, but there is no hope that they will do so, just as they added FLAG_SECURE.

@LexNastin
Copy link

Any progress or plans on this? Would really love a way to bypass FLAG_SECURE

@MlgmXyysd
Copy link

Any progress or plans on this? Would really love a way to bypass FLAG_SECURE

You can use other ROMs that allows the user to ignore FLAG_SECURE, such as KaleidoscopeOS.

@opptimus
Copy link

Wait, it's now possible to use ScrCpy to enable mirroring even protected screens (on rooted devices) ? Is it under development?

I also neet this feature!

@AndroidDeveloperLB
Copy link

It seems that if your device is rooted with Magisk, you can have "Zygisk - LSPosed" module, and using it, there is a module inside that is called "Disable FLAG_SECURE":

image

image

@LexNastin
Copy link

LexNastin commented Aug 21, 2022

It seems that if your device is rooted with Magisk, you can have "Zygisk - LSPosed" module, and using it, there is a module inside that is called "Disable FLAG_SECURE":

image

image

Your proposed solution sadly won't work for most use cases, as this would normally be needed for things like banking apps, but they need to be in the DenyList to work, preventing any modifications to them. So this won't work for that, and we need to modify/use a different service which doesn't have to be DenyListed, the secure display being one of them. Root support would be a very nice feature for scrcpy to have, and I don't believe it would take too much effort to implement. Thanks!

@AndroidDeveloperLB
Copy link

AndroidDeveloperLB commented Aug 21, 2022

...
Your proposed solution sadly won't work for most use cases, as this would normally be needed for things like banking apps, but they need to be in the DenyList to work, preventing any modifications to them. So this won't work for that, and we need to modify/use a different service which doesn't have to be DenyListed, the secure display being one of them. Root support would be a very nice feature for scrcpy to have, and I don't believe it would take too much effort to implement. Thanks!

Maybe. I haven't had an issue with this so far. If you wish, I can test it on specific apps that everyone can check, and I could tell you what I find
Of course, the best thing is to have ScrCpy handle it on its own, overcoming all issues.

@MlgmXyysd
Copy link

MlgmXyysd commented Aug 21, 2022

It seems that if your device is rooted with Magisk, you can have "Zygisk - LSPosed" module, and using it, there is a module inside that is called "Disable FLAG_SECURE":

More easily to detect root lol

@AndroidDeveloperLB
Copy link

Guys I know this issue. I just wrote for other cases, when it does work fine.

@fcaronte
Copy link

So guy's no way for a fix? I arrived from an evox rom were is a stock feature and now i miss it

@Ch4m311eom
Copy link

Check this out https://forum.xda-developers.com/t/module-disable-flag-secure-v5-0-by-mehedi-h-joy.4490475/
It's a Magisk module which doesn't need LSPosed. I can confirm it works on Android 12 and Samsung One UI 4.1

@LexNastin
Copy link

Please read my earlier comment @Ch4m311eom, I’m almost certain it still applies based on the nature of the new DenyList functionality.

@Ch4m311eom
Copy link

Hmm I just checked this module with Shamiko and UniversalSafetyNet Fix and everything seems to be fine. I'm able to add card to Google Pay and launch my banking app. Of course I had to add banking app to DenyList list but when it's paired with Shamiko I can't see any problem.
The only disadvantage is that my phone (SM-G975F) falls in a bootloop everytime I install any Magisk module when DisableFlagSecure is installed. To install any module I have to remove DisableFlagSecure, install new module and then install DisableFlagSecure back.

@LexNastin
Copy link

What I’m saying in that comment is that if an app is in the DenyList, DisableFlagSecure won’t have any effect on that app, and you still won’t be able to take any screenshots in it. AOSPMods can be used to solve this entire issue now though.

@Ch4m311eom
Copy link

Oh, I get it. Personally I only had to "uncover" Bitwarden, that's why I found no issue.

@RiggiG
Copy link

RiggiG commented Jun 23, 2023

All of this Magisk talk seems to be vastly overcomplicating things from where I sit - since that would suggest you've got root, it'd be infinitely simpler to just execute the server as AID_SYSTEM (permitted to display FLAG_SECURE content) by adding in su 1000 -c to the startup argument list here. I did try 1003 for AID_GRAPHICS which also worked for video, but lacked permissions for basically everything else.

With this simple change, I've verified functionality with mirroring such an app on Android 13.
Of course, to add this to production, this changeup should be from a flag passed on the client (--as-root or something along those lines) alongside a warning to only grant root once to the adb shell process, but in the meantime users with root should be able to just use these binaries instead.

It also quite possibly breaks other things, but on my A13 Pixel 5 the audio, video, and touch are working without issue.
Release is here.

@diogotcorreia
Copy link

diogotcorreia commented Jun 26, 2023

I confirm it works on my device as well (Xiaomi 11T Pro with Pixel Experience 12 GSI) on a Linux x86_64 host. Thank you a lot @RiggiG!

@rom1v What do you think about @RiggiG's solution?
I don't mind submitting a pull request to add their solution behind a flag (what would you like the flag to be? --as-root, --secure-flag, or other?) if both of you agree (I don't want to steal @RiggiG's work).

@rom1v
Copy link
Collaborator

rom1v commented Jun 26, 2023

I think it is an acceptable solution, it's quite simple and non invasive. --as-root or --root look good to me, what do other people think?

@RiggiG
Copy link

RiggiG commented Jun 26, 2023

I'd certainly have no qualms with anyone else submitting a PR for bringing this in (of course via a default-inactive flag) - this was just a quick PoC to verify it was as simple as I thought it was after reading these issues. I'm also intending to try (I am woefully ill-equipped to jump into Android development) background camera access + streaming via this root mode.

I like --as-root for clarity, but certainly wouldn't call --root unclear and I'll never complain about a more concise flag.

@rom1v
Copy link
Collaborator

rom1v commented Jun 26, 2023

I'm also intending to try (I am woefully ill-equipped to jump into Android development) background camera access + streaming via this root mode.

Note that since Android 11 (commit 393ad6e0ad1670a1d33e97f7bb07b0df381b5e76), shell has CAMERA permission:
https://github.com/aosp-mirror/platform_frameworks_base/blob/de002b7c953d64125ee3088dd4bf16c28a64c5ba/packages/Shell/AndroidManifest.xml#L290

So it is certainly possible to capture the device camera without root (an option --video-source=camera similar to --audio-source=mic would be neat).

@yume-chan
Copy link
Contributor

yume-chan commented Jul 7, 2023

I quickly put together some code to test camera capturing: https://github.com/Genymobile/scrcpy/compare/dev...yume-chan:scrcpy:feat/camera?expand=1, it works on my Mi 11 (MIUI 14, Android 13).

So besides --video-source=camera, it also needs --camera=<id> and --list-cameras.

--video-source=camera will imply --no-control, touch injection is not possible due to lack of screen size, keyboard injection also doesn't make much sense. Maybe clicking will change the focus region.

Taking screenshot (#2040) will be useful in camera mode.

@rom1v
Copy link
Collaborator

rom1v commented Jul 7, 2023

Awesome 👍 That was quick after my previous message (#3516 (comment)) 😄

So besides --video-source=camera, it also needs --camera= and --list-cameras.

Yes, and also maybe a constant in addition for front and back (so that users don't have to look for the id).

Something like:

for (String cameraId : cameraManager.getCameraIdList()) {
    CameraCharacteristics cc = cameraManager.getCameraCharacteristics(cameraId);
    int lensFacing = cc.get(CameraCharacteristics.LENS_FACING);
    if (lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
        // …
    }
}

As a side note, maybe another possible option (but less important) would be the parameter passed to camera.createCaptureRequest(…); (at least TEMPLATE_PREVIEW for lower latency) or TEMPLATE_RECORD).

@ObsydianBlackKnight
Copy link

Are there any news on supporting root to elude FLAG_SECURE?

@vvb2060
Copy link

vvb2060 commented May 26, 2024

#4947
only server, so magisk is not supported, only userdebug build ROM can use

@Adityashaw
Copy link

I like --as-root for clarity, but certainly wouldn't call --root unclear and I'll never complain about a more concise flag.

I built your dev branch from https://github.com/RiggiG/scrcpy-root.git but running ./run x --root still had black screen.

(I granted root permission to shell on magisk pop up)

Any pointers @RiggiG ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests