Compare commits

..

1 Commits

Author SHA1 Message Date
semantic-release-bot
0f05fbfad9 chore(release): 2.5.1-dev.1 [skip ci]
## [2.5.1-dev.1](https://github.com/revanced/revanced-patches/compare/v2.5.0...v2.5.1-dev.1) (2022-06-30)

### Bug Fixes

* freezing panels when watching video in fullscreen ([#89](https://github.com/revanced/revanced-patches/issues/89)) ([d3e1419](d3e1419d0e))
* invalid version in compatibility annotation ([#90](https://github.com/revanced/revanced-patches/issues/90)) ([c21e177](c21e177ed1))
2022-06-30 19:33:13 +00:00
785 changed files with 3332 additions and 31879 deletions

9
.gitattributes vendored
View File

@@ -1,9 +0,0 @@
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# Linux start script should use lf
/gradlew text eol=lf
# These are Windows script files and should use crlf
*.bat text eol=crlf

View File

@@ -1,73 +0,0 @@
name: 🐞 Bug report
description: Report a very clearly broken issue.
title: 'bug: '
labels: [bug]
body:
- type: markdown
attributes:
value: |
# ReVanced bug report
Important to note that your issue may have already been reported before. Please check for existing issues [here](https://github.com/revanced/revanced-patches/labels/bug).
- type: dropdown
attributes:
label: Type
options:
- Error while patching
- Error at runtime
- Cosmetic
- Other
validations:
required: true
- type: textarea
attributes:
label: Bug description
description: How did you find the bug? Any additional details that might help?
validations:
required: true
- type: textarea
attributes:
label: Steps to reproduce
description: Add the steps to reproduce this bug including your environment.
placeholder: Step 1. Download some files. Step 2. ...
validations:
required: true
- type: textarea
attributes:
label: Relevant log output
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. Capture crash logs by running `logcat | grep AndroidRuntime`.
render: shell
validations:
required: true
- type: textarea
attributes:
label: Screenshots or videos
description: Add screenshots or videos that show the bug here.
placeholder: Drag and drop the screenshots/videos into this box.
validations:
required: false
- type: textarea
attributes:
label: Solution
description: If applicable, add a possible solution.
validations:
required: false
- type: textarea
attributes:
label: Additional context
description: Add additional context here.
validations:
required: false
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: Your issue will be closed if you haven't done these steps.
options:
- label: I have searched the existing issues and this is a new and no duplicate or related to another open issue.
required: true
- label: I have written a short but informative title.
required: true
- label: I filled out all of the requested information in this issue properly.
required: true

View File

@@ -1,8 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: 📃 Documentation
url: https://github.com/revanced/revanced-documentation/
about: Don't know how or where to start? Check out our documentation!
- name: 🗨 Discussions
url: https://github.com/revanced/revanced-suggestions/discussions
about: Got something you think should change or be added? Search for or start a new discussion!

View File

@@ -1,41 +0,0 @@
name: ⭐ Patch Request
description: Create a detailed patch request.
title: 'feat: '
labels: [patch-request]
body:
- type: textarea
attributes:
label: Application
description: Which application is this patch for?
validations:
required: true
- type: textarea
attributes:
label: Issue
description: What is the issue this patch should solve?
validations:
required: true
- type: textarea
attributes:
label: Patch
description: "Describe the patch you'd like to see in detail."
validations:
required: true
- type: textarea
attributes:
label: Motivation
description: Why should your patch request be considered? What makes it valuable to the community?
validations:
required: true
- type: checkboxes
id: acknowledgements
attributes:
label: Acknowledgements
description: Your issue will be closed if you haven't done these steps.
options:
- label: I have searched the existing issues and this is a new and no duplicate or related to another open issue.
required: true
- label: I have written a short but informative title.
required: true
- label: I filled out all of the requested information in this issue properly.
required: true

2
.github/config.yml vendored
View File

@@ -1,2 +0,0 @@
firstPRMergeComment: >
Thank you for contributing to ReVanced. Join us on [Discord](https://revanced.app/discord) if you want to receive a contributor role.

View File

@@ -1,30 +0,0 @@
name: PR to main
on:
push:
branches:
- dev
workflow_dispatch:
env:
MESSAGE: merge branch `${{ github.head_ref || github.ref_name }}` to `main`
jobs:
pull-request:
name: Open pull request
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Open pull request
uses: repo-sync/pull-request@v2
with:
destination_branch: 'main'
pr_title: 'chore: ${{ env.MESSAGE }}'
pr_body: |
This pull request will ${{ env.MESSAGE }}.
## Dependencies before merge
- [ ] https://github.com/revanced/revanced-integrations
pr_draft: true

View File

@@ -1,5 +1,4 @@
name: Release
on:
workflow_dispatch:
push:
@@ -10,36 +9,36 @@ on:
branches:
- main
- dev
jobs:
release:
name: Release
runs-on: ubuntu-latest
runs-on: ubuntu-18.04
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v2
with:
# Make sure the release step uses its own credentials:
# https://github.com/cycjimmy/semantic-release-action#private-packages
persist-credentials: false
fetch-depth: 0
- name: Cache
uses: actions/cache@v3
- name: Setup JDK
uses: actions/setup-java@v2
with:
path: |
${{ runner.home }}/.gradle/caches
${{ runner.home }}/.gradle/wrapper
.gradle
build
node_modules
key: ${{ runner.os }}-gradle-npm-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', 'package-lock.json') }}
java-version: '17'
distribution: 'adopt'
cache: gradle
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: "lts/*"
- name: Setup Android SDK
uses: android-actions/setup-android@v2
- name: Build with Gradle
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew generateMeta clean --no-daemon
run: ./gradlew build clean
- name: Install Android build-tools
run: sdkmanager "build-tools;32.0.0"
- name: Setup semantic-release
run: npm install
run: npm install -g semantic-release @semantic-release/git @semantic-release/changelog gradle-semantic-release-plugin -D
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }}
run: npm exec semantic-release
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx semantic-release

11
.gitignore vendored
View File

@@ -114,13 +114,4 @@ gradle-app.setting
# gradle/wrapper/gradle-wrapper.properties
# Potentially copyrighted test APK
*.apk
# Ignore vscode config
.vscode/
# Dependency directories
node_modules/
# gradle properties, due to Github token
./gradle.properties
*.apk

1
.idea/.gitignore generated vendored
View File

@@ -6,4 +6,3 @@
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/
/kotlinc.xml

2
.idea/misc.xml generated
View File

@@ -4,5 +4,5 @@
<component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="azul-17" project-jdk-type="JavaSDK" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="azul-17" project-jdk-type="JavaSDK" />
</project>

View File

@@ -7,13 +7,7 @@
}
],
"plugins": [
[
"@semantic-release/commit-analyzer", {
"releaseRules": [
{ "type": "build", "scope": "revanced-patcher", "release": "patch" }
]
}
],
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"gradle-semantic-release-plugin",
@@ -21,10 +15,8 @@
"@semantic-release/git",
{
"assets": [
"README.md",
"CHANGELOG.md",
"gradle.properties",
"patches.json"
"gradle.properties"
]
}
],
@@ -36,17 +28,9 @@
"path": "build/libs/*.jar"
},
{
"path": "patches.json"
"path": "build/libs/*.dex"
}
],
successComment: false
}
],
[
"@saithodev/semantic-release-backmerge",
{
backmergeBranches: [{"from": "main", "to": "dev"}],
clearWorkspace: true
]
}
]
]

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1 @@
## 🧩 ReVanced Patches
Patches for ReVanced.
Repo for all ReVanced patches

View File

@@ -1,5 +1,5 @@
plugins {
kotlin("jvm") version "1.8.20"
kotlin("jvm") version "1.7.0"
}
group = "app.revanced"
@@ -17,41 +17,25 @@ repositories {
password = githubPassword
}
}
// Required for FlexVer-Java
maven {
url = uri("https://repo.sleeping.town")
content {
includeGroup("com.unascribed")
}
}
}
dependencies {
implementation("app.revanced:revanced-patcher:11.0.3")
implementation("app.revanced:multidexlib2:2.5.3-a3836654")
// Required for meta
implementation("com.google.code.gson:gson:2.10.1")
// Required for FlexVer-Java
implementation("com.unascribed:flexver-java:1.0.2")
implementation(kotlin("stdlib"))
// A dependency to the Android library unfortunately fails the build,
// which is why this is required for the patch change-oauth-client-id
compileOnly(project("dummy"))
}
kotlin {
jvmToolchain(11)
implementation("app.revanced:revanced-patcher:2.1.2")
implementation("app.revanced:multidexlib2:2.5.2.r2")
}
tasks {
register<DefaultTask>("generateBundle") {
description = "Generate dex files from build and bundle them in the jar file"
register<DefaultTask>("generateDex") {
description = "Generate dex files from build"
dependsOn(build)
doLast {
val androidHome = System.getenv("ANDROID_HOME") ?: throw GradleException("ANDROID_HOME not found")
val d8 = "${androidHome}/build-tools/33.0.1/d8"
val d8 = "${androidHome}/build-tools/32.0.0/d8"
val input = configurations.archives.get().allArtifacts.files.files.first().absolutePath
val output = input.replace(".jar", ".dex")
val work = File("${buildDir}/libs")
exec {
@@ -61,23 +45,16 @@ tasks {
exec {
workingDir = work
commandLine = listOf("zip", "-u", input, "classes.dex")
commandLine = listOf("mv", "classes.dex", output)
}
}
}
register<JavaExec>("generateMeta") {
description = "Generate metadata for this bundle"
dependsOn(build)
classpath = sourceSets["main"].runtimeClasspath
mainClass.set("app.revanced.meta.PatchesFileGenerator")
}
// Dummy task to fix the Gradle semantic-release plugin.
// Remove this if you forked it to support building only.
// Tracking issue: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435
register<DefaultTask>("publish") {
group = "publish"
description = "Dummy task"
dependsOn(named("generateBundle"), named("generateMeta"))
dependsOn(named("generateDex"))
}
}

View File

@@ -1,9 +0,0 @@
plugins {
id("java")
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(11))
}
}

View File

@@ -1,9 +0,0 @@
package android.os;
import java.io.File;
public final class Environment {
public static File getExternalStorageDirectory() {
throw new UnsupportedOperationException("Stub");
}
}

View File

@@ -1,4 +1,2 @@
org.gradle.parallel = true
org.gradle.caching = true
kotlin.code.style = official
version = 2.186.0-dev.1
version = 2.5.1-dev.1

Binary file not shown.

View File

@@ -1,7 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

281
gradlew vendored
View File

@@ -1,7 +1,7 @@
#!/bin/sh
#!/usr/bin/env sh
#
# Copyright © 2015-2021 the original authors.
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,98 +17,67 @@
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
MAX_FD="maximum"
warn () {
echo "$*"
} >&2
}
die () {
echo
echo "$*"
echo
exit 1
} >&2
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MSYS* | MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -118,9 +87,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD=$JAVA_HOME/bin/java
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -129,120 +98,88 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=$( cygpath --unix "$JAVACMD" )
JAVACMD=`cygpath --unix "$JAVACMD"`
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

15
gradlew.bat vendored
View File

@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,8 +25,7 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -41,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -76,15 +75,13 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal

6722
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +0,0 @@
{
"devDependencies": {
"@saithodev/semantic-release-backmerge": "^3.1.0",
"@semantic-release/changelog": "^6.0.2",
"@semantic-release/git": "^10.0.1",
"gradle-semantic-release-plugin": "^1.7.6",
"semantic-release": "^20.1.0"
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,3 +1 @@
include("dummy")
rootProject.name = "revanced-patches"

View File

@@ -1,45 +1,17 @@
package app.revanced.extensions
import app.revanced.patcher.extensions.MethodFingerprintExtensions.name
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.Method
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
import org.jf.dexlib2.util.MethodUtil
import app.revanced.patcher.util.smali.toInstruction
import org.jf.dexlib2.builder.MutableMethodImplementation
import org.w3c.dom.Node
// TODO: populate this to all patches
/**
* Convert a [MethodFingerprint] to a [PatchResultError].
*
* @return A [PatchResultError] for the [MethodFingerprint].
*/
internal fun MethodFingerprint.toErrorResult() = PatchResultError("Failed to resolve $name")
/**
* Find the [MutableMethod] from a given [Method] in a [MutableClass].
*
* @param method The [Method] to find.
* @return The [MutableMethod].
*/
internal fun MutableClass.findMutableMethodOf(method: Method) = this.methods.first {
MethodUtil.methodSignaturesMatch(it, method)
}
/**
* apply a transform to all methods of the class
*
* @param transform the transformation function. original method goes in, transformed method goes out
*/
internal fun MutableClass.transformMethods(transform: MutableMethod.() -> MutableMethod) {
val transformedMethods = methods.map { it.transform() }
methods.clear()
methods.addAll(transformedMethods)
internal fun MutableMethodImplementation.injectHideCall(
index: Int,
register: Int
) {
this.addInstruction(
index,
"invoke-static { v$register }, Lapp/revanced/integrations/patches/HideHomeAdsPatch;->HideHomeAds(Landroid/view/View;)V".toInstruction()
)
}
internal fun Node.doRecursively(action: (Node) -> Unit) {
@@ -47,38 +19,18 @@ internal fun Node.doRecursively(action: (Node) -> Unit) {
for (i in 0 until this.childNodes.length) this.childNodes.item(i).doRecursively(action)
}
internal fun MutableMethod.injectHideViewCall(
insertIndex: Int,
viewRegister: Int,
classDescriptor: String,
targetMethod: String
) = addInstruction(
insertIndex,
"invoke-static { v$viewRegister }, $classDescriptor->$targetMethod(Landroid/view/View;)V"
)
internal fun String.startsWithAny(vararg prefixes: String): Boolean {
for (prefix in prefixes)
if (this.startsWith(prefix))
return true
internal fun Method.findIndexForIdResource(resourceName: String): Int {
fun getIdResourceId(resourceName: String) = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == resourceName
}.id
return indexOfFirstConstantInstructionValue(getIdResourceId(resourceName))
return false
}
/**
* @return the first constant instruction with the value, or -1 if not found.
*/
fun Method.indexOfFirstConstantInstructionValue(constantValue: Long): Int {
return implementation?.let {
it.instructions.indexOfFirst { instruction ->
instruction.opcode == Opcode.CONST && (instruction as WideLiteralInstruction).wideLiteral == constantValue
}
} ?: -1
}
internal fun String.equalsAny(vararg other: String): Boolean {
for (_other in other)
if (this == _other)
return true
/**
* @return if the method contains a constant with the given value.
*/
fun Method.containsConstantInstructionValue(constantValue: Long): Boolean {
return indexOfFirstConstantInstructionValue(constantValue) >= 0
return false
}

View File

@@ -1,70 +0,0 @@
package app.revanced.meta
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
import app.revanced.patcher.extensions.PatchExtensions.dependencies
import app.revanced.patcher.extensions.PatchExtensions.description
import app.revanced.patcher.extensions.PatchExtensions.include
import app.revanced.patcher.extensions.PatchExtensions.options
import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.extensions.PatchExtensions.version
import app.revanced.patcher.patch.PatchOption
import com.google.gson.GsonBuilder
import java.io.File
internal class JsonGenerator : PatchesFileGenerator {
override fun generate(bundle: PatchBundlePatches) {
val patches = bundle.map {
JsonPatch(
it.patchName,
it.description ?: "This patch has no description.",
it.version ?: "0.0.0",
!it.include,
it.options?.map { option ->
JsonPatch.Option(
option.key,
option.title,
option.description,
option.required,
option.let { listOption ->
if (listOption is PatchOption.ListOption<*>) {
listOption.options.toMutableList().toTypedArray()
} else null
}
)
}?.toTypedArray() ?: emptyArray(),
it.dependencies?.map { dep ->
dep.java.patchName
}?.toTypedArray() ?: emptyArray(),
it.compatiblePackages?.map { pkg ->
JsonPatch.CompatiblePackage(pkg.name, pkg.versions)
}?.toTypedArray() ?: emptyArray()
)
}
val json = File("patches.json")
json.writeText(GsonBuilder().serializeNulls().create().toJson(patches))
}
private class JsonPatch(
val name: String,
val description: String,
val version: String,
val excluded: Boolean,
val options: Array<Option>,
val dependencies: Array<String>,
val compatiblePackages: Array<CompatiblePackage>,
) {
class CompatiblePackage(
val name: String,
val versions: Array<String>,
)
class Option(
val key: String,
val title: String,
val description: String,
val required: Boolean,
val choices: Array<*>?,
)
}
}

View File

@@ -1,25 +0,0 @@
package app.revanced.meta
import app.revanced.patcher.data.Context
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.util.patch.PatchBundle
import java.io.File
internal typealias PatchBundlePatches = List<Class<out Patch<Context>>>
internal interface PatchesFileGenerator {
fun generate(bundle: PatchBundlePatches)
private companion object {
@JvmStatic
fun main(args: Array<String>) = PatchBundle.Jar(
File("build/libs/").listFiles()!!.first {
it.name.startsWith("revanced-patches-") && it.name.endsWith(".jar")
}.absolutePath
).loadPatches().also {
if (it.isEmpty()) throw IllegalStateException("No patches found")
}.let { bundle ->
arrayOf(JsonGenerator()).forEach { it.generate(bundle) }
}
}
}

View File

@@ -1,45 +0,0 @@
package app.revanced.patches.all.activity.exportAll.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.Patch
@Patch(false)
@Name("Export all activities")
@Description("Makes all app activities exportable.")
@Version("0.0.1")
class ExportAllActivitiesPatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
context.xmlEditor["AndroidManifest.xml"].use { editor ->
val document = editor.file
val activities = document.getElementsByTagName("activity")
for(i in 0..activities.length) {
activities.item(i)?.apply {
val exportedAttribute = attributes.getNamedItem(EXPORTED_FLAG)
if (exportedAttribute != null) {
if (exportedAttribute.nodeValue != "true")
exportedAttribute.nodeValue = "true"
}
// Reason why the attribute is added in the case it does not exist:
// https://github.com/revanced/revanced-patches/pull/1751/files#r1141481604
else document.createAttribute(EXPORTED_FLAG)
.apply { value = "true" }
.let(attributes::setNamedItem)
}
}
}
return PatchResultSuccess()
}
private companion object {
const val EXPORTED_FLAG = "android:exported"
}
}

View File

@@ -1,208 +0,0 @@
package app.revanced.patches.all.connectivity.wifi.spoof.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.annotations.RequiresIntegrations
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.util.patch.*
import org.jf.dexlib2.iface.ClassDef
import org.jf.dexlib2.iface.Method
import org.jf.dexlib2.iface.instruction.Instruction
import java.util.*
@Patch(false)
@Name("Spoof wifi connection")
@Description("Spoofs an existing Wi-Fi connection.")
@Version("0.0.1")
@RequiresIntegrations
internal class SpoofWifiPatch : AbstractTransformInstructionsPatch<Instruction35cInfo>() {
private companion object {
const val INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX = "Lapp/revanced/all/connectivity/wifi/spoof/SpoofWifiPatch"
const val INTEGRATIONS_CLASS_DESCRIPTOR = "${INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX};"
}
// Information about method calls we want to replace
enum class MethodCall(
override val definedClassName: String,
override val methodName: String,
override val methodParams: Array<String>,
override val returnType: String,
): IMethodCall {
GetSystemService1(
"Landroid/content/Context;",
"getSystemService",
arrayOf("Ljava/lang/String;"),
"Ljava/lang/Object;",
),
GetSystemService2(
"Landroid/content/Context;",
"getSystemService",
arrayOf("Ljava/lang/Class;"),
"Ljava/lang/Object;",
),
GetActiveNetworkInfo(
"Landroid/net/ConnectivityManager;",
"getActiveNetworkInfo",
arrayOf(),
"Landroid/net/NetworkInfo;",
),
IsConnected(
"Landroid/net/NetworkInfo;",
"isConnected",
arrayOf(),
"Z",
),
IsConnectedOrConnecting(
"Landroid/net/NetworkInfo;",
"isConnectedOrConnecting",
arrayOf(),
"Z",
),
IsAvailable(
"Landroid/net/NetworkInfo;",
"isAvailable",
arrayOf(),
"Z",
),
GetState(
"Landroid/net/NetworkInfo;",
"getState",
arrayOf(),
"Landroid/net/NetworkInfo\$State;",
),
GetDetailedState(
"Landroid/net/NetworkInfo;",
"getDetailedState",
arrayOf(),
"Landroid/net/NetworkInfo\$DetailedState;",
),
IsActiveNetworkMetered(
"Landroid/net/ConnectivityManager;",
"isActiveNetworkMetered",
arrayOf(),
"Z",
),
GetActiveNetwork(
"Landroid/net/ConnectivityManager;",
"getActiveNetwork",
arrayOf(),
"Landroid/net/Network;",
),
GetNetworkInfo(
"Landroid/net/ConnectivityManager;",
"getNetworkInfo",
arrayOf("Landroid/net/Network;"),
"Landroid/net/NetworkInfo;",
),
HasTransport(
"Landroid/net/NetworkCapabilities;",
"hasTransport",
arrayOf("I"),
"Z",
),
HasCapability(
"Landroid/net/NetworkCapabilities;",
"hasCapability",
arrayOf("I"),
"Z",
),
RegisterBestMatchingNetworkCallback(
"Landroid/net/ConnectivityManager;",
"registerBestMatchingNetworkCallback",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"),
"V",
),
RegisterDefaultNetworkCallback1(
"Landroid/net/ConnectivityManager;",
"registerDefaultNetworkCallback",
arrayOf("Landroid/net/ConnectivityManager\$NetworkCallback;"),
"V",
),
RegisterDefaultNetworkCallback2(
"Landroid/net/ConnectivityManager;",
"registerDefaultNetworkCallback",
arrayOf("Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"),
"V",
),
RegisterNetworkCallback1(
"Landroid/net/ConnectivityManager;",
"registerNetworkCallback",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;"),
"V",
),
RegisterNetworkCallback2(
"Landroid/net/ConnectivityManager;",
"registerNetworkCallback",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/app/PendingIntent;"),
"V",
),
RegisterNetworkCallback3(
"Landroid/net/ConnectivityManager;",
"registerNetworkCallback",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"),
"V",
),
RequestNetwork1(
"Landroid/net/ConnectivityManager;",
"requestNetwork",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;"),
"V",
),
RequestNetwork2(
"Landroid/net/ConnectivityManager;",
"requestNetwork",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "I"),
"V",
),
RequestNetwork3(
"Landroid/net/ConnectivityManager;",
"requestNetwork",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"),
"V",
),
RequestNetwork4(
"Landroid/net/ConnectivityManager;",
"requestNetwork",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/app/PendingIntent;"),
"V",
),
RequestNetwork5(
"Landroid/net/ConnectivityManager;",
"requestNetwork",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;", "I"),
"V",
),
UnregisterNetworkCallback1(
"Landroid/net/ConnectivityManager;",
"unregisterNetworkCallback",
arrayOf("Landroid/net/ConnectivityManager\$NetworkCallback;"),
"V",
),
UnregisterNetworkCallback2(
"Landroid/net/ConnectivityManager;",
"unregisterNetworkCallback",
arrayOf("Landroid/app/PendingIntent;"),
"V",
);
}
override fun filterMap(
classDef: ClassDef,
method: Method,
instruction: Instruction,
instructionIndex: Int
) = filterMapInstruction35c<MethodCall>(
INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX,
classDef,
instruction,
instructionIndex
)
override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) {
val (methodType, instruction, instructionIndex) = entry
methodType.replaceInvokeVirtualWithIntegrations(INTEGRATIONS_CLASS_DESCRIPTOR, mutableMethod, instruction, instructionIndex)
}
}

View File

@@ -1,37 +0,0 @@
package app.revanced.patches.all.interaction.gestures.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.Patch
@Patch(false)
@Name("Predictive back gesture")
@Description("Enables the predictive back gesture introduced on Android 13.")
@Version("0.0.1")
class PredictiveBackGesturePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
context.xmlEditor["AndroidManifest.xml"].use { editor ->
val document = editor.file
with(document.getElementsByTagName("application").item(0)) {
if (attributes.getNamedItem(FLAG) != null) return@with
document.createAttribute(FLAG)
.apply { value = "true" }
.let(attributes::setNamedItem)
}
}
return PatchResultSuccess()
}
private companion object {
const val FLAG = "android:enableOnBackInvokedCallback"
}
}

View File

@@ -1,30 +0,0 @@
package app.revanced.patches.all.misc.debugging.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.*
import app.revanced.patcher.patch.annotations.Patch
import org.w3c.dom.Element
@Patch(false)
@Name("Enable android debugging")
@Description("Enables Android debugging capabilities.")
@Version("0.0.1")
class EnableAndroidDebuggingPatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
context.xmlEditor["AndroidManifest.xml"].use { dom ->
val applicationNode = dom
.file
.getElementsByTagName("application")
.item(0) as Element
// set application as debuggable
applicationNode.setAttribute("android:debuggable", "true")
}
return PatchResultSuccess()
}
}

View File

@@ -1,50 +0,0 @@
package app.revanced.patches.all.misc.packagename.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.*
import app.revanced.patcher.patch.annotations.Patch
import org.w3c.dom.Element
@Patch(false)
@Name("Change package name")
@Description("Changes the package name.")
@Version("0.0.1")
class ChangePackageNamePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
packageName?.let { packageName ->
val packageNameRegex = Regex("^[a-z]\\w*(\\.[a-z]\\w*)+\$")
if (!packageName.matches(packageNameRegex))
return PatchResultError("Invalid package name")
var originalPackageName: String
context.xmlEditor["AndroidManifest.xml"].use { editor ->
val manifest = editor.file.getElementsByTagName("manifest").item(0) as Element
originalPackageName = manifest.getAttribute("package")
}
if (!originalPackageName.matches(packageNameRegex))
return PatchResultError("Failed to get the original package name")
context["AndroidManifest.xml"].apply {
readText().replace(originalPackageName, packageName).let(::writeText)
}
} ?: return PatchResultError("No package name provided")
return PatchResultSuccess()
}
companion object : OptionsContainer() {
var packageName: String? by option(
PatchOption.StringOption(
key = "packageName",
default = null,
title = "Package name",
description = "The name of the package to rename of the app.",
)
)
}
}

View File

@@ -1,66 +0,0 @@
package app.revanced.patches.all.screencapture.removerestriction.bytecode.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.annotations.RequiresIntegrations
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.all.screencapture.removerestriction.resource.patch.RemoveCaptureRestrictionResourcePatch
import app.revanced.util.patch.*
import org.jf.dexlib2.iface.ClassDef
import org.jf.dexlib2.iface.Method
import org.jf.dexlib2.iface.instruction.Instruction
@Patch(false)
@Name("Remove screen capture restriction")
@Description("Removes the restriction of capturing audio from apps that normally wouldn't allow it.")
@Version("0.0.1")
@DependsOn([RemoveCaptureRestrictionResourcePatch::class])
@RequiresIntegrations
internal class RemoveCaptureRestrictionPatch : AbstractTransformInstructionsPatch<Instruction35cInfo>() {
// Information about method calls we want to replace
enum class MethodCall(
override val definedClassName: String,
override val methodName: String,
override val methodParams: Array<String>,
override val returnType: String
): IMethodCall {
SetAllowedCapturePolicySingle(
"Landroid/media/AudioAttributes\$Builder;",
"setAllowedCapturePolicy",
arrayOf("I"),
"Landroid/media/AudioAttributes\$Builder;",
),
SetAllowedCapturePolicyGlobal(
"Landroid/media/AudioManager;",
"setAllowedCapturePolicy",
arrayOf("I"),
"V",
);
}
override fun filterMap(
classDef: ClassDef,
method: Method,
instruction: Instruction,
instructionIndex: Int
) = filterMapInstruction35c<MethodCall>(
INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX,
classDef,
instruction,
instructionIndex
)
override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) {
val (methodType, instruction, instructionIndex) = entry
methodType.replaceInvokeVirtualWithIntegrations(INTEGRATIONS_CLASS_DESCRIPTOR, mutableMethod, instruction, instructionIndex)
}
private companion object {
const val INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX =
"Lapp/revanced/all/screencapture/removerestriction/RemoveScreencaptureRestrictionPatch"
const val INTEGRATIONS_CLASS_DESCRIPTOR = "$INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX;"
}
}

View File

@@ -1,27 +0,0 @@
package app.revanced.patches.all.screencapture.removerestriction.resource.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import org.w3c.dom.Element
@Description("Sets allowAudioPlaybackCapture in manifest to true.")
internal class RemoveCaptureRestrictionResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
// create an xml editor instance
context.xmlEditor["AndroidManifest.xml"].use { dom ->
// get the application node
val applicationNode = dom
.file
.getElementsByTagName("application")
.item(0) as Element
// set allowAudioPlaybackCapture attribute to true
applicationNode.setAttribute("android:allowAudioPlaybackCapture", "true")
}
return PatchResultSuccess()
}
}

View File

@@ -1,59 +0,0 @@
package app.revanced.patches.all.screenshot.removerestriction.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.annotations.RequiresIntegrations
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.util.patch.*
import org.jf.dexlib2.iface.ClassDef
import org.jf.dexlib2.iface.Method
import org.jf.dexlib2.iface.instruction.Instruction
import java.util.*
@Patch(false)
@Name("Remove screenshot restriction")
@Description("Removes the restriction of taking screenshots in apps that normally wouldn't allow it.")
@Version("0.0.1")
@RequiresIntegrations
internal class RemoveScreenshotRestrictionPatch : AbstractTransformInstructionsPatch<Instruction35cInfo>() {
private companion object {
const val INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX =
"Lapp/revanced/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch"
const val INTEGRATIONS_CLASS_DESCRIPTOR = "$INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX;"
}
// Information about method calls we want to replace
enum class MethodCall(
override val definedClassName: String,
override val methodName: String,
override val methodParams: Array<String>,
override val returnType: String
): IMethodCall {
SetFlags(
"Landroid/view/Window;",
"setFlags",
arrayOf("I", "I"),
"V",
);
}
override fun filterMap(
classDef: ClassDef,
method: Method,
instruction: Instruction,
instructionIndex: Int
) = filterMapInstruction35c<MethodCall>(
INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX,
classDef,
instruction,
instructionIndex
)
override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) {
val (methodType, instruction, instructionIndex) = entry
methodType.replaceInvokeVirtualWithIntegrations(INTEGRATIONS_CLASS_DESCRIPTOR, mutableMethod, instruction, instructionIndex)
}
}

View File

@@ -1,7 +0,0 @@
package app.revanced.patches.backdrops.misc.pro.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.backdrops.wallpapers", arrayOf("4.52"))])
internal annotation class ProUnlockCompatibility

View File

@@ -1,18 +0,0 @@
package app.revanced.patches.backdrops.misc.pro.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode
object ProUnlockFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/backdrops/wallpapers/data/local/DatabaseHandlerIAB;"
&& methodDef.name == "lambda\$existPurchase\$0"
}
)

View File

@@ -1,44 +0,0 @@
package app.revanced.patches.backdrops.misc.pro.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.backdrops.misc.pro.annotations.ProUnlockCompatibility
import app.revanced.patches.backdrops.misc.pro.fingerprints.ProUnlockFingerprint
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Patch
@Name("Pro unlock")
@Description("Unlocks pro-only functions.")
@ProUnlockCompatibility
@Version("0.0.1")
class ProUnlockPatch : BytecodePatch(
listOf(ProUnlockFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
ProUnlockFingerprint.result?.let { result ->
val registerIndex = result.scanResult.patternScanResult!!.endIndex - 1
result.mutableMethod.apply {
val register = getInstruction<OneRegisterInstruction>(registerIndex).registerA
addInstruction(
result.scanResult.patternScanResult!!.endIndex,
"""
const/4 v$register, 0x1
"""
)
}
} ?: return ProUnlockFingerprint.toErrorResult()
return PatchResultSuccess()
}
}

View File

@@ -1,8 +0,0 @@
package app.revanced.patches.candylinkvpn.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.candylink.openvpn")])
@Target(AnnotationTarget.CLASS)
internal annotation class UnlockProCompatibility

View File

@@ -1,11 +0,0 @@
package app.revanced.patches.candylinkvpn.fingereprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object IsPremiumPurchasedFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("PreferenceProvider;") &&
methodDef.name == "isPremiumPurchased"
}
) {
}

View File

@@ -1,35 +0,0 @@
package app.revanced.patches.candylinkvpn.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.candylinkvpn.annotations.UnlockProCompatibility
import app.revanced.patches.candylinkvpn.fingereprints.IsPremiumPurchasedFingerprint
@Patch
@Name("Unlock pro")
@Description("Unlocks premium features.")
@UnlockProCompatibility
@Version("0.0.1")
class UnlockProPatch : BytecodePatch(
listOf(IsPremiumPurchasedFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
IsPremiumPurchasedFingerprint.result?.mutableMethod?.addInstructions(
0,
"""
const/4 v0, 0x1
return v0
"""
) ?: return IsPremiumPurchasedFingerprint.toErrorResult()
return PatchResultSuccess()
}
}

View File

@@ -1,30 +0,0 @@
package app.revanced.patches.finanzonline.detection.bootloader.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
// Located @ at.gv.bmf.bmf2go.taxequalization.tools.utils.AttestationHelper#isBootStateOk (3.0.1)
object BootStateFingerprint : MethodFingerprint(
"Z",
accessFlags = AccessFlags.PUBLIC.value,
opcodes = listOf(
Opcode.INVOKE_DIRECT,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_4,
Opcode.NEW_ARRAY,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_4,
Opcode.APUT_OBJECT,
Opcode.CONST_STRING,
Opcode.INVOKE_STATIC,
Opcode.SGET_OBJECT,
Opcode.IF_EQ,
Opcode.SGET_OBJECT,
Opcode.IF_NE,
Opcode.GOTO,
Opcode.MOVE,
Opcode.RETURN
)
)

View File

@@ -1,11 +0,0 @@
package app.revanced.patches.finanzonline.detection.bootloader.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
// Located @ at.gv.bmf.bmf2go.taxequalization.tools.utils.AttestationHelper#createKey (3.0.1)
object CreateKeyFingerprint : MethodFingerprint(
"Z",
accessFlags = AccessFlags.PUBLIC.value,
strings = listOf("attestation", "SHA-256", "random", "EC", "AndroidKeyStore")
)

View File

@@ -1,39 +0,0 @@
package app.revanced.patches.finanzonline.detection.bootloader.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.finanzonline.detection.bootloader.fingerprints.BootStateFingerprint
import app.revanced.patches.finanzonline.detection.bootloader.fingerprints.CreateKeyFingerprint
import app.revanced.patches.finanzonline.detection.shared.annotations.DetectionCompatibility
@Patch
@Name("Remove bootloader detection")
@Description("Removes the check for an unlocked bootloader.")
@DetectionCompatibility
@Version("0.0.1")
class BootloaderDetectionPatch : BytecodePatch(
listOf(CreateKeyFingerprint, BootStateFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
arrayOf(CreateKeyFingerprint, BootStateFingerprint).forEach { fingerprint ->
fingerprint.result?.mutableMethod?.addInstructions(
0,
"""
const/4 v0, 0x1
return v0
"""
) ?: return fingerprint.toErrorResult()
}
return PatchResultSuccess()
}
}

View File

@@ -1,22 +0,0 @@
package app.revanced.patches.finanzonline.detection.root.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
// Located @ at.gv.bmf.bmf2go.taxequalization.tools.utils.RootDetection#isRooted (3.0.1)
object RootDetectionFingerprint : MethodFingerprint(
"L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("L"),
opcodes = listOf(
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.RETURN_OBJECT
)
)

View File

@@ -1,35 +0,0 @@
package app.revanced.patches.finanzonline.detection.root.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.finanzonline.detection.root.fingerprints.RootDetectionFingerprint
import app.revanced.patches.finanzonline.detection.shared.annotations.DetectionCompatibility
@Patch
@Name("Remove root detection")
@Description("Removes the check for root permissions.")
@DetectionCompatibility
@Version("0.0.1")
class RootDetectionPatch : BytecodePatch(
listOf(RootDetectionFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
RootDetectionFingerprint.result?.mutableMethod?.addInstructions(
0,
"""
sget-object v0, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean;
return-object v0
"""
) ?: return RootDetectionFingerprint.toErrorResult()
return PatchResultSuccess()
}
}

View File

@@ -1,8 +0,0 @@
package app.revanced.patches.finanzonline.detection.shared.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("at.gv.bmf.bmf2go")])
@Target(AnnotationTarget.CLASS)
internal annotation class DetectionCompatibility

View File

@@ -1,12 +0,0 @@
package app.revanced.patches.googlerecorder.restrictions.fingereprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object OnApplicationCreateFingerprint : MethodFingerprint(
strings = listOf("com.google.android.feature.PIXEL_2017_EXPERIENCE"),
customFingerprint = custom@{ methodDef, classDef ->
if (methodDef.name != "onCreate") return@custom false
classDef.type.endsWith("RecorderApplication;")
}
)

View File

@@ -1,45 +0,0 @@
package app.revanced.patches.googlerecorder.restrictions.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Package
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.googlerecorder.restrictions.fingereprints.OnApplicationCreateFingerprint
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Patch
@Name("Remove device restrictions")
@Description("Removes restrictions from using the app on any device.")
@Compatibility([Package("com.google.android.apps.recorder")])
@Version("0.0.1")
class RemoveDeviceRestrictions : BytecodePatch(
listOf(OnApplicationCreateFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
OnApplicationCreateFingerprint.result?.let {
val featureStringIndex = it.scanResult.stringsScanResult!!.matches.first().index
it.mutableMethod.apply {
// Remove check for device restrictions.
removeInstructions(featureStringIndex - 2, 5)
val featureAvailableRegister = getInstruction<OneRegisterInstruction>(featureStringIndex).registerA
// Override "isPixelDevice()" to return true.
addInstruction(featureStringIndex, "const/4 v$featureAvailableRegister, 0x1")
}
} ?: return OnApplicationCreateFingerprint.toErrorResult()
return PatchResultSuccess()
}
}

View File

@@ -1,12 +0,0 @@
package app.revanced.patches.hexeditor.ad.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[
Package("com.myprog.hexedit")
]
)
@Target(AnnotationTarget.CLASS)
internal annotation class HexEditorAdsCompatibility

View File

@@ -1,9 +0,0 @@
package app.revanced.patches.hexeditor.ad.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object PrimaryAdsFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("PreferencesHelper;") && methodDef.name == "isAdsDisabled"
}
)

View File

@@ -1,39 +0,0 @@
package app.revanced.patches.hexeditor.ad.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.hexeditor.ad.annotations.HexEditorAdsCompatibility
import app.revanced.patches.hexeditor.ad.fingerprints.PrimaryAdsFingerprint
@Patch
@Name("Disable ads")
@Description("Disables ads in HexEditor.")
@HexEditorAdsCompatibility
@Version("0.0.1")
class HexEditorAdsPatch : BytecodePatch(
listOf(
PrimaryAdsFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
val method = PrimaryAdsFingerprint.result!!.mutableMethod
method.replaceInstructions(
0,
"""
const/4 v0, 0x1
return v0
"""
)
return PatchResultSuccess()
}
}

View File

@@ -1,8 +0,0 @@
package app.revanced.patches.iconpackstudio.misc.pro.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("ginlemon.iconpackstudio")])
@Target(AnnotationTarget.CLASS)
internal annotation class UnlockProCompatibility

View File

@@ -1,8 +0,0 @@
package app.revanced.patches.iconpackstudio.misc.pro.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object CheckProFingerprint : MethodFingerprint(
"Z",
customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("IPSPurchaseRepository;")}
)

View File

@@ -1,37 +0,0 @@
package app.revanced.patches.iconpackstudio.misc.pro.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.iconpackstudio.misc.pro.annotations.UnlockProCompatibility
import app.revanced.patches.iconpackstudio.misc.pro.fingerprints.CheckProFingerprint
@Patch
@Name("Unlock pro")
@Description("Unlocks all pro features.")
@UnlockProCompatibility
@Version("0.0.1")
class UnlockProPatch : BytecodePatch(
listOf(
CheckProFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
val method = CheckProFingerprint.result!!.mutableMethod
method.addInstructions(
0,
"""
const/4 v0, 0x1
return v0
"""
)
return PatchResultSuccess()
}
}

View File

@@ -1,12 +0,0 @@
package app.revanced.patches.idaustria.detection.root.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
object RootDetectionFingerprint : MethodFingerprint(
"V",
accessFlags = AccessFlags.PUBLIC.value,
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/DeviceIntegrityCheck;")
}
)

View File

@@ -1,27 +0,0 @@
package app.revanced.patches.idaustria.detection.root.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.idaustria.detection.root.fingerprints.RootDetectionFingerprint
import app.revanced.patches.idaustria.detection.shared.annotations.DetectionCompatibility
@Patch
@Name("Remove root detection")
@Description("Removes the check for root permissions and unlocked bootloader.")
@DetectionCompatibility
@Version("0.0.1")
class RootDetectionPatch : BytecodePatch(
listOf(RootDetectionFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
RootDetectionFingerprint.result!!.mutableMethod.addInstruction(0, "return-void")
return PatchResultSuccess()
}
}

View File

@@ -1,8 +0,0 @@
package app.revanced.patches.idaustria.detection.shared.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("at.gv.oe.app")])
@Target(AnnotationTarget.CLASS)
internal annotation class DetectionCompatibility

View File

@@ -1,13 +0,0 @@
package app.revanced.patches.idaustria.detection.signature.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
object SpoofSignatureFingerprint : MethodFingerprint(
"L",
parameters = listOf("L"),
accessFlags = AccessFlags.PRIVATE.value,
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/SL2Step1Task;") && methodDef.name == "getPubKey"
}
)

View File

@@ -1,47 +0,0 @@
package app.revanced.patches.idaustria.detection.signature.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.idaustria.detection.shared.annotations.DetectionCompatibility
import app.revanced.patches.idaustria.detection.signature.fingerprints.SpoofSignatureFingerprint
@Patch
@Name("Spoof signature")
@Description("Spoofs the signature of the app.")
@DetectionCompatibility
@Version("0.0.1")
class SpoofSignaturePatch : BytecodePatch(
listOf(SpoofSignatureFingerprint)
) {
companion object {
const val EXPECTED_SIGNATURE = "OpenSSLRSAPublicKey{modulus=ac3e6fd6050aa7e0d6010ae58190404cd89a56935b44f6fee" +
"067c149768320026e10b24799a1339e414605e448e3f264444a327b9ae292be2b62ad567dd1800dbed4a88f718a33dc6db6b" +
"f5178aa41aa0efff8a3409f5ca95dbfccd92c7b4298966df806ea7a0204a00f0e745f6d9f13bdf24f3df715d7b62c1600906" +
"15de1c8a956b9286764985a3b3c060963c435fb9481a5543aaf0671fc2dba6c5c2b17d1ef1d85137f14dc9bbdf3490288087" +
"324cd48341cce64fabf6a9b55d1a7bf23b2fcdff451fd85bf0c7feb0a5e884d7c5c078e413149566a12a686e6efa70ae5161" +
"a0201307692834cda336c55157fef125e67c01c1359886f94742105596b42a790404bbcda5dad6a65f115aaff5e45ef3c28b" +
"2316ff6cef07aa49a45aa58c07bf258051b13ef449ccb37a3679afd5cfb9132f70bb9d931a937897544f90c3bcc80ed012e9" +
"f6ba020b8cdc23f8c29ac092b88f0e370ff9434e4f0f359e614ae0868dc526fa41e4b7596533e8d10279b66e923ecd9f0b20" +
"0def55be2c1f6f9c72c92fb45d7e0a9ac571cb38f0a9a37bb33ea06f223fde8c7a92e8c47769e386f9799776e8f110c21df2" +
"77ef1be61b2c01ebdabddcbf53cc4b6fd9a3c445606ee77b3758162c80ad8f8137b3c6864e92db904807dcb2be9d7717dd21" +
"bf42c121d620ddfb7914f7a95c713d9e1c1b7bdb4a03d618e40cf7e9e235c0b5687e03b7ab3,publicExponent=10001}"
}
override fun execute(context: BytecodeContext): PatchResult {
SpoofSignatureFingerprint.result!!.mutableMethod.addInstructions(
0,
"""
const-string v0, "$EXPECTED_SIGNATURE"
return-object v0
"""
)
return PatchResultSuccess()
}
}

View File

@@ -1,9 +0,0 @@
package app.revanced.patches.inshorts.ad.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.nis.app")])
@Target(AnnotationTarget.CLASS)
internal annotation class HideAdsCompatibility

View File

@@ -1,8 +0,0 @@
package app.revanced.patches.inshorts.ad.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object InshortsAdsFingerprint : MethodFingerprint(
"V",
strings = listOf("GoogleAdLoader","exception in requestAd"),
)

View File

@@ -1,38 +0,0 @@
package app.revanced.patches.inshorts.ad.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.inshorts.ad.annotations.HideAdsCompatibility
import app.revanced.patches.inshorts.ad.fingerprints.InshortsAdsFingerprint
@Patch
@Name("Hide ads")
@Description("Removes ads from Inshorts.")
@HideAdsCompatibility
@Version("0.0.1")
class HideAdsPatch : BytecodePatch(
listOf(InshortsAdsFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
InshortsAdsFingerprint.result?.let { result ->
result.apply {
mutableMethod.addInstruction(
0,
"""
return-void
"""
)
}
} ?: return InshortsAdsFingerprint.toErrorResult()
return PatchResultSuccess()
}
}

View File

@@ -1,7 +0,0 @@
package app.revanced.patches.instagram.patches.ads.timeline.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object MediaFingerprint : MethodFingerprint(
strings = listOf("force_overlay", "Media#updateFields", "live_reels_metadata")
)

View File

@@ -1,25 +0,0 @@
package app.revanced.patches.instagram.patches.ads.timeline.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object ShowAdFingerprint : MethodFingerprint(
"Z",
AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.FINAL,
listOf("L", "L", "Z", "Z"),
opcodes = listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.RETURN,
Opcode.CONST_4,
Opcode.GOTO,
Opcode.CONST_4,
Opcode.GOTO,
Opcode.CONST_4,
Opcode.GOTO,
Opcode.CONST_4,
),
)

View File

@@ -1,18 +0,0 @@
package app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads
import org.jf.dexlib2.Opcode
object GenericMediaAdFingerprint : MediaAdFingerprint(
opcodes = listOf(
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.CONST_4,
Opcode.RETURN,
)
) {
override fun toString() = result!!.method.toString()
}

View File

@@ -1,24 +0,0 @@
package app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.ClassDef
import org.jf.dexlib2.iface.Method
abstract class MediaAdFingerprint(
returnType: String? = "Z",
accessFlags: Int? = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters: Iterable<String>? = listOf(),
opcodes: Iterable<Opcode>?,
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null
) : MethodFingerprint(
returnType,
accessFlags,
parameters,
opcodes,
customFingerprint = customFingerprint
) {
abstract override fun toString(): String
}

View File

@@ -1,29 +0,0 @@
package app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.reference.MethodReference
object PaidPartnershipAdFingerprint : MediaAdFingerprint(
"V",
null,
listOf("L", "L"),
listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IPUT_BOOLEAN,
Opcode.IPUT_BOOLEAN
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("ClipsEditMetadataController;")
}
) {
override fun toString() = result!!.let {
val adCheckIndex = it.scanResult.patternScanResult!!.startIndex
val adCheckInstruction = it.method.implementation!!.instructions.elementAt(adCheckIndex)
val adCheckMethod = (adCheckInstruction as ReferenceInstruction).reference as MethodReference
adCheckMethod.toString()
}
}

View File

@@ -1,21 +0,0 @@
package app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads
import org.jf.dexlib2.Opcode
object ShoppingAdFingerprint : MediaAdFingerprint(
opcodes = listOf(
Opcode.IF_EQZ,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.XOR_INT_LIT8,
Opcode.IF_EQZ,
)
) {
override fun toString() = result!!.method.toString()
}

View File

@@ -1,106 +0,0 @@
package app.revanced.patches.instagram.patches.ads.timeline.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.*
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.MediaFingerprint
import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ShowAdFingerprint
import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.GenericMediaAdFingerprint
import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.MediaAdFingerprint
import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.PaidPartnershipAdFingerprint
import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.ShoppingAdFingerprint
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Patch
@Name("Hide timeline ads")
@Description("Removes ads from the timeline.")
@Compatibility([Package("com.instagram.android", arrayOf("275.0.0.27.98"))])
@Version("0.0.1")
class HideTimelineAdsPatch : BytecodePatch(
listOf(
ShowAdFingerprint,
MediaFingerprint,
PaidPartnershipAdFingerprint // Unlike the other ads this one is resolved from all classes.
)
) {
override fun execute(context: BytecodeContext): PatchResult {
// region Resolve required methods to check for ads.
ShowAdFingerprint.result ?: return ShowAdFingerprint.toErrorResult()
PaidPartnershipAdFingerprint.result ?: return PaidPartnershipAdFingerprint.toErrorResult()
MediaFingerprint.result?.let {
GenericMediaAdFingerprint.resolve(context, it.classDef)
ShoppingAdFingerprint.resolve(context, it.classDef)
return@let
} ?: return MediaFingerprint.toErrorResult()
// endregion
ShowAdFingerprint.result!!.apply {
// region Create instructions.
val scanStart = scanResult.patternScanResult!!.startIndex
val jumpIndex = scanStart - 1
val mediaInstanceRegister = mutableMethod.getInstruction<FiveRegisterInstruction>(scanStart).registerC
val freeRegister = mutableMethod.getInstruction<OneRegisterInstruction>(jumpIndex).registerA
val returnFalseLabel = "an_ad"
val checkForAdInstructions =
listOf(GenericMediaAdFingerprint, PaidPartnershipAdFingerprint, ShoppingAdFingerprint)
.map(MediaAdFingerprint::toString)
.joinToString("\n") {
"""
invoke-virtual {v$mediaInstanceRegister}, $it
move-result v$freeRegister
if-nez v$freeRegister, :$returnFalseLabel
""".trimIndent()
}.let { "$it\nconst/4 v0, 0x1\nreturn v0" }
// endregion
// region Patch.
val insertIndex = scanStart + 3
mutableMethod.addInstructionsWithLabels(
insertIndex,
checkForAdInstructions,
ExternalLabel(
returnFalseLabel,
mutableMethod.getInstruction(mutableMethod.implementation!!.instructions.size - 2 /* return false = ad */)
)
)
// endregion
// region Jump to checks for ads from previous patch.
mutableMethod.apply {
addInstructionsWithLabels(
jumpIndex + 1,
"if-nez v$freeRegister, :start_check",
ExternalLabel("start_check", getInstruction(insertIndex))
)
}.removeInstruction(jumpIndex)
// endregion
}
return PatchResultSuccess()
}
}

View File

@@ -1,8 +0,0 @@
package app.revanced.patches.irplus.ad.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("net.binarymode.android.irplus")])
@Target(AnnotationTarget.CLASS)
internal annotation class IrplusAdsCompatibility

View File

@@ -1,12 +0,0 @@
package app.revanced.patches.irplus.ad.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
object IrplusAdsFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
listOf("L", "Z"),
strings = listOf("TAGGED")
)

View File

@@ -1,33 +0,0 @@
package app.revanced.patches.irplus.ad.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.irplus.ad.annotations.IrplusAdsCompatibility
import app.revanced.patches.irplus.ad.fingerprints.IrplusAdsFingerprint
@Patch
@Name("Remove ads")
@Description("Removes all ads from the app.")
@IrplusAdsCompatibility
@Version("0.0.1")
class IrplusAdsPatch : BytecodePatch(
listOf(IrplusAdsFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
val method = IrplusAdsFingerprint.result!!.mutableMethod
// By overwriting the second parameter of the method,
// the view which holds the advertisement is removed.
method.addInstruction(0, "const/4 p2, 0x0")
return PatchResultSuccess()
}
}

View File

@@ -1,24 +0,0 @@
package app.revanced.patches.memegenerator.detection.license.fingerprint
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object LicenseValidationFingerprint : MethodFingerprint(
returnType = "Z",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("Landroid/content/Context;"),
opcodes = listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_WIDE,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_WIDE,
Opcode.CMP_LONG,
Opcode.IF_GEZ,
Opcode.CONST_4,
Opcode.RETURN,
Opcode.CONST_4,
Opcode.RETURN
)
)

View File

@@ -1,31 +0,0 @@
package app.revanced.patches.memegenerator.detection.license.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.memegenerator.detection.license.fingerprint.LicenseValidationFingerprint
@Description("Disables Firebase license validation.")
@Version("0.0.1")
class LicenseValidationPatch : BytecodePatch(
listOf(LicenseValidationFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
LicenseValidationFingerprint.result?.apply {
mutableMethod.replaceInstructions(
0,
"""
const/4 p0, 0x1
return p0
"""
)
} ?: throw LicenseValidationFingerprint.toErrorResult()
return PatchResultSuccess()
}
}

View File

@@ -1,35 +0,0 @@
package app.revanced.patches.memegenerator.detection.signature.fingerprint
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@FuzzyPatternScanMethod(2)
object VerifySignatureFingerprint : MethodFingerprint(
returnType = "Z",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("Landroid/app/Activity;"),
opcodes = listOf(
Opcode.SGET_OBJECT,
Opcode.IF_NEZ,
Opcode.INVOKE_STATIC,
Opcode.CONST_4,
Opcode.CONST_4,
Opcode.SGET_OBJECT,
Opcode.ARRAY_LENGTH,
Opcode.IF_GE,
Opcode.AGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.SGET_OBJECT,
Opcode.IF_EQZ,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.CONST_4,
Opcode.RETURN,
Opcode.ADD_INT_LIT8
),
)

View File

@@ -1,31 +0,0 @@
package app.revanced.patches.memegenerator.detection.signature.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.memegenerator.detection.signature.fingerprint.VerifySignatureFingerprint
@Description("Disables detection of incorrect signature.")
@Version("0.0.1")
class SignatureVerificationPatch : BytecodePatch(
listOf(VerifySignatureFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
VerifySignatureFingerprint.result?.apply {
mutableMethod.replaceInstructions(
0,
"""
const/4 p0, 0x1
return p0
"""
)
} ?: throw VerifySignatureFingerprint.toErrorResult()
return PatchResultSuccess()
}
}

View File

@@ -1,17 +0,0 @@
package app.revanced.patches.memegenerator.misc.pro.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.zombodroid.MemeGenerator", arrayOf(
"4.6364",
"4.6370",
"4.6375",
"4.6377",
)
)]
)
@Target(AnnotationTarget.CLASS)
internal annotation class UnlockProCompatibility

View File

@@ -1,22 +0,0 @@
package app.revanced.patches.memegenerator.misc.pro.fingerprint
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object IsFreeVersionFingerprint : MethodFingerprint(
returnType = "Ljava/lang/Boolean;",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
strings = listOf("free"),
parameters = listOf("Landroid/content/Context;"),
opcodes = listOf(
Opcode.SGET,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_STRING,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ
)
)

View File

@@ -1,45 +0,0 @@
package app.revanced.patches.memegenerator.misc.pro.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.memegenerator.detection.license.patch.LicenseValidationPatch
import app.revanced.patches.memegenerator.detection.signature.patch.SignatureVerificationPatch
import app.revanced.patches.memegenerator.misc.pro.annotations.UnlockProCompatibility
import app.revanced.patches.memegenerator.misc.pro.fingerprint.IsFreeVersionFingerprint
@Patch
@Name("Unlock pro")
@Description("Unlocks pro features.")
@DependsOn([
SignatureVerificationPatch::class,
LicenseValidationPatch::class
])
@UnlockProCompatibility
@Version("0.0.1")
class UnlockProVersionPatch : BytecodePatch(
listOf(
IsFreeVersionFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
IsFreeVersionFingerprint.result?.apply {
mutableMethod.replaceInstructions(0,
"""
sget-object p0, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean;
return-object p0
"""
)
} ?: throw IsFreeVersionFingerprint.toErrorResult()
return PatchResultSuccess()
}
}

View File

@@ -1,18 +0,0 @@
package app.revanced.patches.messenger.ads.inbox.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
object LoadInboxAdsFingerprint : MethodFingerprint(
returnType = "V",
strings = listOf(
"ads_load_begin",
"inbox_ads_fetch_start"
),
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/facebook/messaging/business/inboxads/plugins/inboxads/itemsupplier/InboxAdsItemSupplierImplementation;"
}
)

View File

@@ -1,29 +0,0 @@
package app.revanced.patches.messenger.ads.inbox.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.*
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.messenger.ads.inbox.fingerprints.LoadInboxAdsFingerprint
@Patch
@Name("Hide inbox ads")
@Description("Hides ads in inbox.")
@Compatibility([Package("com.facebook.orca")])
@Version("0.0.1")
class HideInboxAdsPatch : BytecodePatch(
listOf(LoadInboxAdsFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
LoadInboxAdsFingerprint.result?.mutableMethod?.apply {
this.replaceInstruction(0, "return-void")
} ?: return LoadInboxAdsFingerprint.toErrorResult()
return PatchResultSuccess()
}
}

View File

@@ -1,15 +0,0 @@
package app.revanced.patches.messenger.inputfield.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.dexbacked.value.DexBackedStringEncodedValue
object SendTypingIndicatorFingerprint : MethodFingerprint(
returnType = "V",
parameters = listOf(),
customFingerprint = { methodDef, classDef ->
methodDef.name == "run" && classDef.fields.any {
it.name == "__redex_internal_original_name"
&& (it.initialValue as? DexBackedStringEncodedValue)?.value == "ConversationTypingContext\$sendActiveStateRunnable\$1"
}
}
)

View File

@@ -1,18 +0,0 @@
package app.revanced.patches.messenger.inputfield.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode
object SwitchMessangeInputEmojiButtonFingerprint : MethodFingerprint(
returnType = "V",
parameters = listOf("L", "Z"),
strings = listOf("afterTextChanged", "expression_search"),
opcodes = listOf(
Opcode.IGET_OBJECT,
Opcode.IF_EQZ,
Opcode.CONST_STRING,
Opcode.GOTO,
Opcode.CONST_STRING,
Opcode.GOTO
)
)

View File

@@ -1,37 +0,0 @@
package app.revanced.patches.messenger.inputfield.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.*
import app.revanced.patcher.data.BytecodeContext
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.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.messenger.inputfield.fingerprints.SwitchMessangeInputEmojiButtonFingerprint
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Patch
@Name("Disable switching emoji to sticker in message input field")
@Description("Disables switching from emoji to sticker search mode in message input field")
@Compatibility([Package("com.facebook.orca")])
@Version("0.0.1")
class DisableSwitchingEmojiToStickerInMessageInputField : BytecodePatch(listOf(SwitchMessangeInputEmojiButtonFingerprint)) {
override fun execute(context: BytecodeContext): PatchResult {
SwitchMessangeInputEmojiButtonFingerprint.result?.let {
val setStringIndex = it.scanResult.patternScanResult!!.startIndex + 2
it.mutableMethod.apply {
val targetRegister = getInstruction<OneRegisterInstruction>(setStringIndex).registerA
replaceInstruction(
setStringIndex,
"const-string v$targetRegister, \"expression\""
)
}
} ?: throw SwitchMessangeInputEmojiButtonFingerprint.toErrorResult()
return PatchResultSuccess()
}
}

View File

@@ -1,29 +0,0 @@
package app.revanced.patches.messenger.inputfield.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Package
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.messenger.inputfield.fingerprints.SendTypingIndicatorFingerprint
@Patch
@Name("Disable typing indicator")
@Description("Disables the indicator while typing a message")
@Compatibility([Package("com.facebook.orca")])
@Version("0.0.1")
class DisableTypingIndicator : BytecodePatch(listOf(SendTypingIndicatorFingerprint)) {
override fun execute(context: BytecodeContext): PatchResult {
SendTypingIndicatorFingerprint.result?.mutableMethod?.replaceInstruction(0, "return-void")
?: throw SendTypingIndicatorFingerprint.toErrorResult()
return PatchResultSuccess()
}
}

View File

@@ -1,8 +0,0 @@
package app.revanced.patches.moneymanager.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.ithebk.expensemanager")])
@Target(AnnotationTarget.CLASS)
internal annotation class UnlockProCompatibility

View File

@@ -1,19 +0,0 @@
package app.revanced.patches.moneymanager.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object UnlockProFingerprint : MethodFingerprint(
"Z",
AccessFlags.STATIC or AccessFlags.SYNTHETIC,
parameters = listOf("L"),
opcodes = listOf(
Opcode.IGET_BOOLEAN,
Opcode.RETURN
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("MainActivity;")
}
)

View File

@@ -1,33 +0,0 @@
package app.revanced.patches.moneymanager.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.moneymanager.annotations.UnlockProCompatibility
import app.revanced.patches.moneymanager.fingerprints.UnlockProFingerprint
@Patch
@Name("Unlock pro")
@Description("Unlocks pro features.")
@UnlockProCompatibility
@Version("0.0.1")
class UnlockProPatch : BytecodePatch(
listOf(UnlockProFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
UnlockProFingerprint.result!!.mutableMethod.addInstructions(
0,
"""
const/4 v0, 0x1
return v0
"""
)
return PatchResultSuccess()
}
}

View File

@@ -1,14 +0,0 @@
package app.revanced.patches.music.ad.video.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object ShowMusicVideoAdsFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("Z"), listOf(
Opcode.IPUT_BOOLEAN,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID
)
)

View File

@@ -1,39 +0,0 @@
package app.revanced.patches.music.ad.video.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.music.ad.video.fingerprints.ShowMusicVideoAdsConstructorFingerprint
import app.revanced.patches.music.ad.video.fingerprints.ShowMusicVideoAdsFingerprint
import app.revanced.patches.music.annotations.MusicCompatibility
@Patch
@Name("Music video ads")
@Description("Removes ads in the music player.")
@MusicCompatibility
@Version("0.0.1")
class MusicVideoAdsPatch : BytecodePatch(
listOf(ShowMusicVideoAdsConstructorFingerprint)
) {
override fun execute(context: BytecodeContext): PatchResult {
ShowMusicVideoAdsFingerprint.resolve(context, ShowMusicVideoAdsConstructorFingerprint.result!!.classDef)
val result = ShowMusicVideoAdsFingerprint.result!!
result.mutableMethod.addInstruction(
result.scanResult.patternScanResult!!.startIndex,
"""
const/4 p1, 0x0
"""
)
return PatchResultSuccess()
}
}

View File

@@ -1,8 +0,0 @@
package app.revanced.patches.music.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.google.android.apps.youtube.music")])
@Target(AnnotationTarget.CLASS)
internal annotation class MusicCompatibility

View File

@@ -0,0 +1,14 @@
package app.revanced.patches.music.audio.codecs.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.apps.youtube.music", arrayOf("5.03.50")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class CodecsUnlockCompatibility

View File

@@ -1,13 +1,23 @@
package app.revanced.patches.music.audio.codecs.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher. fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.music.audio.codecs.annotations.CodecsUnlockCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("all-codecs-reference-fingerprint")
@MatchingMethod(
"Laari;",
"b",
)
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
@CodecsUnlockCompatibility
@Version("0.0.1")
object AllCodecsReferenceFingerprint : MethodFingerprint(
"J", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf(
Opcode.INVOKE_STATIC,

View File

@@ -1,15 +1,27 @@
package app.revanced.patches.music.audio.codecs.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.music.audio.codecs.annotations.CodecsUnlockCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("codec-lock-fingerprint")
@MatchingMethod(
"Labwj;",
"a",
)
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
@CodecsUnlockCompatibility
@Version("0.0.1")
object CodecsLockFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, opcodes = listOf(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "L", "L", "L"), listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
@@ -17,13 +29,19 @@ object CodecsLockFingerprint : MethodFingerprint(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.SGET,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_INTERFACE,
Opcode.INVOKE_DIRECT,
Opcode.RETURN_OBJECT
),
strings = listOf("eac3_supported")
)
)
)

View File

@@ -3,52 +3,41 @@ package app.revanced.patches.music.audio.codecs.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.data.toMethodWalker
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.data.impl.BytecodeData
import app.revanced.patcher.data.impl.toMethodWalker
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.patch.impl.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.smali.toInstruction
import app.revanced.patches.music.annotations.MusicCompatibility
import app.revanced.patches.music.audio.codecs.annotations.CodecsUnlockCompatibility
import app.revanced.patches.music.audio.codecs.fingerprints.AllCodecsReferenceFingerprint
import app.revanced.patches.music.audio.codecs.fingerprints.CodecsLockFingerprint
import org.jf.dexlib2.Opcode
@Patch
@Name("Codecs unlock")
@Description("Adds more audio codec options. The new audio codecs usually result in better audio quality.")
@MusicCompatibility
@Name("codecs-unlock")
@Description("Enables more audio codecs. Usually results in better audio quality but may depend on song and device.")
@CodecsUnlockCompatibility
@Version("0.0.1")
class CodecsUnlockPatch : BytecodePatch(
listOf(
CodecsLockFingerprint, AllCodecsReferenceFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
val codecsLockResult = CodecsLockFingerprint.result!!
override fun execute(data: BytecodeData): PatchResult {
var result = CodecsLockFingerprint.result!!
val implementation = codecsLockResult.mutableMethod.implementation!!
val implementation = result.mutableMethod.implementation!!
val scanResultStartIndex = codecsLockResult.scanResult.patternScanResult!!.startIndex
val instructionIndex = scanResultStartIndex +
if (implementation.instructions[scanResultStartIndex - 1].opcode == Opcode.CHECK_CAST) {
// for 5.16.xx and lower
-3
} else {
// since 5.17.xx
-2
}
val instructionIndex = result.patternScanResult!!.startIndex
val allCodecsResult = AllCodecsReferenceFingerprint.result!!
val allCodecsMethod =
context.toMethodWalker(allCodecsResult.method)
.nextMethod(allCodecsResult.scanResult.patternScanResult!!.startIndex)
.getMethod()
result = AllCodecsReferenceFingerprint.result!!
val codecMethod =
data.toMethodWalker(result.method).nextMethod(result.patternScanResult!!.startIndex).getMethod()
implementation.replaceInstruction(
instructionIndex,
"invoke-static {}, ${allCodecsMethod.definingClass}->${allCodecsMethod.name}()Ljava/util/Set;".toInstruction()
"invoke-static {}, ${codecMethod.definingClass}->${codecMethod.name}()Ljava/util/Set;".toInstruction()
)
return PatchResultSuccess()

View File

@@ -0,0 +1,14 @@
package app.revanced.patches.music.audio.exclusiveaudio.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.apps.youtube.music", arrayOf("5.03.50")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class ExclusiveAudioCompatibility

View File

@@ -1,10 +1,23 @@
package app.revanced.patches.music.audio.exclusiveaudio.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.DirectPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.music.audio.exclusiveaudio.annotations.ExclusiveAudioCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("audio-only-enabler-fingerprint")
@MatchingMethod(
"Lgmd;",
"d"
)
@DirectPatternScanMethod
@ExclusiveAudioCompatibility
@Version(
"0.0.1"
)
object AudioOnlyEnablerFingerprint: MethodFingerprint(
"Z", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf(
Opcode.IGET_OBJECT,

View File

@@ -1,13 +1,22 @@
package app.revanced.patches.music.audio.exclusiveaudio.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
import app.revanced.patches.music.audio.exclusiveaudio.annotations.ExclusiveAudioCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("exclusive-audio-fingerprints")
@MatchingMethod(
"Lgmd;", "c"
)
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
@ExclusiveAudioCompatibility
@Version("0.0.1")
object ExclusiveAudioFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,

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