Skip to content

Commit

Permalink
feat: add capability to filter from protobuf buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
oSumAtrIX committed May 18, 2023
1 parent 67d237c commit b738b6b
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package app.revanced.patches.youtube.misc.litho.filter.fingerprints

import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode

object ProtobufBufferFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.IGET_OBJECT, // References the field required below.
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
Opcode.IF_NEZ,
Opcode.CONST_4,
Opcode.GOTO,
Opcode.CHECK_CAST, // Casts the referenced field to a specific type that stores the protobuf buffer.
Opcode.INVOKE_VIRTUAL
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.litho.filter.annotation.LithoFilterCompatibility
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ComponentContextParserFingerprint
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.EmptyComponentBuilderFingerprint
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ProtobufBufferFingerprint
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ReadComponentIdentifierFingerprint
import org.jf.dexlib2.iface.instruction.Instruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
Expand All @@ -32,7 +33,9 @@ class LithoFilterPatch : BytecodePatch(
) {
override fun execute(context: BytecodeContext): PatchResult {
ComponentContextParserFingerprint.result?.also {
arrayOf(EmptyComponentBuilderFingerprint, ReadComponentIdentifierFingerprint).forEach { fingerprint ->
arrayOf(
EmptyComponentBuilderFingerprint, ReadComponentIdentifierFingerprint, ProtobufBufferFingerprint
).forEach { fingerprint ->
if (!fingerprint.resolve(context, it.mutableMethod, it.mutableClass))
return fingerprint.toErrorResult()
}
Expand All @@ -45,26 +48,54 @@ class LithoFilterPatch : BytecodePatch(
val builderMethodDescriptor = instruction(builderMethodIndex).descriptor
val emptyComponentFieldDescriptor = instruction(emptyComponentFieldIndex).descriptor
// Register is overwritten right after it is used in this patch, therefore free to clobber.
val clobberedRegister = instruction(insertHookIndex - 1).twoRegisterA
val free = instruction<TwoRegisterInstruction>(insertHookIndex - 1).registerA
val free2 = instruction<OneRegisterInstruction>(insertHookIndex).registerA

@Suppress("UnnecessaryVariable")
// The register, this patch clobbers, is previously used for the StringBuilder,
// later on a new StringBuilder is instantiated on it.
val stringBuilderRegister = clobberedRegister
val stringBuilderRegister = free

val identifierRegister = instruction(ReadComponentIdentifierFingerprint.patternScanEndIndex).oneRegisterA
val identifierRegister =
instruction<OneRegisterInstruction>(ReadComponentIdentifierFingerprint.patternScanEndIndex).registerA

// Parameter that holds a ref to a type with a field that ref the protobuf buffer object.
val protobufParameterNumber = 3

// Get the field that stores an protobuf buffer required below.
val protobufBufferRefTypeRefFieldDescriptor =
instruction(ProtobufBufferFingerprint.patternScanStartIndex).descriptor
val protobufBufferRefTypeDescriptor =
instruction(ProtobufBufferFingerprint.patternScanEndIndex - 1).descriptor
val protobufBufferFieldDescriptor = "$protobufBufferRefTypeDescriptor->b:Ljava/nio/ByteBuffer;"

addInstructions(
insertHookIndex, // right after setting the component.pathBuilder field,
insertHookIndex, // right after setting the component.pathBuilder field.
"""
invoke-static {v$stringBuilderRegister, v$identifierRegister}, Lapp/revanced/integrations/patches/LithoFilterPatch;->filter(Ljava/lang/StringBuilder;Ljava/lang/String;)Z
move-result v$clobberedRegister
if-eqz v$clobberedRegister, :not_an_ad
move-object/from16 v$clobberedRegister, p1
invoke-static {v$clobberedRegister}, $builderMethodDescriptor
move-result-object v$clobberedRegister
iget-object v$clobberedRegister, v$clobberedRegister, $emptyComponentFieldDescriptor
return-object v$clobberedRegister
# Get the protobuf buffer object.
move-object/from16 v$free2, p$protobufParameterNumber
iget-object v$free2, v$free2, $protobufBufferRefTypeRefFieldDescriptor
check-cast v$free2, $protobufBufferRefTypeDescriptor
# Register "free" now holds the protobuf buffer object
iget-object v$free2, v$free2, $protobufBufferFieldDescriptor
# Invoke the filter method.
invoke-static { v$stringBuilderRegister, v$identifierRegister, v$free2 }, $FILTER_METHOD_DESCRIPTOR
move-result v$free
if-eqz v$free, :not_an_ad
# If the filter method returned true, then return a replacement empty component.
move-object/from16 v$free, p1
invoke-static {v$free}, $builderMethodDescriptor
move-result-object v$free
iget-object v$free, v$free, $emptyComponentFieldDescriptor
return-object v$free
""",
listOf(ExternalLabel("not_an_ad", instruction(insertHookIndex)))
)
Expand All @@ -75,16 +106,20 @@ class LithoFilterPatch : BytecodePatch(
}

private companion object {
private val MethodFingerprint.patternScanResult
get() = result!!.scanResult.patternScanResult!!

val MethodFingerprint.patternScanEndIndex
get() = result!!.scanResult.patternScanResult!!.endIndex
get() = patternScanResult.endIndex

val MethodFingerprint.patternScanStartIndex
get() = patternScanResult.startIndex

val Instruction.descriptor
get() = (this as ReferenceInstruction).reference.toString()

val Instruction.oneRegisterA
get() = (this as OneRegisterInstruction).registerA

val Instruction.twoRegisterA
get() = (this as TwoRegisterInstruction).registerA
const val FILTER_METHOD_DESCRIPTOR =
"Lapp/revanced/integrations/patches/litho/LithoFilterPatch;" +
"->filter(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/nio/ByteBuffer;)Z"
}
}

0 comments on commit b738b6b

Please sign in to comment.