diff --git a/api/revanced-patches.api b/api/revanced-patches.api index a602a5b4c5..cba63bcabe 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -30,6 +30,42 @@ public final class app/revanced/patches/all/location/hide/HideMockLocationPatch public fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Lkotlin/Pair;)V } +public abstract class app/revanced/patches/all/misc/build/BaseSpoofBuildInfoPatch : app/revanced/patches/all/misc/transformation/BaseTransformInstructionsPatch { + public fun ()V + public synthetic fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Ljava/lang/Object; + public fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Lkotlin/Pair; + protected fun getBoard ()Ljava/lang/String; + protected fun getBootloader ()Ljava/lang/String; + protected fun getBrand ()Ljava/lang/String; + protected fun getCpuAbi ()Ljava/lang/String; + protected fun getCpuAbi2 ()Ljava/lang/String; + protected fun getDevice ()Ljava/lang/String; + protected fun getDisplay ()Ljava/lang/String; + protected fun getFingerprint ()Ljava/lang/String; + protected fun getHardware ()Ljava/lang/String; + protected fun getHost ()Ljava/lang/String; + protected fun getId ()Ljava/lang/String; + protected fun getManufacturer ()Ljava/lang/String; + protected fun getModel ()Ljava/lang/String; + protected fun getOdmSku ()Ljava/lang/String; + protected fun getProduct ()Ljava/lang/String; + protected fun getRadio ()Ljava/lang/String; + protected fun getSerial ()Ljava/lang/String; + protected fun getSku ()Ljava/lang/String; + protected fun getSocManufacturer ()Ljava/lang/String; + protected fun getSocModel ()Ljava/lang/String; + protected fun getTags ()Ljava/lang/String; + protected fun getTime ()Ljava/lang/Long; + protected fun getType ()Ljava/lang/String; + protected fun getUser ()Ljava/lang/String; + public synthetic fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Ljava/lang/Object;)V + public fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Lkotlin/Pair;)V +} + +public final class app/revanced/patches/all/misc/build/SpoofBuildInfoPatch : app/revanced/patches/all/misc/build/BaseSpoofBuildInfoPatch { + public fun ()V +} + public final class app/revanced/patches/all/misc/debugging/EnableAndroidDebuggingPatch : app/revanced/patcher/patch/ResourcePatch { public static final field INSTANCE Lapp/revanced/patches/all/misc/debugging/EnableAndroidDebuggingPatch; public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V diff --git a/src/main/kotlin/app/revanced/patches/all/misc/build/BaseSpoofBuildInfoPatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/build/BaseSpoofBuildInfoPatch.kt new file mode 100644 index 0000000000..15ef20e08c --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/all/misc/build/BaseSpoofBuildInfoPatch.kt @@ -0,0 +1,120 @@ +package app.revanced.patches.all.misc.build + +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.all.misc.transformation.BaseTransformInstructionsPatch +import app.revanced.util.getReference +import com.android.tools.smali.dexlib2.iface.ClassDef +import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.instruction.Instruction +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference + +abstract class BaseSpoofBuildInfoPatch : BaseTransformInstructionsPatch>>() { + // The build information supported32BitAbis, supported64BitAbis, and supportedAbis are not supported for now, + // because initializing an array in transform is a bit more complex. + + protected open val board: String? = null + + protected open val bootloader: String? = null + + protected open val brand: String? = null + + protected open val cpuAbi: String? = null + + protected open val cpuAbi2: String? = null + + protected open val device: String? = null + + protected open val display: String? = null + + protected open val fingerprint: String? = null + + protected open val hardware: String? = null + + protected open val host: String? = null + + protected open val id: String? = null + + protected open val manufacturer: String? = null + + protected open val model: String? = null + + protected open val odmSku: String? = null + + protected open val product: String? = null + + protected open val radio: String? = null + + protected open val serial: String? = null + + protected open val sku: String? = null + + protected open val socManufacturer: String? = null + + protected open val socModel: String? = null + + protected open val tags: String? = null + + protected open val time: Long? = null + + protected open val type: String? = null + + protected open val user: String? = null + + + // Lazy, so that patch options above are initialized before they are accessed. + private val replacements: Map> by lazy { + buildMap { + if (board != null) put("BOARD", "const-string" to "\"$board\"") + if (bootloader != null) put("BOOTLOADER", "const-string" to "\"$bootloader\"") + if (brand != null) put("BRAND", "const-string" to "\"$brand\"") + if (cpuAbi != null) put("CPU_ABI", "const-string" to "\"$cpuAbi\"") + if (cpuAbi2 != null) put("CPU_ABI2", "const-string" to "\"$cpuAbi2\"") + if (device != null) put("DEVICE", "const-string" to "\"$device\"") + if (display != null) put("DISPLAY", "const-string" to "\"$display\"") + if (fingerprint != null) put("FINGERPRINT", "const-string" to "\"$fingerprint\"") + if (hardware != null) put("HARDWARE", "const-string" to "\"$hardware\"") + if (host != null) put("HOST", "const-string" to "\"$host\"") + if (id != null) put("ID", "const-string" to "\"$id\"") + if (manufacturer != null) put("MANUFACTURER", "const-string" to "\"$manufacturer\"") + if (model != null) put("MODEL", "const-string" to "\"$model\"") + if (odmSku != null) put("ODM_SKU", "const-string" to "\"$odmSku\"") + if (product != null) put("PRODUCT", "const-string" to "\"$product\"") + if (radio != null) put("RADIO", "const-string" to "\"$radio\"") + if (serial != null) put("SERIAL", "const-string" to "\"$serial\"") + if (sku != null) put("SKU", "const-string" to "\"$sku\"") + if (socManufacturer != null) put("SOC_MANUFACTURER", "const-string" to "\"$socManufacturer\"") + if (socModel != null) put("SOC_MODEL", "const-string" to "\"$socModel\"") + if (tags != null) put("TAGS", "const-string" to "\"$tags\"") + if (time != null) put("TIME", "const-wide" to "$time") + if (type != null) put("TYPE", "const-string" to "\"$type\"") + if (user != null) put("USER", "const-string" to "\"$user\"") + } + } + + override fun filterMap( + classDef: ClassDef, + method: Method, + instruction: Instruction, + instructionIndex: Int + ): Pair>? { + val reference = instruction.getReference() ?: return null + if (reference.definingClass != BUILD_CLASS_DESCRIPTOR) return null + + return replacements[reference.name]?.let { instructionIndex to it } + } + + override fun transform(mutableMethod: MutableMethod, entry: Pair>) { + val (index, replacement) = entry + val (opcode, operand) = replacement + val register = mutableMethod.getInstruction(index).registerA + + mutableMethod.replaceInstruction(index, "$opcode v$register, $operand") + } + + private companion object { + private const val BUILD_CLASS_DESCRIPTOR = "Landroid/os/Build;" + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/all/misc/build/SpoofBuildInfoPatch.kt b/src/main/kotlin/app/revanced/patches/all/misc/build/SpoofBuildInfoPatch.kt new file mode 100644 index 0000000000..994ddd4551 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/all/misc/build/SpoofBuildInfoPatch.kt @@ -0,0 +1,183 @@ +package app.revanced.patches.all.misc.build + +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.longPatchOption +import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption + +@Patch( + name = "Spoof build info", + description = "Spoof the information about the current build.", + use = false +) +@Suppress("unused") +class SpoofBuildInfoPatch : BaseSpoofBuildInfoPatch() { + override val board by stringPatchOption( + key = "board", + default = null, + title = "Board", + description = "The name of the underlying board, like \"goldfish\"." + ) + + override val bootloader by stringPatchOption( + key = "bootloader", + default = null, + title = "Bootloader", + description = "The system bootloader version number." + ) + + override val brand by stringPatchOption( + key = "brand", + default = null, + title = "Brand", + description = "The consumer-visible brand with which the product/hardware will be associated, if any." + ) + + override val cpuAbi by stringPatchOption( + key = "cpu-abi", + default = null, + title = "CPU ABI", + description = "This field was deprecated in API level 21. Use SUPPORTED_ABIS instead." + ) + + override val cpuAbi2 by stringPatchOption( + key = "cpu-abi-2", + default = null, + title = "CPU ABI 2", + description = "This field was deprecated in API level 21. Use SUPPORTED_ABIS instead." + ) + + override val device by stringPatchOption( + key = "device", + default = null, + title = "Device", + description = "The name of the industrial design." + ) + + override val display by stringPatchOption( + key = "display", + default = null, + title = "Display", + description = "A build ID string meant for displaying to the user." + ) + + override val fingerprint by stringPatchOption( + key = "fingerprint", + default = null, + title = "Fingerprint", + description = "A string that uniquely identifies this build." + ) + + override val hardware by stringPatchOption( + key = "hardware", + default = null, + title = "Hardware", + description = "The name of the hardware (from the kernel command line or /proc)." + ) + + override val host by stringPatchOption( + key = "host", + default = null, + title = "Host", + description = "The host." + ) + + override val id by stringPatchOption( + key = "id", + default = null, + title = "ID", + description = "Either a changelist number, or a label like \"M4-rc20\"." + ) + + override val manufacturer by stringPatchOption( + key = "manufacturer", + default = null, + title = "Manufacturer", + description = "The manufacturer of the product/hardware." + ) + + override val model by stringPatchOption( + key = "model", + default = null, + title = "Model", + description = "The end-user-visible name for the end product." + ) + + override val odmSku by stringPatchOption( + key = "odm-sku", + default = null, + title = "ODM SKU", + description = "The SKU of the device as set by the original design manufacturer (ODM)." + ) + + override val product by stringPatchOption( + key = "product", + default = null, + title = "Product", + description = "The name of the overall product." + ) + + override val radio by stringPatchOption( + key = "radio", + default = null, + title = "Radio", + description = "This field was deprecated in API level 15. " + + "The radio firmware version is frequently not available when this class is initialized, " + + "leading to a blank or \"unknown\" value for this string. Use getRadioVersion() instead." + ) + + override val serial by stringPatchOption( + key = "serial", + default = null, + title = "Serial", + description = "This field was deprecated in API level 26. Use getSerial() instead." + ) + + override val sku by stringPatchOption( + key = "sku", + default = null, + title = "SKU", + description = "The SKU of the hardware (from the kernel command line)." + ) + + override val socManufacturer by stringPatchOption( + key = "soc-manufacturer", + default = null, + title = "SOC Manufacturer", + description = "The manufacturer of the device's primary system-on-chip." + ) + + override val socModel by stringPatchOption( + key = "soc-model", + default = null, + title = "SOC Model", + description = "The model name of the device's primary system-on-chip." + ) + + override val tags by stringPatchOption( + key = "tags", + default = null, + title = "Tags", + description = "Comma-separated tags describing the build, like \"unsigned,debug\"." + ) + + override val time by longPatchOption( + key = "time", + default = null, + title = "Time", + description = "The time at which the build was produced, given in milliseconds since the UNIX epoch." + ) + + override val type by stringPatchOption( + key = "type", + default = null, + title = "Type", + description = "The type of build, like \"user\" or \"eng\"." + ) + + override val user by stringPatchOption( + key = "user", + default = null, + title = "User", + description = "The user." + ) +} \ No newline at end of file