refactor: Modernize APIs

This commit is contained in:
Ushie 2026-01-22 07:08:20 +03:00
parent 29699557aa
commit 69aa683901
166 changed files with 969 additions and 885 deletions

View file

@ -11,7 +11,7 @@ val deepLinkingPatch = bytecodePatch(
compatibleWith("com.amazon.mShop.android.shopping")
apply {
deepLinkingFingerprint.method.addInstructions(
deepLinkingMethod.addInstructions(
0,
"""
const/4 v0, 0x1

View file

@ -1,11 +1,17 @@
package app.revanced.patches.amazon
import app.revanced.patcher.fingerprint
import app.revanced.patcher.accessFlags
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.parameterTypes
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
import com.android.tools.smali.dexlib2.AccessFlags
internal val deepLinkingFingerprint = fingerprint {
internal val BytecodePatchContext.deepLinkingMethod by gettingFirstMutableMethodDeclaratively(
"https://www.",
"android.intent.action.VIEW"
) {
accessFlags(AccessFlags.PRIVATE)
returns("Z")
parameters("L")
strings("https://www.", "android.intent.action.VIEW")
returnType("Z")
parameterTypes("L")
}

View file

@ -1,6 +1,9 @@
package app.revanced.patches.angulus.ads
import app.revanced.patcher.fingerprint
import app.revanced.patcher.accessFlags
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
import com.android.tools.smali.dexlib2.AccessFlags
// Keywords to search for in case the method name changes:
@ -11,8 +14,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
// This fingerprint targets a method that returns the daily measurement count.
// This method is used to determine if the user has reached the daily limit of measurements.
internal val getDailyMeasurementCountFingerprint = fingerprint {
internal val BytecodePatchContext.getDailyMeasurementCountMethod by gettingFirstMutableMethodDeclaratively("dailyMeasurementCount") {
accessFlags(AccessFlags.PRIVATE)
returns("I")
strings("dailyMeasurementCount")
returnType("I")
}

View file

@ -12,6 +12,6 @@ val angulusPatch = bytecodePatch(name = "Hide ads") {
apply {
// Always return 0 as the daily measurement count.
getDailyMeasurementCountFingerprint.method.returnEarly(0)
getDailyMeasurementCountMethod.returnEarly(0)
}
}

View file

@ -1,7 +1,9 @@
package app.revanced.patches.bandcamp.limitations
import app.revanced.patcher.fingerprint
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.patch.BytecodePatchContext
internal val handlePlaybackLimitsFingerprint = fingerprint {
strings("track_id", "play_count")
}
internal val BytecodePatchContext.handlePlaybackLimitsMethod by gettingFirstMutableMethodDeclaratively(
"track_id",
"play_count"
)

View file

@ -11,6 +11,6 @@ val removePlayLimitsPatch = bytecodePatch(
compatibleWith("com.bandcamp.android")
apply {
handlePlaybackLimitsFingerprint.method.returnEarly()
handlePlaybackLimitsMethod.returnEarly()
}
}

View file

@ -11,6 +11,6 @@ val bypassRootChecksPatch = bytecodePatch(
compatibleWith("it.ipzs.cieid")
apply {
checkRootFingerprint.method.addInstruction(1, "return-void")
checkRootMethod.addInstruction(1, "return-void")
}
}

View file

@ -1,9 +1,11 @@
package app.revanced.patches.cieid.restrictions.root
import app.revanced.patcher.fingerprint
import app.revanced.patcher.definingClass
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.name
import app.revanced.patcher.patch.BytecodePatchContext
internal val checkRootFingerprint = fingerprint {
custom { method, _ ->
method.name == "onResume" && method.definingClass == "Lit/ipzs/cieid/BaseActivity;"
}
internal val BytecodePatchContext.checkRootMethod by gettingFirstMutableMethodDeclaratively {
name("onResume")
definingClass("Lit/ipzs/cieid/BaseActivity;")
}

View file

@ -1,28 +1,26 @@
package app.revanced.patches.com.sbs.ondemand.tv
import app.revanced.patcher.fingerprint
import app.revanced.patcher.definingClass
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.name
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
internal val shouldShowAdvertisingTVFingerprint = fingerprint {
returns("Z")
custom { method, classDef ->
method.name == "getShouldShowAdvertisingTV" &&
classDef.type == "Lcom/sbs/ondemand/common/InMemoryStorage;"
}
internal val BytecodePatchContext.shouldShowAdvertisingTVMethod by gettingFirstMutableMethodDeclaratively {
name("getShouldShowAdvertisingTV")
definingClass("Lcom/sbs/ondemand/common/InMemoryStorage;")
returnType("Z")
}
internal val shouldShowPauseAdFingerprint = fingerprint {
returns("Z")
custom { method, classDef ->
method.name == "shouldShowPauseAd" &&
classDef.type == "Lcom/sbs/ondemand/player/viewmodels/PauseAdController;"
}
}
internal val requestAdStreamFingerprint = fingerprint {
returns("V")
custom { method, classDef ->
method.name == "requestAdStream\$player_googleStoreTvRelease" &&
classDef.type == "Lcom/sbs/ondemand/player/viewmodels/AdsController;"
}
internal val BytecodePatchContext.shouldShowPauseAdMethod by gettingFirstMutableMethodDeclaratively {
name("shouldShowPauseAd")
definingClass("Lcom/sbs/ondemand/player/viewmodels/PauseAdController;")
returnType("Z")
}
internal val BytecodePatchContext.requestAdStreamMethod by gettingFirstMutableMethodDeclaratively {
name("requestAdStream\$player_googleStoreTvRelease")
definingClass("Lcom/sbs/ondemand/player/viewmodels/AdsController;")
returnType("V")
}

View file

@ -15,8 +15,8 @@ val removeAdsPatch = bytecodePatch(
dependsOn(disableLicenseCheckPatch)
apply {
shouldShowAdvertisingTVFingerprint.method.returnEarly(true)
shouldShowPauseAdFingerprint.method.returnEarly(false)
shouldShowAdvertisingTVMethod.returnEarly(true)
shouldShowPauseAdMethod.returnEarly(false)
// Remove on-demand pre-roll advertisements using exception handling.
// Exception handling is used instead of returnEarly() because:
@ -24,7 +24,7 @@ val removeAdsPatch = bytecodePatch(
// 2. SBS app has built-in exception handling in handleProviderFailure().
// 3. Exception triggers fallbackToAkamaiProvider() which loads actual content.
// 4. This preserves the intended app flow: first try ads, then fail gracefully, then load content.
requestAdStreamFingerprint.method.addInstructions(
requestAdStreamMethod.addInstructions(
0,
"""
new-instance v0, Ljava/lang/RuntimeException;

View file

@ -23,11 +23,11 @@ val disableAdsPatch = bytecodePatch (
dependsOn(sharedExtensionPatch)
apply {
userStateSwitchFingerprint.method.returnEarly(true)
userStateSwitchMethod.returnEarly(true)
// Remove region-specific Cricbuzz11 elements.
cb11ConstructorFingerprint.method.addInstruction(0, "const/4 p7, 0x0")
getBottomBarFingerprint.method.apply {
cb11ConstructorMethod.addInstruction(0, "const/4 p7, 0x0")
getBottomBarMethod.apply {
val getIndex = indexOfFirstInstructionOrThrow() {
opcode == Opcode.IGET_OBJECT && getReference<FieldReference>()?.name == "bottomBar"
}

View file

@ -1,15 +1,16 @@
package app.revanced.patches.cricbuzz.ads
import app.revanced.patcher.fingerprint
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
internal val userStateSwitchFingerprint = fingerprint {
internal val BytecodePatchContext.userStateSwitchMethod by gettingFirstMutableMethodDeclaratively("key.user.state", "NA") {
opcodes(Opcode.SPARSE_SWITCH)
strings("key.user.state", "NA")
}
internal val cb11ConstructorFingerprint = fingerprint {
parameters(
}
internal val BytecodePatchContext.cb11ConstructorMethod by gettingFirstMutableMethodDeclaratively {
definingClass("CB11Details;"::endsWith)
parameterTypes(
"Ljava/lang/String;",
"Ljava/lang/String;",
"Ljava/lang/String;",
@ -21,13 +22,8 @@ internal val cb11ConstructorFingerprint = fingerprint {
"Ljava/lang/String;",
"L"
)
custom { _, classDef ->
classDef.endsWith("CB11Details;")
}
}
internal val getBottomBarFingerprint = fingerprint {
custom { method, classDef ->
method.name == "getBottomBar" && classDef.endsWith("HomeMenu;")
}
internal val BytecodePatchContext.getBottomBarMethod by gettingFirstMutableMethodDeclaratively {
name("getBottombar")
definingClass("HomeMenu;"::endsWith)
}

View file

@ -1,7 +1,8 @@
package app.revanced.patches.crunchyroll.ads
import app.revanced.patcher.fingerprint
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.patch.BytecodePatchContext
internal val videoUrlReadyToStringFingerprint = fingerprint {
strings("VideoUrlReady(url=", ", enableAds=")
}
internal val BytecodePatchContext.videoUrlReadyToStringMethod by gettingFirstMutableMethodDeclaratively(
"VideoUrlReady(url=", ", enableAds="
)

View file

@ -1,5 +1,6 @@
package app.revanced.patches.crunchyroll.ads
import app.revanced.patcher.classDef
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.getInstruction
import app.revanced.patcher.extensions.instructions
@ -20,19 +21,19 @@ val hideAdsPatch = bytecodePatch(
apply {
// Get obfuscated "enableAds" field from toString method.
val enableAdsField = videoUrlReadyToStringFingerprint.let {
val strIndex = videoUrlReadyToStringFingerprint.stringMatches.last().index
val fieldIndex = it.method.indexOfFirstInstruction(strIndex, Opcode.IGET_BOOLEAN)
it.method.getInstruction<ReferenceInstruction>(fieldIndex).getReference<FieldReference>()!!
val enableAdsField = videoUrlReadyToStringMethod.let {
val strIndex = videoUrlReadyToStringMethod.stringMatches.last().index // TODO
val fieldIndex = it.indexOfFirstInstruction(strIndex, Opcode.IGET_BOOLEAN)
it.getInstruction<ReferenceInstruction>(fieldIndex).getReference<FieldReference>()!!
}
// Remove final access flag on field.
videoUrlReadyToStringFingerprint.classDef.fields
videoUrlReadyToStringMethod.classDef.fields
.first { it.name == enableAdsField.name }
.removeFlags(AccessFlags.FINAL)
// Override enableAds field in non-default constructor.
val constructor = videoUrlReadyToStringFingerprint.classDef.methods.first {
val constructor = videoUrlReadyToStringMethod.classDef.methods.first {
AccessFlags.CONSTRUCTOR.isSet(it.accessFlags) && it.parameters.isNotEmpty()
}
constructor.addInstructions(

View file

@ -1,19 +1,21 @@
package app.revanced.patches.disneyplus
import app.revanced.patcher.fingerprint
import app.revanced.patcher.definingClass
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.name
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
internal val insertionGetPointsFingerprint = fingerprint {
returns("Ljava/util/List")
custom { method, _ ->
method.name == "getPoints" &&
method.definingClass == "Lcom/dss/sdk/internal/media/Insertion;"
}
internal val BytecodePatchContext.insertionGetPointsMethod by gettingFirstMutableMethodDeclaratively {
name("getPoints")
definingClass("Lcom/dss/sdk/internal/media/Insertion;")
returnType("Ljava/util/List")
}
internal val insertionGetRangesFingerprint = fingerprint {
returns("Ljava/util/List")
custom { method, _ ->
method.name == "getRanges" &&
method.definingClass == "Lcom/dss/sdk/internal/media/Insertion;"
}
internal val BytecodePatchContext.insertionGetRangesMethod by gettingFirstMutableMethodDeclaratively {
name("getRanges")
definingClass("Lcom/dss/sdk/internal/media/Insertion;")
returnType("Ljava/util/List")
}

View file

@ -11,8 +11,8 @@ val skipAdsPatch = bytecodePatch(
compatibleWith("com.disney.disneyplus")
apply {
arrayOf(insertionGetPointsFingerprint, insertionGetRangesFingerprint).forEach {
it.method.addInstructions(
arrayOf(insertionGetPointsMethod, insertionGetRangesMethod).forEach {
it.addInstructions(
0,
"""
new-instance v0, Ljava/util/ArrayList;

View file

@ -1,5 +1,6 @@
package app.revanced.patches.duolingo.ad
import app.revanced.patcher.classDef
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
@ -20,10 +21,10 @@ val disableAdsPatch = bytecodePatch(
// SharedPreferences has a debug boolean value with key "disable_ads", which maps to "DebugCategory.DISABLE_ADS".
//
// MonetizationDebugSettings seems to be the most general setting to work fine.
initializeMonetizationDebugSettingsFingerprint.match(
monetizationDebugSettingsToStringFingerprint.classDef
initializeMonetizationDebugSettingsMethod.match( // TODO
monetizationDebugSettingsToStringMethod.classDef
).method.apply {
val insertIndex = initializeMonetizationDebugSettingsFingerprint.instructionMatches.first().index
val insertIndex = initializeMonetizationDebugSettingsMethod.instructionMatches.first().index
val register = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
addInstructions(

View file

@ -1,17 +1,19 @@
package app.revanced.patches.duolingo.ad
import app.revanced.patcher.fingerprint
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal val initializeMonetizationDebugSettingsFingerprint = fingerprint {
internal val BytecodePatchContext.initializeMonetizationDebugSettingsMethod by gettingFirstMutableMethodDeclaratively {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
returns("V")
returnType("V")
// Parameters have not been reliable for fingerprinting between versions.
opcodes(Opcode.IPUT_BOOLEAN)
}
internal val monetizationDebugSettingsToStringFingerprint = fingerprint {
strings("MonetizationDebugSettings(") // Partial string match.
custom { method, _ -> method.name == "toString" }
internal val BytecodePatchContext.monetizationDebugSettingsToStringMethod by gettingFirstMutableMethodDeclaratively(
"MonetizationDebugSettings(" // Partial string match.
) {
name("toString")
}

View file

@ -1,5 +1,6 @@
package app.revanced.patches.duolingo.debug
import app.revanced.patcher.classDef
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
@ -15,16 +16,16 @@ val enableDebugMenuPatch = bytecodePatch(
apply {
// It seems all categories are allowed on release. Force this on anyway.
debugCategoryAllowOnReleaseBuildsFingerprint.method.returnEarly(true)
debugCategoryAllowOnReleaseBuildsMethod.returnEarly(true)
// Change build config debug build flag.
buildConfigProviderConstructorFingerprint.match(
buildConfigProviderToStringFingerprint.classDef
buildConfigProviderConstructorMethod.match( // TODO
buildConfigProviderToStringMethod.classDef
).let {
val index = it.patternMatch.startIndex
val index = it.patternMatch.startIndex // TODO
it.method.apply {
val register = getInstruction<OneRegisterInstruction>(index).registerA
it.apply {
val register = getInstruction<OneRegisterInstruction>(index).registerA // TODO
addInstruction(
index + 1,
"const/4 v$register, 0x1"

View file

@ -1,28 +1,28 @@
package app.revanced.patches.duolingo.debug
import app.revanced.patcher.fingerprint
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal val debugCategoryAllowOnReleaseBuildsFingerprint = fingerprint {
returns("Z")
parameters()
custom { method, classDef ->
method.name == "getAllowOnReleaseBuilds" && classDef.type == "Lcom/duolingo/debug/DebugCategory;"
}
internal val BytecodePatchContext.debugCategoryAllowOnReleaseBuildsMethod by gettingFirstMutableMethodDeclaratively {
name("getAllowOnReleaseBuilds")
definingClass("Lcom/duolingo/debug/DebugCategory;")
returnType("Z")
parameterTypes()
}
internal val buildConfigProviderConstructorFingerprint = fingerprint {
internal val BytecodePatchContext.buildConfigProviderConstructorMethod by gettingFirstMutableMethodDeclaratively {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
parameters()
parameterTypes()
opcodes(Opcode.CONST_4)
}
internal val buildConfigProviderToStringFingerprint = fingerprint {
parameters()
returns("Ljava/lang/String;")
strings("BuildConfigProvider(") // Partial string match.
custom { method, _ ->
method.name == "toString"
}
internal val BytecodePatchContext.buildConfigProviderToStringMethod by gettingFirstMutableMethodDeclaratively(
"BuildConfigProvider(" // Partial string match.
) {
name("toString")
parameterTypes()
returnType("Ljava/lang/String;")
}

View file

@ -1,21 +1,23 @@
package app.revanced.patches.duolingo.energy
import app.revanced.patcher.fingerprint
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
/**
* Matches the class found in [energyConfigToStringFingerprint].
* Matches the class found in [initializeEnergyConfigMethod].
*/
internal val initializeEnergyConfigFingerprint = fingerprint {
internal val BytecodePatchContext.initializeEnergyConfigMethod by gettingFirstMutableMethodDeclaratively {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
opcodes(Opcode.RETURN_VOID)
}
// Class name currently is not obfuscated but it may be in the future.
internal val energyConfigToStringFingerprint = fingerprint {
parameters()
returns("Ljava/lang/String;")
strings("EnergyConfig(", "maxEnergy=") // Partial string matches.
custom { method, _ -> method.name == "toString" }
// Class name currently is not obfuscated, but it may be in the future.
internal val BytecodePatchContext.energyConfigToStringMethod by gettingFirstMutableMethodDeclaratively(
"EnergyConfig(", "maxEnergy=" // Partial string matches.
) {
name("toString")
parameterTypes()
returnType("Ljava/lang/String;")
}

View file

@ -1,5 +1,6 @@
package app.revanced.patches.duolingo.energy
import app.revanced.patcher.classDef
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.util.findFieldFromToString
@ -12,12 +13,12 @@ val skipEnergyRechargeAdsPatch = bytecodePatch(
compatibleWith("com.duolingo")
apply {
initializeEnergyConfigFingerprint
.match(energyConfigToStringFingerprint.classDef)
initializeEnergyConfigMethod
.match(energyConfigToStringMethod.classDef) // TODO
.method.apply {
val energyField = energyConfigToStringFingerprint.method
val energyField = energyConfigToStringMethod
.findFieldFromToString("energy=")
val insertIndex = initializeEnergyConfigFingerprint.patternMatch.startIndex
val insertIndex = initializeEnergyConfigMethod.patternMatch.startIndex // TODO
addInstructions(
insertIndex,

View file

@ -1,13 +1,14 @@
package app.revanced.patches.facebook.ads.mainfeed
import app.revanced.patcher.fingerprint
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal val baseModelMapperFingerprint = fingerprint {
internal val BytecodePatchContext.baseModelMapperMethod by gettingFirstMutableMethodDeclaratively {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("Lcom/facebook/graphql/modelutil/BaseModelWithTree;")
parameters("Ljava/lang/Class", "I", "I")
returnType("Lcom/facebook/graphql/modelutil/BaseModelWithTree;")
parameterTypes("Ljava/lang/Class", "I", "I")
opcodes(
Opcode.SGET_OBJECT,
Opcode.INVOKE_STATIC,
@ -16,11 +17,11 @@ internal val baseModelMapperFingerprint = fingerprint {
Opcode.IF_EQ,
)
}
internal val getSponsoredDataModelTemplateFingerprint = fingerprint {
internal val BytecodePatchContext.getSponsoredDataModelTemplateMethod by gettingFirstMutableMethodDeclaratively {
definingClass("Lcom/facebook/graphql/model/GraphQLFBMultiAdsFeedUnit;")
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("L")
parameters()
returnType("L")
parameterTypes()
opcodes(
Opcode.CONST,
Opcode.CONST,
@ -28,14 +29,11 @@ internal val getSponsoredDataModelTemplateFingerprint = fingerprint {
Opcode.MOVE_RESULT_OBJECT,
Opcode.RETURN_OBJECT,
)
custom { _, classDef ->
classDef.type == "Lcom/facebook/graphql/model/GraphQLFBMultiAdsFeedUnit;"
}
}
internal val getStoryVisibilityFingerprint = fingerprint {
}
internal val BytecodePatchContext.getStoryVisibilityMethod by gettingFirstMutableMethodDeclaratively("This should not be called for base class object") {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("Ljava/lang/String;")
returnType("Ljava/lang/String;")
opcodes(
Opcode.INSTANCE_OF,
Opcode.IF_NEZ,
@ -45,5 +43,4 @@ internal val getStoryVisibilityFingerprint = fingerprint {
Opcode.IF_NEZ,
Opcode.CONST,
)
strings("This should not be called for base class object")
}
}

View file

@ -11,8 +11,8 @@ val bootloaderDetectionPatch = bytecodePatch(
compatibleWith("at.gv.bmf.bmf2go")
apply {
setOf(createKeyFingerprint, bootStateFingerprint).forEach { fingerprint ->
fingerprint.method.addInstructions(
setOf(createKeyMethod, bootStateMethod).forEach { fingerprint ->
fingerprint.addInstructions(
0,
"""
const/4 v0, 0x1

View file

@ -1,13 +1,17 @@
package app.revanced.patches.finanzonline.detection.bootloader
import com.android.tools.smali.dexlib2.Opcode
import app.revanced.patcher.accessFlags
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.opcodes
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.Opcode
// Located @ at.gv.bmf.bmf2go.taxequalization.tools.utils.AttestationHelper#isBootStateOk (3.0.1)
internal val bootStateFingerprint = fingerprint {
internal val BytecodePatchContext.bootStateMethod by gettingFirstMutableMethodDeclaratively {
accessFlags(AccessFlags.PUBLIC)
returns("Z")
returnType("Z")
opcodes(
Opcode.INVOKE_DIRECT,
Opcode.MOVE_RESULT_OBJECT,
@ -29,9 +33,15 @@ internal val bootStateFingerprint = fingerprint {
)
}
// Located @ at.gv.bmf.bmf2go.taxequalization.tools.utils.AttestationHelper#createKey (3.0.1)
internal val createKeyFingerprint = fingerprint {
internal val BytecodePatchContext.createKeyMethod by gettingFirstMutableMethodDeclaratively(
"attestation",
"SHA-256",
"random",
"EC",
"AndroidKeyStore"
) {
accessFlags(AccessFlags.PUBLIC)
returns("Z")
strings("attestation", "SHA-256", "random", "EC", "AndroidKeyStore")
}
returnType("Z")
}

View file

@ -1,14 +1,15 @@
package app.revanced.patches.finanzonline.detection.root
import com.android.tools.smali.dexlib2.Opcode
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.Opcode
// Located @ at.gv.bmf.bmf2go.taxequalization.tools.utils.RootDetection#isRooted (3.0.1)
internal val rootDetectionFingerprint = fingerprint {
internal val BytecodePatchContext.rootDetectionMethod by gettingFirstMutableMethodDeclaratively {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("L")
parameters("L")
returnType("L")
parameterTypes("L")
opcodes(
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,

View file

@ -10,7 +10,7 @@ val `Remove root detection` by creatingBytecodePatch(
compatibleWith("at.gv.bmf.bmf2go")
apply {
rootDetectionFingerprint.method.addInstructions(
rootDetectionMethod.addInstructions(
0,
"""
sget-object v0, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean;

View file

@ -13,8 +13,8 @@ val enableCustomTabsPatch = bytecodePatch(
compatibleWith("com.google.android.apps.magazines")
apply {
launchCustomTabFingerprint.method.apply {
val checkIndex = launchCustomTabFingerprint.instructionMatches.last().index + 1
launchCustomTabMethod.apply {
val checkIndex = launchCustomTabMethod.instructionMatches.last().index + 1 // TODO
val register = getInstruction<OneRegisterInstruction>(checkIndex).registerA
replaceInstruction(checkIndex, "const/4 v$register, 0x1")

View file

@ -1,10 +1,15 @@
package app.revanced.patches.googlenews.customtabs
import app.revanced.patcher.fingerprint
import app.revanced.patcher.accessFlags
import app.revanced.patcher.definingClass
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.opcodes
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal val launchCustomTabFingerprint = fingerprint {
internal val BytecodePatchContext.launchCustomTabMethod by gettingFirstMutableMethodDeclaratively {
definingClass("CustomTabsArticleLauncher;"::endsWith)
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
opcodes(
Opcode.IPUT_OBJECT,
@ -13,5 +18,4 @@ internal val launchCustomTabFingerprint = fingerprint {
Opcode.CONST_4,
Opcode.IPUT_BOOLEAN,
)
custom { _, classDef -> classDef.endsWith("CustomTabsArticleLauncher;") }
}

View file

@ -13,6 +13,6 @@ val enableDCIMFoldersBackupControlPatch = bytecodePatch(
compatibleWith("com.google.android.apps.photos")
apply {
isDCIMFolderBackupControlDisabled.method.returnEarly(false)
isDCIMFolderBackupControlMethod.returnEarly(false)
}
}

View file

@ -1,8 +1,9 @@
package app.revanced.patches.googlephotos.misc.backup
import app.revanced.patcher.fingerprint
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
internal val isDCIMFolderBackupControlDisabled = fingerprint {
returns("Z")
strings("/dcim", "/mars_files/")
internal val BytecodePatchContext.isDCIMFolderBackupControlMethod by gettingFirstMutableMethodDeclaratively("/dcim", "/mars_files/") {
returnType("Z")
}

View file

@ -1,7 +1,6 @@
package app.revanced.patches.googlephotos.misc.features
import app.revanced.patcher.fingerprint
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.patch.BytecodePatchContext
internal val initializeFeaturesEnumFingerprint = fingerprint {
strings("com.google.android.apps.photos.NEXUS_PRELOAD")
}
internal val BytecodePatchContext.initializeFeaturesEnumMethod by gettingFirstMutableMethodDeclaratively("com.google.android.apps.photos.NEXUS_PRELOAD")

View file

@ -60,7 +60,7 @@ val spoofFeaturesPatch = bytecodePatch(
@Suppress("NAME_SHADOWING")
val featuresToDisable = featuresToDisable!!.toSet()
initializeFeaturesEnumFingerprint.method.apply {
initializeFeaturesEnumMethod.apply {
instructions.filter { it.opcode == Opcode.CONST_STRING }.forEach {
val feature = it.getReference<StringReference>()!!.string

View file

@ -10,7 +10,7 @@ val disableAdsPatch = bytecodePatch(
compatibleWith("com.myprog.hexedit")
apply {
primaryAdsFingerprint.method.replaceInstructions(
primaryAdsMethod.replaceInstructions(
0,
"""
const/4 v0, 0x1

View file

@ -1,9 +1,11 @@
package app.revanced.patches.hexeditor.ad
import app.revanced.patcher.fingerprint
import app.revanced.patcher.definingClass
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.name
import app.revanced.patcher.patch.BytecodePatchContext
internal val primaryAdsFingerprint = fingerprint {
custom { method, classDef ->
classDef.endsWith("PreferencesHelper;") && method.name == "isAdsDisabled"
}
internal val BytecodePatchContext.primaryAdsMethod by gettingFirstMutableMethodDeclaratively {
name("isAdsDisabled")
definingClass("PreferencesHelper;"::endsWith)
}

View file

@ -1,8 +1,11 @@
package app.revanced.patches.iconpackstudio.misc.pro
import app.revanced.patcher.fingerprint
import app.revanced.patcher.definingClass
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
internal val checkProFingerprint = fingerprint {
returns("Z")
custom { _, classDef -> classDef.endsWith("IPSPurchaseRepository;") }
internal val BytecodePatchContext.checkProMethod by gettingFirstMutableMethodDeclaratively {
definingClass("IPSPurchaseRepository;"::endsWith)
returnType("Z")
}

View file

@ -10,7 +10,7 @@ val unlockProPatch = bytecodePatch(
compatibleWith("ginlemon.iconpackstudio"("2.2 build 016"))
apply {
checkProFingerprint.method.addInstructions(
checkProMethod.addInstructions(
0,
"""
const/4 v0, 0x1

View file

@ -1,22 +1,19 @@
package app.revanced.patches.idaustria.detection.deviceintegrity
import app.revanced.patcher.fingerprint
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
internal val isDeviceBootloaderOpenFingerprint = fingerprint {
internal val BytecodePatchContext.isDeviceBootloaderOpenMethod by gettingFirstMutableMethodDeclaratively {
name("isDeviceBootloaderOpen")
definingClass("/DeviceIntegrityCheckProviderImpl;"::endsWith)
accessFlags(AccessFlags.PUBLIC)
returns("Ljava/lang/Object;")
custom { method, classDef ->
method.name == "isDeviceBootloaderOpen" &&
classDef.endsWith("/DeviceIntegrityCheckProviderImpl;")
}
returnType("Ljava/lang/Object;")
}
internal val isDeviceRootedFingerprint = fingerprint {
internal val BytecodePatchContext.isDeviceRootedMethod by gettingFirstMutableMethodDeclaratively {
name("isDeviceRooted")
definingClass("/DeviceIntegrityCheckProviderImpl;"::endsWith)
accessFlags(AccessFlags.PUBLIC)
returns("Z")
custom { method, classDef ->
method.name == "isDeviceRooted" &&
classDef.endsWith("/DeviceIntegrityCheckProviderImpl;")
}
returnType("Z")
}

View file

@ -1,10 +1,9 @@
package app.revanced.patches.idaustria.detection.deviceintegrity
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.util.returnEarly
@Suppress("unused")
val removeDeviceIntegrityChecksPatch = bytecodePatch(
name = "Remove device integrity checks",
@ -13,9 +12,9 @@ val removeDeviceIntegrityChecksPatch = bytecodePatch(
compatibleWith("at.gv.oe.app")
apply {
isDeviceRootedFingerprint.method.returnEarly(false)
isDeviceRootedMethod.returnEarly(false)
isDeviceBootloaderOpenFingerprint.method.apply {
isDeviceBootloaderOpenMethod.apply {
addInstructions(
0,
"""

View file

@ -1,13 +1,13 @@
package app.revanced.patches.idaustria.detection.signature
import app.revanced.patcher.fingerprint
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
internal val spoofSignatureFingerprint = fingerprint {
internal val BytecodePatchContext.spoofSignatureMethod by gettingFirstMutableMethodDeclaratively {
name("getPubKey")
definingClass("/SL2Step1Task;"::endsWith)
accessFlags(AccessFlags.PRIVATE)
returns("L")
parameters("L")
custom { method, classDef ->
classDef.endsWith("/SL2Step1Task;") && method.name == "getPubKey"
}
returnType("L")
parameterTypes("L")
}

View file

@ -24,6 +24,6 @@ val spoofSignaturePatch = bytecodePatch(
"77ef1be61b2c01ebdabddcbf53cc4b6fd9a3c445606ee77b3758162c80ad8f8137b3c6864e92db904807dcb2be9d7717dd21" +
"bf42c121d620ddfb7914f7a95c713d9e1c1b7bdb4a03d618e40cf7e9e235c0b5687e03b7ab3,publicExponent=10001}"
spoofSignatureFingerprint.method.returnEarly(expectedSignature)
spoofSignatureMethod.returnEarly(expectedSignature)
}
}

View file

@ -1,8 +1,11 @@
package app.revanced.patches.inshorts.ad
import app.revanced.patcher.fingerprint
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
internal val inshortsAdsFingerprint = fingerprint {
returns("V")
strings("GoogleAdLoader", "exception in requestAd")
internal val BytecodePatchContext.inshortsAdsMethod by gettingFirstMutableMethodDeclaratively(
"GoogleAdLoader", "exception in requestAd"
) {
returnType("V")
}

View file

@ -10,7 +10,7 @@ val hideAdsPatch = bytecodePatch(
compatibleWith("com.nis.app")
apply {
inshortsAdsFingerprint.method.addInstruction(
inshortsAdsMethod.addInstruction(
0,
"""
return-void

View file

@ -1,7 +1,7 @@
package app.revanced.patches.instagram.ads
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.meta.ads.adInjectorFingerprint
import app.revanced.patches.meta.ads.adInjectorMethod
import app.revanced.util.returnEarly
@Suppress("unused")
@ -11,6 +11,6 @@ val hideAdsPatch = bytecodePatch(
compatibleWith("com.instagram.android")
apply {
adInjectorFingerprint.method.returnEarly(false)
adInjectorMethod.returnEarly(false)
}
}

View file

@ -1,11 +1,12 @@
package app.revanced.patches.instagram.feed
import app.revanced.patcher.fingerprint
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.patch.BytecodePatchContext
internal val mainFeedRequestClassFingerprint = fingerprint {
strings("Request{mReason=", ", mInstanceNumber=")
}
internal val BytecodePatchContext.mainFeedRequestClassMethod by gettingFirstMutableMethodDeclaratively(
"Request{mReason=", ", mInstanceNumber="
)
internal val mainFeedHeaderMapFinderFingerprint = fingerprint {
strings("pagination_source", "FEED_REQUEST_SENT")
}
internal val BytecodePatchContext.mainFeedHeaderMapFinderMethod by gettingFirstMutableMethodDeclaratively(
"pagination_source", "FEED_REQUEST_SENT"
)

View file

@ -1,5 +1,6 @@
package app.revanced.patches.instagram.feed
import app.revanced.patcher.classDef
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.getInstruction
import app.revanced.patcher.fingerprint
@ -30,11 +31,11 @@ val limitFeedToFollowedProfiles = bytecodePatch(
*/
val mainFeedRequestHeaderFieldName: String
with(mainFeedHeaderMapFinderFingerprint.method) {
with(mainFeedHeaderMapFinderMethod) {
mainFeedRequestHeaderFieldName = indexOfFirstInstructionOrThrow {
getReference<FieldReference>().let { ref ->
ref?.type == "Ljava/util/Map;" &&
ref.definingClass == mainFeedRequestClassFingerprint.classDef.toString()
ref.definingClass == mainFeedRequestClassMethod.classDef.toString()
}
}.let { instructionIndex ->
@ -45,7 +46,7 @@ val limitFeedToFollowedProfiles = bytecodePatch(
val initMainFeedRequestFingerprint = fingerprint {
custom { method, classDef ->
method.name == "<init>" &&
classDef == mainFeedRequestClassFingerprint.classDef
classDef == mainFeedRequestClassMethod.classDef
}
}
initMainFeedRequestFingerprint.method.apply {

View file

@ -18,6 +18,6 @@ val anonymousStoryViewingPatch = bytecodePatch(
apply {
// Prevent the hashmap of the seen media to be filled
setMediaSeenHashmapFingerprint.method.returnEarly()
setMediaSeenHashmapMethod.returnEarly()
}
}

View file

@ -1,9 +1,11 @@
package app.revanced.patches.instagram.ghost.story
import app.revanced.patcher.fingerprint
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.parameterTypes
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
internal val setMediaSeenHashmapFingerprint = fingerprint {
parameters()
returns("V")
strings("media/seen/")
internal val BytecodePatchContext.setMediaSeenHashmapMethod by gettingFirstMutableMethodDeclaratively("media/seen/") {
parameterTypes()
returnType("V")
}

View file

@ -1,9 +1,14 @@
package app.revanced.patches.instagram.misc.links
import app.revanced.patcher.fingerprint
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
internal const val TARGET_STRING = "Tracking.ARG_CLICK_SOURCE"
internal val inAppBrowserFunctionFingerprint = fingerprint {
returns("Z")
strings("TrackingInfo.ARG_MODULE_NAME", TARGET_STRING)
internal val BytecodePatchContext.inAppBrowserFunctionMethod by gettingFirstMutableMethodDeclaratively(
"TrackingInfo.ARG_MODULE_NAME",
TARGET_STRING
) {
returnType("Z")
}

View file

@ -1,5 +1,6 @@
package app.revanced.patches.instagram.reels
import app.revanced.patcher.classDef
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.util.returnEarly
@ -14,12 +15,12 @@ val disableReelsScrollingPatch = bytecodePatch(
compatibleWith("com.instagram.android")
apply {
val viewPagerField = clipsViewPagerImplGetViewAtIndexFingerprint.classDef.fields.first {
val viewPagerField = clipsViewPagerImplGetViewAtIndexMethod.classDef.fields.first {
it.type == "Landroidx/viewpager2/widget/ViewPager2;"
}
// Disable user input on the ViewPager2 to prevent scrolling.
clipsViewPagerImplGetViewAtIndexFingerprint.method.addInstructions(
clipsViewPagerImplGetViewAtIndexMethod.addInstructions(
0,
"""
iget-object v0, p0, $viewPagerField
@ -29,6 +30,6 @@ val disableReelsScrollingPatch = bytecodePatch(
)
// Return false in onInterceptTouchEvent to disable pull-to-refresh.
clipsSwipeRefreshLayoutOnInterceptTouchEventFingerprint.method.returnEarly(false)
clipsSwipeRefreshLayoutOnInterceptTouchEventMethod.returnEarly(false)
}
}

View file

@ -1,13 +1,14 @@
package app.revanced.patches.instagram.reels
import app.revanced.patcher.fingerprint
import app.revanced.patcher.definingClass
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.parameterTypes
import app.revanced.patcher.patch.BytecodePatchContext
internal val clipsViewPagerImplGetViewAtIndexFingerprint = fingerprint {
strings("ClipsViewPagerImpl_getViewAtIndex")
}
internal val clipsSwipeRefreshLayoutOnInterceptTouchEventFingerprint = fingerprint {
parameters("Landroid/view/MotionEvent;")
custom { _, classDef -> classDef.type == "Linstagram/features/clips/viewer/ui/ClipsSwipeRefreshLayout;" }
internal val BytecodePatchContext.clipsViewPagerImplGetViewAtIndexMethod by gettingFirstMutableMethodDeclaratively("ClipsViewPagerImpl_getViewAtIndex")
internal val BytecodePatchContext.clipsSwipeRefreshLayoutOnInterceptTouchEventMethod by gettingFirstMutableMethodDeclaratively {
parameterTypes("Landroid/view/MotionEvent;")
definingClass("Linstagram/features/clips/viewer/ui/ClipsSwipeRefreshLayout;")
}

View file

@ -12,6 +12,6 @@ val disableStoryAutoFlippingPatch = bytecodePatch(
compatibleWith("com.instagram.android")
apply {
onStoryTimeoutActionFingerprint.method.returnEarly()
onStoryTimeoutActionMethod.returnEarly()
}
}

View file

@ -1,12 +1,13 @@
package app.revanced.patches.instagram.story.flipping
import app.revanced.patcher.fingerprint
import app.revanced.patcher.definingClass
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.parameterTypes
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
internal val onStoryTimeoutActionFingerprint = fingerprint {
parameters("Ljava/lang/Object;")
returns("V")
strings("userSession")
custom { _, classDef ->
classDef.type == "Linstagram/features/stories/fragment/ReelViewerFragment;"
}
internal val BytecodePatchContext.onStoryTimeoutActionMethod by gettingFirstMutableMethodDeclaratively("userSession") {
parameterTypes("Ljava/lang/Object;")
returnType("V")
definingClass("Linstagram/features/stories/fragment/ReelViewerFragment;")
}

View file

@ -1,10 +1,12 @@
package app.revanced.patches.irplus.ad
import app.revanced.patcher.accessFlags
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.parameterTypes
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.fingerprint
internal val irplusAdsFingerprint = fingerprint {
internal val BytecodePatchContext.irplusAdsMethod by gettingFirstMutableMethodDeclaratively("TAGGED") {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
parameters("L", "Z")
strings("TAGGED")
parameterTypes("L", "Z")
}

View file

@ -12,6 +12,6 @@ val removeAdsPatch = bytecodePatch(
apply {
// By overwriting the second parameter of the method,
// the view which holds the advertisement is removed.
irplusAdsFingerprint.method.addInstruction(0, "const/4 p2, 0x0")
irplusAdsMethod.addInstruction(0, "const/4 p2, 0x0")
}
}

View file

@ -1,29 +1,29 @@
package app.revanced.patches.letterboxd.ads
import app.revanced.patcher.fingerprint
import app.revanced.patcher.definingClass
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.name
import app.revanced.patcher.patch.BytecodePatchContext
internal const val admobHelperClassName = "Lcom/letterboxd/letterboxd/helpers/AdmobHelper;"
internal val admobHelperSetShowAdsFingerprint = fingerprint {
custom { method, classDef ->
method.name == "setShowAds" && classDef.type == admobHelperClassName
}
internal val BytecodePatchContext.admobHelperSetShowAdsMethod by gettingFirstMutableMethodDeclaratively {
name("setShowAds")
definingClass(admobHelperClassName)
}
internal val admobHelperShouldShowAdsFingerprint = fingerprint {
custom { method, classDef ->
method.name == "shouldShowAds" && classDef.type == admobHelperClassName
}
internal val BytecodePatchContext.admobHelperShouldShowAdsMethod by gettingFirstMutableMethodDeclaratively {
name("shouldShowAds")
definingClass(admobHelperClassName)
}
internal val filmFragmentShowAdsFingerprint = fingerprint {
custom { method, classDef ->
method.name == "showAds" && classDef.type.endsWith("/FilmFragment;")
}
internal val BytecodePatchContext.filmFragmentShowAdsMethod by gettingFirstMutableMethodDeclaratively {
name("showAds")
definingClass("/FilmFragment;"::endsWith)
}
internal val memberExtensionShowAdsFingerprint = fingerprint {
custom { method, classDef ->
method.name == "showAds" && classDef.type.endsWith("/AMemberExtensionKt;")
}
}
internal val BytecodePatchContext.memberExtensionShowAdsMethod by gettingFirstMutableMethodDeclaratively {
name("showAds")
definingClass("/AMemberExtensionKt;"::endsWith)
}

View file

@ -1,7 +1,6 @@
package app.revanced.patches.letterboxd.ads
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.util.returnEarly
@ -12,9 +11,9 @@ val hideAdsPatch = bytecodePatch(
compatibleWith("com.letterboxd.letterboxd")
apply {
admobHelperSetShowAdsFingerprint.method.addInstruction(0, "const p1, 0x0")
listOf(admobHelperShouldShowAdsFingerprint, filmFragmentShowAdsFingerprint, memberExtensionShowAdsFingerprint).forEach {
it.method.returnEarly(false)
admobHelperSetShowAdsMethod.addInstruction(0, "const p1, 0x0")
listOf(admobHelperShouldShowAdsMethod, filmFragmentShowAdsMethod, memberExtensionShowAdsMethod).forEach {
it.returnEarly(false)
}
}
}

View file

@ -1,9 +1,11 @@
package app.revanced.patches.letterboxd.unlock.unlockAppIcons
import app.revanced.patcher.fingerprint
import app.revanced.patcher.definingClass
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.name
import app.revanced.patcher.patch.BytecodePatchContext
internal val getCanChangeAppIconFingerprint = fingerprint {
custom { method, classDef ->
method.name == "getCanChangeAppIcon" && classDef.type.endsWith("SettingsAppIconFragment;")
}
internal val BytecodePatchContext.getCanChangeAppIconMethod by gettingFirstMutableMethodDeclaratively {
name("getCanChangeAppIcon")
definingClass("SettingsAppIconFragment;"::endsWith)
}

View file

@ -10,6 +10,6 @@ val unlockAppIconsPatch = bytecodePatch(
compatibleWith("com.letterboxd.letterboxd")
apply {
getCanChangeAppIconFingerprint.method.returnEarly(true)
getCanChangeAppIconMethod.returnEarly(true)
}
}

View file

@ -1,8 +1,7 @@
package app.revanced.patches.lightroom.misc.version
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.bytecodePatch
import com.android.tools.smali.dexlib2.Opcode
import app.revanced.patches.lightroom.misc.bypassVersionCheck.refreshRemoteConfigurationMethod
@Suppress("unused")
val disableVersionCheckPatch = bytecodePatch(
@ -12,8 +11,8 @@ val disableVersionCheckPatch = bytecodePatch(
compatibleWith("com.adobe.lrmobile"("9.3.0"))
apply {
refreshRemoteConfigurationFingerprint.method.apply {
val igetIndex = refreshRemoteConfigurationFingerprint.patternMatch!!.endIndex
refreshRemoteConfigurationMethod.apply {
val igetIndex = refreshRemoteConfigurationMethod.patternMatch!!.endIndex // TODO
// This value represents the server command to clear all version restrictions.
val statusForceReset = "-0x2";

View file

@ -1,15 +1,17 @@
package app.revanced.patches.lightroom.misc.version
package app.revanced.patches.lightroom.misc.bypassVersionCheck
import app.revanced.patcher.fingerprint
import app.revanced.patcher.accessFlags
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.opcodes
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal val refreshRemoteConfigurationFingerprint = fingerprint {
internal val BytecodePatchContext.refreshRemoteConfigurationMethod by gettingFirstMutableMethodDeclaratively(
"com.adobe.lrmobile.denylisted_version_set_key",
"com.adobe.lrmobile.app_min_version_key"
) {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
strings(
"com.adobe.lrmobile.denylisted_version_set_key",
"com.adobe.lrmobile.app_min_version_key"
)
opcodes(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,

View file

@ -10,7 +10,7 @@ val disableMandatoryLoginPatch = bytecodePatch(
compatibleWith("com.adobe.lrmobile"("9.3.0"))
apply {
isLoggedInFingerprint.method.apply {
isLoggedInMethod.apply {
val index = implementation!!.instructions.lastIndex - 1
// Set isLoggedIn = true.
replaceInstruction(index, "const/4 v0, 0x1")

View file

@ -1,12 +1,16 @@
package app.revanced.patches.lightroom.misc.login
import com.android.tools.smali.dexlib2.Opcode
import app.revanced.patcher.accessFlags
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.opcodes
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.Opcode
internal val isLoggedInFingerprint = fingerprint {
internal val BytecodePatchContext.isLoggedInMethod by gettingFirstMutableMethodDeclaratively {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC, AccessFlags.FINAL)
returns("Z")
returnType("Z")
opcodes(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,

View file

@ -1,17 +1,20 @@
package app.revanced.patches.lightroom.misc.premium
import com.android.tools.smali.dexlib2.Opcode
import app.revanced.patcher.accessFlags
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.opcodes
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.Opcode
internal val hasPurchasedFingerprint = fingerprint {
internal val BytecodePatchContext.hasPurchasedMethod by gettingFirstMutableMethodDeclaratively("isPurchaseDoneRecently = true, access platform profile present? = ") {
accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL)
returns("Z")
returnType("Z")
opcodes(
Opcode.SGET_OBJECT,
Opcode.CONST_4,
Opcode.CONST_4,
Opcode.CONST_4,
)
strings("isPurchaseDoneRecently = true, access platform profile present? = ")
}

View file

@ -11,6 +11,6 @@ val unlockPremiumPatch = bytecodePatch(
apply {
// Set hasPremium = true.
hasPurchasedFingerprint.method.replaceInstruction(2, "const/4 v2, 0x1")
hasPurchasedMethod.replaceInstruction(2, "const/4 v2, 0x1")
}
}

View file

@ -1,13 +1,14 @@
package app.revanced.patches.memegenerator.detection.license
import com.android.tools.smali.dexlib2.Opcode
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.Opcode
internal val licenseValidationFingerprint = fingerprint {
internal val BytecodePatchContext.licenseValidationMethod by gettingFirstMutableMethodDeclaratively {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("Z")
parameters("Landroid/content/Context;")
returnType("Z")
parameterTypes("Landroid/content/Context;")
opcodes(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_WIDE,

View file

@ -8,7 +8,7 @@ val licenseValidationPatch = bytecodePatch(
) {
apply {
licenseValidationFingerprint.method.replaceInstructions(
licenseValidationMethod.replaceInstructions(
0,
"""
const/4 p0, 0x1

View file

@ -1,13 +1,14 @@
package app.revanced.patches.memegenerator.detection.signature
import com.android.tools.smali.dexlib2.Opcode
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.Opcode
internal val verifySignatureFingerprint = fingerprint {
internal val BytecodePatchContext.verifySignatureMethod by gettingFirstMutableMethodDeclaratively {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("Z")
parameters("Landroid/app/Activity;")
returnType("Z")
parameterTypes("Landroid/app/Activity;")
opcodes(
Opcode.SGET_OBJECT,
Opcode.IF_NEZ,

View file

@ -8,7 +8,7 @@ val signatureVerificationPatch = bytecodePatch(
) {
apply {
verifySignatureFingerprint.method.replaceInstructions(
verifySignatureMethod.replaceInstructions(
0,
"""
const/4 p0, 0x1

View file

@ -1,13 +1,14 @@
package app.revanced.patches.memegenerator.misc.pro
import com.android.tools.smali.dexlib2.Opcode
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.Opcode
internal val isFreeVersionFingerprint = fingerprint {
internal val BytecodePatchContext.isFreeVersionMethod by gettingFirstMutableMethodDeclaratively("free") {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("Ljava/lang/Boolean;")
parameters("Landroid/content/Context;")
returnType("Ljava/lang/Boolean;")
parameterTypes("Landroid/content/Context;")
opcodes(
Opcode.SGET,
Opcode.INVOKE_VIRTUAL,
@ -17,5 +18,4 @@ internal val isFreeVersionFingerprint = fingerprint {
Opcode.MOVE_RESULT,
Opcode.IF_EQZ
)
strings("free")
}

View file

@ -14,7 +14,7 @@ val unlockProVersionPatch = bytecodePatch(
compatibleWith("com.zombodroid.MemeGenerator"("4.6364", "4.6370", "4.6375", "4.6377"))
apply {
isFreeVersionFingerprint.method.replaceInstructions(
isFreeVersionMethod.replaceInstructions(
0,
"""
sget-object p0, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean;

View file

@ -1,35 +1,35 @@
package app.revanced.patches.messenger.inbox
import app.revanced.patcher.fingerprint
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.value.StringEncodedValue
internal val createInboxSubTabsFingerprint = fingerprint {
returns("V")
internal val BytecodePatchContext.createInboxSubTabsMethod by gettingFirstMutableMethodDeclaratively {
name("run")
returnType("V")
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
opcodes(
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID,
)
custom { method, classDef ->
method.name == "run" &&
classDef.fields.any any@{ field ->
if (field.name != "__redex_internal_original_name") return@any false
(field.initialValue as? StringEncodedValue)?.value == "InboxSubtabsItemSupplierImplementation\$onSubscribe\$1"
}
custom {
immutableClassDef.fields.any { field ->
if (field.name != "__redex_internal_original_name") return@any false
(field.initialValue as? StringEncodedValue)?.value == "InboxSubtabsItemSupplierImplementation\$onSubscribe\$1"
}
}
}
internal val loadInboxAdsFingerprint = fingerprint {
returns("V")
strings(
"ads_load_begin",
"inbox_ads_fetch_start",
internal val BytecodePatchContext.loadInboxAdsMethod by gettingFirstMutableMethodDeclaratively(
"ads_load_begin",
"inbox_ads_fetch_start"
) {
returnType("V")
definingClass(
"Lcom/facebook/messaging/business/inboxads/plugins/inboxads/itemsupplier/" +
"InboxAdsItemSupplierImplementation;"
)
custom { method, _ ->
method.definingClass == "Lcom/facebook/messaging/business/inboxads/plugins/inboxads/itemsupplier/" +
"InboxAdsItemSupplierImplementation;"
}
}

View file

@ -11,6 +11,6 @@ val hideInboxAdsPatch = bytecodePatch(
compatibleWith("com.facebook.orca")
apply {
loadInboxAdsFingerprint.method.replaceInstruction(0, "return-void")
loadInboxAdsMethod.replaceInstruction(0, "return-void")
}
}

View file

@ -11,6 +11,6 @@ val hideInboxSubtabsPatch = bytecodePatch(
compatibleWith("com.facebook.orca")
apply {
createInboxSubTabsFingerprint.method.replaceInstruction(2, "const/4 v0, 0x0")
createInboxSubTabsMethod.replaceInstruction(2, "const/4 v0, 0x0")
}
}

View file

@ -1,9 +1,11 @@
package app.revanced.patches.messenger.layout
import app.revanced.patcher.fingerprint
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.parameterTypes
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
internal val isFacebookButtonEnabledFingerprint = fingerprint {
parameters()
returns("Z")
strings("FacebookButtonTabButtonImplementation")
internal val BytecodePatchContext.isFacebookButtonEnabledMethod by gettingFirstMutableMethodDeclaratively("FacebookButtonTabButtonImplementation") {
parameterTypes()
returnType("Z")
}

View file

@ -11,6 +11,6 @@ val hideFacebookButtonPatch = bytecodePatch(
compatibleWith("com.facebook.orca")
apply {
isFacebookButtonEnabledFingerprint.method.returnEarly(false)
isFacebookButtonEnabledMethod.returnEarly(false)
}
}

View file

@ -1,25 +1,20 @@
package app.revanced.patches.messenger.metaai
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
import app.revanced.patcher.fingerprint
internal val getMobileConfigBoolFingerprint = fingerprint {
parameters("J")
returns("Z")
internal val BytecodePatchContext.getMobileConfigBoolMethod by gettingFirstMutableMethodDeclaratively {
returnType("Z")
opcodes(Opcode.RETURN)
custom { _, classDef ->
classDef.interfaces.contains("Lcom/facebook/mobileconfig/factory/MobileConfigUnsafeContext;")
}
custom { immutableClassDef.interfaces.contains("Lcom/facebook/mobileconfig/factory/MobileConfigUnsafeContext;") }
}
internal val metaAIKillSwitchCheckFingerprint = fingerprint {
internal val BytecodePatchContext.metaAIKillSwitchCheckMethod by gettingFirstMutableMethodDeclaratively("SearchAiagentImplementationsKillSwitch") {
opcodes(Opcode.CONST_WIDE)
strings("SearchAiagentImplementationsKillSwitch")
}
internal val extensionMethodFingerprint = fingerprint {
strings("REPLACED_BY_PATCH")
custom { method, classDef ->
method.name == EXTENSION_METHOD_NAME && classDef.type == EXTENSION_CLASS_DESCRIPTOR
}
}
internal val BytecodePatchContext.extensionMethodMethod by gettingFirstMutableMethodDeclaratively("REPLACED_BY_PATCH") {
name(EXTENSION_METHOD_NAME)
definingClass(EXTENSION_CLASS_DESCRIPTOR)
}

View file

@ -3,6 +3,7 @@ package app.revanced.patches.messenger.metaai
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.getInstruction
import app.revanced.patcher.extensions.replaceInstruction
import app.revanced.patcher.method
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.messenger.misc.extension.sharedExtensionPatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@ -21,8 +22,8 @@ val removeMetaAIPatch = bytecodePatch(
dependsOn(sharedExtensionPatch)
apply {
getMobileConfigBoolFingerprint.method.apply {
val returnIndex = getMobileConfigBoolFingerprint.patternMatch.startIndex
getMobileConfigBoolMethod.apply {
val returnIndex = getMobileConfigBoolMethod.patternMatch.startIndex // TODO
val returnRegister = getInstruction<OneRegisterInstruction>(returnIndex).registerA
addInstructions(
@ -35,18 +36,16 @@ val removeMetaAIPatch = bytecodePatch(
}
// Extract the common starting digits of Meta AI flag IDs from a flag found in code.
val relevantDigits = with(metaAIKillSwitchCheckFingerprint) {
method.getInstruction<WideLiteralInstruction>(patternMatch.startIndex).wideLiteral
val relevantDigits = with(metaAIKillSwitchCheckMethod) {
method.getInstruction<WideLiteralInstruction>(patternMatch.startIndex).wideLiteral // TODO
}.toString().substring(0, 7)
// Replace placeholder in the extension method.
with(extensionMethodFingerprint) {
method.replaceInstruction(
stringMatches.first().index,
"""
extensionMethodMethod.replaceInstruction(
stringM.first().index, // TODO
"""
const-string v1, "$relevantDigits"
"""
)
}
)
}
}

View file

@ -1,13 +1,16 @@
package app.revanced.patches.meta.ads
import app.revanced.patcher.fingerprint
import app.revanced.patcher.accessFlags
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.parameterTypes
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
import com.android.tools.smali.dexlib2.AccessFlags
internal val adInjectorFingerprint = fingerprint {
internal val BytecodePatchContext.adInjectorMethod by gettingFirstMutableMethodDeclaratively(
"SponsoredContentController.insertItem",
) {
accessFlags(AccessFlags.PRIVATE)
returns("Z")
parameters("L", "L")
strings(
"SponsoredContentController.insertItem",
)
returnType("Z")
parameterTypes("L", "L")
}

View file

@ -1,12 +1,14 @@
package app.revanced.patches.mifitness.misc.locale
import app.revanced.patcher.fingerprint
import app.revanced.patcher.definingClass
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.name
import app.revanced.patcher.opcodes
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
internal val syncBluetoothLanguageFingerprint = fingerprint {
internal val BytecodePatchContext.syncBluetoothLanguageMethod by gettingFirstMutableMethodDeclaratively {
name("syncBluetoothLanguage")
definingClass("Lcom/xiaomi/fitness/devicesettings/DeviceSettingsSyncer")
opcodes(Opcode.MOVE_RESULT_OBJECT)
custom { method, _ ->
method.name == "syncBluetoothLanguage" &&
method.definingClass == "Lcom/xiaomi/fitness/devicesettings/DeviceSettingsSyncer;"
}
}

View file

@ -16,8 +16,8 @@ val forceEnglishLocalePatch = bytecodePatch(
dependsOn(fixLoginPatch)
apply {
syncBluetoothLanguageFingerprint.method.apply {
val resolvePhoneLocaleInstruction = syncBluetoothLanguageFingerprint.instructionMatches.first().index
syncBluetoothLanguageMethod.apply {
val resolvePhoneLocaleInstruction = syncBluetoothLanguageMethod.instructionMatches.first().index // TODO
val registerIndexToUpdate = getInstruction<OneRegisterInstruction>(resolvePhoneLocaleInstruction).registerA
replaceInstruction(

View file

@ -1,12 +1,14 @@
package app.revanced.patches.mifitness.misc.login
import app.revanced.patcher.fingerprint
import app.revanced.patcher.accessFlags
import app.revanced.patcher.definingClass
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.parameterTypes
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
internal val xiaomiAccountManagerConstructorFingerprint = fingerprint {
internal val BytecodePatchContext.xiaomiAccountManagerConstructorMethod by gettingFirstMutableMethodDeclaratively {
accessFlags(AccessFlags.PRIVATE, AccessFlags.CONSTRUCTOR)
parameters("Landroid/content/Context;", "Z")
custom { method, _ ->
method.definingClass == "Lcom/xiaomi/passport/accountmanager/XiaomiAccountManager;"
}
parameterTypes("Landroid/content/Context;", "Z")
definingClass("Lcom/xiaomi/passport/accountmanager/XiaomiAccountManager;")
}

View file

@ -10,6 +10,6 @@ val fixLoginPatch = bytecodePatch(
compatibleWith("com.xiaomi.wearable")
apply {
xiaomiAccountManagerConstructorFingerprint.method.addInstruction(0, "const/16 p2, 0x0")
xiaomiAccountManagerConstructorMethod.addInstruction(0, "const/16 p2, 0x0")
}
}

View file

@ -1,13 +1,14 @@
package app.revanced.patches.music.interaction.permanentrepeat
import com.android.tools.smali.dexlib2.Opcode
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.Opcode
internal val repeatTrackFingerprint = fingerprint {
internal val BytecodePatchContext.repeatTrackMethod by gettingFirstMutableMethodDeclaratively("w_st") {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V")
parameters("L", "L")
returnType("V")
parameterTypes("L", "L")
opcodes(
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
@ -16,5 +17,4 @@ internal val repeatTrackFingerprint = fingerprint {
Opcode.MOVE_RESULT,
Opcode.IF_NEZ
)
strings("w_st")
}

View file

@ -1,9 +1,9 @@
package app.revanced.patches.music.interaction.permanentrepeat
import app.revanced.patcher.extensions.ExternalLabel
import app.revanced.patcher.extensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.instructions
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.extensions.ExternalLabel
import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.music.misc.extension.sharedExtensionPatch
@ -39,10 +39,10 @@ val permanentRepeatPatch = bytecodePatch(
SwitchPreference("revanced_music_play_permanent_repeat"),
)
val startIndex = repeatTrackFingerprint.instructionMatches.last().index
val startIndex = repeatTrackMethod.instructionMatches.last().index // TODO
val repeatIndex = startIndex + 1
repeatTrackFingerprint.method.apply {
repeatTrackMethod.apply {
// Start index is at a branch, but the same
// register is clobbered in both branch paths.
val freeRegister = findFreeRegister(startIndex + 1)

View file

@ -32,7 +32,7 @@ private val disableSplashAnimationPatch = bytecodePatch {
// Could replace the lottie animation file with our own custom animation (app_launch.json),
// but the animation is not always the same size as the launch screen and it's still
// barely shown. Instead turn off the animation entirely (app will also launch a little faster).
cairoSplashAnimationConfigFingerprint.method.apply {
cairoSplashAnimationConfigMethod.apply {
val literalIndex = indexOfFirstLiteralInstructionOrThrow(
getResourceId(ResourceType.LAYOUT, "main_activity_launch_animation")
)

View file

@ -1,17 +1,17 @@
package app.revanced.patches.music.layout.branding
import app.revanced.patcher.fingerprint
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patches.music.shared.YOUTUBE_MUSIC_MAIN_ACTIVITY_CLASS_TYPE
import app.revanced.patches.shared.misc.mapping.ResourceType
import app.revanced.patches.shared.misc.mapping.resourceLiteral
internal val cairoSplashAnimationConfigFingerprint = fingerprint {
returns("V")
parameters("Landroid/os/Bundle;")
internal val BytecodePatchContext.cairoSplashAnimationConfigMethod by gettingFirstMutableMethodDeclaratively {
name("onCreate")
returnType("V")
definingClass(YOUTUBE_MUSIC_MAIN_ACTIVITY_CLASS_TYPE)
parameterTypes("Landroid/os/Bundle;")
instructions(
resourceLiteral(ResourceType.LAYOUT, "main_activity_launch_animation")
)
custom { method, classDef ->
method.name == "onCreate" && method.definingClass == YOUTUBE_MUSIC_MAIN_ACTIVITY_CLASS_TYPE
}
}

View file

@ -1,24 +1,27 @@
package app.revanced.patches.music.layout.premium
import app.revanced.patcher.fingerprint
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal val hideGetPremiumFingerprint = fingerprint {
internal val BytecodePatchContext.hideGetPremiumMethod by gettingFirstMutableMethodDeclaratively(
"FEmusic_history",
"FEmusic_offline"
) {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V")
parameters()
returnType("V")
parameterTypes()
opcodes(
Opcode.IF_NEZ,
Opcode.CONST_16,
Opcode.INVOKE_VIRTUAL,
)
strings("FEmusic_history", "FEmusic_offline")
}
internal val membershipSettingsFingerprint = fingerprint {
internal val BytecodePatchContext.membershipSettingsMethod by gettingFirstMutableMethodDeclaratively {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("Ljava/lang/CharSequence;")
returnType("Ljava/lang/CharSequence;")
opcodes(
Opcode.IGET_OBJECT,
Opcode.INVOKE_INTERFACE,

View file

@ -40,8 +40,8 @@ val hideGetPremiumPatch = bytecodePatch(
SwitchPreference("revanced_music_hide_get_premium_label"),
)
hideGetPremiumFingerprint.method.apply {
val insertIndex = hideGetPremiumFingerprint.instructionMatches.last().index
hideGetPremiumMethod.apply {
val insertIndex = hideGetPremiumMethod.instructionMatches.last().index // TODO
val setVisibilityInstruction = getInstruction<FiveRegisterInstruction>(insertIndex)
val getPremiumViewRegister = setVisibilityInstruction.registerC
@ -55,11 +55,11 @@ val hideGetPremiumPatch = bytecodePatch(
addInstruction(
insertIndex + 1,
"invoke-virtual {v$getPremiumViewRegister, v$visibilityRegister}, " +
"Landroid/view/View;->setVisibility(I)V",
"Landroid/view/View;->setVisibility(I)V",
)
}
membershipSettingsFingerprint.method.addInstructionsWithLabels(
membershipSettingsMethod.addInstructionsWithLabels(
0,
"""
invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->hideGetPremiumLabel()Z

View file

@ -23,6 +23,6 @@ val bypassCertificateChecksPatch = bytecodePatch(
)
apply {
checkCertificateFingerprint.method.returnEarly(true)
checkCertificateMethod.returnEarly(true)
}
}

View file

@ -1,13 +1,14 @@
package app.revanced.patches.music.misc.androidauto
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.fingerprint
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.parameterTypes
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
internal val checkCertificateFingerprint = fingerprint {
returns("Z")
parameters("Ljava/lang/String;")
strings(
"X509",
"Failed to get certificate" // Partial String match.
)
internal val BytecodePatchContext.checkCertificateMethod by gettingFirstMutableMethodDeclaratively(
"X509",
"Failed to get certificate" // Partial String match.
) {
returnType("Z")
parameterTypes("Ljava/lang/String;")
}

View file

@ -23,11 +23,11 @@ val backgroundPlaybackPatch = bytecodePatch(
)
apply {
kidsBackgroundPlaybackPolicyControllerFingerprint.method.addInstruction(
kidsBackgroundPlaybackPolicyControllerMethod.addInstruction(
0,
"return-void",
)
backgroundPlaybackDisableFingerprint.method.returnEarly(true)
backgroundPlaybackDisableMethod.returnEarly(true)
}
}

View file

@ -1,13 +1,14 @@
package app.revanced.patches.music.misc.backgroundplayback
import com.android.tools.smali.dexlib2.Opcode
import app.revanced.patcher.*
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.Opcode
internal val backgroundPlaybackDisableFingerprint = fingerprint {
internal val BytecodePatchContext.backgroundPlaybackDisableMethod by gettingFirstMutableMethodDeclaratively {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("Z")
parameters("L")
returnType("Z")
parameterTypes("L")
opcodes(
Opcode.CONST_4,
Opcode.IF_EQZ,
@ -21,10 +22,10 @@ internal val backgroundPlaybackDisableFingerprint = fingerprint {
)
}
internal val kidsBackgroundPlaybackPolicyControllerFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("V")
parameters("I", "L", "Z")
internal val BytecodePatchContext.kidsBackgroundPlaybackPolicyControllerMethod by gettingFirstMutableMethodDeclaratively {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returnType("V")
parameterTypes("I", "L", "Z")
opcodes(
Opcode.IGET,
Opcode.IF_NE,
@ -39,4 +40,4 @@ internal val kidsBackgroundPlaybackPolicyControllerFingerprint = fingerprint {
Opcode.IF_NE,
Opcode.IPUT_BOOLEAN,
)
}
}

View file

@ -3,7 +3,6 @@ package app.revanced.patches.music.misc.fileprovider
import app.revanced.patcher.extensions.addInstructionsWithLabels
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.packagename.setOrGetFallbackPackageName
import app.revanced.patches.music.utils.fix.fileprovider.fileProviderResolverFingerprint
internal fun fileProviderPatch(
youtubePackageName: String,
@ -22,7 +21,7 @@ internal fun fileProviderPatch(
// https://github.com/ReVanced/revanced-patches/issues/55
//
// To solve this issue, replace the package name of YouTube with YT Music's package name.
fileProviderResolverFingerprint.method.addInstructionsWithLabels(
fileProviderResolverMethod.addInstructionsWithLabels(
0,
"""
const-string v0, "com.google.android.youtube.fileprovider"

View file

@ -1,11 +1,12 @@
package app.revanced.patches.music.utils.fix.fileprovider
package app.revanced.patches.music.misc.fileprovider
import app.revanced.patcher.fingerprint
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
internal val fileProviderResolverFingerprint = fingerprint {
returns("L")
strings(
"android.support.FILE_PROVIDER_PATHS",
"Name must not be empty"
)
internal val BytecodePatchContext.fileProviderResolverMethod by gettingFirstMutableMethodDeclaratively(
"android.support.FILE_PROVIDER_PATHS",
"Name must not be empty"
) {
returnType("L")
}

View file

@ -1,11 +1,17 @@
package app.revanced.patches.piccomafr.misc
import app.revanced.patcher.accessFlags
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.parameterTypes
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.returnType
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.fingerprint
internal val getAndroidIdFingerprint = fingerprint {
internal val BytecodePatchContext.getAndroidIdMethod by gettingFirstMutableMethodDeclaratively(
"context",
"android_id"
) {
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
returns("Ljava/lang/String;")
parameters("Landroid/content/Context;")
strings("context", "android_id")
}
returnType("Ljava/lang/String;")
parameterTypes("Landroid/content/Context;")
}

View file

@ -38,6 +38,6 @@ val spoofAndroidDeviceIdPatch = bytecodePatch(
) { it!!.matches("[A-Fa-f0-9]{16}".toRegex()) }
apply {
getAndroidIdFingerprint.method.returnEarly(androidDeviceId!!)
getAndroidIdMethod.returnEarly(androidDeviceId!!)
}
}

View file

@ -1,11 +1,12 @@
package app.revanced.patches.protonvpn.splittunneling
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.name
import app.revanced.patcher.opcodes
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode
internal val enableSplitTunnelingUiFingerprint = fingerprint {
strings("currentModeAppNames")
internal val BytecodePatchContext.enableSplitTunnelingUiMethod by gettingFirstMutableMethodDeclaratively("currentModeAppNames") {
opcodes(
Opcode.MOVE_OBJECT,
Opcode.MOVE_FROM16,
@ -13,8 +14,6 @@ internal val enableSplitTunnelingUiFingerprint = fingerprint {
)
}
internal val initializeSplitTunnelingSettingsUIFingerprint = fingerprint {
custom { method, _ ->
method.name == "applyRestrictions"
}
internal val BytecodePatchContext.initializeSplitTunnelingSettingsUIMethod by gettingFirstMutableMethodDeclaratively {
name("applyRestrictions")
}

View file

@ -17,14 +17,14 @@ val unlockSplitTunnelingPatch =
compatibleWith("ch.protonvpn.android")
apply {
val registerIndex = enableSplitTunnelingUiFingerprint.patternMatch!!.endIndex - 1
val registerIndex = enableSplitTunnelingUiMethod.patternMatch!!.endIndex - 1 // TODO
enableSplitTunnelingUiFingerprint.method.apply {
enableSplitTunnelingUiMethod.apply {
val register = getInstruction<OneRegisterInstruction>(registerIndex).registerA
replaceInstruction(registerIndex, "const/4 v$register, 0x0")
}
initializeSplitTunnelingSettingsUIFingerprint.method.apply {
initializeSplitTunnelingSettingsUIMethod.apply {
val initSettingsIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.name == "getSplitTunneling"
}

View file

@ -1,12 +1,13 @@
package app.revanced.patches.samsung.radio.misc.fix.crash
import app.revanced.patcher.fingerprint
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.name
import app.revanced.patcher.patch.BytecodePatchContext
internal val permissionRequestListFingerprint = fingerprint {
strings(
"android.permission.POST_NOTIFICATIONS",
"android.permission.READ_MEDIA_AUDIO",
"android.permission.RECORD_AUDIO"
)
custom { method, _ -> method.name == "<clinit>" }
internal val BytecodePatchContext.permissionRequestListMethod by gettingFirstMutableMethodDeclaratively(
"android.permission.POST_NOTIFICATIONS",
"android.permission.READ_MEDIA_AUDIO",
"android.permission.RECORD_AUDIO"
) {
name("<clinit>")
}

Some files were not shown because too many files have changed in this diff Show more