Repo created
This commit is contained in:
parent
8ed267efd9
commit
bca80f6a46
22 changed files with 1516 additions and 2 deletions
1
app/.gitignore
vendored
Normal file
1
app/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
101
app/app.iml
Normal file
101
app/app.iml
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
<option name="GRADLE_PROJECT_PATH" value=":app" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
||||
<afterSyncTasks>
|
||||
<task>generateDebugSources</task>
|
||||
</afterSyncTasks>
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
|
||||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7">
|
||||
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
|
||||
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-safeguard" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/reports" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" name="de.robv.android.xposed:api:82:sources@jar" level="project" />
|
||||
<orderEntry type="library" exported="" name="de.robv.android.xposed:api:82@jar" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
74
app/build.gradle.kts
Executable file
74
app/build.gradle.kts
Executable file
|
|
@ -0,0 +1,74 @@
|
|||
@file:Suppress("UnstableApiUsage")
|
||||
|
||||
import com.android.build.gradle.tasks.PackageAndroidArtifact
|
||||
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "inc.whew.android.fakegapps"
|
||||
compileSdk = 35
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "inc.whew.android.fakegapps"
|
||||
minSdk = 15
|
||||
targetSdk = 35
|
||||
versionCode = 13
|
||||
versionName = "6.6"
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
create("release") {
|
||||
if (project.hasProperty("RELEASE_KEY_ALIAS")) {
|
||||
storeFile = file(project.properties["RELEASE_STORE_FILE"].toString())
|
||||
storePassword = project.properties["RELEASE_STORE_PASSWORD"].toString()
|
||||
keyAlias = project.properties["RELEASE_KEY_ALIAS"].toString()
|
||||
keyPassword = project.properties["RELEASE_KEY_PASSWORD"].toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = false
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro",
|
||||
)
|
||||
if (project.hasProperty("RELEASE_KEY_ALIAS")) {
|
||||
signingConfig = signingConfigs["release"]
|
||||
}
|
||||
vcsInfo {
|
||||
include = false
|
||||
}
|
||||
}
|
||||
debug {
|
||||
vcsInfo {
|
||||
include = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
packaging {
|
||||
dex {
|
||||
useLegacyPackaging = false
|
||||
}
|
||||
}
|
||||
|
||||
// https://gitlab.com/IzzyOnDroid/repo/-/issues/491
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
includeInBundle = false
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/a/77745844
|
||||
tasks.withType<PackageAndroidArtifact> {
|
||||
doFirst { appMetadata.asFile.orNull?.writeText("") }
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("de.robv.android.xposed:api:82")
|
||||
compileOnly("de.robv.android.xposed:api:82:sources")
|
||||
}
|
||||
17
app/proguard-rules.pro
vendored
Normal file
17
app/proguard-rules.pro
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /home/thermatk/android-sdk-linux/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.kts.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
19
app/src/main/AndroidManifest.xml
Normal file
19
app/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application android:allowBackup="true" android:label="FakeGapps"
|
||||
android:icon="@mipmap/ic_launcher" android:theme="@android:style/Theme.Holo.Light.DarkActionBar">
|
||||
<meta-data
|
||||
android:name="xposedmodule"
|
||||
android:value="true" />
|
||||
<meta-data
|
||||
android:name="xposeddescription"
|
||||
android:value="MicroG fake signature helper" />
|
||||
<meta-data
|
||||
android:name="xposedminversion"
|
||||
android:value="54" />
|
||||
<meta-data
|
||||
android:name="xposedscope"
|
||||
android:resource="@array/lsposed_scope" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
1
app/src/main/assets/xposed_init
Executable file
1
app/src/main/assets/xposed_init
Executable file
|
|
@ -0,0 +1 @@
|
|||
inc.whew.android.fakegapps.FakeSignatures
|
||||
193
app/src/main/java/inc/whew/android/fakegapps/FakeSignatures.java
Executable file
193
app/src/main/java/inc/whew/android/fakegapps/FakeSignatures.java
Executable file
|
|
@ -0,0 +1,193 @@
|
|||
package inc.whew.android.fakegapps;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.Signature;
|
||||
import android.content.pm.SigningInfo;
|
||||
import android.os.Build;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Base64;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.lang.ReflectiveOperationException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.PublicKey;
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage;
|
||||
import de.robv.android.xposed.XC_MethodHook;
|
||||
import de.robv.android.xposed.XposedBridge;
|
||||
import de.robv.android.xposed.XposedHelpers;
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
|
||||
|
||||
public class FakeSignatures implements IXposedHookLoadPackage {
|
||||
private static final String TAG = "FakeGApps";
|
||||
private static final String _x509cert = "MIIEQzCCAyugAwIBAgIJAMLgh0ZkSjCNMA0GCSqGSIb3DQEBBAUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDAeFw0wODA4MjEyMzEzMzRaFw0zNjAxMDcyMzEzMzRaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBAKtWLgDYO6IIrgqWbxJOKdoR8qtW0I9Y4sypEwPpt1TTcvZApxsdyxMJZ2JORland2qSGT2y5b+3JKkedxiLDmpHpDsz2WCbdxgxRczfey5YZnTJ4VZbH0xqWVW/8lGmPav5xVwnIiJS6HXk+BVKZF+JcWjAsb/GEuq/eFdpuzSqeYTcfi6idkyugwfYwXFU1+5fZKUaRKYCwkkFQVfcAs1fXA5V+++FGfvjJ/CxURaSxaBvGdGDhfXE28LWuT9ozCl5xw4Yq5OGazvV24mZVSoOO0yZ31j7kYvtwYK6NeADwbSxDdJEqO4k//0zOHKrUiGYXtqw/A0LFFtqoZKFjnkCAQOjgdkwgdYwHQYDVR0OBBYEFMd9jMIhF1Ylmn/Tgt9r45jk14alMIGmBgNVHSMEgZ4wgZuAFMd9jMIhF1Ylmn/Tgt9r45jk14aloXikdjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLR29vZ2xlIEluYy4xEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMTB0FuZHJvaWSCCQDC4IdGZEowjTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4IBAQBt0lLO74UwLDYKqs6Tm8/yzKkEu116FmH4rkaymUIE0P9KaMftGlMexFlaYjzmB2OxZyl6euNXEsQH8gjwyxCUKRJNexBiGcCEyj6z+a1fuHHvkiaai+KL8W1EyNmgjmyy8AW7P+LLlkR+ho5zEHatRbM/YAnqGcFh5iZBqpknHf1SKMXFh4dd239FJ1jWYfbMDMy3NS5CTMQ2XFI1MvcyUTdZPErjQfTbQe3aDQsQcafEQPD+nqActifKZ0Np0IS9L9kR/wbNvyz6ENwPiTrjV2KRkEjH78ZMcUQXg0L3BYHJ3lc69Vs5Ddf9uUGGMYldX3WfMBEmh/9iFBDAaTCK";
|
||||
|
||||
@Override
|
||||
public void handleLoadPackage(LoadPackageParam loadedPackage) throws CertificateException {
|
||||
if (!loadedPackage.packageName.equals("android"))
|
||||
return;
|
||||
|
||||
final byte[] certBytes = Base64.decode(_x509cert, Base64.DEFAULT);
|
||||
final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
|
||||
final Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(certBytes));
|
||||
|
||||
XC_MethodHook hook = new XC_MethodHook() {
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) {
|
||||
PackageInfo pi = (PackageInfo) param.getResult();
|
||||
if (pi != null) {
|
||||
String packageName = pi.packageName;
|
||||
if (packageName.equals("com.google.android.gms") || packageName.equals("com.android.vending")) {
|
||||
pi.signatures = new Signature[]{new Signature(certBytes)};
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
|
||||
SigningInfo signingInfo = createSigningInfo(new Signature(certBytes), cert.getPublicKey());
|
||||
if (signingInfo != null) {
|
||||
pi.signingInfo = signingInfo;
|
||||
}
|
||||
}
|
||||
|
||||
param.setResult(pi);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
String classToHook;
|
||||
switch (Build.VERSION.SDK_INT) {
|
||||
case Build.VERSION_CODES.BASE: // SDK 1
|
||||
case Build.VERSION_CODES.BASE_1_1: // SDK 2
|
||||
case Build.VERSION_CODES.CUPCAKE: // SDK 3
|
||||
case Build.VERSION_CODES.DONUT: // SDK 4
|
||||
case Build.VERSION_CODES.ECLAIR: // SDK 5
|
||||
case Build.VERSION_CODES.ECLAIR_0_1: // SDK 6
|
||||
case Build.VERSION_CODES.ECLAIR_MR1: // SDK 7
|
||||
case Build.VERSION_CODES.FROYO: // SDK 8
|
||||
case Build.VERSION_CODES.GINGERBREAD: // SDK 9
|
||||
case Build.VERSION_CODES.GINGERBREAD_MR1: // SDK 10
|
||||
case Build.VERSION_CODES.HONEYCOMB: // SDK 11
|
||||
case Build.VERSION_CODES.HONEYCOMB_MR1: // SDK 12
|
||||
case Build.VERSION_CODES.HONEYCOMB_MR2: // SDK 13
|
||||
case Build.VERSION_CODES.ICE_CREAM_SANDWICH: // SDK 14
|
||||
case Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1: // SDK 15
|
||||
case Build.VERSION_CODES.JELLY_BEAN: // SDK 16
|
||||
case Build.VERSION_CODES.JELLY_BEAN_MR1: // SDK 17
|
||||
case Build.VERSION_CODES.JELLY_BEAN_MR2: // SDK 18
|
||||
case Build.VERSION_CODES.KITKAT: // SDK 19
|
||||
case Build.VERSION_CODES.KITKAT_WATCH: // SDK 20
|
||||
case Build.VERSION_CODES.LOLLIPOP: // SDK 21
|
||||
case Build.VERSION_CODES.LOLLIPOP_MR1: // SDK 22
|
||||
case Build.VERSION_CODES.M: // SDK 23
|
||||
case Build.VERSION_CODES.N: // SDK 24
|
||||
case Build.VERSION_CODES.N_MR1: // SDK 25
|
||||
case Build.VERSION_CODES.O: // SDK 26
|
||||
case Build.VERSION_CODES.O_MR1: // SDK 27
|
||||
case Build.VERSION_CODES.P: // SDK 28
|
||||
case Build.VERSION_CODES.Q: // SDK 29
|
||||
case Build.VERSION_CODES.R: // SDK 30
|
||||
classToHook = "com.android.server.pm.PackageManagerService";
|
||||
break;
|
||||
case Build.VERSION_CODES.S: // SDK 31
|
||||
case Build.VERSION_CODES.S_V2: // SDK 32
|
||||
classToHook = "com.android.server.pm.PackageManagerService.ComputerEngine";
|
||||
break;
|
||||
case Build.VERSION_CODES.TIRAMISU: // SDK 33
|
||||
case Build.VERSION_CODES.UPSIDE_DOWN_CAKE: // SDK 34
|
||||
default:
|
||||
classToHook = "com.android.server.pm.ComputerEngine";
|
||||
break;
|
||||
}
|
||||
|
||||
final Class<?> hookedClass = XposedHelpers.findClass(classToHook, loadedPackage.classLoader);
|
||||
XposedBridge.hookAllMethods(hookedClass, "generatePackageInfo", hook);
|
||||
}
|
||||
|
||||
private static Class<?> findFirstLoadableClass(String... candidates) throws ClassNotFoundException {
|
||||
ClassNotFoundException exc = new ClassNotFoundException();
|
||||
for (String candidate : candidates) {
|
||||
try {
|
||||
return Class.forName(candidate);
|
||||
} catch (ClassNotFoundException e) {
|
||||
exc = e;
|
||||
}
|
||||
}
|
||||
throw exc;
|
||||
}
|
||||
|
||||
private static <T> T invokeFirstConstructor(
|
||||
Class<T> cls,
|
||||
SimpleEntry<Class<?>[], Object[]>... candidates
|
||||
) throws ReflectiveOperationException {
|
||||
NoSuchMethodException exc = new NoSuchMethodException();
|
||||
for (SimpleEntry<Class<?>[], Object[]> candidate : candidates) {
|
||||
Constructor<T> constructor;
|
||||
try {
|
||||
constructor = cls.getDeclaredConstructor(candidate.getKey());
|
||||
} catch (NoSuchMethodException e) {
|
||||
exc = e;
|
||||
continue;
|
||||
}
|
||||
|
||||
constructor.setAccessible(true);
|
||||
return constructor.newInstance(candidate.getValue());
|
||||
}
|
||||
throw exc;
|
||||
}
|
||||
|
||||
@TargetApi(android.os.Build.VERSION_CODES.P)
|
||||
private SigningInfo createSigningInfo(Signature sig, PublicKey publicKey) {
|
||||
final int SIGNING_BLOCK_V3 = 3;
|
||||
final Signature[] sigs = new Signature[]{sig};
|
||||
final ArraySet<PublicKey> pks = new ArraySet<>();
|
||||
pks.add(publicKey);
|
||||
|
||||
// Unfortunately, SigningDetails is not exported in SDK, so we have to rely on reflection.
|
||||
// Also, public SigningInfo constructor is only available from API 35, so we can't use it.
|
||||
try {
|
||||
Class<?> signingDetailsClass = findFirstLoadableClass(
|
||||
"android.content.pm.SigningDetails",
|
||||
// Android 9 to 12 have SigningDetails embedded in the PackageParser class
|
||||
"android.content.pm.PackageParser$SigningDetails"
|
||||
);
|
||||
Object signingDetails = invokeFirstConstructor(
|
||||
signingDetailsClass,
|
||||
// https://cs.android.com/android/platform/superproject/+/android-15.0.0_r17:frameworks/base/core/java/android/content/pm/SigningDetails.java;l=146
|
||||
new SimpleEntry<Class<?>[], Object[]>(
|
||||
new Class<?>[]{
|
||||
Signature[].class, // signatures
|
||||
int.class, // signatureSchemeVersion
|
||||
ArraySet.class, // keys
|
||||
Signature[].class // pastSigningCertificates
|
||||
},
|
||||
new Object[]{sigs, SIGNING_BLOCK_V3, pks, null}
|
||||
),
|
||||
// Android 9 had an extra "pastSigningCertificatesFlags" argument
|
||||
// https://cs.android.com/android/platform/superproject/+/android-9.0.0_r60:frameworks/base/core/java/android/content/pm/PackageParser.java;l=5739
|
||||
new SimpleEntry<Class<?>[], Object[]>(
|
||||
new Class<?>[]{
|
||||
Signature[].class, // signatures
|
||||
int.class, // signatureSchemeVersion
|
||||
ArraySet.class, // keys
|
||||
Signature[].class, // pastSigningCertificates
|
||||
int[].class // pastSigningCertificatesFlags
|
||||
},
|
||||
new Object[]{sigs, SIGNING_BLOCK_V3, pks, null, null}
|
||||
)
|
||||
);
|
||||
|
||||
Constructor<SigningInfo> signingInfoConstructor = SigningInfo.class.getDeclaredConstructor(signingDetailsClass);
|
||||
signingInfoConstructor.setAccessible(true);
|
||||
return signingInfoConstructor.newInstance(signingDetails);
|
||||
} catch (Exception e) {
|
||||
XposedBridge.log(String.format("%s failed to create signingInfo", TAG));
|
||||
XposedBridge.log(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.5 KiB |
6
app/src/main/res/values/arrays.xml
Normal file
6
app/src/main/res/values/arrays.xml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="lsposed_scope" >
|
||||
<item>android</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
Loading…
Add table
Add a link
Reference in a new issue