From c66c42e946cbe7f02e5f27cfb8661ac442835b1e Mon Sep 17 00:00:00 2001 From: Eric Ahn Date: Thu, 4 Sep 2025 14:29:58 -0700 Subject: [PATCH] feat(Boost/Sync for Reddit): Add `Fix Redgifs` patch (#5725) --- extensions/boostforreddit/build.gradle.kts | 2 + .../boostforreddit/FixRedgifsApiPatch.java | 22 +++++ extensions/shared/build.gradle.kts | 1 + extensions/shared/library/build.gradle.kts | 1 + .../fixes/redgifs/BaseFixRedgifsApiPatch.java | 71 ++++++++++++++ .../fixes/redgifs/RedgifsTokenManager.java | 94 +++++++++++++++++++ extensions/syncforreddit/build.gradle.kts | 1 + .../syncforreddit/FixRedgifsApiPatch.java | 22 +++++ patches/api/patches.api | 15 +++ .../customclients/FixRedgifsApiPatch.kt | 17 ++++ .../fix/redgifs/Fingerprints.kt | 20 ++++ .../fix/redgifs/FixRedgifsApiPatch.kt | 38 ++++++++ .../syncforreddit/fix/redgifs/Fingerprints.kt | 39 ++++++++ .../fix/redgifs/FixRedgifsApiPatch.kt | 56 +++++++++++ .../kotlin/app/revanced/util/BytecodeUtils.kt | 1 + 15 files changed, 400 insertions(+) create mode 100644 extensions/boostforreddit/src/main/java/app/revanced/extension/boostforreddit/FixRedgifsApiPatch.java create mode 100644 extensions/shared/library/src/main/java/app/revanced/extension/shared/fixes/redgifs/BaseFixRedgifsApiPatch.java create mode 100644 extensions/shared/library/src/main/java/app/revanced/extension/shared/fixes/redgifs/RedgifsTokenManager.java create mode 100644 extensions/syncforreddit/src/main/java/app/revanced/extension/syncforreddit/FixRedgifsApiPatch.java create mode 100644 patches/src/main/kotlin/app/revanced/patches/reddit/customclients/FixRedgifsApiPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/redgifs/Fingerprints.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/redgifs/FixRedgifsApiPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/redgifs/Fingerprints.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/redgifs/FixRedgifsApiPatch.kt diff --git a/extensions/boostforreddit/build.gradle.kts b/extensions/boostforreddit/build.gradle.kts index 54c06871b..4f79f5a79 100644 --- a/extensions/boostforreddit/build.gradle.kts +++ b/extensions/boostforreddit/build.gradle.kts @@ -1,4 +1,6 @@ dependencies { compileOnly(project(":extensions:shared:library")) compileOnly(project(":extensions:boostforreddit:stub")) + compileOnly(libs.annotation) + compileOnly(libs.okhttp) } diff --git a/extensions/boostforreddit/src/main/java/app/revanced/extension/boostforreddit/FixRedgifsApiPatch.java b/extensions/boostforreddit/src/main/java/app/revanced/extension/boostforreddit/FixRedgifsApiPatch.java new file mode 100644 index 000000000..92757dabf --- /dev/null +++ b/extensions/boostforreddit/src/main/java/app/revanced/extension/boostforreddit/FixRedgifsApiPatch.java @@ -0,0 +1,22 @@ +package app.revanced.extension.boostforreddit; + +import app.revanced.extension.shared.fixes.redgifs.BaseFixRedgifsApiPatch; +import okhttp3.OkHttpClient; + +/** + * @noinspection unused + */ +public class FixRedgifsApiPatch extends BaseFixRedgifsApiPatch { + static { + INSTANCE = new FixRedgifsApiPatch(); + } + + public String getDefaultUserAgent() { + // Boost uses a static user agent for Redgifs API calls + return "Boost"; + } + + public static OkHttpClient createClient() { + return new OkHttpClient.Builder().addInterceptor(INSTANCE).build(); + } +} diff --git a/extensions/shared/build.gradle.kts b/extensions/shared/build.gradle.kts index 2da2e1e89..8f037894c 100644 --- a/extensions/shared/build.gradle.kts +++ b/extensions/shared/build.gradle.kts @@ -1,3 +1,4 @@ dependencies { implementation(project(":extensions:shared:library")) + compileOnly(libs.okhttp) } diff --git a/extensions/shared/library/build.gradle.kts b/extensions/shared/library/build.gradle.kts index 95969234f..100de7ae1 100644 --- a/extensions/shared/library/build.gradle.kts +++ b/extensions/shared/library/build.gradle.kts @@ -18,4 +18,5 @@ android { dependencies { compileOnly(libs.annotation) + compileOnly(libs.okhttp) } diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/fixes/redgifs/BaseFixRedgifsApiPatch.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/fixes/redgifs/BaseFixRedgifsApiPatch.java new file mode 100644 index 000000000..b6fa2caa0 --- /dev/null +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/fixes/redgifs/BaseFixRedgifsApiPatch.java @@ -0,0 +1,71 @@ +package app.revanced.extension.shared.fixes.redgifs; + +import androidx.annotation.NonNull; + +import org.json.JSONException; + +import java.io.IOException; +import java.net.HttpURLConnection; + +import app.revanced.extension.shared.Logger; +import okhttp3.Interceptor; +import okhttp3.MediaType; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; + + +public abstract class BaseFixRedgifsApiPatch implements Interceptor { + protected static BaseFixRedgifsApiPatch INSTANCE; + public abstract String getDefaultUserAgent(); + + @NonNull + @Override + public Response intercept(@NonNull Chain chain) throws IOException { + Request request = chain.request(); + if (!request.url().host().equals("api.redgifs.com")) { + return chain.proceed(request); + } + + String userAgent = getDefaultUserAgent(); + + if (request.header("Authorization") != null) { + Response response = chain.proceed(request.newBuilder().header("User-Agent", userAgent).build()); + if (response.isSuccessful()) { + return response; + } + // It's possible that the user agent is being overwritten later down in the interceptor + // chain, so make sure we grab the new user agent from the request headers. + userAgent = response.request().header("User-Agent"); + response.close(); + } + + try { + RedgifsTokenManager.RedgifsToken token = RedgifsTokenManager.refreshToken(userAgent); + + // Emulate response for old OAuth endpoint + if (request.url().encodedPath().equals("/v2/oauth/client")) { + String responseBody = RedgifsTokenManager.getEmulatedOAuthResponseBody(token); + return new Response.Builder() + .message("OK") + .code(HttpURLConnection.HTTP_OK) + .protocol(Protocol.HTTP_1_1) + .request(request) + .header("Content-Type", "application/json") + .body(ResponseBody.create( + responseBody, MediaType.get("application/json"))) + .build(); + } + + Request modifiedRequest = request.newBuilder() + .header("Authorization", "Bearer " + token.getAccessToken()) + .header("User-Agent", userAgent) + .build(); + return chain.proceed(modifiedRequest); + } catch (JSONException ex) { + Logger.printException(() -> "Could not parse Redgifs response", ex); + throw new IOException(ex); + } + } +} diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/fixes/redgifs/RedgifsTokenManager.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/fixes/redgifs/RedgifsTokenManager.java new file mode 100644 index 000000000..792465a89 --- /dev/null +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/fixes/redgifs/RedgifsTokenManager.java @@ -0,0 +1,94 @@ +package app.revanced.extension.shared.fixes.redgifs; + +import static app.revanced.extension.shared.requests.Route.Method.GET; + +import androidx.annotation.GuardedBy; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import app.revanced.extension.shared.requests.Requester; + + +/** + * Manages Redgifs token lifecycle. + */ +public class RedgifsTokenManager { + public static class RedgifsToken { + // Expire after 23 hours to provide some breathing room + private static final long EXPIRY_SECONDS = 23 * 60 * 60; + + private final String accessToken; + private final long refreshTimeInSeconds; + + public RedgifsToken(String accessToken, long refreshTime) { + this.accessToken = accessToken; + this.refreshTimeInSeconds = refreshTime; + } + + public String getAccessToken() { + return accessToken; + } + + public long getExpiryTimeInSeconds() { + return refreshTimeInSeconds + EXPIRY_SECONDS; + } + + public boolean isValid() { + if (accessToken == null) return false; + return getExpiryTimeInSeconds() >= System.currentTimeMillis() / 1000; + } + } + public static final String REDGIFS_API_HOST = "https://api.redgifs.com"; + private static final String GET_TEMPORARY_TOKEN = REDGIFS_API_HOST + "/v2/auth/temporary"; + @GuardedBy("itself") + private static final Map tokenMap = new HashMap<>(); + + private static String getToken(String userAgent) throws IOException, JSONException { + HttpURLConnection connection = (HttpURLConnection) new URL(GET_TEMPORARY_TOKEN).openConnection(); + connection.setFixedLengthStreamingMode(0); + connection.setRequestMethod(GET.name()); + connection.setRequestProperty("User-Agent", userAgent); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("Accept", "application/json"); + connection.setUseCaches(false); + + JSONObject responseObject = Requester.parseJSONObject(connection); + return responseObject.getString("token"); + } + + public static RedgifsToken refreshToken(String userAgent) throws IOException, JSONException { + synchronized(tokenMap) { + // Reference: https://github.com/JeffreyCA/Apollo-ImprovedCustomApi/pull/67 + RedgifsToken token = tokenMap.get(userAgent); + if (token != null && token.isValid()) { + return token; + } + + // Copy user agent from original request if present because Redgifs verifies + // that the user agent in subsequent requests matches the one in the OAuth token. + String accessToken = getToken(userAgent); + long refreshTime = System.currentTimeMillis() / 1000; + token = new RedgifsToken(accessToken, refreshTime); + tokenMap.put(userAgent, token); + return token; + } + } + + public static String getEmulatedOAuthResponseBody(RedgifsToken token) throws JSONException { + // Reference: https://github.com/JeffreyCA/Apollo-ImprovedCustomApi/pull/67 + JSONObject responseObject = new JSONObject(); + responseObject.put("access_token", token.accessToken); + responseObject.put("expiry_time", token.getExpiryTimeInSeconds() - (System.currentTimeMillis() / 1000)); + responseObject.put("scope", "read"); + responseObject.put("token_type", "Bearer"); + return responseObject.toString(); + } +} diff --git a/extensions/syncforreddit/build.gradle.kts b/extensions/syncforreddit/build.gradle.kts index a2b2899db..ae95bb48f 100644 --- a/extensions/syncforreddit/build.gradle.kts +++ b/extensions/syncforreddit/build.gradle.kts @@ -2,4 +2,5 @@ dependencies { compileOnly(project(":extensions:shared:library")) compileOnly(project(":extensions:syncforreddit:stub")) compileOnly(libs.annotation) + compileOnly(libs.okhttp) } diff --git a/extensions/syncforreddit/src/main/java/app/revanced/extension/syncforreddit/FixRedgifsApiPatch.java b/extensions/syncforreddit/src/main/java/app/revanced/extension/syncforreddit/FixRedgifsApiPatch.java new file mode 100644 index 000000000..78c910ecf --- /dev/null +++ b/extensions/syncforreddit/src/main/java/app/revanced/extension/syncforreddit/FixRedgifsApiPatch.java @@ -0,0 +1,22 @@ +package app.revanced.extension.syncforreddit; + +import app.revanced.extension.shared.fixes.redgifs.BaseFixRedgifsApiPatch; +import okhttp3.OkHttpClient; + +/** + * @noinspection unused + */ +public class FixRedgifsApiPatch extends BaseFixRedgifsApiPatch { + static { + INSTANCE = new FixRedgifsApiPatch(); + } + + public String getDefaultUserAgent() { + // To be filled in by patch + return ""; + } + + public static OkHttpClient install(OkHttpClient.Builder builder) { + return builder.addInterceptor(INSTANCE).build(); + } +} diff --git a/patches/api/patches.api b/patches/api/patches.api index fd788e221..8b275fc72 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -512,6 +512,13 @@ public final class app/revanced/patches/reddit/ad/general/HideAdsPatchKt { public static final fun getHideAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/reddit/customclients/FixRedgifsApiPatchKt { + public static final field CREATE_NEW_CLIENT_METHOD Ljava/lang/String; + public static final field INSTALL_NEW_CLIENT_METHOD Ljava/lang/String; + public static final fun fixRedgifsApiPatch (Lapp/revanced/patcher/patch/Patch;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/BytecodePatch; + public static synthetic fun fixRedgifsApiPatch$default (Lapp/revanced/patcher/patch/Patch;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/reddit/customclients/FixSLinksPatchKt { public static final field RESOLVE_S_LINK_METHOD Ljava/lang/String; public static final field SET_ACCESS_TOKEN_METHOD Ljava/lang/String; @@ -540,6 +547,10 @@ public final class app/revanced/patches/reddit/customclients/boostforreddit/fix/ public static final fun getFixAudioMissingInDownloadsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/reddit/customclients/boostforreddit/fix/redgifs/FixRedgifsApiPatchKt { + public static final fun getFixRedgifsApi ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/FixSLinksPatchKt { public static final field EXTENSION_CLASS_DESCRIPTOR Ljava/lang/String; public static final fun getFixSlinksPatch ()Lapp/revanced/patcher/patch/BytecodePatch; @@ -610,6 +621,10 @@ public final class app/revanced/patches/reddit/customclients/sync/syncforreddit/ public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/redgifs/FixRedgifsApiPatchKt { + public static final fun getFixRedgifsApi ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/slink/FixSLinksPatchKt { public static final field EXTENSION_CLASS_DESCRIPTOR Ljava/lang/String; public static final fun getFixSLinksPatch ()Lapp/revanced/patcher/patch/BytecodePatch; diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/FixRedgifsApiPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/FixRedgifsApiPatch.kt new file mode 100644 index 000000000..92ff76f9e --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/FixRedgifsApiPatch.kt @@ -0,0 +1,17 @@ +package app.revanced.patches.reddit.customclients + +import app.revanced.patcher.patch.BytecodePatchBuilder +import app.revanced.patcher.patch.Patch +import app.revanced.patcher.patch.bytecodePatch + +const val INSTALL_NEW_CLIENT_METHOD = "install(Lokhttp3/OkHttpClient${'$'}Builder;)Lokhttp3/OkHttpClient;" +const val CREATE_NEW_CLIENT_METHOD = "createClient()Lokhttp3/OkHttpClient;" + +fun fixRedgifsApiPatch( + extensionPatch: Patch<*>, + block: BytecodePatchBuilder.() -> Unit = {}, +) = bytecodePatch(name = "Fix Redgifs API") { + dependsOn(extensionPatch) + + block() +} diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/redgifs/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/redgifs/Fingerprints.kt new file mode 100644 index 000000000..1f3560d73 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/redgifs/Fingerprints.kt @@ -0,0 +1,20 @@ +package app.revanced.patches.reddit.customclients.boostforreddit.fix.redgifs + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal val createOkHttpClientFingerprint = fingerprint { + accessFlags(AccessFlags.PRIVATE) + opcodes( + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT + ) + custom { _, classDef -> classDef.sourceFile == "RedGifsAPIv2.java" } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/redgifs/FixRedgifsApiPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/redgifs/FixRedgifsApiPatch.kt new file mode 100644 index 000000000..f19a5964d --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/fix/redgifs/FixRedgifsApiPatch.kt @@ -0,0 +1,38 @@ +package app.revanced.patches.reddit.customclients.boostforreddit.fix.redgifs + +import app.revanced.patcher.extensions.InstructionExtensions.instructions +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patches.reddit.customclients.CREATE_NEW_CLIENT_METHOD +import app.revanced.patches.reddit.customclients.boostforreddit.misc.extension.sharedExtensionPatch +import app.revanced.patches.reddit.customclients.fixRedgifsApiPatch +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionOrThrow +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/boostforreddit/FixRedgifsApiPatch;" + +@Suppress("unused") +val fixRedgifsApi = fixRedgifsApiPatch( + extensionPatch = sharedExtensionPatch +) { + compatibleWith("com.rubenmayayo.reddit") + + execute { + // region Patch Redgifs OkHttp3 client. + + createOkHttpClientFingerprint.method.apply { + val index = indexOfFirstInstructionOrThrow { + val reference = getReference() + reference?.name == "build" && reference.definingClass == "Lokhttp3/OkHttpClient\$Builder;" + } + replaceInstruction( + index, + """ + invoke-static { }, ${EXTENSION_CLASS_DESCRIPTOR}->$CREATE_NEW_CLIENT_METHOD + """ + ) + } + + // endregion + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/redgifs/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/redgifs/Fingerprints.kt new file mode 100644 index 000000000..16dfa4620 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/redgifs/Fingerprints.kt @@ -0,0 +1,39 @@ +package app.revanced.patches.reddit.customclients.sync.syncforreddit.fix.redgifs + +import app.revanced.patcher.extensions.InstructionExtensions.instructions +import app.revanced.patcher.fingerprint +import app.revanced.util.indexOfFirstInstruction +import app.revanced.util.writeRegister +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction11n + + +internal val createOkHttpClientFingerprint = fingerprint { + accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC) + returns("V") + parameters() + custom { method, classDef -> + // There are four functions (each creating a client) defined in this file with very similar fingerprints. + // We're looking for the one that only creates one object (the builder) and sets client options true + // (thus never reloading the register with a 0). + classDef.sourceFile == "OkHttpHelper.java" && + method.instructions.count { it.opcode == Opcode.NEW_INSTANCE } == 1 && + method.indexOfFirstInstruction { + opcode == Opcode.CONST_4 && writeRegister == 1 && (this as Instruction11n).narrowLiteral == 0 + } == -1 + } +} + +internal val getDefaultUserAgentFingerprint = fingerprint { + custom { method, classDef -> + method.name == "getDefaultUserAgent" && classDef.type == EXTENSION_CLASS_DESCRIPTOR + } +} + +internal val getOriginalUserAgentFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) + returns("Ljava/lang/String;") + parameters() + custom { _, classDef -> classDef.sourceFile == "AccountSingleton.java" } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/redgifs/FixRedgifsApiPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/redgifs/FixRedgifsApiPatch.kt new file mode 100644 index 000000000..a4f3842f9 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/redgifs/FixRedgifsApiPatch.kt @@ -0,0 +1,56 @@ +package app.revanced.patches.reddit.customclients.sync.syncforreddit.fix.redgifs + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patches.reddit.customclients.INSTALL_NEW_CLIENT_METHOD +import app.revanced.patches.reddit.customclients.fixRedgifsApiPatch +import app.revanced.patches.reddit.customclients.sync.syncforreddit.extension.sharedExtensionPatch +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionOrThrow +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/syncforreddit/FixRedgifsApiPatch;" + +@Suppress("unused") +val fixRedgifsApi = fixRedgifsApiPatch( + extensionPatch = sharedExtensionPatch +) { + compatibleWith( + "com.laurencedawson.reddit_sync", + "com.laurencedawson.reddit_sync.pro", + "com.laurencedawson.reddit_sync.dev", + ) + + execute { + // region Patch Redgifs OkHttp3 client. + + createOkHttpClientFingerprint.method.apply { + val index = indexOfFirstInstructionOrThrow { + val reference = getReference() + reference?.name == "build" && reference.definingClass == "Lokhttp3/OkHttpClient\$Builder;" + } + val register = getInstruction(index).registerC + replaceInstruction( + index, + """ + invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->$INSTALL_NEW_CLIENT_METHOD + """ + ) + } + + getDefaultUserAgentFingerprint.method.apply { + addInstructions( + 0, + """ + invoke-static { }, ${getOriginalUserAgentFingerprint.method} + move-result-object v0 + return-object v0 + """ + ) + } + + // endregion + } +} diff --git a/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt index 6883776e6..993fa820b 100644 --- a/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt +++ b/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -132,6 +132,7 @@ internal val Instruction.registersUsed: List get() = when (this) { is FiveRegisterInstruction -> { when (registerCount) { + 0 -> listOf() 1 -> listOf(registerC) 2 -> listOf(registerC, registerD) 3 -> listOf(registerC, registerD, registerE)