From 24c0d1798a2f35598293e3cfcfb445f46a337625 Mon Sep 17 00:00:00 2001 From: rospino74 <34315725+rospino74@users.noreply.github.com> Date: Thu, 13 Nov 2025 20:33:00 +0100 Subject: [PATCH 01/10] refactor(Spoof SIM country)!: Rename patch to `SpoofSimDataPatch` --- patches/api/patches.api | 4 ++-- .../spoof/{SpoofSimCountryPatch.kt => SpoofSimDataPatch.kt} | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) rename patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/{SpoofSimCountryPatch.kt => SpoofSimDataPatch.kt} (95%) diff --git a/patches/api/patches.api b/patches/api/patches.api index ca59944025..7b56866fb5 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -52,8 +52,8 @@ public final class app/revanced/patches/all/misc/connectivity/location/hide/Hide public static final fun getHideMockLocationPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatchKt { - public static final fun getSpoofSimCountryPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +public final class app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatchKt { + public static final fun getSpoofSimDataPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } public final class app/revanced/patches/all/misc/connectivity/wifi/spoof/SpoofWifiPatchKt { diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt similarity index 95% rename from patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatch.kt rename to patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt index 2f90b5ec35..1670445b2e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt @@ -14,9 +14,9 @@ import com.android.tools.smali.dexlib2.util.MethodUtil import java.util.* @Suppress("unused") -val spoofSimCountryPatch = bytecodePatch( - name = "Spoof SIM country", - description = "Spoofs country information returned by the SIM card provider.", +val spoofSimDataPatch = bytecodePatch( + name = "Spoof SIM data", + description = "Spoofs information returned by the SIM card provider.", use = false, ) { val countries = Locale.getISOCountries().associateBy { Locale("", it).displayCountry } From 2e0024853d968f1add4786b56cbbb0c32f1456ca Mon Sep 17 00:00:00 2001 From: rospino74 <34315725+rospino74@users.noreply.github.com> Date: Fri, 14 Nov 2025 02:00:02 +0200 Subject: [PATCH 02/10] feat(Spoof SIM Data): Add methods fingerprints --- .../telephony/sim/spoof/SpoofSimDataPatch.kt | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt index 1670445b2e..8c78faf062 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt @@ -11,7 +11,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodReference import com.android.tools.smali.dexlib2.util.MethodUtil -import java.util.* +import java.util.Locale @Suppress("unused") val spoofSimDataPatch = bytecodePatch( @@ -75,6 +75,7 @@ private fun transformMethodCall( ) { val (instructionIndex, methodCallValue) = entry + // Get the register which would have contained the return value val register = mutableMethod.getInstruction(instructionIndex + 1).registerA mutableMethod.replaceInstruction( @@ -94,6 +95,22 @@ private enum class MethodCall( "Ljava/lang/String;", ), ), + NetworkOperator( + ImmutableMethodReference( + "Landroid/telephony/TelephonyManager;", + "getNetworkOperator", + emptyList(), + "Ljava/lang/String;", + ), + ), + NetworkOperatorName( + ImmutableMethodReference( + "Landroid/telephony/TelephonyManager;", + "getNetworkOperatorName", + emptyList(), + "Ljava/lang/String;", + ), + ), SimCountryIso( ImmutableMethodReference( "Landroid/telephony/TelephonyManager;", @@ -102,4 +119,20 @@ private enum class MethodCall( "Ljava/lang/String;", ), ), + SimOperator( + ImmutableMethodReference( + "Landroid/telephony/TelephonyManager;", + "getSimOperator", + emptyList(), + "Ljava/lang/String;", + ), + ), + SimOperatorName( + ImmutableMethodReference( + "Landroid/telephony/TelephonyManager;", + "getSimOperatorName", + emptyList(), + "Ljava/lang/String;", + ), + ), } From 56b68036186bb4ffdc670c2d053bc70a3557b345 Mon Sep 17 00:00:00 2001 From: rospino74 <34315725+rospino74@users.noreply.github.com> Date: Fri, 14 Nov 2025 02:35:54 +0200 Subject: [PATCH 03/10] feat(Spoof SIM Data): Add patch options --- .../telephony/sim/spoof/SpoofSimDataPatch.kt | 40 ++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt index 8c78faf062..25ccb56894 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt @@ -4,6 +4,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.stringOption +import app.revanced.patcher.patch.intOption import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.all.misc.transformation.transformInstructionsPatch import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @@ -39,11 +40,36 @@ val spoofSimDataPatch = bytecodePatch( "Network ISO country code", ) + val networkOperator by intOption( + key = "networkOperator", + title = "MCC+MNC network operator code", + description = "The 5 or 6 digits MCC+MNC (Mobile Country Code + Mobile Network Code) of the network operator.", + ) + + val networkOperatorName by stringOption( + key = "networkOperatorName", + title = "Network operator name", + description = "The full name of the network operator.", + ) + val simCountryIso by isoCountryPatchOption( "simCountryIso", "SIM ISO country code", ) + val simOperator by intOption( + key = "simOperator", + title = "MCC+MNC SIM operator code", + description = "The 5 or 6 digits MCC+MNC (Mobile Country Code + Mobile Network Code) of the SIM operator.", + ) + + val simOperatorName by stringOption( + key = "simOperatorName", + title = "SIM operator name", + description = "The full name of the SIM operator.", + ) + + dependsOn( transformInstructionsPatch( filterMap = { _, _, instruction, instructionIndex -> @@ -55,12 +81,16 @@ val spoofSimDataPatch = bytecodePatch( MethodUtil.methodSignaturesMatch(reference, search.reference) } ?: return@transformInstructionsPatch null - val iso = when (match) { - MethodCall.NetworkCountryIso -> networkCountryIso - MethodCall.SimCountryIso -> simCountryIso - }?.lowercase() + val replacement = when (match) { + MethodCall.NetworkCountryIso -> networkCountryIso?.lowercase() + MethodCall.NetworkOperator -> networkOperator.toString() + MethodCall.NetworkOperatorName -> networkOperatorName + MethodCall.SimCountryIso -> simCountryIso?.lowercase() + MethodCall.SimOperator -> simOperator.toString() + MethodCall.SimOperatorName -> simOperatorName + } - iso?.let { instructionIndex to it } + replacement?.let { instructionIndex to it } }, transform = { mutableMethod, entry: Pair -> transformMethodCall(entry, mutableMethod) From feb69109412669f331613afe9884991fcc9f91a5 Mon Sep 17 00:00:00 2001 From: rospino74 <34315725+rospino74@users.noreply.github.com> Date: Fri, 14 Nov 2025 03:14:33 +0200 Subject: [PATCH 04/10] refactor(Spoof SIM Data): Compress lambda into method reference --- .../connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt index 25ccb56894..a1d7cc4b54 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt @@ -89,25 +89,23 @@ val spoofSimDataPatch = bytecodePatch( MethodCall.SimOperator -> simOperator.toString() MethodCall.SimOperatorName -> simOperatorName } - replacement?.let { instructionIndex to it } }, - transform = { mutableMethod, entry: Pair -> - transformMethodCall(entry, mutableMethod) - }, + transform = ::transformMethodCall, ), ) } private fun transformMethodCall( - entry: Pair, mutableMethod: MutableMethod, + entry: Pair, ) { val (instructionIndex, methodCallValue) = entry // Get the register which would have contained the return value val register = mutableMethod.getInstruction(instructionIndex + 1).registerA + // Replace the move-result instruction with our fake value mutableMethod.replaceInstruction( instructionIndex + 1, "const-string v$register, \"$methodCallValue\"", From c18d3aca6db9a97cb09edf6868b9e5630a819918 Mon Sep 17 00:00:00 2001 From: rospino74 <34315725+rospino74@users.noreply.github.com> Date: Fri, 14 Nov 2025 23:28:55 +0100 Subject: [PATCH 05/10] feat(Spoof SIM Data): Add validators and null checks --- .../connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt index a1d7cc4b54..0431e9b981 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt @@ -13,6 +13,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodReference import com.android.tools.smali.dexlib2.util.MethodUtil import java.util.Locale +import java.util.regex.Pattern @Suppress("unused") val spoofSimDataPatch = bytecodePatch( @@ -44,6 +45,7 @@ val spoofSimDataPatch = bytecodePatch( key = "networkOperator", title = "MCC+MNC network operator code", description = "The 5 or 6 digits MCC+MNC (Mobile Country Code + Mobile Network Code) of the network operator.", + validator = { it: Int? -> it == null || Pattern.matches("[0-9]{5,6}", it.toString()) } ) val networkOperatorName by stringOption( @@ -61,6 +63,7 @@ val spoofSimDataPatch = bytecodePatch( key = "simOperator", title = "MCC+MNC SIM operator code", description = "The 5 or 6 digits MCC+MNC (Mobile Country Code + Mobile Network Code) of the SIM operator.", + validator = { it: Int? -> it == null || Pattern.matches("[0-9]{5,6}", it.toString()) } ) val simOperatorName by stringOption( @@ -83,10 +86,10 @@ val spoofSimDataPatch = bytecodePatch( val replacement = when (match) { MethodCall.NetworkCountryIso -> networkCountryIso?.lowercase() - MethodCall.NetworkOperator -> networkOperator.toString() + MethodCall.NetworkOperator -> networkOperator?.toString() MethodCall.NetworkOperatorName -> networkOperatorName MethodCall.SimCountryIso -> simCountryIso?.lowercase() - MethodCall.SimOperator -> simOperator.toString() + MethodCall.SimOperator -> simOperator?.toString() MethodCall.SimOperatorName -> simOperatorName } replacement?.let { instructionIndex to it } From 4665b5617e7f5b7e5eddb1ddb0f75fe4c9792787 Mon Sep 17 00:00:00 2001 From: rospino74 <34315725+rospino74@users.noreply.github.com> Date: Sat, 15 Nov 2025 11:02:52 +0100 Subject: [PATCH 06/10] feat(Spoof SIM Data): Add stub of previous patch name --- patches/api/patches.api | 1 + .../connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/patches/api/patches.api b/patches/api/patches.api index 7b56866fb5..f85b07eb6d 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -53,6 +53,7 @@ public final class app/revanced/patches/all/misc/connectivity/location/hide/Hide } public final class app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatchKt { + public static final fun getSpoofSimCountryPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun getSpoofSimDataPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt index 0431e9b981..39c168ea6f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt @@ -167,3 +167,9 @@ private enum class MethodCall( ), ), } + +@Deprecated("Patch was renamed", ReplaceWith("spoofSimDataPatch")) +@Suppress("unused") +val spoofSimCountryPatch = bytecodePatch { + dependsOn(spoofSimDataPatch) +} \ No newline at end of file From 871c453bd1256c874b3af8c28fedb155fc0c6b82 Mon Sep 17 00:00:00 2001 From: rospino74 <34315725+rospino74@users.noreply.github.com> Date: Sat, 15 Nov 2025 11:09:40 +0100 Subject: [PATCH 07/10] feat(Spoof SIM Data): Restore previous file name --- patches/api/patches.api | 2 +- .../sim/spoof/{SpoofSimDataPatch.kt => SpoofSimCountryPatch.kt} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/{SpoofSimDataPatch.kt => SpoofSimCountryPatch.kt} (100%) diff --git a/patches/api/patches.api b/patches/api/patches.api index f85b07eb6d..98b8610232 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -52,7 +52,7 @@ public final class app/revanced/patches/all/misc/connectivity/location/hide/Hide public static final fun getHideMockLocationPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatchKt { +public final class app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatchKt { public static final fun getSpoofSimCountryPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun getSpoofSimDataPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatch.kt similarity index 100% rename from patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimDataPatch.kt rename to patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatch.kt From 96032587380d4b91dc9f08ab3b5a5cf66a9dbeeb Mon Sep 17 00:00:00 2001 From: rospino74 <34315725+rospino74@users.noreply.github.com> Date: Sat, 15 Nov 2025 11:33:47 +0100 Subject: [PATCH 08/10] refactor(Spoof SIM Data): Rename spoofSimDataPatch to spoofSimProviderPatch --- patches/api/patches.api | 2 +- .../telephony/sim/spoof/SpoofSimCountryPatch.kt | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/patches/api/patches.api b/patches/api/patches.api index 98b8610232..4a53ff23ab 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -54,7 +54,7 @@ public final class app/revanced/patches/all/misc/connectivity/location/hide/Hide public final class app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatchKt { public static final fun getSpoofSimCountryPatch ()Lapp/revanced/patcher/patch/BytecodePatch; - public static final fun getSpoofSimDataPatch ()Lapp/revanced/patcher/patch/BytecodePatch; + public static final fun getSpoofSimProviderPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } public final class app/revanced/patches/all/misc/connectivity/wifi/spoof/SpoofWifiPatchKt { diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatch.kt index 39c168ea6f..176b2c20e9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatch.kt @@ -16,9 +16,9 @@ import java.util.Locale import java.util.regex.Pattern @Suppress("unused") -val spoofSimDataPatch = bytecodePatch( - name = "Spoof SIM data", - description = "Spoofs information returned by the SIM card provider.", +val spoofSimProviderPatch = bytecodePatch( + name = "Spoof SIM provider", + description = "Spoofs information about the SIM card provider.", use = false, ) { val countries = Locale.getISOCountries().associateBy { Locale("", it).displayCountry } @@ -168,8 +168,8 @@ private enum class MethodCall( ), } -@Deprecated("Patch was renamed", ReplaceWith("spoofSimDataPatch")) +@Deprecated("Patch was renamed", ReplaceWith("spoofSimProviderPatch")) @Suppress("unused") val spoofSimCountryPatch = bytecodePatch { - dependsOn(spoofSimDataPatch) + dependsOn(spoofSimProviderPatch) } \ No newline at end of file From 48f98a9ed83a99094b64605cab8e6078d59d28bc Mon Sep 17 00:00:00 2001 From: rospino74 <34315725+rospino74@users.noreply.github.com> Date: Sun, 16 Nov 2025 12:35:40 +0001 Subject: [PATCH 09/10] Revert 871c453bd and split patches in different files --- patches/api/patches.api | 3 + .../sim/spoof/SpoofSimCountryPatch.kt | 166 ----------------- .../sim/spoof/SpoofSimProviderPatch.kt | 169 ++++++++++++++++++ 3 files changed, 172 insertions(+), 166 deletions(-) create mode 100644 patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimProviderPatch.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index 4a53ff23ab..d1ff2779a3 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -54,6 +54,9 @@ public final class app/revanced/patches/all/misc/connectivity/location/hide/Hide public final class app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatchKt { public static final fun getSpoofSimCountryPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + +public final class app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimProviderPatchKt { public static final fun getSpoofSimProviderPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatch.kt index 176b2c20e9..fe418b1ae1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimCountryPatch.kt @@ -1,172 +1,6 @@ package app.revanced.patches.all.misc.connectivity.telephony.sim.spoof -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patcher.patch.stringOption -import app.revanced.patcher.patch.intOption -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.all.misc.transformation.transformInstructionsPatch -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference -import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodReference -import com.android.tools.smali.dexlib2.util.MethodUtil -import java.util.Locale -import java.util.regex.Pattern - -@Suppress("unused") -val spoofSimProviderPatch = bytecodePatch( - name = "Spoof SIM provider", - description = "Spoofs information about the SIM card provider.", - use = false, -) { - val countries = Locale.getISOCountries().associateBy { Locale("", it).displayCountry } - - fun isoCountryPatchOption( - key: String, - title: String, - ) = stringOption( - key, - null, - countries, - title, - "ISO-3166-1 alpha-2 country code equivalent for the SIM provider's country code.", - false, - validator = { it: String? -> it == null || it.uppercase() in countries.values }, - ) - - val networkCountryIso by isoCountryPatchOption( - "networkCountryIso", - "Network ISO country code", - ) - - val networkOperator by intOption( - key = "networkOperator", - title = "MCC+MNC network operator code", - description = "The 5 or 6 digits MCC+MNC (Mobile Country Code + Mobile Network Code) of the network operator.", - validator = { it: Int? -> it == null || Pattern.matches("[0-9]{5,6}", it.toString()) } - ) - - val networkOperatorName by stringOption( - key = "networkOperatorName", - title = "Network operator name", - description = "The full name of the network operator.", - ) - - val simCountryIso by isoCountryPatchOption( - "simCountryIso", - "SIM ISO country code", - ) - - val simOperator by intOption( - key = "simOperator", - title = "MCC+MNC SIM operator code", - description = "The 5 or 6 digits MCC+MNC (Mobile Country Code + Mobile Network Code) of the SIM operator.", - validator = { it: Int? -> it == null || Pattern.matches("[0-9]{5,6}", it.toString()) } - ) - - val simOperatorName by stringOption( - key = "simOperatorName", - title = "SIM operator name", - description = "The full name of the SIM operator.", - ) - - - dependsOn( - transformInstructionsPatch( - filterMap = { _, _, instruction, instructionIndex -> - if (instruction !is ReferenceInstruction) return@transformInstructionsPatch null - - val reference = instruction.reference as? MethodReference ?: return@transformInstructionsPatch null - - val match = MethodCall.entries.firstOrNull { search -> - MethodUtil.methodSignaturesMatch(reference, search.reference) - } ?: return@transformInstructionsPatch null - - val replacement = when (match) { - MethodCall.NetworkCountryIso -> networkCountryIso?.lowercase() - MethodCall.NetworkOperator -> networkOperator?.toString() - MethodCall.NetworkOperatorName -> networkOperatorName - MethodCall.SimCountryIso -> simCountryIso?.lowercase() - MethodCall.SimOperator -> simOperator?.toString() - MethodCall.SimOperatorName -> simOperatorName - } - replacement?.let { instructionIndex to it } - }, - transform = ::transformMethodCall, - ), - ) -} - -private fun transformMethodCall( - mutableMethod: MutableMethod, - entry: Pair, -) { - val (instructionIndex, methodCallValue) = entry - - // Get the register which would have contained the return value - val register = mutableMethod.getInstruction(instructionIndex + 1).registerA - - // Replace the move-result instruction with our fake value - mutableMethod.replaceInstruction( - instructionIndex + 1, - "const-string v$register, \"$methodCallValue\"", - ) -} - -private enum class MethodCall( - val reference: MethodReference, -) { - NetworkCountryIso( - ImmutableMethodReference( - "Landroid/telephony/TelephonyManager;", - "getNetworkCountryIso", - emptyList(), - "Ljava/lang/String;", - ), - ), - NetworkOperator( - ImmutableMethodReference( - "Landroid/telephony/TelephonyManager;", - "getNetworkOperator", - emptyList(), - "Ljava/lang/String;", - ), - ), - NetworkOperatorName( - ImmutableMethodReference( - "Landroid/telephony/TelephonyManager;", - "getNetworkOperatorName", - emptyList(), - "Ljava/lang/String;", - ), - ), - SimCountryIso( - ImmutableMethodReference( - "Landroid/telephony/TelephonyManager;", - "getSimCountryIso", - emptyList(), - "Ljava/lang/String;", - ), - ), - SimOperator( - ImmutableMethodReference( - "Landroid/telephony/TelephonyManager;", - "getSimOperator", - emptyList(), - "Ljava/lang/String;", - ), - ), - SimOperatorName( - ImmutableMethodReference( - "Landroid/telephony/TelephonyManager;", - "getSimOperatorName", - emptyList(), - "Ljava/lang/String;", - ), - ), -} @Deprecated("Patch was renamed", ReplaceWith("spoofSimProviderPatch")) @Suppress("unused") diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimProviderPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimProviderPatch.kt new file mode 100644 index 0000000000..9715ecce74 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimProviderPatch.kt @@ -0,0 +1,169 @@ +package app.revanced.patches.all.misc.connectivity.telephony.sim.spoof + +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.patch.stringOption +import app.revanced.patcher.patch.intOption +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.all.misc.transformation.transformInstructionsPatch +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodReference +import com.android.tools.smali.dexlib2.util.MethodUtil +import java.util.Locale +import java.util.regex.Pattern + +@Suppress("unused") +val spoofSimProviderPatch = bytecodePatch( + name = "Spoof SIM provider", + description = "Spoofs information about the SIM card provider.", + use = false, +) { + val countries = Locale.getISOCountries().associateBy { Locale("", it).displayCountry } + + fun isoCountryPatchOption( + key: String, + title: String, + ) = stringOption( + key, + null, + countries, + title, + "ISO-3166-1 alpha-2 country code equivalent for the SIM provider's country code.", + false, + validator = { it: String? -> it == null || it.uppercase() in countries.values }, + ) + + val networkCountryIso by isoCountryPatchOption( + "networkCountryIso", + "Network ISO country code", + ) + + val networkOperator by intOption( + key = "networkOperator", + title = "MCC+MNC network operator code", + description = "The 5 or 6 digits MCC+MNC (Mobile Country Code + Mobile Network Code) of the network operator.", + validator = { it: Int? -> it == null || Pattern.matches("[0-9]{5,6}", it.toString()) } + ) + + val networkOperatorName by stringOption( + key = "networkOperatorName", + title = "Network operator name", + description = "The full name of the network operator.", + ) + + val simCountryIso by isoCountryPatchOption( + "simCountryIso", + "SIM ISO country code", + ) + + val simOperator by intOption( + key = "simOperator", + title = "MCC+MNC SIM operator code", + description = "The 5 or 6 digits MCC+MNC (Mobile Country Code + Mobile Network Code) of the SIM operator.", + validator = { it: Int? -> it == null || Pattern.matches("[0-9]{5,6}", it.toString()) } + ) + + val simOperatorName by stringOption( + key = "simOperatorName", + title = "SIM operator name", + description = "The full name of the SIM operator.", + ) + + + dependsOn( + transformInstructionsPatch( + filterMap = { _, _, instruction, instructionIndex -> + if (instruction !is ReferenceInstruction) return@transformInstructionsPatch null + + val reference = instruction.reference as? MethodReference ?: return@transformInstructionsPatch null + + val match = MethodCall.entries.firstOrNull { search -> + MethodUtil.methodSignaturesMatch(reference, search.reference) + } ?: return@transformInstructionsPatch null + + val replacement = when (match) { + MethodCall.NetworkCountryIso -> networkCountryIso?.lowercase() + MethodCall.NetworkOperator -> networkOperator?.toString() + MethodCall.NetworkOperatorName -> networkOperatorName + MethodCall.SimCountryIso -> simCountryIso?.lowercase() + MethodCall.SimOperator -> simOperator?.toString() + MethodCall.SimOperatorName -> simOperatorName + } + replacement?.let { instructionIndex to it } + }, + transform = ::transformMethodCall, + ), + ) +} + +private fun transformMethodCall( + mutableMethod: MutableMethod, + entry: Pair, +) { + val (instructionIndex, methodCallValue) = entry + + // Get the register which would have contained the return value + val register = mutableMethod.getInstruction(instructionIndex + 1).registerA + + // Replace the move-result instruction with our fake value + mutableMethod.replaceInstruction( + instructionIndex + 1, + "const-string v$register, \"$methodCallValue\"", + ) +} + +private enum class MethodCall( + val reference: MethodReference, +) { + NetworkCountryIso( + ImmutableMethodReference( + "Landroid/telephony/TelephonyManager;", + "getNetworkCountryIso", + emptyList(), + "Ljava/lang/String;", + ), + ), + NetworkOperator( + ImmutableMethodReference( + "Landroid/telephony/TelephonyManager;", + "getNetworkOperator", + emptyList(), + "Ljava/lang/String;", + ), + ), + NetworkOperatorName( + ImmutableMethodReference( + "Landroid/telephony/TelephonyManager;", + "getNetworkOperatorName", + emptyList(), + "Ljava/lang/String;", + ), + ), + SimCountryIso( + ImmutableMethodReference( + "Landroid/telephony/TelephonyManager;", + "getSimCountryIso", + emptyList(), + "Ljava/lang/String;", + ), + ), + SimOperator( + ImmutableMethodReference( + "Landroid/telephony/TelephonyManager;", + "getSimOperator", + emptyList(), + "Ljava/lang/String;", + ), + ), + SimOperatorName( + ImmutableMethodReference( + "Landroid/telephony/TelephonyManager;", + "getSimOperatorName", + emptyList(), + "Ljava/lang/String;", + ), + ), +} From 02581aa3182cbf5380dc3f06e2142d97643aa8d8 Mon Sep 17 00:00:00 2001 From: rospino74 <34315725+rospino74@users.noreply.github.com> Date: Sun, 16 Nov 2025 13:32:13 +0001 Subject: [PATCH 10/10] Extract MCC+MNC validation into a function --- .../telephony/sim/spoof/SpoofSimProviderPatch.kt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimProviderPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimProviderPatch.kt index 9715ecce74..78a534a846 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimProviderPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimProviderPatch.kt @@ -36,6 +36,9 @@ val spoofSimProviderPatch = bytecodePatch( validator = { it: String? -> it == null || it.uppercase() in countries.values }, ) + fun isMccMncValid(it: Int?): Boolean = + it == null || Pattern.matches("[0-9]{5,6}", it.toString()) + val networkCountryIso by isoCountryPatchOption( "networkCountryIso", "Network ISO country code", @@ -44,8 +47,8 @@ val spoofSimProviderPatch = bytecodePatch( val networkOperator by intOption( key = "networkOperator", title = "MCC+MNC network operator code", - description = "The 5 or 6 digits MCC+MNC (Mobile Country Code + Mobile Network Code) of the network operator.", - validator = { it: Int? -> it == null || Pattern.matches("[0-9]{5,6}", it.toString()) } + description = "The 5 or 6 digits MCC+MNC (Mobile Country Code + Mobile Network Code) of the network operator.", + validator = { isMccMncValid(it) } ) val networkOperatorName by stringOption( @@ -62,8 +65,8 @@ val spoofSimProviderPatch = bytecodePatch( val simOperator by intOption( key = "simOperator", title = "MCC+MNC SIM operator code", - description = "The 5 or 6 digits MCC+MNC (Mobile Country Code + Mobile Network Code) of the SIM operator.", - validator = { it: Int? -> it == null || Pattern.matches("[0-9]{5,6}", it.toString()) } + description = "The 5 or 6 digits MCC+MNC (Mobile Country Code + Mobile Network Code) of the SIM operator.", + validator = { isMccMncValid(it) } ) val simOperatorName by stringOption(