Chainfire / liveboot

Sources for the LiveBoot app for rooted Android devices
Other
214 stars 24 forks source link

Android 12 Support? #4

Closed DavidBerdik closed 2 years ago

DavidBerdik commented 2 years ago

Are there plans to update LiveBoot to support Android 12? I've been trying to dig through the code to figure out how I could make it work, but I have not made any progress.

VladWinner commented 2 years ago

Here's what happens when you press "Test run":

6516 W eu.chainfire.liveboot:root: ART APEX data files are untrusted.
6516 W eu.chainfire.liveboot:root: ClassLoaderContext shared library size mismatch. Expected=1, found=0 (PCL[]{PCL[/system/framework/android.test.base.jar*3790657674]} | PCL[])

Source

DavidBerdik commented 2 years ago

Thank you. I will pass this on to Chainfire on Twitter.

Chainfire commented 2 years ago

I don't really know. I've been out of Android since for a while now and I do not have any rooted devices capable of running Android 12 at the moment. Seems it cannot find the shared libraries it requires, probably due to new/changed security stuff. That's quite a rabbit hole to go down to find the fix for.

DavidBerdik commented 2 years ago

@Chainfire Fair enough. Do you have any idea if this is relevant, at least? - https://source.android.com/devices/tech/dalvik/art-class-loader-context

Specifically: https://source.android.com/devices/tech/dalvik/art-class-loader-context#boot-time-clc-mismatch

DavidBerdik commented 2 years ago

I managed to get a more verbose log output when trying to run the test:

2022-02-01 17:18:46.047 25075-25075/? W/Thread-5: type=1400 audit(0.0:9532): avc: denied { getattr } for path="/system/lib64/bootstrap" dev="dm-0" ino=2088 scontext=u:r:untrusted_app_29:s0:c33,c257,c512,c768 tcontext=u:object_r:system_bootstrap_lib_file:s0 tclass=dir permissive=0 app=eu.chainfire.liveboot
2022-02-01 17:18:46.050 25075-25075/? W/Thread-5: type=1400 audit(0.0:9533): avc: denied { getattr } for path="/vendor/lib64/android.frameworks.sensorservice@1.0.so" dev="dm-1" ino=1430 scontext=u:r:untrusted_app_29:s0:c33,c257,c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
2022-02-01 17:18:46.050 25075-25075/? W/Thread-5: type=1400 audit(0.0:9534): avc: denied { getattr } for path="/vendor/lib64/android.frameworks.stats-V1-ndk_platform.so" dev="dm-1" ino=1431 scontext=u:r:untrusted_app_29:s0:c33,c257,c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
2022-02-01 17:18:46.050 25075-25075/? W/Thread-5: type=1400 audit(0.0:9535): avc: denied { getattr } for path="/vendor/lib64/android.frameworks.stats@1.0.so" dev="dm-1" ino=1432 scontext=u:r:untrusted_app_29:s0:c33,c257,c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
2022-02-01 17:18:46.050 25075-25075/? W/Thread-5: type=1400 audit(0.0:9536): avc: denied { getattr } for path="/vendor/lib64/android.hardware.atrace@1.0.so" dev="dm-1" ino=1433 scontext=u:r:untrusted_app_29:s0:c33,c257,c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
2022-02-01 17:18:46.380 25363-25363/? I/eu.chainfire.liveboot:root: Core platform API reporting enabled, enforcing=false
2022-02-01 17:18:46.477 25363-25363/? D/eu.chainfire.liveboot:root: Time zone APEX ICU file found: /apex/com.android.tzdata/etc/icu/icu_tzdata.dat
2022-02-01 17:18:46.477 25363-25363/? D/eu.chainfire.liveboot:root: I18n APEX ICU file found: /apex/com.android.i18n/etc/icu/icudt68l.dat
2022-02-01 17:18:46.486 25363-25363/? W/eu.chainfire.liveboot:root: ClassLoaderContext shared library size mismatch. Expected=1, found=0 (PCL[]{PCL[/system/framework/android.test.base.jar*2441921855]} | PCL[])
2022-02-01 17:18:46.509 25363-25363/? D/AndroidRuntime: Calling main entry eu.chainfire.liveboot.e.d
2022-02-01 17:18:46.789 25363-25363/? I/eu.chainfire.liveboot:root: System.exit called, status: 0
DavidBerdik commented 2 years ago

When I install LiveBoot as a priv-app, the test run still fails, but the ClassLoaderContext shared library size mismatch. error seems to not occur.

2022-02-01 17:39:00.859 9637-9637/? W/Thread-13: type=1400 audit(0.0:20527): avc: denied { getattr } for path="/system/lib64/bootstrap" dev="dm-0" ino=1953 scontext=u:r:priv_app:s0:c512,c768 tcontext=u:object_r:system_bootstrap_lib_file:s0 tclass=dir permissive=0 app=eu.chainfire.liveboot
2022-02-01 17:39:00.862 9637-9637/? W/Thread-13: type=1400 audit(0.0:20528): avc: denied { getattr } for path="/vendor/lib64/android.frameworks.sensorservice@1.0.so" dev="dm-1" ino=1716 scontext=u:r:priv_app:s0:c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
2022-02-01 17:39:00.862 9637-9637/? W/Thread-13: type=1400 audit(0.0:20529): avc: denied { getattr } for path="/vendor/lib64/android.frameworks.stats-V1-ndk_platform.so" dev="dm-1" ino=1717 scontext=u:r:priv_app:s0:c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
2022-02-01 17:39:00.862 9637-9637/? W/Thread-13: type=1400 audit(0.0:20530): avc: denied { getattr } for path="/vendor/lib64/android.frameworks.stats@1.0.so" dev="dm-1" ino=1718 scontext=u:r:priv_app:s0:c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
2022-02-01 17:39:00.862 9637-9637/? W/Thread-13: type=1400 audit(0.0:20531): avc: denied { getattr } for path="/vendor/lib64/android.hardware.atrace@1.0.so" dev="dm-1" ino=1719 scontext=u:r:priv_app:s0:c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
2022-02-01 17:39:01.126 14168-14168/? D/eu.chainfire.liveboot:root: Time zone APEX ICU file found: /apex/com.android.tzdata/etc/icu/icu_tzdata.dat
2022-02-01 17:39:01.126 14168-14168/? D/eu.chainfire.liveboot:root: I18n APEX ICU file found: /apex/com.android.i18n/etc/icu/icudt68l.dat
2022-02-01 17:39:01.151 14168-14168/? D/AndroidRuntime: Calling main entry eu.chainfire.liveboot.e.d
2022-02-01 17:39:01.302 14168-14168/? I/eu.chainfire.liveboot:root: System.exit called, status: 0
DavidBerdik commented 2 years ago

Finally managed to compile my own build from source! Here's the error I'm getting now when I run the tester:

D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0
D/libsuperuser: [libsuperuser][C][SU+] /su/bin/sush -c "echo OK"
D/libsuperuser: [libsuperuser][O][SU*] /system/bin/sh: <stdin>[362]: /su/bin/sush: inaccessible or not found
D/libsuperuser: [libsuperuser][O][SU-] 7ab4e20b-f079-4b32-8dd6-37215ae97be5-00000042 127
D/libsuperuser: [libsuperuser][O][SU*] 7ab4e20b-f079-4b32-8dd6-37215ae97be5-00000042
D/libsuperuser: [libsuperuser][P] releaseReservation
D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0
D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0
D/libsuperuser: [libsuperuser][C][SU+] /tmp-mksh/tmp-mksh -c "echo OK"
D/libsuperuser: [libsuperuser][O][SU-] 7ba5f9c7-fe51-4085-a827-8d78240dd58e-00000043 127
D/libsuperuser: [libsuperuser][O][SU*] /system/bin/sh: <stdin>[365]: /tmp-mksh/tmp-mksh: inaccessible or not found
D/libsuperuser: [libsuperuser][O][SU*] 7ba5f9c7-fe51-4085-a827-8d78240dd58e-00000043
D/libsuperuser: [libsuperuser][P] releaseReservation
D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0
W/Thread-8: type=1400 audit(0.0:16037): avc: denied { getattr } for path="/system/lib64/bootstrap" dev="dm-0" ino=1953 scontext=u:r:untrusted_app:s0:c109,c257,c512,c768 tcontext=u:object_r:system_bootstrap_lib_file:s0 tclass=dir permissive=0 app=eu.chainfire.liveboot
W/Thread-8: type=1400 audit(0.0:16038): avc: denied { getattr } for path="/vendor/lib64/android.frameworks.sensorservice@1.0.so" dev="dm-1" ino=1716 scontext=u:r:untrusted_app:s0:c109,c257,c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
W/Thread-8: type=1400 audit(0.0:16039): avc: denied { getattr } for path="/vendor/lib64/android.frameworks.stats-V1-ndk_platform.so" dev="dm-1" ino=1717 scontext=u:r:untrusted_app:s0:c109,c257,c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
W/Thread-8: type=1400 audit(0.0:16040): avc: denied { getattr } for path="/vendor/lib64/android.frameworks.stats@1.0.so" dev="dm-1" ino=1718 scontext=u:r:untrusted_app:s0:c109,c257,c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
W/Thread-8: type=1400 audit(0.0:16041): avc: denied { getattr } for path="/vendor/lib64/android.hardware.atrace@1.0.so" dev="dm-1" ino=1719 scontext=u:r:untrusted_app:s0:c109,c257,c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
W/Thread-8: type=1400 audit(0.0:16042): avc: denied { getattr } for path="/vendor/lib64/android.hardware.audio.common@5.0.so" dev="dm-1" ino=1720 scontext=u:r:untrusted_app:s0:c109,c257,c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
W/Thread-8: type=1400 audit(0.0:16043): avc: denied { getattr } for path="/vendor/lib64/android.hardware.authsecret@1.0-impl.nos.so" dev="dm-1" ino=1721 scontext=u:r:untrusted_app:s0:c109,c257,c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
W/Thread-8: type=1400 audit(0.0:16044): avc: denied { getattr } for path="/vendor/lib64/android.hardware.authsecret@1.0.so" dev="dm-1" ino=1722 scontext=u:r:untrusted_app:s0:c109,c257,c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
W/Thread-8: type=1400 audit(0.0:16045): avc: denied { getattr } for path="/vendor/lib64/android.hardware.biometrics.fingerprint@2.1.so" dev="dm-1" ino=1723 scontext=u:r:untrusted_app:s0:c109,c257,c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0
D/libsuperuser: [libsuperuser][C][SU+] toybox rm /data/user_de/0/eu.chainfire.liveboot/files/app_process
D/libsuperuser: [libsuperuser][C][SU+] toybox rm /data/user_de/0/eu.chainfire.liveboot/files/liveboot
D/libsuperuser: [libsuperuser][C][SU+] toybox cp /system/bin/app_process64 /data/user_de/0/eu.chainfire.liveboot/files/app_process
D/libsuperuser: [libsuperuser][C][SU+] toybox chown 0.0 /data/user_de/0/eu.chainfire.liveboot/files/app_process
D/libsuperuser: [libsuperuser][C][SU+] toybox chmod 0700 /data/user_de/0/eu.chainfire.liveboot/files/app_process
D/libsuperuser: [libsuperuser][C][SU+] toybox chcon u:object_r:app_data_file:s0 /data/user_de/0/eu.chainfire.liveboot/files/app_process
D/libsuperuser: [libsuperuser][C][SU+] echo '#!/system/bin/sh' > /data/user_de/0/eu.chainfire.liveboot/files/liveboot
D/libsuperuser: [libsuperuser][C][SU+] echo '#app_process=/system/bin/app_process64' >> /data/user_de/0/eu.chainfire.liveboot/files/liveboot
D/libsuperuser: [libsuperuser][C][SU+] toybox chmod 0700 /data/user_de/0/eu.chainfire.liveboot/files/liveboot
D/libsuperuser: [libsuperuser][C][SU+] echo 'NO_ADDR_COMPAT_LAYOUT_FIXUP=1 ANDROID_ROOT=/system LD_LIBRARY_PATH=/system/lib64:/system/lib64/hw:/system/lib64/drm:/vendor/lib64:/vendor/lib64/camera:/vendor/lib64/egl:/vendor/lib64/hw:/vendor/lib64/mediacas:/vendor/lib64/mediadrm:/vendor/lib64/soundfx:/system/bin:/librootjava CLASSPATH=/data/app/~~mO4YUIvDVeaSjeEXWW9Rwg==/eu.chainfire.liveboot-VLsuck1CJaFbzX1nMWJu7Q==/base.apk /data/app/~~mO4YUIvDVeaSjeEXWW9Rwg==/eu.chainfire.liveboot-VLsuck1CJaFbzX1nMWJu7Q==/lib/arm64/libdaemonize.so /system/bin/app_process64 /system/bin --nice-name=eu.chainfire.liveboot:root eu.chainfire.liveboot.shell.Runner /data/app/~~mO4YUIvDVeaSjeEXWW9Rwg==/eu.chainfire.liveboot-VLsuck1CJaFbzX1nMWJu7Q==/base.apk boot logcatlevels=VDIWEFS logcatbuffers=MSC logcatformat=brief dmesg=0-99 lines=80 wordwrap' >> /data/user_de/0/eu.chainfire.liveboot/files/liveboot
D/libsuperuser: [libsuperuser][C][SU+] toybox chmod 0700 /data/user_de/0/eu.chainfire.liveboot/files/liveboot
D/libsuperuser: [libsuperuser][C][SU+] echo '#!/system/bin/sh' > /data/user_de/0/eu.chainfire.liveboot/files/test
D/libsuperuser: [libsuperuser][C][SU+] echo '#app_process=/system/bin/app_process64' >> /data/user_de/0/eu.chainfire.liveboot/files/test
D/libsuperuser: [libsuperuser][C][SU+] toybox chmod 0700 /data/user_de/0/eu.chainfire.liveboot/files/test
D/libsuperuser: [libsuperuser][C][SU+] echo 'NO_ADDR_COMPAT_LAYOUT_FIXUP=1 ANDROID_ROOT=/system LD_LIBRARY_PATH=/system/lib64:/system/lib64/hw:/system/lib64/drm:/vendor/lib64:/vendor/lib64/camera:/vendor/lib64/egl:/vendor/lib64/hw:/vendor/lib64/mediacas:/vendor/lib64/mediadrm:/vendor/lib64/soundfx:/system/bin:/librootjava CLASSPATH=/data/app/~~mO4YUIvDVeaSjeEXWW9Rwg==/eu.chainfire.liveboot-VLsuck1CJaFbzX1nMWJu7Q==/base.apk /system/bin/app_process64 /system/bin --nice-name=eu.chainfire.liveboot:root eu.chainfire.liveboot.shell.Runner /data/app/~~mO4YUIvDVeaSjeEXWW9Rwg==/eu.chainfire.liveboot-VLsuck1CJaFbzX1nMWJu7Q==/base.apk test logcatlevels=VDIWEFS logcatbuffers=MSC logcatformat=brief dmesg=0--1 lines=80 wordwrap' >> /data/user_de/0/eu.chainfire.liveboot/files/test
D/libsuperuser: [libsuperuser][C][SU+] toybox chmod 0700 /data/user_de/0/eu.chainfire.liveboot/files/test
D/libsuperuser: [libsuperuser][O][SU-] d10da70d-41e6-4439-842f-38d6ba3d3aa9-00000044 0
D/libsuperuser: [libsuperuser][O][SU*] d10da70d-41e6-4439-842f-38d6ba3d3aa9-00000044
D/libsuperuser: [libsuperuser][P] releaseReservation
D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0
D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0
D/libsuperuser: [libsuperuser][C][SU+] /data/user_de/0/eu.chainfire.liveboot/files/test
D/libsuperuser: [libsuperuser][O][SU*] java.lang.NoSuchMethodException: android.view.SurfaceControl.getDisplayConfigs [interface android.os.IBinder]
D/libsuperuser: [libsuperuser][O][SU*]  at java.lang.Class.getMethod(Class.java:2103)
D/libsuperuser: [libsuperuser][O][SU*]  at java.lang.Class.getDeclaredMethod(Class.java:2081)
D/libsuperuser: [libsuperuser][O][SU*]  at eu.chainfire.libcfsurface.SurfaceHost.initSurface(SurfaceHost.java:129)
D/libsuperuser: [libsuperuser][O][SU*]  at eu.chainfire.libcfsurface.SurfaceHost.run(SurfaceHost.java:435)
D/libsuperuser: [libsuperuser][O][SU*]  at eu.chainfire.liveboot.shell.Runner.main(Runner.java:73)
D/libsuperuser: [libsuperuser][O][SU*]  at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
D/libsuperuser: [libsuperuser][O][SU*]  at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:355)
D/libsuperuser: [libsuperuser][O][SU*] java.lang.RuntimeException: CFSurface: unexpected exception during SurfaceControl creation
D/libsuperuser: [libsuperuser][O][SU*]  at eu.chainfire.libcfsurface.SurfaceHost.initSurface(SurfaceHost.java:250)
D/libsuperuser: [libsuperuser][O][SU*]  at eu.chainfire.libcfsurface.SurfaceHost.run(SurfaceHost.java:435)
D/libsuperuser: [libsuperuser][O][SU*]  at eu.chainfire.liveboot.shell.Runner.main(Runner.java:73)
D/libsuperuser: [libsuperuser][O][SU*]  at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
D/libsuperuser: [libsuperuser][O][SU*]  at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:355)
D/libsuperuser: [libsuperuser][O][SU*] d185f7cf-087d-4d74-abb1-3a6d92dbae40-00000045
D/libsuperuser: [libsuperuser][O][SU-] d185f7cf-087d-4d74-abb1-3a6d92dbae40-00000045 0
D/libsuperuser: [libsuperuser][P] releaseReservation
D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0

Found the relevant function in the Android 11 code: https://cs.android.com/android/platform/superproject/+/android-11.0.0_r48:frameworks/base/core/java/android/view/SurfaceControl.java;l=1530

It does not appear in the Android 12 code. I'm trying to narrow it down right now. Any help would be appreciated.

DavidBerdik commented 2 years ago

So, I think I have made some progress towards resolving the issue with Android 12, but it is not done yet, and I would welcome help.

I have forked this repo and pushed my work to an android-12-support branch. Any comments, suggestions, and of course, code contributions, would be greatly appreciated!

https://github.com/DavidBerdik/liveboot/tree/android-12-support

My code resolves the first missing function, but there's another one that gets hit later on.

2022-02-01 20:24:23.022 29746-29793/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*] java.lang.NoSuchMethodException: android.view.SurfaceControl.setLayer [class android.view.SurfaceControl, int]
2022-02-01 20:24:23.023 29746-29793/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*]    at java.lang.Class.getMethod(Class.java:2103)
2022-02-01 20:24:23.024 29746-29793/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*]    at java.lang.Class.getDeclaredMethod(Class.java:2081)
2022-02-01 20:24:23.024 29746-29793/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*]    at eu.chainfire.libcfsurface.SurfaceHost.initSurface(SurfaceHost.java:247)
2022-02-01 20:24:23.025 29746-29793/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*]    at eu.chainfire.libcfsurface.SurfaceHost.run(SurfaceHost.java:458)
2022-02-01 20:24:23.025 29746-29793/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*]    at eu.chainfire.liveboot.shell.Runner.main(Runner.java:73)
2022-02-01 20:24:23.026 29746-29793/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*]    at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
2022-02-01 20:24:23.026 29746-29793/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*]    at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:355)
2022-02-01 20:24:23.027 29746-29793/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*] java.lang.RuntimeException: CFSurface: unexpected exception during SurfaceControl creation
2022-02-01 20:24:23.028 29746-29793/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*]    at eu.chainfire.libcfsurface.SurfaceHost.initSurface(SurfaceHost.java:273)
2022-02-01 20:24:23.028 29746-29793/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*]    at eu.chainfire.libcfsurface.SurfaceHost.run(SurfaceHost.java:458)
2022-02-01 20:24:23.029 29746-29793/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*]    at eu.chainfire.liveboot.shell.Runner.main(Runner.java:73)
2022-02-01 20:24:23.029 29746-29793/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*]    at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
2022-02-01 20:24:23.029 29746-29793/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*]    at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:355)
2022-02-01 20:24:23.058 29746-29793/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*] 92b2f697-4f28-445d-9d92-c5032eac272d-0000001b
2022-02-01 20:24:23.058 29746-29792/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU-] 92b2f697-4f28-445d-9d92-c5032eac272d-0000001b 0
2022-02-01 20:24:23.058 29746-29936/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][P] releaseReservation
2022-02-01 20:24:23.059 29746-29936/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0
Chainfire commented 2 years ago

When I install LiveBoot as a priv-app, the test run still fails, but the ClassLoaderContext shared library size mismatch. error seems to not occur.

Was this fixed by any of the changes you've made? This all seems like a core libCFSurface/libRootJava issue, not so much a LiveBoot issue. It'd be unfortunate if they have to be priv-apps now. Probably a way around.

@Chainfire Fair enough. Do you have any idea if this is relevant, at least? - https://source.android.com/devices/tech/dalvik/art-class-loader-context

Specifically: https://source.android.com/devices/tech/dalvik/art-class-loader-context#boot-time-clc-mismatch

Not sure, really.

Finally managed to compile my own build from source! Here's the error I'm getting now when I run the tester

Why wouldn't it compile before? I think I heard something about the jfrog/bintray shutting down, which may kill all package includes, I don't think I've migrated anything.

https://github.com/DavidBerdik/liveboot/commit/d847c391b9e050751b4091bf2f56fa81c60a6e31?diff=unified

I'm not a fan of what you did here. The detections are done in this fashion because internal Android code does not cleanly port on those lines. Preview releases (which always persist in the wild longer than needed) do not adhere to them, and OEMs don't always port all the relevant code right away, so even if their public API matches the private may not. This happens a LOT.

The code is worded exactly this way because of testing through the years, changes like this for "neatness" tend to unintentionally break things.

My code resolves the first missing function, but there's another one that gets hit later on.

Seems the setLayer call was removed. It still exists in the transaction though, so you can just imitate the original function. Synchronize on the SurfaceControl.class, grab sGlobalTransaction, and call setLayer on that.

Any comments, suggestions, and of course, code contributions, would be greatly appreciated!

Well, not sure what your plans are, but it would be great if the eventual fixes get back-PR'd to libRootJava/libCFSurface/LiveBoot rather than just live in your fork.

DavidBerdik commented 2 years ago

When I install LiveBoot as a priv-app, the test run still fails, but the ClassLoaderContext shared library size mismatch. error seems to not occur.

Was this fixed by any of the changes you've made? This all seems like a core libCFSurface/libRootJava issue, not so much a LiveBoot issue. It'd be unfortunate if they have to be priv-apps now. Probably a way around.

It appears that it is indeed a libCFSurface issue! The error message does not appear to be happening when I run my build of the app, so I'm not sure what to make of it. I figure that if it continues to happen after the function call updates are made, then I will deal with it at that time if the app is still not working after that.

@Chainfire Fair enough. Do you have any idea if this is relevant, at least? - https://source.android.com/devices/tech/dalvik/art-class-loader-context Specifically: https://source.android.com/devices/tech/dalvik/art-class-loader-context#boot-time-clc-mismatch

Not sure, really.

After digging into it a bit more, I believe the answer is no, but I'm not 100% confident about it either.

Finally managed to compile my own build from source! Here's the error I'm getting now when I run the tester

Why wouldn't it compile before? I think I heard something about the jfrog/bintray shutting down, which may kill all package includes, I don't think I've migrated anything.

The reason I couldn't get it to compile was because Gradle couldn't fetch the libCFSurface dependency. Presumably, this is because of the repo shutdown you mentioned. To work around this, the libCFSurface code is now integrated in my Android 12 branch rather than referencing the prebuilt library. I didn't do the import myself. Instead, I cherry-picked the import off of another liveboot fork (https://github.com/mrjarvis698/liveboot). If you look at the commit history on my Android 12 branch, you should see it.

DavidBerdik@d847c39?diff=unified

I'm not a fan of what you did here. The detections are done in this fashion because internal Android code does not cleanly port on those lines. Preview releases (which always persist in the wild longer than needed) do not adhere to them, and OEMs don't always port all the relevant code right away, so even if their public API matches the private may not. This happens a LOT.

The code is worded exactly this way because of testing through the years, changes like this for "neatness" tend to unintentionally break things.

I will revert the change once I get things working properly on my phone, however, I want to leave it alone for now since messing with it will only lead to further confusion for me.

My code resolves the first missing function, but there's another one that gets hit later on.

Seems the setLayer call was removed. It still exists in the transaction though, so you can just imitate the original function. Synchronize on the SurfaceControl.class, grab sGlobalTransaction, and call setLayer on that.

I could use a little help with this, as I am having a hard time figuring out how to properly do the reflection to make it work. I seem to have something that runs properly, but I am not sure if it's done right. Here is the relevant commit that adds the changes here: https://github.com/DavidBerdik/liveboot/commit/ba3d978f8eb7249630e704917676351a1719662c

After making these changes, trying to do a test run fails with a new error, and I am again struggling to track down how to fix it and could use some help here as well.

2022-02-02 22:48:28.810 456-620/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*] Assertion failed: src == nullptr && gDefaultTypeface == nullptr
2022-02-02 22:48:28.858 456-620/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*] java.lang.IllegalArgumentException: Expected receiver of type android.view.SurfaceControl$Transaction, but got android.view.SurfaceControl
2022-02-02 22:48:28.858 456-620/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*]    at java.lang.reflect.Method.invoke(Native Method)
2022-02-02 22:48:28.858 456-620/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*]    at eu.chainfire.libcfsurface.SurfaceHost.updateSurfaceVisibility(SurfaceHost.java:308)
2022-02-02 22:48:28.860 456-620/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*]    at eu.chainfire.libcfsurface.SurfaceHost.access$300(SurfaceHost.java:43)
2022-02-02 22:48:28.860 456-620/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*]    at eu.chainfire.libcfsurface.SurfaceHost$1.run(SurfaceHost.java:389)
2022-02-02 22:48:29.297 456-620/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*] Aborted 

Any comments, suggestions, and of course, code contributions, would be greatly appreciated!

Well, not sure what your plans are, but it would be great if the eventual fixes get back-PR'd to libRootJava/libCFSurface/LiveBoot rather than just live in your fork.

I'm kind of struggling with it right now, but ultimately, I would really like to get this working on Android 12 and submit a PR to your repo so you can push an update to the Play Store! 😁 I definitely need your advice and assistance with achieving this goal, however.

Chainfire commented 2 years ago

The reason I couldn't get it to compile was because Gradle couldn't fetch the libCFSurface dependency

Guh... repos in widespread use going down is such a drag. I was afraid this was going to happen years and years ago when everybody started using bintray. Guess we're picking up the pieces now.

After making these changes, trying to do a test run fails with a new error, and I am again struggling to track down how to fix it and could use some help here as well.

I'm just stabbing in the dark a bit here (no device, and not using an IDE to write this), but I'll give it a look.

OK, so first off, you didn't synchronize the setLayer call as is done in the original function we're replicating. #L281 should probably be wrapped like this:

synchronized (cSurfaceControl) {
    mSurfaceControlSetLayer.invoke(sGlobalTransaction, mSurfaceControl, 0x7FFFFFFF);
}

However, you're not creating sGlobalTransaction correctly either. When we need it above, that call is wrapped in openTransaction and closeTransaction, which create and destroy the sGlobalTransaction as needed. Your cTransaction.newInstance call creates a new Transaction yourself.

Also, why are you suddenly passing cTransaction to openTransaction and closeTransaction? I don't see that in the Android 12 source?

So, get rid of sGlobalTransaction declaration on L241, and its instantiation on L254. Make mGetGlobalTransaction a field rather than local variable and call it mSurfaceControlGetGlobalTransaction. Also make cTransaction a field. Additionally, create new fields mTransactionSetLayer, mTransactionShow, and mTransactionHide, rather than reusing mSurfaceControlXXXX:

            if (Build.VERSION.SDK_INT <= 30) {
                mSurfaceControlSetLayer = cSurfaceControl.getDeclaredMethod("setLayer", int.class);
                mSurfaceControlShow = cSurfaceControl.getDeclaredMethod("show");
                mSurfaceControlHide = cSurfaceControl.getDeclaredMethod("hide");
            } else {
                mSurfaceControlGetGlobalTransaction = cSurfaceControl.getDeclaredMethod("getGlobalTransaction");
                cTransaction = Class.forName("android.view.SurfaceControl$Transaction");
                mTransactionSetLayer = cTransaction.getDeclaredMethod("setLayer", cSurfaceControl, int.class);
                mTransactionShow = cTransaction.getDeclaredMethod("show", cSurfaceControl);
                mTransactionHide = cTransaction.getDeclaredMethod("hide", cSurfaceControl);
            }

Then, check on mSurfaceControlGetGlobalTransaction being null rather than reusing an API check.

            // Set top z-index
            mSurfaceControlOpenTransaction.invoke(null);
            if (mSurfaceControlGetGlobalTransaction != null) {
                // API 31+
                synchronized (cSurfaceControl) {
                    mSurfaceControlSetLayer.invoke(mSurfaceControlGetGlobalTransaction.invoke(mSurfaceControl), mSurfaceControl, 0x7FFFFFFF);
                }
            } else {
                // API 30-
                mSurfaceControlSetLayer.invoke(mSurfaceControl, 0x7FFFFFFF);
            }
            mSurfaceControlCloseTransaction.invoke(null);

Next, we're also taking show and hide from Transaction rather than from SurfaceControl, so their calls in updateSurfaceVisibility have to be changed:

    private final void updateSurfaceVisibility() {
        if (mShow != mIsVisible) {
            try {
                mSurfaceControlOpenTransaction.invoke(null);
                if (mSurfaceControlGetGlobalTransaction != null) {
                    // API 31+
                    synchronized (cSurfaceControl) {
                        if (mShow) {
                            mTransactionShow.invoke(mSurfaceControlGetGlobalTransaction.invoke(mSurfaceControl), mSurfaceControl);
                        } else {
                            mTransactionHide.invoke(mSurfaceControlGetGlobalTransaction.invoke(mSurfaceControl), mSurfaceControl);
                        }
                    }
                } else {
                    // API 30-
                    if (mShow) {
                        mSurfaceControlShow.invoke(mSurfaceControl);
                    } else {
                        mSurfaceControlHide.invoke(mSurfaceControl);
                    }
                }
                mSurfaceControlCloseTransaction.invoke(null);
            } catch (Exception e) {
                Logger.ex(e);
            }
            mIsVisible = mShow;
        }
    }

Something like this should do it.

Interesting tidbit, seems the entire sGlobalTransaction thing is going away in Android 13, so this'll all have to be refactored again then. Unfortunately it seems there's little we can do to preempt that.

Additionally, I see you have the habit of putting the else on a new line rather than continuing after the }. While that is obviously fine code-wise, it doesn't fit the libCFSurface codestyle.

Chainfire commented 2 years ago

If the above works, updateSurfaceSize should be updated in the same way as updateSurfaceVisibility, calling Transaction.setBufferSize (synchronized) rather than SurfaceControl.setSize. Seems this has been broken since Q, and may be the reason some users get a wrongly-sized buffer.

DavidBerdik commented 2 years ago

Guh... repos in widespread use going down is such a drag. I was afraid this was going to happen years and years ago when everybody started using bintray. Guess we're picking up the pieces now.

Apparently so. What is the long-term plan, then? When this gets to a usable point, would you want to break the changes out and package a new version to host elsewhere? Or would you just leave it as-is?

I'm just stabbing in the dark a bit here (no device, and not using an IDE to write this), but I'll give it a look.

Thank you! It didn't work exactly as-is, but it was incredibly helpful for making progress. This time around, the work is split between two commits:

Also, why are you suddenly passing cTransaction to openTransaction and closeTransaction? I don't see that in the Android 12 source?

I could have sworn I saw it in there somewhere, but I can't find it now. Either way, I can't argue with the fact that what I was trying to do there did not work.

Interesting tidbit, seems the entire sGlobalTransaction thing is going away in Android 13, so this'll all have to be refactored again then. Unfortunately it seems there's little we can do to preempt that.

Yeah I think I saw a comment about that in the source, but as you say, it's not really clear what's going to be happening in the future, so I guess we're stuck for now.

Additionally, I see you have the habit of putting the else on a new line rather than continuing after the }. While that is obviously fine code-wise, it doesn't fit the libCFSurface codestyle.

Fair enough. I'm more interested in trying to get everything working right now, but I will keep this in mind for all work going forward, and will revise my earlier work to follow this standard as well.

If the above works, updateSurfaceSize should be updated in the same way as updateSurfaceVisibility, calling Transaction.setBufferSize (synchronized) rather than SurfaceControl.setSize. Seems this has been broken since Q, and may be the reason some users get a wrongly-sized buffer.

I believe I have done it: https://github.com/DavidBerdik/liveboot/commit/2058c6537f8ed40cc41188fc73ea3119b3cda889

Anyway, after making the changes I linked to above, there's finally some visible progress! When I execute the test run, the display flashes dark for a fraction of a second. It definitely doesn't wait the whole 5 seconds. Unfortunately though, there is no text output to the screen, and I suspect that the cause for that has to do with the libsuperuser library, because the errors in the output seem to be related to it.

2022-02-03 21:56:33.072 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0
2022-02-03 21:56:33.073 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] /su/bin/sush -c "echo OK"
2022-02-03 21:56:33.075 21479-21542/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*] /system/bin/sh: <stdin>[118]: /su/bin/sush: inaccessible or not found
2022-02-03 21:56:33.075 21479-21541/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU-] 4cc09773-fe9a-42aa-a17e-4464075d30a7-00000018 127
2022-02-03 21:56:33.076 21479-21542/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*] 4cc09773-fe9a-42aa-a17e-4464075d30a7-00000018
2022-02-03 21:56:33.076 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][P] releaseReservation
2022-02-03 21:56:33.076 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0
2022-02-03 21:56:33.077 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0
2022-02-03 21:56:33.077 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] /tmp-mksh/tmp-mksh -c "echo OK"
2022-02-03 21:56:33.078 21479-21542/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*] /system/bin/sh: <stdin>[121]: /tmp-mksh/tmp-mksh: inaccessible or not found
2022-02-03 21:56:33.078 21479-21541/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU-] fe155361-48bd-44be-b5fb-cc109f441a2a-00000019 127
2022-02-03 21:56:33.078 21479-21542/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*] fe155361-48bd-44be-b5fb-cc109f441a2a-00000019
2022-02-03 21:56:33.079 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][P] releaseReservation
2022-02-03 21:56:33.079 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0
2022-02-03 21:56:33.083 21479-21479/eu.chainfire.liveboot W/Thread-3: type=1400 audit(0.0:33148): avc: denied { getattr } for path="/system/lib64/bootstrap" dev="dm-0" ino=1953 scontext=u:r:untrusted_app:s0:c150,c257,c512,c768 tcontext=u:object_r:system_bootstrap_lib_file:s0 tclass=dir permissive=0 app=eu.chainfire.liveboot
2022-02-03 21:56:33.090 21479-21479/eu.chainfire.liveboot W/Thread-3: type=1400 audit(0.0:33149): avc: denied { getattr } for path="/vendor/lib64/android.frameworks.sensorservice@1.0.so" dev="dm-1" ino=1716 scontext=u:r:untrusted_app:s0:c150,c257,c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
2022-02-03 21:56:33.090 21479-21479/eu.chainfire.liveboot W/Thread-3: type=1400 audit(0.0:33150): avc: denied { getattr } for path="/vendor/lib64/android.frameworks.stats-V1-ndk_platform.so" dev="dm-1" ino=1717 scontext=u:r:untrusted_app:s0:c150,c257,c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
2022-02-03 21:56:33.090 21479-21479/eu.chainfire.liveboot W/Thread-3: type=1400 audit(0.0:33151): avc: denied { getattr } for path="/vendor/lib64/android.frameworks.stats@1.0.so" dev="dm-1" ino=1718 scontext=u:r:untrusted_app:s0:c150,c257,c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
2022-02-03 21:56:33.090 21479-21479/eu.chainfire.liveboot W/Thread-3: type=1400 audit(0.0:33152): avc: denied { getattr } for path="/vendor/lib64/android.hardware.atrace@1.0.so" dev="dm-1" ino=1719 scontext=u:r:untrusted_app:s0:c150,c257,c512,c768 tcontext=u:object_r:vendor_file:s0 tclass=file permissive=0 app=eu.chainfire.liveboot
2022-02-03 21:56:33.122 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0
2022-02-03 21:56:33.122 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] toybox rm /data/user_de/0/eu.chainfire.liveboot/files/app_process
2022-02-03 21:56:33.122 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] toybox rm /data/user_de/0/eu.chainfire.liveboot/files/liveboot
2022-02-03 21:56:33.122 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] toybox cp /system/bin/app_process64 /data/user_de/0/eu.chainfire.liveboot/files/app_process
2022-02-03 21:56:33.122 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] toybox chown 0.0 /data/user_de/0/eu.chainfire.liveboot/files/app_process
2022-02-03 21:56:33.122 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] toybox chmod 0700 /data/user_de/0/eu.chainfire.liveboot/files/app_process
2022-02-03 21:56:33.123 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] toybox chcon u:object_r:app_data_file:s0 /data/user_de/0/eu.chainfire.liveboot/files/app_process
2022-02-03 21:56:33.123 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] echo '#!/system/bin/sh' > /data/user_de/0/eu.chainfire.liveboot/files/liveboot
2022-02-03 21:56:33.123 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] echo '#app_process=/system/bin/app_process64' >> /data/user_de/0/eu.chainfire.liveboot/files/liveboot
2022-02-03 21:56:33.123 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] toybox chmod 0700 /data/user_de/0/eu.chainfire.liveboot/files/liveboot
2022-02-03 21:56:33.123 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] echo 'NO_ADDR_COMPAT_LAYOUT_FIXUP=1 ANDROID_ROOT=/system LD_LIBRARY_PATH=/system/lib64:/system/lib64/drm:/system/lib64/hw:/vendor/lib64:/vendor/lib64/camera:/vendor/lib64/egl:/vendor/lib64/hw:/vendor/lib64/mediacas:/vendor/lib64/mediadrm:/vendor/lib64/soundfx:/system/bin:/librootjava CLASSPATH=/data/app/~~DrWHQaxSXsfPu6Ti1EMEvA==/eu.chainfire.liveboot-REhA8zabyMsOPZkF9SFLUQ==/base.apk /data/app/~~DrWHQaxSXsfPu6Ti1EMEvA==/eu.chainfire.liveboot-REhA8zabyMsOPZkF9SFLUQ==/lib/arm64/libdaemonize.so /system/bin/app_process64 /system/bin --nice-name=eu.chainfire.liveboot:root eu.chainfire.liveboot.shell.Runner /data/app/~~DrWHQaxSXsfPu6Ti1EMEvA==/eu.chainfire.liveboot-REhA8zabyMsOPZkF9SFLUQ==/base.apk boot logcatlevels=VDIWEFS logcatbuffers=MSC logcatformat=brief dmesg=0-99 lines=80 wordwrap' >> /data/user_de/0/eu.chainfire.liveboot/files/liveboot
2022-02-03 21:56:33.123 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] toybox chmod 0700 /data/user_de/0/eu.chainfire.liveboot/files/liveboot
2022-02-03 21:56:33.123 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] echo '#!/system/bin/sh' > /data/user_de/0/eu.chainfire.liveboot/files/test
2022-02-03 21:56:33.123 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] echo '#app_process=/system/bin/app_process64' >> /data/user_de/0/eu.chainfire.liveboot/files/test
2022-02-03 21:56:33.123 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] toybox chmod 0700 /data/user_de/0/eu.chainfire.liveboot/files/test
2022-02-03 21:56:33.123 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] echo 'NO_ADDR_COMPAT_LAYOUT_FIXUP=1 ANDROID_ROOT=/system LD_LIBRARY_PATH=/system/lib64:/system/lib64/drm:/system/lib64/hw:/vendor/lib64:/vendor/lib64/camera:/vendor/lib64/egl:/vendor/lib64/hw:/vendor/lib64/mediacas:/vendor/lib64/mediadrm:/vendor/lib64/soundfx:/system/bin:/librootjava CLASSPATH=/data/app/~~DrWHQaxSXsfPu6Ti1EMEvA==/eu.chainfire.liveboot-REhA8zabyMsOPZkF9SFLUQ==/base.apk /system/bin/app_process64 /system/bin --nice-name=eu.chainfire.liveboot:root eu.chainfire.liveboot.shell.Runner /data/app/~~DrWHQaxSXsfPu6Ti1EMEvA==/eu.chainfire.liveboot-REhA8zabyMsOPZkF9SFLUQ==/base.apk test logcatlevels=VDIWEFS logcatbuffers=MSC logcatformat=brief dmesg=0--1 lines=80 wordwrap' >> /data/user_de/0/eu.chainfire.liveboot/files/test
2022-02-03 21:56:33.124 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] toybox chmod 0700 /data/user_de/0/eu.chainfire.liveboot/files/test
2022-02-03 21:56:33.232 21479-21541/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU-] 035825df-d005-432e-b62d-97a5d86948cb-0000001a 0
2022-02-03 21:56:33.232 21479-21542/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*] 035825df-d005-432e-b62d-97a5d86948cb-0000001a
2022-02-03 21:56:33.233 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][P] releaseReservation
2022-02-03 21:56:33.233 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0
2022-02-03 21:56:33.234 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0
2022-02-03 21:56:33.234 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][C][SU+] /data/user_de/0/eu.chainfire.liveboot/files/test
2022-02-03 21:56:33.757 21479-21542/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*] Assertion failed: src == nullptr && gDefaultTypeface == nullptr
2022-02-03 21:56:34.214 21479-21542/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*] Aborted 
2022-02-03 21:56:34.214 21479-21541/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU-] bfed80a2-b522-4fa3-b1b3-fc2305a0726b-0000001b 134
2022-02-03 21:56:34.216 21479-21542/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][O][SU*] bfed80a2-b522-4fa3-b1b3-fc2305a0726b-0000001b
2022-02-03 21:56:34.216 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][P] releaseReservation
2022-02-03 21:56:34.216 21479-21674/eu.chainfire.liveboot D/libsuperuser: [libsuperuser][P] cleanup: shell:SU count:1 reserved:0
Chainfire commented 2 years ago

Apparently so. What is the long-term plan, then? When this gets to a usable point, would you want to break the changes out and package a new version to host elsewhere? Or would you just leave it as-is?

Repackaging is the idea, but from the tutorials I've found moving to MavenCentral is quite involved. So it'll take time and effort and... :)

I believe I have done it: https://github.com/DavidBerdik/liveboot/commit/2058c6537f8ed40cc41188fc73ea3119b3cda889

mSurfaceControlSetSize should still be checked for null and the call skipped if so. We know it can happen on Q, and the new code you made does not activate for Q, so it would crash on Q.

Unfortunately though, there is no text output to the screen, and I suspect that the cause for that has to do with the libsuperuser library, because the errors in the output seem to be related to it.

Actually, it appears to be an issue in the rendering stage. The error Assertion failed: src == nullptr && gDefaultTypeface == nullptr seems to be coming from the TypeFace code: https://cs.android.com/android/platform/superproject/+/master:frameworks/base/libs/hwui/hwui/Typeface.cpp;drc=954ce27d13b651e916689ff996700a8987540064;l=66

I have never encountered this before.

Chainfire commented 2 years ago

I think this is the code that should be added to the end of SurfaceHost::initSurface to fix the error:

import android.graphics.Typeface;

if (Build.VERSION.SDK_INT >= 31) {
    if (Typeface.getDefault() == null) {
        Typeface.loadPreinstalledSystemFontMap();
    }
}

Obviously that needs to be converted to reflection.

DavidBerdik commented 2 years ago

https://github.com/Chainfire/liveboot/pull/5 😁

Chainfire commented 2 years ago

Great work. But, you neglected to use the Typeface.getDefault() == null check which is needed in case an OEM does not use lazy font loading, loadPreinstalledSystemFontMap() should only be called once, and would be called twice in that case.

Additionally, PRs should be made for the correct repos. If we import libCFSurface here, the code will have to be re-ported later, and it's not a good solution anyway.

Instead of just copying all the files in, you could have used git submodules to pull the code in without duplicating, or used gradle's installMavenLocal option to compile and install the module locally, so you can use it from other projects before publishing.

EDIT: I'm currently looking into migrating to JitPack rather than MavenCentral, which should be much easier.

Chainfire commented 2 years ago

libsuperuser, librootjava, librootjavadaemon, and libcfsurface have all been migrated to JitPack. Automatic dependency resolution should be fully operational again.

I've pushed changes to liveboot to reflect the new repositories and updated build settings. Please do not touch the build.gradle files beyond this point - the Android Studio suggested changes that you (or the previous commiter) set cause problems down the line.

As far as I can see, these are the open issues with the PR:

I hope you're still up for making these changes, we've come far and I think we're almost done.

DavidBerdik commented 2 years ago

Great work.

Thank you!

But, you neglected to use the Typeface.getDefault() == null check which is needed in case an OEM does not use lazy font loading, loadPreinstalledSystemFontMap() should only be called once, and would be called twice in that case.

This was an unintentional oversight on my part. I have made the appropriate change to add it.

Additionally, PRs should be made for the correct repos. If we import libCFSurface here, the code will have to be re-ported later, and it's not a good solution anyway.

I agree that it is not a good solution for the long-term. My intention was to put it in this repo temporarily, but in the long term, also make a PR to libCFSurface with the relevant code changes so that the inclusion in this repo could be removed. My assumption was that you didn't want to mess with fixing the repos for now, so this seemed like an acceptable workaround.

Instead of just copying all the files in, you could have used git submodules to pull the code in without duplicating, or used gradle's installMavenLocal option to compile and install the module locally, so you can use it from other projects before publishing.

I experimented with using git submodules, actually, but the problem is that the directory structure of the imported code does not match the structure of the source repos, making it not possible. At least, not as far as I am aware. As for the installMavenLocal option, that had not occurred to me, but even if it had, I probably still would have chosen to do it this way simply because it would make building easier for newcomers. Either way, it sounds like you've migrated the libraries to a new repo, so it's irrelevant now.

libsuperuser, librootjava, librootjavadaemon, and libcfsurface have all been migrated to JitPack. Automatic dependency resolution should be fully operational again.

Great!

I've pushed changes to liveboot to reflect the new repositories and updated build settings. Please do not touch the build.gradle files beyond this point - the Android Studio suggested changes that you (or the previous commiter) set cause problems down the line.

I have reverted the Gradle change on my branch, but may I ask why it is necessary? What problems does the change cause? In my mind, I would think that it would make more sense to bring the Gradle stuff up to date as I did.

As far as I can see, these are the open issues with the PR:

  • Typeface.getDefault() is not checked

It is now.

  • mSurfaceControlSetSize == null check is either in the wrong place or mTransactionSetBufferSize als needs to be checked; currently it makes mTransactionSetBufferSize usage unreachable

I have added && mTransactionSetBufferSize == null to that line.

  • "else on new line" style issues

I thought I had fixed all of them, but apparently not. I have rechecked and as far as I can tell, they are all good now.

  • do we still need to be priv-app ?

Nope! I suspected that it might have been necessary when doing early testing, but that suspicion turned out to be incorrect.

  • the PR's should be made to the appropriate repos rather than copying all dependencies into this repo

Since you made the changes to allow for this sooner than I had anticipated, I have self-rejected my pull request to liveboot and opened a new one on libcfsurface. - https://github.com/Chainfire/libcfsurface/pull/1

I hope you're still up for making these changes, we've come far and I think we're almost done.

Certainly! I hope it's all good now! I assume that once the PR is approved, you will make the updates to the Liveboot repo yourself and push it out?

Chainfire commented 2 years ago

My assumption was that you didn't want to mess with fixing the repos for now, so this seemed like an acceptable workaround.

I didn't. If it had had to be Maven Central, I wouldn't have done it. But somebody pointed out JitPack to me, and while it's apparently not as secure as Maven Central, it only took a few hours to get everything ported. It's really easy, and if it weren't for some weird construct in libRootJava, it would've only taken minutes instead of hours.

I experimented with using git submodules, actually, but the problem is that the directory structure of the imported code does not match the structure of the source repos, making it not possible. At least, not as far as I am aware. As for the installMavenLocal option, that had not occurred to me, but even if it had, I probably still would have chosen to do it this way simply because it would make building easier for newcomers.

Fair enough on the submodules. Using the local repo is really handy though, I use it for all my local library development. Just add mavenLocal() to your root build.gradle and gradle install or gradle installMavenLocal. Just as a tip, indeed it is no longer relevant now for this case.

I have reverted the Gradle change on my branch, but may I ask why it is necessary? What problems does the change cause? In my mind, I would think that it would make more sense to bring the Gradle stuff up to date as I did.

(rant warning)

Because this is Google. Granted, it is not as bad as it once was, but I've been playing with Android since 1.x days, and I pretty much have PTSD from all the random breakage minor updates cause. That and users generally being asshats are the two primary reasons I've stopped doing Android things.

Particularly with code that runs on the fringes (anything root or system related) you do not want to upgrade any of these things beyond what is absolutely necessary to get it published, and make those changes as rarely as possible. It's a problem even if you only follow true public APIs already, but once you diverge from them (as we do) you have to watch out a factor more. Ideally you'd test everything on a plethora of real devices running many different version of Android. And that is actually what I used to do, I had dozens of phones lying around that I'd test every little change on. It's not so relevant for LiveBoot (though undoubtedly we've broken it for someone), but imagine SuperSU, with 100M users across thousands of different Android versions and OEM ports. Any potential breakage will break for someone.

By far most handling differences revolve around the targetSdkVersion setting, and even if you go through the docs with every update to it (which I normally do, but haven't now), things under the hood change with it as well that normal API usage may not run in to, but our fringe code will. Add to that that Google will often unbreak or break-in-a-different-way things again the next update, keeping that setting as low as possible to get it published is the only way to go to save yourself headaches, unless you have a particular reason to upgrade to a specific level (new functionality for example).

But, buildToolsVersion and compileSdkVersion have also been known to randomly break things. Change them with care.

Gradle itself breaks things with every update too (but also, less than it used to), not to mention that for the latest version you usually need to run the latest Android Studio as well. I've kept it below the very latest this round to keep it compatible with early-2021 version of Android Studio.

One specific thing that broke in the patch is minSdkVersion, don't touch that unless you have a good reason to.

Maybe I'm overly cautious these days, but through the years I've seen so much random and unintentional breakage in these things - including things that should've been caught by all the compatibility/support libraries - that the only way to stay sane was treating every Google-pushed change with a healthy dose of skepticism and the assumption it would unintentionally break something. I'm pretty sure I've spent more time debugging weird issues caused by such changes on random user X's random device Y than I have developing new code.

Certainly! I hope it's all good now! I assume that once the PR is approved, you will make the updates to the Liveboot repo yourself and push it out?

Yes, doing so now. There have been a lot of changes to Google Play since I last pushed anything though, so let's hope (probably in vain) it isn't going to be too involved.

Chainfire commented 2 years ago

Well, of course it was an issue pushing to Play. Had to replace the whole billing system 🙄 . Anyway, it's been uploaded, I guess Google reviews updates now so that can take a while to clear. I've pushed the changes to GitHub, as well as posted the APK on XDA.

If you can give the "official" build a try, that'd be great. Closing this for the time being. Great work, and thanks again.

DavidBerdik commented 2 years ago

Thank you for your detailed explanations to my questions. I greatly appreciate it!

I have learned quite a lot from collaborating with you on this and I have really enjoyed it! Prior to your departure from the Android community, I was always a huge fan of your work and never imagined that I would someday get a chance to work with you.

If you can give the "official" build a try, that'd be great.

It seems to be working for me!

Great work, and thanks again.

Thank you! Although to be fair, it was a team effort. 😁