feat(spoof-app-version): change to abstract patch

This commit is contained in:
inotia00 2023-06-18 23:12:21 +09:00
parent 5c99e9a16a
commit ef03b3afbd
4 changed files with 75 additions and 94 deletions

View File

@ -4,33 +4,27 @@ import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.music.utils.settings.resource.patch.MusicSettingsPatch import app.revanced.patches.music.utils.settings.resource.patch.MusicSettingsPatch
import app.revanced.patches.shared.annotation.YouTubeMusicCompatibility import app.revanced.patches.shared.annotation.YouTubeMusicCompatibility
import app.revanced.patches.shared.patch.versionspoof.GeneralVersionSpoofPatch import app.revanced.patches.shared.patch.versionspoof.AbstractVersionSpoofPatch
import app.revanced.util.enum.CategoryType import app.revanced.util.enum.CategoryType
import app.revanced.util.integrations.Constants.MUSIC_MISC_PATH import app.revanced.util.integrations.Constants.MUSIC_MISC_PATH
@Patch @Patch
@Name("spoof-app-version") @Name("spoof-app-version")
@Description("Spoof the YouTube Music client version.") @Description("Spoof the YouTube Music client version.")
@DependsOn( @DependsOn([MusicSettingsPatch::class])
[
GeneralVersionSpoofPatch::class,
MusicSettingsPatch::class
]
)
@YouTubeMusicCompatibility @YouTubeMusicCompatibility
@Version("0.0.1") @Version("0.0.1")
class SpoofAppVersionPatch : BytecodePatch() { class SpoofAppVersionPatch : AbstractVersionSpoofPatch(
"$MUSIC_MISC_PATH/SpoofAppVersionPatch;->getVersionOverride(Ljava/lang/String;)Ljava/lang/String;"
) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
GeneralVersionSpoofPatch.injectSpoof("$MUSIC_MISC_PATH/SpoofAppVersionPatch;->getVersionOverride(Ljava/lang/String;)Ljava/lang/String;")
MusicSettingsPatch.addMusicPreference(CategoryType.MISC, "revanced_spoof_app_version", "false") MusicSettingsPatch.addMusicPreference(CategoryType.MISC, "revanced_spoof_app_version", "false")
return PatchResultSuccess() return PatchResultSuccess()

View File

@ -0,0 +1,60 @@
package app.revanced.patches.shared.patch.versionspoof
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.shared.fingerprints.ClientInfoFingerprint
import app.revanced.patches.shared.fingerprints.ClientInfoParentFingerprint
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
@Name("abstract-version-spoof")
@Version("0.0.1")
abstract class AbstractVersionSpoofPatch(
private val descriptor: String
) : BytecodePatch(
listOf(ClientInfoParentFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
ClientInfoParentFingerprint.result?.let { parentResult ->
ClientInfoFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.mutableMethod?.let {
it.apply {
var insertIndex = 0
val insertInstructions = implementation!!.instructions
val targetString = "Landroid/os/Build\$VERSION;->RELEASE:Ljava/lang/String;"
for ((index, instruction) in insertInstructions.withIndex()) {
if (instruction.opcode != Opcode.SGET_OBJECT) continue
val indexString = ((instruction as? ReferenceInstruction)?.reference as? DexBackedFieldReference).toString()
if (indexString != targetString) continue
val targetRegister = (instruction as OneRegisterInstruction).registerA
insertIndex = index - 1
addInstructions(
insertIndex, """
invoke-static {v$targetRegister}, $descriptor
move-result-object v$targetRegister
"""
)
break
}
if (insertIndex <= 0) return ClientInfoFingerprint.toErrorResult()
}
} ?: return ClientInfoFingerprint.toErrorResult()
} ?: return ClientInfoParentFingerprint.toErrorResult()
return PatchResultSuccess()
}
}

View File

@ -1,69 +0,0 @@
package app.revanced.patches.shared.patch.versionspoof
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.fingerprints.ClientInfoFingerprint
import app.revanced.patches.shared.fingerprints.ClientInfoParentFingerprint
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import kotlin.properties.Delegates
@Name("general-version-spoof")
@Version("0.0.1")
class GeneralVersionSpoofPatch : BytecodePatch(
listOf(
ClientInfoParentFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
ClientInfoParentFingerprint.result?.let { parentResult ->
ClientInfoFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.mutableMethod?.let {
val insertInstructions = it.implementation!!.instructions
val targetString = "Landroid/os/Build\$VERSION;->RELEASE:Ljava/lang/String;"
for ((index, instruction) in insertInstructions.withIndex()) {
if (instruction.opcode != Opcode.SGET_OBJECT) continue
val indexString = ((instruction as? ReferenceInstruction)?.reference as? DexBackedFieldReference).toString()
if (indexString != targetString) continue
insertMethod = it
insertIndex = index - 1
targetRegister = (instruction as OneRegisterInstruction).registerA
break
}
if (insertIndex <= 0) return ClientInfoFingerprint.toErrorResult()
} ?: return ClientInfoFingerprint.toErrorResult()
} ?: return ClientInfoParentFingerprint.toErrorResult()
return PatchResultSuccess()
}
companion object {
private var insertIndex by Delegates.notNull<Int>()
private var targetRegister by Delegates.notNull<Int>()
private lateinit var insertMethod: MutableMethod
fun injectSpoof(methodDescriptor: String) {
insertMethod.addInstructions(
insertIndex, """
invoke-static {v$targetRegister}, $methodDescriptor
move-result-object v$targetRegister
"""
)
}
}
}

View File

@ -3,38 +3,34 @@ package app.revanced.patches.youtube.misc.spoofappversion.patch
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.shared.annotation.YouTubeCompatibility import app.revanced.patches.shared.annotation.YouTubeCompatibility
import app.revanced.patches.shared.patch.versionspoof.GeneralVersionSpoofPatch import app.revanced.patches.shared.patch.versionspoof.AbstractVersionSpoofPatch
import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch
import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch.Companion.contexts
import app.revanced.util.integrations.Constants.MISC_PATH import app.revanced.util.integrations.Constants.MISC_PATH
import app.revanced.util.resources.ResourceUtils.copyXmlNode import app.revanced.util.resources.ResourceUtils.copyXmlNode
@Patch @Patch
@Name("spoof-app-version") @Name("spoof-app-version")
@Description("Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI.") @Description("Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI.")
@DependsOn( @DependsOn([SettingsPatch::class])
[
GeneralVersionSpoofPatch::class,
SettingsPatch::class
]
)
@YouTubeCompatibility @YouTubeCompatibility
@Version("0.0.1") @Version("0.0.1")
class SpoofAppVersionPatch : ResourcePatch { class SpoofAppVersionPatch : AbstractVersionSpoofPatch(
override fun execute(context: ResourceContext): PatchResult { "$MISC_PATH/VersionOverridePatch;->getVersionOverride(Ljava/lang/String;)Ljava/lang/String;"
) {
GeneralVersionSpoofPatch.injectSpoof("$MISC_PATH/VersionOverridePatch;->getVersionOverride(Ljava/lang/String;)Ljava/lang/String;") override fun execute(context: BytecodeContext): PatchResult {
super.execute(context)
/** /**
* Copy arrays * Copy arrays
*/ */
context.copyXmlNode("youtube/spoofappversion/host", "values/arrays.xml", "resources") contexts.copyXmlNode("youtube/spoofappversion/host", "values/arrays.xml", "resources")
/** /**
* Add settings * Add settings