implement package spoofing(676c98acda)

This commit is contained in:
inotia00 2022-10-26 15:02:55 +09:00
commit d110baa9a7
2 changed files with 165 additions and 4 deletions

View file

@ -123,7 +123,8 @@ public class PackageUtils {
for (Signature sig : info.signatures) {
String digest = sha1sum(sig.toByteArray());
if (digest != null) {
return digest;
// spoof or use real one
return PackageSpoofUtils.spoofStringSignature(packageManager, packageName, digest);
}
}
}
@ -147,7 +148,8 @@ public class PackageUtils {
for (Signature sig : info.signatures) {
byte[] digest = sha1bytes(sig.toByteArray());
if (digest != null) {
return digest;
// spoof or use real one
return PackageSpoofUtils.spoofBytesSignature(packageManager, packageName, digest);
}
}
}
@ -161,7 +163,9 @@ public class PackageUtils {
if (packageName == null) {
packageName = firstPackageFromUserId(context, callingUid);
}
return packageName;
// spoof or use real one
return PackageSpoofUtils.spoofPackageName(context.getPackageManager(), packageName);
}
public static byte[] sha1bytes(byte[] bytes) {
@ -239,7 +243,9 @@ public class PackageUtils {
if (packageName != null && suggestedPackageName != null && !packageName.equals(suggestedPackageName)) {
throw new SecurityException("UID [" + callingUid + "] is not related to packageName [" + suggestedPackageName + "] (seems to be " + packageName + ")");
}
return packageName;
// spoof or use real one
return PackageSpoofUtils.spoofPackageName(context.getPackageManager(), packageName);
}
@Nullable

View file

@ -0,0 +1,155 @@
package org.microg.gms.common
import android.content.pm.PackageManager
import android.os.Bundle
import android.util.Log
/**
* utilities to spoof package information
*/
internal object PackageSpoofUtils {
private const val TAG = "SpoofUtils"
private const val META_SPOOF_PACKAGE_NAME =
"com.mgoogle.android.gms.SPOOFED_PACKAGE_NAME"
private const val META_SPOOF_PACKAGE_SIGNATURE =
"com.mgoogle.android.gms.SPOOFED_PACKAGE_SIGNATURE"
private val spoofedPackageNameCache = HashMap<String, String>()
private val spoofedPackageSignatureCache = HashMap<String, String>()
/**
* spoof the package name of a package, if a spoofed name is set
*
* @param packageManager manager used to get package information
* @param realPackageName the real package name
* @return either the spoofed or the real package name, depending on if the package requested spoofing
*/
@JvmStatic
fun spoofPackageName(
packageManager: PackageManager,
realPackageName: String?
): String? {
if (realPackageName.isNullOrEmpty()) return realPackageName
val spoofedPackageName = getSpoofedPackageName(packageManager, realPackageName)
return if (!spoofedPackageName.isNullOrEmpty()) {
Log.i(TAG, "package name of $realPackageName spoofed to $spoofedPackageName")
spoofedPackageName
} else realPackageName
}
/**
* spoof the signature of a package, if a spoofed name is set
*
* @param packageManager manager used to get package information
* @param packageName name of the package to check
* @param realSignature the real package signature
* @return either the spoofed or the real signature, depending on if the package requested spoofing
*/
@JvmStatic
@JvmName("spoofStringSignature")
fun spoofSignature(
packageManager: PackageManager,
packageName: String,
realSignature: String?
): String? {
val spoofedSignature = getSpoofedSignature(packageManager, packageName)
return if (!spoofedSignature.isNullOrEmpty()) {
Log.i(TAG, "package signature of $packageName spoofed to $spoofedSignature")
spoofedSignature
} else realSignature
}
/**
* spoof the signature of a package, if a spoofed name is set
*
* @param packageManager manager used to get package information
* @param packageName name of the package to check
* @param realSignature the real package signature
* @return either the spoofed or the real signature, depending on if the package requested spoofing
*/
@JvmStatic
@JvmName("spoofBytesSignature")
fun spoofSignature(
packageManager: PackageManager,
packageName: String,
realSignature: ByteArray?
): ByteArray? {
val spoofedSignatureString = getSpoofedSignature(packageManager, packageName)
return if (!spoofedSignatureString.isNullOrEmpty()) {
Log.i(TAG, "package signature of $packageName spoofed to $spoofedSignatureString")
// convert hex string to bytes
spoofedSignatureString.chunked(2)
.map { it.toInt(16).toByte() }
.toByteArray()
} else realSignature
}
/**
* get the spoofed package name for a package
*
* @param packageManager manager used to get package information
* @param packageName name of the package to get spoofed name of
* @return spoofed name string, or null if none set
*/
private fun getSpoofedPackageName(
packageManager: PackageManager,
packageName: String
): String? {
return spoofedPackageNameCache[packageName] ?: run {
// fetch value
val meta = getPackageMetadata(packageManager, packageName)
val spoofedPackageName = meta?.getString(META_SPOOF_PACKAGE_NAME)
if (spoofedPackageName != null) {
spoofedPackageNameCache[packageName] = spoofedPackageName
}
spoofedPackageName
}
}
/**
* get the spoofed package signature for a package
*
* @param packageManager manager used to get package information
* @param packageName name of the package to get spoofed signature of
* @return spoofed signature string, or null if none set
*/
private fun getSpoofedSignature(
packageManager: PackageManager,
packageName: String
): String? {
return spoofedPackageSignatureCache[packageName] ?: run {
// fetch value
val meta = getPackageMetadata(packageManager, packageName)
val spoofedSignature = meta?.getString(META_SPOOF_PACKAGE_SIGNATURE)
if (spoofedSignature != null) {
spoofedPackageSignatureCache[packageName] = spoofedSignature
}
spoofedSignature
}
}
/**
* get package metadata
*
* @param packageManager manager used to get package information
* @param packageName name of the package to get metadata of
* @return package metadata bundle
*/
private fun getPackageMetadata(packageManager: PackageManager, packageName: String): Bundle? {
return try {
// PackageManager.getPackageInfo() has been deprecated in targetSdkVersion 30+
// To solve this, add the QUERY_ALL_PACKAGES permission to AndroidManifest.xml
packageManager
.getPackageInfo(packageName, PackageManager.GET_META_DATA)
?.applicationInfo
?.metaData
} catch (e: PackageManager.NameNotFoundException) {
Log.e(TAG, "failed to get application metadata for $packageName", e)
null
}
}
}