fix(duolingo): fix missing StringBuilder in skip energy recharge ads
Duolingo optimized the toString() method, removing StringBuilder. Replaced findFieldFromToString with custom smali bytecode parsing.
This commit is contained in:
parent
6b06b9d132
commit
c450a795ea
1 changed files with 36 additions and 3 deletions
|
|
@ -2,7 +2,10 @@ package app.revanced.patches.duolingo.energy
|
|||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.util.findFieldFromToString
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
|
||||
@Suppress("unused")
|
||||
val skipEnergyRechargeAdsPatch = bytecodePatch(
|
||||
|
|
@ -15,8 +18,38 @@ val skipEnergyRechargeAdsPatch = bytecodePatch(
|
|||
initializeEnergyConfigFingerprint
|
||||
.match(energyConfigToStringFingerprint.classDef)
|
||||
.method.apply {
|
||||
val energyField = energyConfigToStringFingerprint.method
|
||||
.findFieldFromToString("energy=")
|
||||
val toStringMethod = energyConfigToStringFingerprint.method
|
||||
val instructions = toStringMethod.implementation!!.instructions.toList()
|
||||
|
||||
var energyField: String? = null
|
||||
|
||||
// Search for the string "energy=" and get the preceding IGET instruction.
|
||||
for (i in instructions.indices) {
|
||||
val instr = instructions[i]
|
||||
val ref = (instr as? ReferenceInstruction)?.reference
|
||||
|
||||
if (ref is StringReference && ref.string.contains("energy=")) {
|
||||
// Search backwards for the field getter (IGET)
|
||||
for (j in i downTo 0) {
|
||||
val prevInstr = instructions[j]
|
||||
if (prevInstr.opcode == Opcode.IGET) {
|
||||
val fieldRef = (prevInstr as ReferenceInstruction).reference as FieldReference
|
||||
// Construct the full valid Smali field reference: Lclass;->name:type
|
||||
energyField = "${fieldRef.definingClass}->${fieldRef.name}:${fieldRef.type}"
|
||||
break
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: The first IGET instruction is guaranteed to be the 'energy' property.
|
||||
if (energyField == null) {
|
||||
val fallbackInstr = instructions.first { it.opcode == Opcode.IGET }
|
||||
val fieldRef = (fallbackInstr as ReferenceInstruction).reference as FieldReference
|
||||
energyField = "${fieldRef.definingClass}->${fieldRef.name}:${fieldRef.type}"
|
||||
}
|
||||
|
||||
val insertIndex = initializeEnergyConfigFingerprint.patternMatch!!.startIndex
|
||||
|
||||
addInstructions(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue