changhuapeng / FrameworkPatcherGO

A Magisk/KernelSU/APatch module to modify framework.jar directly on the phone, to build a valid system-level certificate chain.
https://xdaforums.com/t/module-framework-patcher-go.4674536/
312 stars 30 forks source link

Module Installs, but Device Bootloops #6

Open DavidBerdik opened 3 months ago

DavidBerdik commented 3 months ago

I have tried to install this module on a Pixel 3 XL running the crosshatch-unity-20240512-1420-release build of the PixelBuilds ROM. The module installation completes successfully, however, the device boot loops when I attempt to restart. I used a custom classes.dex file for it.

Contained in attached zip file is the copy of the framework.jar that I extracted from the phone.

framework.zip

If there is any additional information that I can provide to aid in solving this issue, please let me know!

Unfortunately, I did not obtain an install log, but if it would be helpful for you to have one, I do not mind reproducing the issue.

changhuapeng commented 3 months ago

Have you tried clearing dalvik-cache or using the default classes.dex file to see if the boot loops stop?

From your framework.jar, I see that the ROM you're on has implemented PixelPropsUtils to spoof both bootloader and fingerprint so you may actually not need this module at all.

Besides your report, I have also heard from some users with PixelPropsUtils in their ROMs, that FrameworkPatch is not working properly even after everything are patched correctly.

There may be some conflicts between PixelPropsUtils and FrameworkPatch that we do not know of and may have no solution about it.

DavidBerdik commented 3 months ago

Have you tried clearing dalvik-cache or using the default classes.dex file to see if the boot loops stop?

I have not, but I will, and this time, I will also make a copy of the log.

From your framework.jar, I see that the ROM you're on has implemented PixelPropsUtils to spoof both bootloader and fingerprint so you may actually not need this module at all.

I am not sure if this is relevant, but unless I use PIF, the device fails even basic integrity. With PIF, I am able to pass basic and device. I was hoping to give FrameworkPatcher a try because, based on my understanding of what I have read, it is possible to pass hardware-backed if you find a working keybox.

DavidBerdik commented 3 months ago

Okay, I have tried again with a fresh install of the crosshatch-unity-20240609-1449-release release and the boot loop is happening again. This time, I collected a log!

The next thing I will try is to install the last official Android release that Google put out for this phone and see if it works.

- Copying zip to temp directory
- Installing FrameworkPatcherGO-v1.0.1.zip
Getting: busybox
Getting: bash
Getting: bin
Getting: core
------------Device INFO------------
API=34
ABI=arm
ABILONG=arm64-v8a
PROC=crosshatch
arch=arm64
arch32=arm
max_arch=arm64
is64bit=true
chipname=snapdragon
status=Enforcing
encrypted=true
slot=_b
dynamic_partitions=true
virtual_partitions=false
free_root=0
free_system=0
free_vendor=0
------------Setup INFO------------
CUSTOM_SETUP=0
TMP=/dev/tmp7511
di_version=4.8-b
main_version=4.8
----------------------------------

Currently using: "/dev/tmp7511/ugu/unzip" binary
No possible changes found for: "unzip" binary

---------Installer Configs----------
devices=off
apex_mount=off
magisk_support=on
ensure_root=on
import_addons=off
extraction_speed=default
permissions=0:0:0755:0644
-----------------------------------
ZIP: Cant find folder [META-INF/addons]
/data/adb/magisk/util_functions.sh: line 35: ui_print: readonly function
/data/adb/magisk/util_functions.sh: line 39: toupper: readonly function
/data/adb/magisk/util_functions.sh: line 46: grep_cmdline: readonly function
/data/adb/magisk/util_functions.sh: line 54: grep_prop: readonly function
/data/adb/magisk/util_functions.sh: line 78: is_mounted: readonly function
/data/adb/magisk/util_functions.sh: line 86: abort: readonly function
/data/adb/magisk/util_functions.sh: line 244: find_block: readonly function
/data/adb/magisk/util_functions.sh: line 599: set_perm: readonly function
/data/adb/magisk/util_functions.sh: line 608: set_perm_recursive: readonly function
/data/adb/magisk/util_functions.sh: line 741: TMPDIR: readonly variable
----------------Running SCRIPTs------------
- Current boot slot: _b
- Device is system-as-root
----------------------------------------
 >>> Powered by Magisk 27000
----------------------------------------

- Setting common permissions/contexts

set_context: u:object_r:system_file:s0 in /data/adb/modules_update/FrameworkPatcherGo
set_context: u:object_r:system_file:s0 in /data/adb/modules_update/FrameworkPatcherGo/dex
set_context: u:object_r:system_file:s0 in /data/adb/modules_update/FrameworkPatcherGo/customize.sh
set_context: u:object_r:system_file:s0 in /data/adb/modules_update/FrameworkPatcherGo/dex/Paste FrameworkPatch classes.dex here
set_context: u:object_r:system_file:s0 in /data/adb/modules_update/FrameworkPatcherGo/module.prop
set_context: u:object_r:system_file:s0 in /data/adb/modules_update/FrameworkPatcherGo/func.sh
- Installing from Magisk app

******************************
> Pre-installation check ...
******************************
[ OK ] Checking for existing Framework Patcher GO module.
[ OK ] Checking for deodexed /system/framework/framework.jar.
Required classes.dex file is not found in META-INF/com/google/android/magisk/dex directory

Do you want to download a pre-compiled classes.dex file from the FrameworkPatch source?
- YES  [Press volume UP]
- NO   [Press volume DOWN]

Downloading classes.dex ...
wget: note: TLS certificate validation not implemented
Connecting to github.com (140.82.114.4:443)
Connecting to objects.githubusercontent.com (185.199.109.133:443)
saving to '/data/adb/modules_update/FrameworkPatcherGo/dex/classes.dex'
classes.dex          100% |********************************|  181k  0:00:00 ETA
'/data/adb/modules_update/FrameworkPatcherGo/dex/classes.dex' saved

******************************
> Decompiling framework.jar ...
******************************
I: Using Apktool 2.7.0 on framework.jar
I: Baksmaling classes.dex...
I: Baksmaling classes2.dex...
I: Baksmaling classes3.dex...
I: Baksmaling classes4.dex...
I: Baksmaling classes5.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...

File found: /dev/tmp7511/framework/smali_classes3/android/security/keystore2/AndroidKeyStoreSpi.smali

******************************
> Patching AndroidKeyStoreSpi.smali file...
******************************

Method found: .method public whitelist test-api engineGetCertificateChain(Ljava/lang/String;)[Ljava/security/cert/Certificate;

--------------------
Patching engineGetCertificateChain method:

    invoke-static {v0}, Lcom/android/internal/util/framework/Android;->engineGetCertificateChain([Ljava/security/cert/Certificate;)[Ljava/security/cert/Certificate;

    move-result-object v0

added.
Edited: "/dev/tmp7511/framework/smali_classes3/android/security/keystore2/AndroidKeyStoreSpi.smali"
--------------------

File found: /dev/tmp7511/framework/smali/android/app/Instrumentation.smali

******************************
> Patching Instrumentation.smali file ...
******************************

Method found: .method public static whitelist newApplication(Ljava/lang/Class;Landroid/content/Context;)Landroid/app/Application;

--------------------
Patching newApplication static method:

    invoke-static {p1}, Lcom/android/internal/util/framework/Android;->newApplication(Landroid/content/Context;)V

added.
Edited: "/dev/tmp7511/framework/smali/android/app/Instrumentation.smali"
--------------------

Method found: .method public whitelist newApplication(Ljava/lang/ClassLoader;Ljava/lang/String;Landroid/content/Context;)Landroid/app/Application;

--------------------
Patching newApplication method:

    invoke-static {p3}, Lcom/android/internal/util/framework/Android;->newApplication(Landroid/content/Context;)V

added.
Edited: "/dev/tmp7511/framework/smali/android/app/Instrumentation.smali"
--------------------

File found: /dev/tmp7511/framework/smali/android/app/ApplicationPackageManager.smali

******************************
> Patching ApplicationPackageManager.smali file ...
******************************
It is optional but recommended to patch this file if your device has StrongBox or app attestation key support.
Do you want to patch this file?
- YES  [Press volume UP]
- NO   [Press volume DOWN]

Method found: .method public whitelist hasSystemFeature(Ljava/lang/String;)Z

--------------------
Patching hasSystemFeature method:

    move-result p1

replaced by:

    move-result v0

Edited: "/dev/tmp7511/framework/smali/android/app/ApplicationPackageManager.smali"
--------------------

    invoke-static {v0, p1}, Lcom/android/internal/util/framework/Android;->hasSystemFeature(ZLjava/lang/String;)Z

    move-result v0

added.
Edited: "/dev/tmp7511/framework/smali/android/app/ApplicationPackageManager.smali"
--------------------

    return p1

replaced by:

    return v0

Edited: "/dev/tmp7511/framework/smali/android/app/ApplicationPackageManager.smali"
--------------------

******************************
> Recompiling framework.jar ...
******************************
This may take a while, please wait.
-c/--copy-original has been deprecated. Removal planned for v3.0.0 (#2129)
I: Using Apktool 2.7.0
I: Checking whether sources has changed...
I: Smaling smali folder into classes.dex...
I: Checking whether sources has changed...
I: Smaling smali_classes5 folder into classes5.dex...
I: Checking whether sources has changed...
I: Smaling smali_classes4 folder into classes4.dex...
I: Checking whether sources has changed...
I: Smaling smali_classes3 folder into classes3.dex...
I: Checking whether sources has changed...
I: Smaling smali_classes2 folder into classes2.dex...
W: Could not find resources
I: Copy original files...
I: Copy META-INF...
I: Building apk file...
I: Copying unknown files/dir...
I: Built apk into: /dev/tmp7511/framework-patched.jar

******************************
> Setting up FrameworkPatch ...
******************************
5 dex files found in framework.jar
FrameworkPatch's compiled classes.dex renamed to classes6.dex and patched to framework.jar
Optimising framework.jar with zipalign
Cleaning boot-framework files ...
Some final touches ...

FrameworkPatch set up successfully!

rmdir: '/data/adb/modules_update/FrameworkPatcherGo': Directory not empty
-------------------------------------------

magisk_install_log_2024-06-13T14.29.03.log

DavidBerdik commented 3 months ago

So, the module installs properly when I use the stock image! 🥳

I still fail all integrity checks, but I assume that's probably because Google has blacklisted the keybox you used in the default classes.dex file?

I still haven't wrapped my head around FrameworkPatch well enough to know for sure if a working keybox is all I need or if I also need to use PIF with a device fingerprint, but I will keep researching. I know this isn't the place to ask for help, but if you have anything you are willing and/or able to share, I would appreciate it. 🙂

Screenshot_20240613-153457

CaptainThrowback commented 3 months ago

anything

Try adding the DroidGuard process (Google Play Services -> com.google.android.gms.unstable) to DenyList and see if that makes a difference for Play Integrity.

DavidBerdik commented 3 months ago

@CaptainThrowback Adding it to the DenyList makes it possible for me to pass BASIC, but DEVICE and STRONG still fail. It is still unclear to me if this behavior is expected when using the default keybox.

CaptainThrowback commented 3 months ago

@CaptainThrowback Adding it to the DenyList makes it possible for me to pass BASIC, but DEVICE and STRONG still fail. It is still unclear to me if this behavior is expected when using the default keybox.

The idea is that you would pass both Basic and Device, regardless of the keybox used, since that's determined by the props used in Android.java that spoof to DroidGuard.

changhuapeng commented 3 months ago

So, the module installs properly when I use the stock image! 🥳

You can try out LineageOS if you're looking for a custom ROM that could potentially work properly. At least from what I've seen, there seem to be less issues coming from LineageOS based ROMs.

I still haven't wrapped my head around FrameworkPatch well enough to know for sure if a working keybox is all I need or if I also need to use PIF with a device fingerprint, but I will keep researching. I know this isn't the place to ask for help, but if you have anything you are willing and/or able to share, I would appreciate it. 🙂

The default classes.dex file comes with a working software attestation keybox and a fingerprint (the same used in PIF as of now). They solve 2 different needs, with the keybox used in spoofing bootloader and the fingerprint to pass Play Integrity.

So when using the default classes.dex and if everything is working as it is, your device should see a locked bootloader on local attestation and passing basic and device integrity. And if you replace the current software attestation keybox with a valid and working keybox that is unrevoked by Google, you will pass strong integrity.

To check if your bootloader is spoofed properly, you should use this KeyAttestation app: https://t.me/playintegrityfix/19

DavidBerdik commented 3 months ago

I understand now, I think. Thank you! When I get a chance, I will try it with LineageOS and report back on if it works or not.

The phone that I have been testing this on is a phone that I use for doing development work, but I would really like to use this on my daily-use phone once I am confident that I'm not going to encounter problems with it.

DavidBerdik commented 3 months ago

So, I have finally had a chance to try out this module with the default classes.dex using LineageOS. The good news is that when I check the integrity, I pass BASIC and DEVICE. The bad news is that the Key Attestation Checker does not seem to report the same thing.

Screenshot_20240616-143011_Key Attestation

For reference, here's what the Key Attestation app shows when I am not using the module.

Screenshot_20240616-144633_Key Attestation

And here is the unmodified framework.jar: framework.zip

changhuapeng commented 3 months ago

So, I have finally had a chance to try out this module with the default classes.dex using LineageOS. The good news is that when I check the integrity, I pass BASIC and DEVICE. The bad news is that the Key Attestation Checker does not seem to report the same thing.

That's strange. I've manually patched your unmodified framework.jar using the default classes.dex. You can test with this patched framework.jar to see if you still encounter the "unable to attest" issue.

Simply by installing the FPG module successfully, then reboot your device. Then replace /data/adb/modules/FrameworkPatcherGo/system/framework/framework.jar with my patched framework.jar and reboot the device again.

Here's the patched framework.zip

DavidBerdik commented 3 months ago

Simply by installing the FPG module successfully, then reboot your device. Then replace /data/adb/modules/FrameworkPatcherGo/system/framework/framework.jar with my patched framework.jar and reboot the device again.

Unfortunately, it still happens even with your manually patched jar. In case it is relevant, I tried doing the test using the new v1.1.1 release that you put out several hours ago.

privacyguy123 commented 2 months ago

Have you tried clearing dalvik-cache or using the default classes.dex file to see if the boot loops stop?

From your framework.jar, I see that the ROM you're on has implemented PixelPropsUtils to spoof both bootloader and fingerprint so you may actually not need this module at all.

Besides your report, I have also heard from some users with PixelPropsUtils in their ROMs, that FrameworkPatch is not working properly even after everything are patched correctly.

There may be some conflicts between PixelPropsUtils and FrameworkPatch that we do not know of and may have no solution about it.

Absolutely yes, you cannot mix these 2 "patches" together and expect it not to break.

DavidBerdik commented 2 months ago

I believe that the TEE is broken on the phone that I was using for testing but it is not clear to me why this issue only becomes apparent when I try to use this module.