Skip to content

Commit

Permalink
fix(spotify/disable-capture-restriction): make compatible with latest…
Browse files Browse the repository at this point in the history
… versions (#2095)
  • Loading branch information
timschneeb committed May 7, 2023
1 parent 5863220 commit e48f127
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,13 @@ import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.extensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.spotify.audio.annotation.DisableCaptureRestrictionCompatibility
import app.revanced.patches.spotify.audio.fingerprints.DisableCaptureRestrictionAudioDriverFingerprint
import app.revanced.patches.spotify.audio.resource.patch.DisableCaptureRestrictionResourcePatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.MethodReference

@Patch
@Name("disable-capture-restriction")
Expand All @@ -35,51 +30,16 @@ class DisableCaptureRestrictionBytecodePatch : BytecodePatch(
override fun execute(context: BytecodeContext): PatchResult {
val method = DisableCaptureRestrictionAudioDriverFingerprint.result!!.mutableMethod

var invokePosition: Int? = null
var invokeParamRegister: Int? = null

// Find INVOKE_VIRTUAL opcode with call to AudioAttributesBuilder.setAllowedCapturePolicy(I)
for ((index, instruction) in method.implementation!!.instructions.withIndex()) {
if(instruction.opcode != Opcode.INVOKE_VIRTUAL)
continue

val methodName = ((instruction as ReferenceInstruction).reference as MethodReference).name
if (methodName != "setAllowedCapturePolicy")
continue

// Store register of the integer parameter for setAllowedCapturePolicy
invokeParamRegister = (instruction as FiveRegisterInstruction).registerD
invokePosition = index

break
}

if(invokePosition == null || invokeParamRegister == null)
return PatchResultError("Cannot find setAllowedCapturePolicy method call")

// Walk back to the const/4 instruction that sets the parameter register
var matchFound = false
for (index in invokePosition downTo 0) {
val instruction = method.instruction(index)
if(instruction.opcode != Opcode.CONST_4)
continue

val register = (instruction as OneRegisterInstruction).registerA
if(register != invokeParamRegister)
continue

// Replace parameter value
method.replaceInstruction(
index, "const/4 v$register, $ALLOW_CAPTURE_BY_ALL"
method.apply {
// Replace constant
val original = instruction(0) as OneRegisterInstruction
replaceInstruction(
0,
"const/4 v${original.registerA}, $ALLOW_CAPTURE_BY_ALL"
)
matchFound = true
break
}

return if (matchFound)
PatchResultSuccess()
else
PatchResultError("Const instruction not found")
return PatchResultSuccess()
}

private companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
package app.revanced.patches.spotify.audio.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
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.MethodReference

object DisableCaptureRestrictionAudioDriverFingerprint : MethodFingerprint(
"L",
AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.SYNTHETIC or AccessFlags.BRIDGE,
listOf("L"),
listOf(
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.RETURN_OBJECT
),
customFingerprint = { methodDef ->
methodDef.definingClass == "Lcom/spotify/playback/playbacknative/AudioDriver;" && methodDef.name == "constructAudioAttributes"
// Check for method call to AudioAttributes$Builder.setAllowedCapturePolicy Android API
methodDef.implementation?.instructions?.any {
((it as? ReferenceInstruction)?.reference as? MethodReference)?.name == "setAllowedCapturePolicy"
} == true
}
)

0 comments on commit e48f127

Please sign in to comment.