Skip to content

Commit

Permalink
Updated code to support Android 15
Browse files Browse the repository at this point in the history
The internal PackageLite class is not readily available for reflection anymore, so we have to add a hidden API exemption to get the version of hooked apps
  • Loading branch information
Crazyphil committed Jan 12, 2025
1 parent 469254b commit 7946e5e
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 48 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ android {

dependencies {
implementation 'androidx.core:core-ktx:1.15.0'
implementation 'org.lsposed.hiddenapibypass:hiddenapibypass:4.3'
compileOnly 'de.robv.android.xposed:api:82'
}
97 changes: 51 additions & 46 deletions app/src/main/java/it/kapfer/digitalesamt/liberator/ModuleMain.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import de.robv.android.xposed.XC_MethodReplacement
import de.robv.android.xposed.XposedBridge
import de.robv.android.xposed.XposedHelpers
import de.robv.android.xposed.callbacks.XC_LoadPackage
import org.lsposed.hiddenapibypass.HiddenApiBypass
import java.io.File

// Classes used by multiple apps
Expand All @@ -27,71 +28,31 @@ const val ROOTCHECKS_MOBYWATEL: String = "E6.b"
const val MORE_ROOTCHECKS_MOBYWATEL: String = "Do.p"

class ModuleMain : IXposedHookZygoteInit, IXposedHookLoadPackage {
private lateinit var digitalesAmtPackageName: String
private lateinit var bmf2GoPackageName: String
private lateinit var digitalesAmtPackageName: String
private lateinit var eduDigicardPackageName: String
private lateinit var serviceportalBundPackageName: String
private lateinit var mobywatelPackageName: String
private lateinit var serviceportalBundPackageName: String

override fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam) {
val moduleResources = XModuleResources.createInstance(startupParam.modulePath, null)
digitalesAmtPackageName = moduleResources.getString(R.string.digitales_amt_package_name)
bmf2GoPackageName = moduleResources.getString(R.string.bmf2go_package_name)
digitalesAmtPackageName = moduleResources.getString(R.string.digitales_amt_package_name)
eduDigicardPackageName = moduleResources.getString(R.string.edudigicard_package_name)
serviceportalBundPackageName = moduleResources.getString(R.string.serviceportal_bund_package_name)
mobywatelPackageName = moduleResources.getString(R.string.mobywatel_package_name)
serviceportalBundPackageName = moduleResources.getString(R.string.serviceportal_bund_package_name)
}

override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
when (lpparam.packageName) {
digitalesAmtPackageName -> handleDigitalesAmt(lpparam)
bmf2GoPackageName -> handleBmf2Go(lpparam)
digitalesAmtPackageName -> handleDigitalesAmt(lpparam)
eduDigicardPackageName -> handleEduDigicard(lpparam)
serviceportalBundPackageName -> handleServicePortalBund(lpparam)
mobywatelPackageName -> handleMobywatel(lpparam)
serviceportalBundPackageName -> handleServicePortalBund(lpparam)
}
}

private fun getPackageVersion(lpparam: XC_LoadPackage.LoadPackageParam): Int {
val apkPath = File(lpparam.appInfo.sourceDir)
val packageParser = XposedHelpers.findClass("android.content.pm.PackageParser", lpparam.classLoader)
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val packageLite = XposedHelpers.callStaticMethod(packageParser, "parsePackageLite", apkPath, 0)
XposedHelpers.getIntField(packageLite, "versionCode")
} else {
val packageObject = XposedHelpers.callMethod(packageParser.newInstance(), "parsePackage", apkPath, 0)
XposedHelpers.getIntField(packageObject, "mVersionCode")
}
}

private fun handleASitPlusIntegrityCheck(lpparam: XC_LoadPackage.LoadPackageParam) {
XposedBridge.log("Hooking DeviceIntegrityCheck")
XposedHelpers.findAndHookMethod(DEVICE_INTEGRITY_CHECK_CLASS, lpparam.classLoader, "checkIntegrity", XC_MethodReplacement.DO_NOTHING)
XposedHelpers.findAndHookMethod(DEVICE_INTEGRITY_CHECK_CLASS, lpparam.classLoader, "checkIntegrityForceCheck", XC_MethodReplacement.DO_NOTHING)
}

private fun handleDigitalesAmt(lpparam: XC_LoadPackage.LoadPackageParam) {
XposedBridge.log("Detected Digitales Amt")
if (getPackageVersion(lpparam) >= 2024011841) {
XposedHelpers.findAndHookMethod(DEVICE_INTEGRITY_CHECK_CLASS, lpparam.classLoader, "attestationSupportCheck", XC_MethodReplacement.DO_NOTHING)
}
handleASitPlusIntegrityCheck(lpparam)
}

private fun handleServicePortalBund(lpparam: XC_LoadPackage.LoadPackageParam) {
XposedBridge.log("Detected Serviceportal Bund")
if (getPackageVersion(lpparam) >= 2023122250) {
XposedBridge.log("Hooking attestationSupportCheck")
XposedHelpers.findAndHookMethod(DEVICE_INTEGRITY_CHECK_CLASS, lpparam.classLoader, "attestationSupportCheck", XC_MethodReplacement.DO_NOTHING)
}
if (getPackageVersion(lpparam) >= 2024071055) {
XposedBridge.log("Hooking rootCheck")
XposedHelpers.findAndHookMethod(DEVICE_INTEGRITY_CHECK_CLASS, lpparam.classLoader, "rootCheck", Boolean::class.java, XC_MethodReplacement.DO_NOTHING)
XposedBridge.log("Hooking bootloaderCheck")
XposedHelpers.findAndHookMethod(DEVICE_INTEGRITY_CHECK_CLASS, lpparam.classLoader, "bootloaderCheck", Boolean::class.java, XC_MethodReplacement.returnConstant(true))
}
handleASitPlusIntegrityCheck(lpparam)
}
private fun handleBmf2Go(lpparam: XC_LoadPackage.LoadPackageParam) {
if (getPackageVersion(lpparam) < 161) {
XposedBridge.log("Detected FON [+] version < 3.0.0")
Expand Down Expand Up @@ -121,6 +82,14 @@ class ModuleMain : IXposedHookZygoteInit, IXposedHookLoadPackage {
}
}

private fun handleDigitalesAmt(lpparam: XC_LoadPackage.LoadPackageParam) {
XposedBridge.log("Detected Digitales Amt")
if (getPackageVersion(lpparam) >= 2024011841) {
XposedHelpers.findAndHookMethod(DEVICE_INTEGRITY_CHECK_CLASS, lpparam.classLoader, "attestationSupportCheck", XC_MethodReplacement.DO_NOTHING)
}
handleASitPlusIntegrityCheck(lpparam)
}

private fun handleEduDigicard(lpparam: XC_LoadPackage.LoadPackageParam) {
XposedBridge.log("Hooking RootBeer")
// Hook RootBeer's isRooted() method
Expand Down Expand Up @@ -163,4 +132,40 @@ class ModuleMain : IXposedHookZygoteInit, IXposedHookLoadPackage {
//Hook PackageManager check
XposedHelpers.findAndHookMethod(MORE_ROOTCHECKS_MOBYWATEL, lpparam.classLoader, "h", Context::class.java, String::class.java, XC_MethodReplacement.returnConstant(false))
}

private fun handleServicePortalBund(lpparam: XC_LoadPackage.LoadPackageParam) {
XposedBridge.log("Detected Serviceportal Bund")
if (getPackageVersion(lpparam) >= 2023122250) {
XposedBridge.log("Hooking attestationSupportCheck")
XposedHelpers.findAndHookMethod(DEVICE_INTEGRITY_CHECK_CLASS, lpparam.classLoader, "attestationSupportCheck", XC_MethodReplacement.DO_NOTHING)
}
if (getPackageVersion(lpparam) >= 2024071055) {
XposedBridge.log("Hooking rootCheck")
XposedHelpers.findAndHookMethod(DEVICE_INTEGRITY_CHECK_CLASS, lpparam.classLoader, "rootCheck", Boolean::class.java, XC_MethodReplacement.DO_NOTHING)
XposedBridge.log("Hooking bootloaderCheck")
XposedHelpers.findAndHookMethod(DEVICE_INTEGRITY_CHECK_CLASS, lpparam.classLoader, "bootloaderCheck", Boolean::class.java, XC_MethodReplacement.returnConstant(true))
}
handleASitPlusIntegrityCheck(lpparam)
}

private fun getPackageVersion(lpparam: XC_LoadPackage.LoadPackageParam): Int {
val apkPath = File(lpparam.appInfo.sourceDir)
val packageParser = XposedHelpers.findClass("android.content.pm.PackageParser", lpparam.classLoader)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
HiddenApiBypass.addHiddenApiExemptions("Landroid/content/pm/PackageParser\$PackageLite;")
}
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val packageLite = XposedHelpers.callStaticMethod(packageParser, "parsePackageLite", apkPath, 0)
XposedHelpers.getIntField(packageLite, "versionCode")
} else {
val packageObject = XposedHelpers.callMethod(packageParser.getDeclaredConstructor().newInstance(), "parsePackage", apkPath, 0)
XposedHelpers.getIntField(packageObject, "mVersionCode")
}
}

private fun handleASitPlusIntegrityCheck(lpparam: XC_LoadPackage.LoadPackageParam) {
XposedBridge.log("Hooking DeviceIntegrityCheck")
XposedHelpers.findAndHookMethod(DEVICE_INTEGRITY_CHECK_CLASS, lpparam.classLoader, "checkIntegrity", XC_MethodReplacement.DO_NOTHING)
XposedHelpers.findAndHookMethod(DEVICE_INTEGRITY_CHECK_CLASS, lpparam.classLoader, "checkIntegrityForceCheck", XC_MethodReplacement.DO_NOTHING)
}
}
4 changes: 2 additions & 2 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<resources>
<string name="app_name">E-Government Liberator</string>
<string name="digitales_amt_package_name" translatable="false">at.gv.oe.app</string>
<string name="bmf2go_package_name" translatable="false">at.gv.bmf.bmf2go</string>
<string name="digitales_amt_package_name" translatable="false">at.gv.oe.app</string>
<string name="edudigicard_package_name" translatable="false">at.asitplus.digitalid.wallet.pupilid</string>
<string name="serviceportal_bund_package_name" translatable="false">at.gv.bka.serviceportal</string>
<string name="mobywatel_package_name" translatable="false">pl.nask.mobywatel</string>
<string name="serviceportal_bund_package_name" translatable="false">at.gv.bka.serviceportal</string>
</resources>

0 comments on commit 7946e5e

Please sign in to comment.