feat(litho-filter): change to abstract patch

This commit is contained in:
inotia00
2023-06-20 14:39:35 +09:00
parent e83fa54c87
commit 5b476eca33
32 changed files with 329 additions and 552 deletions

View File

@ -1,19 +0,0 @@
package app.revanced.patches.youtube.misc.litho.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object LithoThemeFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
parameters = listOf("L"),
opcodes = listOf(
Opcode.IF_NEZ,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL, // Paint.setColor: inject point
Opcode.RETURN_VOID
),
customFingerprint = { it, _ -> it.name == "onBoundsChange" }
)

View File

@ -1,50 +0,0 @@
package app.revanced.patches.youtube.misc.litho.patch
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.annotation.YouTubeCompatibility
import app.revanced.patches.youtube.utils.playertype.patch.PlayerTypeHookPatch
@DependsOn(
[
LithoFilterPatch::class,
PlayerTypeHookPatch::class
]
)
@YouTubeCompatibility
@Version("0.0.1")
class ByteBufferFilterPatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
return PatchResultSuccess()
}
companion object{
fun inject(descriptor: String){
LithoFilterPatch.lithoMethod.addInstructionsWithLabels(
0, """
move-object/from16 v10, p3
iget-object v10, v10, ${LithoFilterPatch.objectReference}
if-eqz v10, :do_not_block
check-cast v10, ${LithoFilterPatch.bufferReference}
iget-object v10, v10, ${LithoFilterPatch.bufferReference}->b:Ljava/nio/ByteBuffer;
move-object/from16 v3, p2
invoke-static {v3, v10}, $descriptor(Ljava/lang/Object;Ljava/nio/ByteBuffer;)Z
move-result v10
if-eqz v10, :do_not_block
move-object/from16 v15, p1
invoke-static {v15}, ${LithoFilterPatch.builderMethodDescriptor}
move-result-object v0
iget-object v0, v0, ${LithoFilterPatch.emptyComponentFieldDescriptor}
return-object v0
""", ExternalLabel("do_not_block", LithoFilterPatch.lithoMethod.getInstruction(0))
)
}
}
}

View File

@ -1,116 +0,0 @@
package app.revanced.patches.youtube.misc.litho.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.annotation.YouTubeCompatibility
import app.revanced.patches.shared.fingerprints.LithoBufferFingerprint
import app.revanced.patches.shared.fingerprints.LithoFingerprint
import app.revanced.patches.shared.fingerprints.LithoObjectFingerprint
import app.revanced.patches.youtube.ads.doublebacktoclose.patch.DoubleBackToClosePatch
import app.revanced.patches.youtube.ads.swiperefresh.patch.SwipeRefreshPatch
import app.revanced.util.bytecode.BytecodeHelper.updatePatchStatus
import app.revanced.util.bytecode.getNarrowLiteralIndex
import app.revanced.util.bytecode.getStringIndex
import app.revanced.util.integrations.Constants.ADS_PATH
import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
import org.jf.dexlib2.iface.reference.FieldReference
import org.jf.dexlib2.iface.reference.Reference
import kotlin.properties.Delegates
@DependsOn(
[
DoubleBackToClosePatch::class,
SwipeRefreshPatch::class
]
)
@YouTubeCompatibility
@Version("0.0.1")
class LithoFilterPatch : BytecodePatch(
listOf(
LithoFingerprint,
LithoBufferFingerprint,
LithoObjectFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
LithoBufferFingerprint.result?.let {
val startIndex = it.scanResult.patternScanResult!!.startIndex
bufferReference = it.mutableMethod.getInstruction<ReferenceInstruction>(startIndex).reference
} ?: return LithoBufferFingerprint.toErrorResult()
LithoObjectFingerprint.result?.let {
val endIndex = it.scanResult.patternScanResult!!.endIndex
objectRegister = it.mutableMethod.getInstruction<BuilderInstruction35c>(endIndex).registerC
} ?: return LithoObjectFingerprint.toErrorResult()
LithoFingerprint.result?.let { result ->
val endIndex = result.scanResult.patternScanResult!!.endIndex
lithoMethod = result.mutableMethod
lithoMethod.apply {
val bufferIndex = getNarrowLiteralIndex(168777401)
val bufferRegister = getInstruction<OneRegisterInstruction>(bufferIndex).registerA
val targetIndex = getStringIndex("Element missing type extension") + 2
val identifierRegister = getInstruction<OneRegisterInstruction>(endIndex).registerA
builderMethodDescriptor = getInstruction<ReferenceInstruction>(targetIndex).reference
emptyComponentFieldDescriptor = getInstruction<ReferenceInstruction>(targetIndex + 2).reference
implementation!!.instructions.apply {
filter { instruction ->
val fieldReference = (instruction as? ReferenceInstruction)?.reference as? FieldReference
fieldReference?.let { it.type == "Ljava/lang/StringBuilder;" } == true
}.forEach { instruction ->
val insertIndex = indexOf(instruction)
val stringBuilderRegister = lithoMethod.getInstruction<TwoRegisterInstruction>(insertIndex).registerA
val objectIndex = lithoMethod.getStringIndex("") - 2
objectReference = lithoMethod.getInstruction<ReferenceInstruction>(objectIndex).reference
lithoMethod.addInstructionsWithLabels(
insertIndex + 1, """
move-object/from16 v$bufferRegister, p3
iget-object v$bufferRegister, v$bufferRegister, $objectReference
if-eqz v$bufferRegister, :not_an_ad
check-cast v$bufferRegister, $bufferReference
iget-object v$bufferRegister, v$bufferRegister, $bufferReference->b:Ljava/nio/ByteBuffer;
invoke-static {v$stringBuilderRegister, v$identifierRegister, v$objectRegister, v$bufferRegister}, $ADS_PATH/LithoFilterPatch;->filters(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/Object;Ljava/nio/ByteBuffer;)Z
move-result v$bufferRegister
if-eqz v$bufferRegister, :not_an_ad
move-object/from16 v$identifierRegister, p1
invoke-static {v$identifierRegister}, $builderMethodDescriptor
move-result-object v0
iget-object v0, v0, $emptyComponentFieldDescriptor
return-object v0
""", ExternalLabel("not_an_ad", lithoMethod.getInstruction(insertIndex + 1))
)
}
}
}
} ?: return LithoFingerprint.toErrorResult()
context.updatePatchStatus("ByteBuffer")
return PatchResultSuccess()
}
internal companion object {
var objectRegister by Delegates.notNull<Int>()
lateinit var lithoMethod: MutableMethod
lateinit var bufferReference: Reference
lateinit var builderMethodDescriptor: Reference
lateinit var emptyComponentFieldDescriptor: Reference
lateinit var objectReference: Reference
}
}

View File

@ -1,65 +0,0 @@
package app.revanced.patches.youtube.misc.litho.patch
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.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.annotation.YouTubeCompatibility
import app.revanced.patches.youtube.misc.litho.fingerprints.LithoThemeFingerprint
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
import org.jf.dexlib2.iface.reference.MethodReference
@Name("litho-theme-hook")
@YouTubeCompatibility
@Version("0.0.1")
class LithoThemePatch : BytecodePatch(
listOf(
LithoThemeFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
LithoThemeFingerprint.result?.mutableMethod?.let {
with (it.implementation!!.instructions) {
for (index in size - 1 downTo 0) {
val invokeInstruction = this[index] as? ReferenceInstruction ?: continue
if ((invokeInstruction.reference as MethodReference).name != "setColor") continue
insertIndex = index
insertRegister = (this[index] as Instruction35c).registerD
insertMethod = it
break
}
}
} ?: return LithoThemeFingerprint.toErrorResult()
return PatchResultSuccess()
}
companion object {
private var offset = 0
private var insertIndex: Int = 0
private var insertRegister: Int = 0
private lateinit var insertMethod: MutableMethod
fun injectCall(
methodDescriptor: String
) {
insertMethod.addInstructions(
insertIndex + offset, """
invoke-static {v$insertRegister}, $methodDescriptor
move-result v$insertRegister
"""
)
offset += 2
}
}
}