├── app ├── .gitignore ├── src │ └── main │ │ ├── assets │ │ └── xposed_init │ │ ├── res │ │ └── values │ │ │ ├── strings.xml │ │ │ └── scope.xml │ │ ├── java │ │ └── xmnh │ │ │ └── soulfrog │ │ │ ├── interfaces │ │ │ └── BaseHook.java │ │ │ ├── app │ │ │ ├── Launcher2.java │ │ │ ├── AiClips.java │ │ │ ├── TikTok.java │ │ │ ├── DevCheck.java │ │ │ ├── BearVCR.java │ │ │ ├── Tarot.java │ │ │ ├── FakeLocation.java │ │ │ ├── BrainWave.java │ │ │ ├── Termius.java │ │ │ ├── Launcher3.java │ │ │ ├── JuiceSSH.java │ │ │ ├── APKPure.java │ │ │ ├── Japanese.java │ │ │ ├── AbcVPN.java │ │ │ ├── InfinityAI.java │ │ │ ├── RRVideo.java │ │ │ ├── ESBrowse.java │ │ │ ├── AudioClips.java │ │ │ ├── DailyTask.java │ │ │ ├── SaComic.java │ │ │ ├── TapTap.java │ │ │ ├── SDMaid.java │ │ │ ├── FastLinkVPN.java │ │ │ ├── Tick.java │ │ │ ├── NowMuse.java │ │ │ ├── QQLive.java │ │ │ ├── AiQiYi.java │ │ │ └── KuWo.java │ │ │ ├── application │ │ │ └── SoulFrog.java │ │ │ ├── context │ │ │ └── XpContext.java │ │ │ ├── utils │ │ │ ├── StringUtil.java │ │ │ ├── AppUtil.java │ │ │ ├── KillAdsUtil.java │ │ │ ├── HookUtil.java │ │ │ └── ObjectionUtil.java │ │ │ ├── enums │ │ │ └── AppEnum.java │ │ │ ├── Jump.java │ │ │ └── factory │ │ │ └── AppFactory.java │ │ └── AndroidManifest.xml ├── debug │ ├── app-debug.apk │ └── output-metadata.json ├── release │ ├── app-release.apk │ └── output-metadata.json ├── proguard-rules.pro └── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .idea ├── compiler.xml ├── vcs.xml ├── misc.xml ├── deploymentTargetDropDown.xml ├── migrations.xml └── gradle.xml ├── .gitignore ├── settings.gradle ├── gradle.properties ├── gradlew.bat └── gradlew /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | .gradle 3 | .idea -------------------------------------------------------------------------------- /app/src/main/assets/xposed_init: -------------------------------------------------------------------------------- 1 | xmnh.soulfrog.Jump -------------------------------------------------------------------------------- /app/debug/app-debug.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xmnh/SoulFrog/HEAD/app/debug/app-debug.apk -------------------------------------------------------------------------------- /app/release/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xmnh/SoulFrog/HEAD/app/release/app-release.apk -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | SoulFrog 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xmnh/SoulFrog/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/interfaces/BaseHook.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.interfaces; 2 | 3 | import android.content.Context; 4 | 5 | @FunctionalInterface 6 | public interface BaseHook { 7 | void hook(Context context, ClassLoader classLoader); 8 | } 9 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/deploymentTargetDropDown.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Oct 13 22:31:06 CST 2025 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /.idea/migrations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/Launcher2.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import xmnh.soulfrog.interfaces.BaseHook; 6 | import xmnh.soulfrog.utils.AppUtil; 7 | 8 | 9 | public class Launcher2 implements BaseHook { 10 | 11 | @Override 12 | public void hook(Context context, ClassLoader classLoader) { 13 | 14 | AppUtil.finish(context); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /app/debug/output-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "artifactType": { 4 | "type": "APK", 5 | "kind": "Directory" 6 | }, 7 | "applicationId": "xmnh.soulfrog", 8 | "variantName": "debug", 9 | "elements": [ 10 | { 11 | "type": "SINGLE", 12 | "filters": [], 13 | "attributes": [], 14 | "versionCode": 1, 15 | "versionName": "1.0", 16 | "outputFile": "app-debug.apk" 17 | } 18 | ], 19 | "elementType": "File" 20 | } -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/application/SoulFrog.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.application; 2 | 3 | import android.app.Application; 4 | 5 | public class SoulFrog extends Application { 6 | public static final String TAG = "SoulFrog"; 7 | public static SoulFrog instance; 8 | 9 | @Override 10 | public void onCreate() { 11 | super.onCreate(); 12 | if (instance == null) { 13 | instance = this; 14 | } 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /app/release/output-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "artifactType": { 4 | "type": "APK", 5 | "kind": "Directory" 6 | }, 7 | "applicationId": "xmnh.soulfrog", 8 | "variantName": "release", 9 | "elements": [ 10 | { 11 | "type": "SINGLE", 12 | "filters": [], 13 | "attributes": [], 14 | "versionCode": 1, 15 | "versionName": "1.0", 16 | "outputFile": "app-release.apk" 17 | } 18 | ], 19 | "elementType": "File" 20 | } -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/AiClips.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import xmnh.soulfrog.interfaces.BaseHook; 6 | import xmnh.soulfrog.utils.AppUtil; 7 | 8 | public class AiClips implements BaseHook { 9 | 10 | @Override 11 | public void hook(Context context, ClassLoader classLoader) { 12 | context.getSharedPreferences("Pay", 0).edit().putBoolean("type", true).apply(); 13 | AppUtil.finish(context); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/context/XpContext.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.context; 2 | 3 | import android.content.Context; 4 | 5 | import java.lang.ref.WeakReference; 6 | 7 | public abstract class XpContext { 8 | private static WeakReference context; 9 | public static ClassLoader classLoader; 10 | 11 | public static Context getContext(Context c){ 12 | if (context == null) { 13 | context = new WeakReference<>(c); 14 | } 15 | return context.get(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/TikTok.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import xmnh.soulfrog.enums.AppEnum; 6 | import xmnh.soulfrog.interfaces.BaseHook; 7 | import xmnh.soulfrog.utils.AppUtil; 8 | import xmnh.soulfrog.utils.ObjectionUtil; 9 | 10 | public class TikTok implements BaseHook { 11 | @Override 12 | public void hook(Context context, ClassLoader classLoader) { 13 | ObjectionUtil.ChangeRegion(classLoader); 14 | AppUtil.finish(context, AppEnum.TIKTOK.getAppName()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/DevCheck.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import de.robv.android.xposed.XC_MethodReplacement; 6 | import de.robv.android.xposed.XposedHelpers; 7 | import xmnh.soulfrog.interfaces.BaseHook; 8 | import xmnh.soulfrog.utils.AppUtil; 9 | 10 | public class DevCheck implements BaseHook { 11 | 12 | @Override 13 | public void hook(Context context, ClassLoader classLoader) { 14 | Class cls = XposedHelpers.findClass("a7.q", classLoader); 15 | if (cls != null) { 16 | XposedHelpers.findAndHookMethod(cls, "b", String.class, 17 | XC_MethodReplacement.returnConstant(true)); 18 | } 19 | AppUtil.finish(context); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/BearVCR.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import de.robv.android.xposed.XC_MethodReplacement; 6 | import de.robv.android.xposed.XposedHelpers; 7 | import xmnh.soulfrog.interfaces.BaseHook; 8 | import xmnh.soulfrog.utils.AppUtil; 9 | 10 | public class BearVCR implements BaseHook { 11 | 12 | @Override 13 | public void hook(Context context, ClassLoader classLoader) { 14 | Class cls = XposedHelpers.findClass("com.duapps.recorder.kc0", classLoader); 15 | if (cls != null) { 16 | XposedHelpers.findAndHookMethod(cls, "a", 17 | XC_MethodReplacement.returnConstant(true)); 18 | } 19 | AppUtil.finish(context); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/Tarot.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import de.robv.android.xposed.XC_MethodReplacement; 6 | import de.robv.android.xposed.XposedHelpers; 7 | import xmnh.soulfrog.interfaces.BaseHook; 8 | import xmnh.soulfrog.utils.AppUtil; 9 | 10 | public class Tarot implements BaseHook { 11 | 12 | @Override 13 | public void hook(Context context, ClassLoader classLoader) { 14 | Class cls = XposedHelpers.findClass("taluo.jumeng.com.tarot.data.h", classLoader); 15 | if (cls != null) { 16 | XposedHelpers.findAndHookMethod(cls, "k", 17 | XC_MethodReplacement.returnConstant(true)); 18 | } 19 | AppUtil.finish(context); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/FakeLocation.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import de.robv.android.xposed.XC_MethodReplacement; 6 | import de.robv.android.xposed.XposedHelpers; 7 | import xmnh.soulfrog.interfaces.BaseHook; 8 | import xmnh.soulfrog.utils.AppUtil; 9 | 10 | public class FakeLocation implements BaseHook { 11 | 12 | @Override 13 | public void hook(Context context, ClassLoader classLoader) { 14 | String appVersionName = AppUtil.getAppVersionName(context); 15 | if ("1.3.1.9".equals(appVersionName)) { 16 | XposedHelpers.findAndHookMethod("ށ.ރ.ؠ.ؠ.֏", classLoader, "ޅ", 17 | XC_MethodReplacement.returnConstant(true)); 18 | } 19 | AppUtil.finish(context); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 12 | 13 | 16 | 17 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/BrainWave.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import de.robv.android.xposed.XC_MethodReplacement; 6 | import de.robv.android.xposed.XposedHelpers; 7 | import xmnh.soulfrog.interfaces.BaseHook; 8 | import xmnh.soulfrog.utils.AppUtil; 9 | 10 | public class BrainWave implements BaseHook { 11 | 12 | @Override 13 | public void hook(Context context, ClassLoader classLoader) { 14 | Class cls = XposedHelpers.findClass("kotlin.coroutines.jvm.internal.Boxing", classLoader); 15 | if (cls != null) { 16 | XposedHelpers.findAndHookMethod(cls, "boxBoolean", 17 | boolean.class, 18 | XC_MethodReplacement.returnConstant(true)); 19 | } 20 | AppUtil.finish(context); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/Termius.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import de.robv.android.xposed.XC_MethodReplacement; 6 | import de.robv.android.xposed.XposedHelpers; 7 | import xmnh.soulfrog.interfaces.BaseHook; 8 | import xmnh.soulfrog.utils.AppUtil; 9 | 10 | public class Termius implements BaseHook { 11 | @Override 12 | public void hook(Context context, ClassLoader classLoader) { 13 | Class cls = XposedHelpers.findClass("com.server.auditor.ssh.client.app.w", classLoader); 14 | if (cls != null) { 15 | XposedHelpers.findAndHookMethod(cls, "m0", XC_MethodReplacement.returnConstant(true)); 16 | XposedHelpers.findAndHookMethod(cls, "r0", XC_MethodReplacement.returnConstant(true)); 17 | } 18 | AppUtil.finish(context); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url 'https://maven.aliyun.com/repository/gradle-plugin' } 4 | maven { url 'https://maven.aliyun.com/repository/google' } 5 | maven { url 'https://maven.aliyun.com/repository/public' } 6 | maven { url 'https://jitpack.io' } 7 | mavenLocal() 8 | mavenCentral() 9 | google() 10 | } 11 | } 12 | dependencyResolutionManagement { 13 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 14 | repositories { 15 | maven { url 'https://maven.aliyun.com/repository/public' } 16 | maven { url 'https://maven.aliyun.com/repository/google' } 17 | maven { url 'https://api.xposed.info/' } 18 | maven { url 'https://jitpack.io' } 19 | mavenLocal() 20 | mavenCentral() 21 | google() 22 | } 23 | } 24 | rootProject.name = "SoulFrog" 25 | include ':app' 26 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/Launcher3.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import de.robv.android.xposed.XC_MethodReplacement; 6 | import de.robv.android.xposed.XposedHelpers; 7 | import xmnh.soulfrog.interfaces.BaseHook; 8 | import xmnh.soulfrog.utils.AppUtil; 9 | 10 | 11 | public class Launcher3 implements BaseHook { 12 | 13 | @Override 14 | public void hook(Context context, ClassLoader classLoader) { 15 | Class cls = XposedHelpers.findClass("com.ldmnq.AdSdkInterface", classLoader); 16 | if (cls != null) { 17 | XposedHelpers.findAndHookMethod(cls, "initOnce", Context.class, 18 | XC_MethodReplacement.returnConstant(null)); 19 | XposedHelpers.findAndHookMethod(cls, "isOpenCleanMode", Context.class, 20 | XC_MethodReplacement.returnConstant(true)); 21 | } 22 | AppUtil.finish(context); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/JuiceSSH.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | import android.preference.Preference; 5 | 6 | import de.robv.android.xposed.XC_MethodReplacement; 7 | import de.robv.android.xposed.XposedHelpers; 8 | import xmnh.soulfrog.interfaces.BaseHook; 9 | import xmnh.soulfrog.utils.AppUtil; 10 | 11 | public class JuiceSSH implements BaseHook { 12 | 13 | @Override 14 | public void hook(Context context, ClassLoader classLoader) { 15 | Class cls = XposedHelpers.findClass("com.sonelli.ej0", classLoader); 16 | if (cls != null) { 17 | XposedHelpers.findAndHookMethod(cls, "z", Preference.class, 18 | XC_MethodReplacement.returnConstant(null)); 19 | } 20 | Class cls2 = XposedHelpers.findClass("com.sonelli.oi0", classLoader); 21 | if (cls != null) { 22 | XposedHelpers.findAndHookMethod(cls2, "d", Object.class, 23 | XC_MethodReplacement.returnConstant(true)); 24 | } 25 | AppUtil.finish(context); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/APKPure.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import de.robv.android.xposed.XposedHelpers; 6 | import xmnh.soulfrog.interfaces.BaseHook; 7 | import xmnh.soulfrog.utils.HookUtil; 8 | 9 | public class APKPure implements BaseHook { 10 | 11 | @Override 12 | public void hook(Context context, ClassLoader classLoader) { 13 | Class bannerConfig = XposedHelpers.findClass("com.apkpure.aegon.ads.BannerConfig", classLoader); 14 | if (bannerConfig != null) { 15 | HookUtil.booleAndVoidReplace(bannerConfig, false); 16 | } 17 | Class interstitialConfig = XposedHelpers.findClass("com.apkpure.aegon.ads.InterstitialConfig", classLoader); 18 | if (interstitialConfig != null) { 19 | HookUtil.booleAndVoidReplace(interstitialConfig, false); 20 | } 21 | Class splashConfig = XposedHelpers.findClass("com.apkpure.aegon.ads.SplashConfig", classLoader); 22 | if (splashConfig != null) { 23 | HookUtil.booleAndVoidReplace(splashConfig, false); 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/Japanese.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import xmnh.soulfrog.interfaces.BaseHook; 6 | import xmnh.soulfrog.utils.AppUtil; 7 | 8 | public class Japanese implements BaseHook { 9 | 10 | @Override 11 | public void hook(Context context, ClassLoader classLoader) { 12 | context.getSharedPreferences("onlineconfig_agent_online_setting_com.easysay.japanese", 0).edit() 13 | .putString("goods1_price", "0.01") 14 | .putString("goods2_price", "0.01") 15 | .putString("goods3_price", "0.01") 16 | .putString("goods4_price", "0.01") 17 | .putString("goods5_price", "0.01") 18 | .putString("goods1_price_new", "0.01") 19 | .putString("goods2_price_new", "0.01") 20 | .putString("goods3_price_new", "0.01") 21 | .putString("goods4_price_new", "0.01") 22 | .putString("goods5_price_new", "0.01") 23 | .putString("wangzifu_price_388", "0.01") 24 | .putString("wangzifu_price_398", "0.01") 25 | .apply(); 26 | AppUtil.finish(context); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | 23 | -keep class xmnh.soulfrog.Jump 24 | -keepclassmembers class xmnh.soulfrog.Jump { 25 | public void handleLoadPackage(**); 26 | } 27 | 28 | #-assumenosideeffects class android.util.Log { 29 | #public static boolean isLoggable(java.lang.String, int); 30 | #public static int v(...); 31 | #public static int i(...); 32 | #public static int w(...); 33 | ##public static int d(...); 34 | ##public static int e(...); 35 | #} -------------------------------------------------------------------------------- /app/src/main/res/values/scope.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | cn.kuwo.player 7 | com.tencent.qqlive 8 | 9 | com.lerist.fakelocation 10 | com.shineyie.aijianji 11 | com.sonelli.juicessh 12 | flar2.devcheck 13 | imoblife.brainwavestus 14 | com.imoblife.now 15 | com.estrongs.android.pop 16 | eu.thedarken.sdm 17 | eu.darken.sdmse 18 | taluo.jumeng.com.tarot 19 | com.lixiangdong.songcutter 20 | com.duapps.recorder 21 | cn.ticktick.task 22 | com.qiyi.video 23 | com.example.pptv 24 | com.android.launcher3 25 | com.zfast.xyz 26 | world.letsgo.booster.android.pro 27 | com.server.auditor.ssh.client 28 | 29 | 30 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Enables namespacing of each library's R class so that its R class includes only the 19 | # resources declared in the library itself and none from the library's dependencies, 20 | # thereby reducing the size of the R class for that library 21 | android.nonTransitiveRClass=true -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/AbcVPN.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import static android.content.Context.MODE_PRIVATE; 4 | 5 | import android.content.Context; 6 | import android.util.Log; 7 | 8 | import org.json.JSONObject; 9 | 10 | import java.util.UUID; 11 | 12 | import de.robv.android.xposed.XposedHelpers; 13 | import xmnh.soulfrog.application.SoulFrog; 14 | import xmnh.soulfrog.interfaces.BaseHook; 15 | import xmnh.soulfrog.utils.AppUtil; 16 | import xmnh.soulfrog.utils.HookUtil; 17 | 18 | public class AbcVPN implements BaseHook { 19 | private static final long EXPIRE_TIME = 2_400_000; 20 | // private SharedPreferences sp; 21 | 22 | @Override 23 | public void hook(Context context, ClassLoader classLoader) { 24 | AppUtil.sp = context.getSharedPreferences("alcedo", MODE_PRIVATE); 25 | if (AppUtil.checkSp(UUID.randomUUID().toString(), 0)) { 26 | AppUtil.finish(context); 27 | } 28 | // vip(classLoader); 29 | } 30 | 31 | // private void check() { 32 | // long currentTime = System.currentTimeMillis(); 33 | // if (!sp.contains("expire_time") || currentTime >= sp.getLong("expire_time", 0)) { 34 | // SharedPreferences.Editor editor = sp.edit(); 35 | // editor.putString("device_id", UUID.randomUUID().toString()); 36 | // editor.putLong("expire_time", currentTime + EXPIRE_TIME); 37 | // editor.apply(); 38 | // } 39 | // } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/InfinityAI.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import de.robv.android.xposed.XC_MethodReplacement; 6 | import de.robv.android.xposed.XposedHelpers; 7 | import xmnh.soulfrog.interfaces.BaseHook; 8 | 9 | public class InfinityAI implements BaseHook { 10 | @Override 11 | public void hook(Context context, ClassLoader classLoader) { 12 | Class tradeUserInfo = XposedHelpers.findClass("com.blockmeta.bbs.businesslibrary.TradeUserInfo", classLoader); 13 | if (tradeUserInfo != null) { 14 | XposedHelpers.findAndHookMethod(tradeUserInfo, "isVip", 15 | XC_MethodReplacement.returnConstant(true)); 16 | XposedHelpers.findAndHookMethod(tradeUserInfo, "isInVipWhiteList", 17 | XC_MethodReplacement.returnConstant(true)); 18 | XposedHelpers.findAndHookMethod(tradeUserInfo, "isInSquareWhiteList", 19 | XC_MethodReplacement.returnConstant(true)); 20 | XposedHelpers.findAndHookMethod(tradeUserInfo, "isInAiWhiteList", 21 | XC_MethodReplacement.returnConstant(true)); 22 | XposedHelpers.findAndHookMethod(tradeUserInfo, "isInWhiteList", 23 | XC_MethodReplacement.returnConstant(true)); 24 | } 25 | XposedHelpers.findAndHookMethod("com.blockmeta.bbs.businesslibrary.pojo.PublishOption", classLoader, "getVipOption", 26 | XC_MethodReplacement.returnConstant(false)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/RRVideo.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import de.robv.android.xposed.XC_MethodHook; 6 | import de.robv.android.xposed.XC_MethodReplacement; 7 | import de.robv.android.xposed.XposedHelpers; 8 | import xmnh.soulfrog.interfaces.BaseHook; 9 | import xmnh.soulfrog.utils.AppUtil; 10 | import xmnh.soulfrog.utils.HookUtil; 11 | 12 | 13 | public class RRVideo implements BaseHook { 14 | 15 | @Override 16 | public void hook(Context context, ClassLoader classLoader) { 17 | Class appCommonUtils = XposedHelpers.findClass("com.pptv.common.utils.AppCommonUtils", classLoader); 18 | if (appCommonUtils != null) { 19 | HookUtil.booleReplace(appCommonUtils, true); 20 | } 21 | // Class vipInfo = XposedHelpers.findClass("com.pptv.common.data.bean.vipInfo", classLoader); 22 | // if (vipInfo != null) { 23 | // XposedHelpers.findAndHookMethod(vipInfo, "getValid", XC_MethodReplacement.returnConstant(true)); 24 | // } 25 | // Class baseControllerViewModel = XposedHelpers.findClass("com.pptv.drama.data.vm.base.baseControllerViewModel", classLoader); 26 | // if (baseControllerViewModel != null) { 27 | // XposedHelpers.findAndHookMethod(baseControllerViewModel, "hasVIPPrivilege", XC_MethodReplacement.returnConstant(true)); 28 | // XposedHelpers.findAndHookMethod(baseControllerViewModel, "hasVODPrivilege", XC_MethodReplacement.returnConstant(true)); 29 | // } 30 | AppUtil.finish(context); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/ESBrowse.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import org.json.JSONObject; 6 | 7 | import de.robv.android.xposed.XposedBridge; 8 | import de.robv.android.xposed.XposedHelpers; 9 | import xmnh.soulfrog.application.SoulFrog; 10 | import xmnh.soulfrog.interfaces.BaseHook; 11 | import xmnh.soulfrog.utils.AppUtil; 12 | import xmnh.soulfrog.utils.HookUtil; 13 | 14 | public class ESBrowse implements BaseHook { 15 | boolean flag = true; 16 | 17 | @Override 18 | public void hook(Context context, ClassLoader classLoader) { 19 | if (flag) { 20 | Class accountInfo = XposedHelpers.findClass("com.estrongs.android.pop.app.account.model.AccountInfo", classLoader); 21 | HookUtil.gsonFromJson(classLoader, param -> { 22 | try { 23 | JSONObject jsonObject = new JSONObject((String) param.args[0]); 24 | if (accountInfo != null && param.args[1] == accountInfo) { 25 | if (jsonObject.has("isVip") && jsonObject.has("vipFinishAt")) { 26 | jsonObject.put("isVip", true); 27 | jsonObject.put("vipFinishAt", 218330035688000L); 28 | param.args[0] = jsonObject.toString(); 29 | } 30 | } 31 | } catch (Throwable e) { 32 | XposedBridge.log(SoulFrog.TAG + " ==> " + e.getMessage()); 33 | } 34 | }); 35 | AppUtil.finish(context); 36 | flag = false; 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/AudioClips.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import de.robv.android.xposed.XC_MethodReplacement; 6 | import de.robv.android.xposed.XposedHelpers; 7 | import xmnh.soulfrog.interfaces.BaseHook; 8 | import xmnh.soulfrog.utils.AppUtil; 9 | 10 | public class AudioClips implements BaseHook { 11 | 12 | @Override 13 | public void hook(Context context, ClassLoader classLoader) { 14 | Class cls = XposedHelpers.findClass("com.wm.common.user.UserManager", classLoader); 15 | if (cls != null) { 16 | XposedHelpers.findAndHookMethod(cls, "isPermanentVip", 17 | XC_MethodReplacement.returnConstant(true)); 18 | XposedHelpers.findAndHookMethod("com.wm.common.user.UserManager", classLoader, "isVip", 19 | XC_MethodReplacement.returnConstant(true)); 20 | } 21 | Class cls2 = XposedHelpers.findClass("com.wm.common.user.UserInfoManager", classLoader); 22 | if (cls2 != null) { 23 | XposedHelpers.findAndHookMethod(cls2, "isPermanentVip", 24 | XC_MethodReplacement.returnConstant(true)); 25 | XposedHelpers.findAndHookMethod(cls2, "isVip", 26 | XC_MethodReplacement.returnConstant(true)); 27 | } 28 | Class cls3 = XposedHelpers.findClass("com.wm.common.ad.util.AdUtil", classLoader); 29 | if (cls3 != null) { 30 | XposedHelpers.findAndHookMethod(cls3, "isVip", 31 | XC_MethodReplacement.returnConstant(true)); 32 | } 33 | AppUtil.finish(context); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/DailyTask.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import org.json.JSONObject; 6 | 7 | import de.robv.android.xposed.XposedHelpers; 8 | import xmnh.soulfrog.interfaces.BaseHook; 9 | import xmnh.soulfrog.utils.AppUtil; 10 | import xmnh.soulfrog.utils.HookUtil; 11 | 12 | public class DailyTask implements BaseHook { 13 | 14 | @Override 15 | public void hook(Context context, ClassLoader classLoader) { 16 | context.getSharedPreferences("share_data", 0) 17 | .edit() 18 | .putBoolean("show_splash_activity", false) 19 | .putString("activity_splash", "") 20 | .apply(); 21 | Class queryPayInfo = XposedHelpers.findClass("com.moyan.dailytask.data.QueryPayInfo", classLoader); 22 | HookUtil.gsonFromJson(classLoader, param -> { 23 | try { 24 | JSONObject jSONObject = new JSONObject(param.args[0].toString()); 25 | if (queryPayInfo != null && param.args[1] == queryPayInfo) { 26 | if (jSONObject.has("ret") && jSONObject.has("endTime")) { 27 | jSONObject.put("count", 1); 28 | jSONObject.put("desc", "永久会员"); 29 | jSONObject.put("endTime", "2099-12-31"); 30 | jSONObject.put("message", "已付费"); 31 | jSONObject.put("ret", 200); 32 | param.args[0] = jSONObject.toString(); 33 | } 34 | } 35 | } catch (Throwable e) { 36 | e.printStackTrace(); 37 | } 38 | }); 39 | AppUtil.finish(context); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/SaComic.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import de.robv.android.xposed.XC_MethodReplacement; 6 | import de.robv.android.xposed.XposedHelpers; 7 | import xmnh.soulfrog.interfaces.BaseHook; 8 | import xmnh.soulfrog.utils.HookUtil; 9 | 10 | public class SaComic implements BaseHook { 11 | 12 | @Override 13 | public void hook(Context context, ClassLoader classLoader) { 14 | Class vipUserInfo = XposedHelpers.findClass("com.comic.isaman.mine.vip.bean.vipUserInfo", classLoader); 15 | if (vipUserInfo != null){ 16 | HookUtil.booleReplace(vipUserInfo, true); 17 | } 18 | Class chapterListItemBean = XposedHelpers.findClass( 19 | "com.comic.isaman.icartoon.model.ChapterListItemBean", classLoader); 20 | if (chapterListItemBean != null){ 21 | XposedHelpers.findAndHookMethod(chapterListItemBean, "isAdvanceChapter", 22 | XC_MethodReplacement.returnConstant(false)); 23 | XposedHelpers.findAndHookMethod(chapterListItemBean, "isNeedBuy", 24 | XC_MethodReplacement.returnConstant(false)); 25 | XposedHelpers.findAndHookMethod(chapterListItemBean, "isVipFree", 26 | XC_MethodReplacement.returnConstant(false)); 27 | } 28 | Class comicCartoonEpisodeBean = XposedHelpers.findClass( 29 | "ccom.comic.isaman.cartoon_video.bean.ComicCartoonEpisodeBean", classLoader); 30 | if (comicCartoonEpisodeBean != null){ 31 | XposedHelpers.findAndHookMethod(comicCartoonEpisodeBean, "isVipFree", 32 | XC_MethodReplacement.returnConstant(true)); 33 | XposedHelpers.findAndHookMethod(comicCartoonEpisodeBean, "needBuy", 34 | XC_MethodReplacement.returnConstant(false)); 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'stringfog' 4 | } 5 | 6 | stringfog { 7 | enable false 8 | // 指定加解密的具体实现类,可以用默认实现的xor库或者aes-cbc库,也可以自己定制实现,记得配置dependencies 9 | implementation 'com.github.megatronking.stringfog.xor.StringFogImpl' 10 | // 指定需加密的代码包路径,可配置多个,未指定将默认全部加密 11 | // fogPackages = [''] 12 | // 可选(3.0版本新增):指定密钥生成器,默认使用长度8的随机密钥(每个字符串均有不同随机密钥), 13 | // 也可以指定一个固定的密钥:HardCodeKeyGenerator("This is a key") 14 | // kg new RandomKeyGenerator() 15 | // 可选(4.0版本新增):用于控制字符串加密后在字节码中的存在形式, 默认为base64, 16 | // 也可以使用text或者bytes 17 | // mode StringFogMode.base64 18 | } 19 | 20 | android { 21 | namespace 'xmnh.soulfrog' 22 | compileSdk 36 23 | 24 | buildFeatures { 25 | buildConfig = true 26 | } 27 | 28 | defaultConfig { 29 | applicationId "xmnh.soulfrog" 30 | minSdk 25 31 | targetSdk 36 32 | versionCode 1 33 | versionName "1.0" 34 | // testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 35 | } 36 | buildTypes { 37 | release { 38 | // zipAlignEnabled true //优化我们的java字节码,提高运行效率 39 | // shrinkResources true //资源的压缩 40 | // useProguard true //代码压缩 41 | minifyEnabled true //开启混淆 42 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 43 | } 44 | debug { 45 | minifyEnabled false 46 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 47 | } 48 | } 49 | compileOptions { 50 | sourceCompatibility JavaVersion.VERSION_17 51 | targetCompatibility JavaVersion.VERSION_17 52 | } 53 | } 54 | 55 | 56 | dependencies { 57 | compileOnly 'de.robv.android.xposed:api:82' 58 | 59 | implementation 'com.github.megatronking.stringfog:xor:5.0.0' 60 | 61 | // implementation 'androidx.appcompat:appcompat:1.4.1' 62 | // implementation 'com.google.android.material:material:1.5.0' 63 | // testImplementation 'junit:junit:4.13.2' 64 | // androidTestImplementation 'androidx.test.ext:junit:1.1.3' 65 | // androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' 66 | } -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/utils/StringUtil.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.utils; 2 | 3 | import java.util.Random; 4 | 5 | public class StringUtil { 6 | 7 | public static boolean isEmpty(CharSequence cs) { 8 | return cs == null || cs.length() == 0; 9 | } 10 | 11 | public static boolean containsIgnoreCase(String str, String searchStr) { 12 | if (str != null && searchStr != null) { 13 | int len = searchStr.length(); 14 | int max = str.length() - len; 15 | for (int i = 0; i <= max; ++i) { 16 | if (str.regionMatches(true, i, searchStr, 0, len)) { 17 | return true; 18 | } 19 | } 20 | } 21 | return false; 22 | } 23 | 24 | public static boolean isNumeric(CharSequence cs) { 25 | if (isEmpty(cs)) { 26 | return false; 27 | } 28 | for (int i = 0; i < cs.length(); ++i) { 29 | if (!Character.isDigit(cs.charAt(i))) { 30 | return false; 31 | } 32 | } 33 | return true; 34 | } 35 | 36 | /** 37 | * @param size 生成多少位 38 | * @param lowercase true为小写 , false为大写 39 | * @return String 40 | */ 41 | public static String randomUUID(int size, boolean lowercase) { 42 | String text = "0123456789ABCDEF"; 43 | StringBuilder sb = new StringBuilder(size); 44 | Random random = new Random(); 45 | for (int i = 0; i < size; i++) { 46 | sb.append(text.charAt(random.nextInt(text.length()))); 47 | } 48 | String result = sb.toString(); 49 | return lowercase ? result.toLowerCase() : result; 50 | } 51 | 52 | public static String randomText(int size, boolean lowercase) { 53 | String text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 54 | StringBuilder sb = new StringBuilder(size); 55 | Random random = new Random(); 56 | for (int i = 0; i < size; i++) { 57 | sb.append(text.charAt(random.nextInt(text.length()))); 58 | } 59 | String result = sb.toString(); 60 | return lowercase ? result.toLowerCase() : result; 61 | } 62 | 63 | public static boolean isMD5(String str) { 64 | String regex = "^[a-fA-F\\d]{32}$"; 65 | return str.matches(regex); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/enums/AppEnum.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.enums; 2 | 3 | public enum AppEnum { 4 | KU_WO("酷我音乐", "cn.kuwo.player"), 5 | QQ_LIVE("腾讯视频", "com.tencent.qqlive"), 6 | DAILY_TASK("DailyTask", "com.moyan.dailytask"), 7 | FAKE_LOCATION("FakeLocation", "com.lerist.fakelocation"), 8 | AI_CLIPS("爱剪辑", "com.shineyie.aijianji"), 9 | JUICE_SSH("JuiceSSH", "com.sonelli.juicessh"), 10 | DEV_CHECK("DevCheck", "flar2.devcheck"), 11 | BRAIN_WAVE("神奇脑波", "imoblife.brainwavestus"), 12 | NOW_MUSE("Now冥想", "com.imoblife.now"), 13 | ES_BROWSE("ES文件浏览器", "com.estrongs.android.pop"), 14 | SD_MAID("SdMaid", "eu.thedarken.sdm"), 15 | SD_MAID_SE("SdMaidSE", "eu.darken.sdmse"), 16 | TAROT("塔罗牌占卜", "taluo.jumeng.com.tarot"), 17 | AUDIO_CLIPS("音频剪辑大师", "com.lixiangdong.songcutter"), 18 | BEAR_VCR("小熊录屏", "com.duapps.recorder"), 19 | TICK("滴答清单", "cn.ticktick.task"), 20 | AI_QI_YI("爱奇艺", "com.qiyi.video"), 21 | RR_VIDEO("人人视频", "com.example.pptv"), 22 | LAUNCHER3("雷电launcher3", "com.android.launcher3"), 23 | ABC_VPN("ABC加速器","com.zfast.xyz"), 24 | JAPANESE("日语U学院", "com.easysay.japanese"), 25 | FAST_LINK_VPN("快连加速器","world.letsgo.booster.android.pro"), 26 | TERMIUS("Termius","com.server.auditor.ssh.client"), 27 | SA_COMIC("飒漫画","com.comic.isaman"), 28 | APK_PURE("APKPure","com.apkpure.aegon"), 29 | INFINITY_AI("无界AI","com.blockmeta.trade"), 30 | LAUNCHER2("逍遥launcher2", "com.microvirt.launcher2"), 31 | YOUTUBE("YouTube", "com.google.android.youtube"), 32 | TIKTOK("TikTok", "com.zhiliaoapp.musically"), 33 | 34 | GUI_GU("鬼谷八荒", "com.guigugame.guigubahuang"), 35 | TAP_TAP("TapTap", "com.taptap"), 36 | 37 | // TODO 待填写需要hook的枚举 38 | ; 39 | 40 | private final String appName; 41 | private final String packageName; 42 | 43 | AppEnum(String appName, String packageName) { 44 | this.appName = appName; 45 | this.packageName = packageName; 46 | } 47 | 48 | public String getAppName() { 49 | return appName; 50 | } 51 | 52 | public String getPackageName() { 53 | return packageName; 54 | } 55 | 56 | public static AppEnum getAppEnum(String packageName) { 57 | for (AppEnum appEnum : values()) { 58 | if (appEnum.getPackageName().equals(packageName)) { 59 | return appEnum; 60 | } 61 | } 62 | return null; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/TapTap.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import org.json.JSONObject; 6 | 7 | import de.robv.android.xposed.XC_MethodHook; 8 | import de.robv.android.xposed.XposedBridge; 9 | import de.robv.android.xposed.XposedHelpers; 10 | import xmnh.soulfrog.enums.AppEnum; 11 | import xmnh.soulfrog.interfaces.BaseHook; 12 | import xmnh.soulfrog.utils.AppUtil; 13 | 14 | public class TapTap implements BaseHook { 15 | @Override 16 | public void hook(Context context, ClassLoader classLoader) { 17 | Class momentReview = XposedHelpers.findClass("com.taptap.common.ext.moment.library.momentv2.MomentReview", classLoader); 18 | if (momentReview != null) { 19 | XposedBridge.hookAllConstructors(momentReview, new XC_MethodHook() { 20 | public void afterHookedMethod(XC_MethodHook.MethodHookParam param) { 21 | XposedHelpers.setBooleanField(param.thisObject, "isBought", true); 22 | } 23 | }); 24 | } 25 | Class orderDetailData = XposedHelpers.findClass("com.taptap.game.core.impl.pay.v2.bean.OrderDetailData", classLoader); 26 | if (orderDetailData != null) { 27 | XposedBridge.hookAllConstructors(orderDetailData, new XC_MethodHook() { 28 | public void afterHookedMethod(XC_MethodHook.MethodHookParam param) { 29 | XposedHelpers.setBooleanField(param.thisObject, "isBought", true); 30 | } 31 | }); 32 | } 33 | Class b = XposedHelpers.findClass("com.taptap.game.library.impl.v3.buy.b", classLoader); 34 | if (b != null) { 35 | XposedBridge.hookAllConstructors(b, new XC_MethodHook() { 36 | public void afterHookedMethod(XC_MethodHook.MethodHookParam param) { 37 | XposedHelpers.setBooleanField(param.thisObject, "b", true); 38 | } 39 | }); 40 | } 41 | XposedHelpers.findAndHookMethod(JSONObject.class, "optBoolean", new Object[]{String.class, new XC_MethodHook() { 42 | public void afterHookedMethod(XC_MethodHook.MethodHookParam param) { 43 | String key = (String) param.args[0]; 44 | if ("is_bought".equals(key)) { 45 | param.setResult(true); 46 | } 47 | } 48 | }}); 49 | AppUtil.finish(context, AppEnum.TAP_TAP.getAppName()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/SDMaid.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import java.lang.reflect.Method; 6 | import java.util.Arrays; 7 | 8 | import de.robv.android.xposed.XC_MethodHook; 9 | import de.robv.android.xposed.XC_MethodReplacement; 10 | import de.robv.android.xposed.XposedBridge; 11 | import de.robv.android.xposed.XposedHelpers; 12 | import xmnh.soulfrog.application.SoulFrog; 13 | import xmnh.soulfrog.interfaces.BaseHook; 14 | import xmnh.soulfrog.utils.AppUtil; 15 | 16 | public class SDMaid implements BaseHook { 17 | 18 | @Override 19 | public void hook(Context context, ClassLoader classLoader) { 20 | Class cls = XposedHelpers.findClass("x7.a", classLoader); 21 | if (cls != null) { 22 | XposedHelpers.findAndHookMethod(cls, "c", XC_MethodReplacement.returnConstant(true)); 23 | } 24 | Class cls2 = XposedHelpers.findClass("u7.c", classLoader); 25 | if (cls2 != null) { 26 | XposedHelpers.findAndHookMethod("u7.i", classLoader, "b", 27 | cls2, 28 | XC_MethodReplacement.returnConstant(true)); 29 | } 30 | AppUtil.finish(context); 31 | } 32 | 33 | public static class SDMaidSe implements BaseHook { 34 | 35 | @Override 36 | public void hook(Context context, ClassLoader classLoader) { 37 | Class state = XposedHelpers.findClass("eu.darken.sdmse.corpsefinder.ui.settings.CorpseFinderSettingsViewModel$State", classLoader); 38 | Class corpseFinder = XposedHelpers.findClass("eu.darken.sdmse.corpsefinder.core.CorpseFinder$State", classLoader); 39 | if (state != null && corpseFinder != null) { 40 | XposedHelpers.findAndHookConstructor(state, corpseFinder, boolean.class, boolean.class, new XC_MethodHook() { 41 | @Override 42 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 43 | param.args[1] = true; 44 | } 45 | }); 46 | } 47 | Class info = XposedHelpers.findClass("eu.darken.sdmse.common.upgrade.core.UpgradeRepoGplay$Info", classLoader); 48 | Class billingData = XposedHelpers.findClass("eu.darken.sdmse.common.upgrade.core.billing.BillingData", classLoader); 49 | if (info != null && billingData != null) { 50 | XposedHelpers.findAndHookConstructor(info, boolean.class, billingData, new XC_MethodHook() { 51 | @Override 52 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 53 | param.args[0] = true; 54 | } 55 | }); 56 | } 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/FastLinkVPN.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import static android.content.Context.MODE_PRIVATE; 4 | 5 | import android.app.Activity; 6 | import android.content.ContentResolver; 7 | import android.content.Context; 8 | import android.content.SharedPreferences; 9 | import android.os.Handler; 10 | import android.provider.Settings; 11 | import android.util.Log; 12 | 13 | import de.robv.android.xposed.XC_MethodHook; 14 | import de.robv.android.xposed.XC_MethodReplacement; 15 | import de.robv.android.xposed.XposedBridge; 16 | import de.robv.android.xposed.XposedHelpers; 17 | import xmnh.soulfrog.application.SoulFrog; 18 | import xmnh.soulfrog.enums.AppEnum; 19 | import xmnh.soulfrog.interfaces.BaseHook; 20 | import xmnh.soulfrog.utils.AppUtil; 21 | import xmnh.soulfrog.utils.HookUtil; 22 | import xmnh.soulfrog.utils.StringUtil; 23 | 24 | public class FastLinkVPN implements BaseHook { 25 | @Override 26 | public void hook(Context context, ClassLoader classLoader) { 27 | AppUtil.sp = context.getSharedPreferences("vip", MODE_PRIVATE); 28 | if (AppUtil.checkSp(StringUtil.randomText(16, false), 0)) { 29 | AppUtil.resetDataDir(context, AppEnum.FAST_LINK_VPN.getPackageName()); 30 | AppUtil.sp.edit().putString("inviter", "201271814").apply(); 31 | } 32 | getDeviceId(); 33 | // DeviceInfoUtils.kt 34 | /* switch (appVersionName) { 35 | case "2.18.6": 36 | getDeviceId(classLoader, "u3.a.a.a.a1.b2", "d"); 37 | return; 38 | case "2.18.10": 39 | case "2.18.12": 40 | getDeviceId(classLoader, "cs.m", "f"); 41 | return; 42 | case "2.18.16": 43 | getDeviceId(classLoader, "ds.m", "f"); 44 | return; 45 | case "2.18.18": 46 | getDeviceId(classLoader, "fs.l", "d"); 47 | return; 48 | case "2.18.20": 49 | getDeviceId(classLoader, "gs.l", "d"); 50 | return; 51 | default: 52 | getDeviceId(); 53 | }*/ 54 | AppUtil.finish(context); 55 | } 56 | 57 | private void getDeviceId() { 58 | XposedHelpers.findAndHookMethod(Settings.System.class, "getString", 59 | ContentResolver.class, String.class, 60 | new XC_MethodHook() { 61 | @Override 62 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 63 | String arg = (String) param.args[1]; 64 | if ("android_id".equals(arg)) { 65 | Log.d(SoulFrog.TAG, "device_id: " + AppUtil.sp.getString("device_id", "")); 66 | param.setResult(AppUtil.sp.getString("device_id", "")); 67 | } 68 | } 69 | }); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/Tick.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import org.json.JSONException; 6 | import org.json.JSONObject; 7 | 8 | import de.robv.android.xposed.XC_MethodHook; 9 | import de.robv.android.xposed.XC_MethodReplacement; 10 | import de.robv.android.xposed.XposedBridge; 11 | import de.robv.android.xposed.XposedHelpers; 12 | import xmnh.soulfrog.application.SoulFrog; 13 | import xmnh.soulfrog.interfaces.BaseHook; 14 | import xmnh.soulfrog.utils.AppUtil; 15 | import xmnh.soulfrog.utils.HookUtil; 16 | 17 | public class Tick implements BaseHook { 18 | boolean flag = true; 19 | @Override 20 | public void hook(Context context, ClassLoader classLoader) { 21 | /* Class user = XposedHelpers.findClass("com.ticktick.task.data.User", classLoader); 22 | if (user != null) { 23 | XposedHelpers.findAndHookMethod(user, "isPro", 24 | XC_MethodReplacement.returnConstant(true)); 25 | }*/ 26 | if (flag) { 27 | /* HookUtil.findOkHttpResponseBody(classLoader, param -> { 28 | String result = (String) param.getResult(); 29 | try { 30 | JSONObject jsonObject = new JSONObject(result); 31 | if (jsonObject.has("teamPro") && jsonObject.has("pro") 32 | && jsonObject.has("proEndDate") && jsonObject.has("needSubscribe")) { 33 | jsonObject.put("teamPro", true); 34 | jsonObject.put("pro", true); 35 | jsonObject.put("proEndDate", "2099-12-31T23:59:59.999+9999"); 36 | jsonObject.put("needSubscribe", false); 37 | param.setResult(jsonObject.toString()); 38 | } 39 | } catch (Throwable e) { 40 | XposedBridge.log(SoulFrog.TAG + "findOkHttpResponseBody ==> " + e.getMessage()); 41 | } 42 | });*/ 43 | Class generalApi = XposedHelpers.findClass("com.ticktick.task.sync.network.GeneralApi", classLoader); 44 | Class signUserInfo = XposedHelpers.findClass("com.ticktick.task.network.sync.entity.SignUserInfo", classLoader); 45 | if (generalApi != null){ 46 | XposedHelpers.findAndHookMethod(generalApi, "getUserStatus", new XC_MethodHook() { 47 | @Override 48 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 49 | Object result = param.getResult(); 50 | XposedHelpers.setBooleanField(result,"teamPro",true); 51 | XposedHelpers.setBooleanField(result,"pro",true); 52 | XposedHelpers.setBooleanField(result,"needSubscribe",false); 53 | param.setResult(result); 54 | } 55 | }); 56 | } 57 | 58 | AppUtil.finish(context); 59 | flag = false; 60 | } 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/NowMuse.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import de.robv.android.xposed.XC_MethodReplacement; 6 | import de.robv.android.xposed.XposedHelpers; 7 | import xmnh.soulfrog.interfaces.BaseHook; 8 | import xmnh.soulfrog.utils.AppUtil; 9 | 10 | public class NowMuse implements BaseHook { 11 | 12 | @Override 13 | public void hook(Context context, ClassLoader classLoader) { 14 | Class vipNowRight = XposedHelpers.findClass("com.imoblife.now.bean.VipNowRight", classLoader); 15 | if (vipNowRight != null) { 16 | XposedHelpers.findAndHookMethod(vipNowRight, "isIs_vip", 17 | XC_MethodReplacement.returnConstant(true)); 18 | XposedHelpers.findAndHookMethod(vipNowRight, "isVip_forever", 19 | XC_MethodReplacement.returnConstant(true)); 20 | } 21 | Class vipYogaRight = XposedHelpers.findClass("com.imoblife.now.bean.VipYogaRight", classLoader); 22 | if (vipYogaRight != null) { 23 | XposedHelpers.findAndHookMethod(vipYogaRight, "getIs_vip", 24 | XC_MethodReplacement.returnConstant(true)); 25 | } 26 | Class nowLog = XposedHelpers.findClass("com.imoblife.now.bean.NowLog", classLoader); 27 | if (nowLog != null) { 28 | XposedHelpers.findAndHookMethod(nowLog, "isVipUser", 29 | XC_MethodReplacement.returnConstant(true)); 30 | } 31 | Class vipExpandRight = XposedHelpers.findClass("com.imoblife.now.bean.VipExpandRight", classLoader); 32 | if (vipExpandRight != null) { 33 | XposedHelpers.findAndHookMethod(vipExpandRight, "getIs_vip", 34 | XC_MethodReplacement.returnConstant(true)); 35 | } 36 | Class course = XposedHelpers.findClass("com.imoblife.now.bean.Course", classLoader); 37 | if (course != null) { 38 | XposedHelpers.findAndHookMethod(course, "isVip", 39 | XC_MethodReplacement.returnConstant(true)); 40 | XposedHelpers.findAndHookMethod(course, "isPurchased", 41 | XC_MethodReplacement.returnConstant(true)); 42 | XposedHelpers.findAndHookMethod(course, "isSubscribe", 43 | XC_MethodReplacement.returnConstant(true)); 44 | XposedHelpers.findAndHookMethod(course, "isFreeCourse", 45 | XC_MethodReplacement.returnConstant(true)); 46 | XposedHelpers.findAndHookMethod(course, "isFutureFreeCourse", 47 | XC_MethodReplacement.returnConstant(true)); 48 | } 49 | Class track = XposedHelpers.findClass("com.imoblife.now.bean.Track", classLoader); 50 | if (track != null) { 51 | XposedHelpers.findAndHookMethod(track, "isFree", 52 | XC_MethodReplacement.returnConstant(true)); 53 | XposedHelpers.findAndHookMethod(track, "isUnLock", 54 | XC_MethodReplacement.returnConstant(true)); 55 | } 56 | AppUtil.finish(context); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/Jump.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.util.Log; 6 | 7 | import java.util.function.BiConsumer; 8 | 9 | import de.robv.android.xposed.IXposedHookLoadPackage; 10 | import de.robv.android.xposed.XC_MethodHook; 11 | import de.robv.android.xposed.XposedBridge; 12 | import de.robv.android.xposed.XposedHelpers; 13 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 14 | import xmnh.soulfrog.context.XpContext; 15 | import xmnh.soulfrog.factory.AppFactory; 16 | import xmnh.soulfrog.interfaces.BaseHook; 17 | import xmnh.soulfrog.utils.HookUtil; 18 | import xmnh.soulfrog.utils.KillAdsUtil; 19 | import xmnh.soulfrog.utils.ObjectionUtil; 20 | 21 | public class Jump implements IXposedHookLoadPackage { 22 | 23 | /** 24 | * 加固以及多dex处理方式 25 | * 26 | * @param consumer context 上下文 , ClassLoader 类加载器 27 | */ 28 | private void hookAttach(BiConsumer consumer) { 29 | XposedHelpers.findAndHookMethod(Application.class, "attach", 30 | Context.class, 31 | new XC_MethodHook() { 32 | public void afterHookedMethod(MethodHookParam param) throws Throwable { 33 | // 获取context上下文 34 | Context context = XpContext.getContext((Context) param.args[0]); 35 | try { 36 | // 获取classLoader类加载器 37 | XpContext.classLoader = context.getClassLoader(); 38 | } catch (XposedHelpers.ClassNotFoundError e) { 39 | XposedHelpers.findAndHookMethod(ClassLoader.class, "loadClass", String.class, new XC_MethodHook() { 40 | public void afterHookedMethod(XC_MethodHook.MethodHookParam param) { 41 | Class result = (Class) param.getResult(); 42 | Log.d("SoulFrog", "loadClass => " + result); 43 | if (result == null) { 44 | return; 45 | } 46 | XpContext.classLoader = result.getClassLoader(); 47 | } 48 | }); 49 | } finally { 50 | if (XpContext.classLoader != null) { 51 | consumer.accept(XpContext.getContext(context), XpContext.classLoader); 52 | } 53 | } 54 | } 55 | }); 56 | } 57 | 58 | @Override 59 | public void handleLoadPackage(XC_LoadPackage.LoadPackageParam param) throws Throwable { 60 | try { 61 | ObjectionUtil.hideAll(); 62 | // 实例化工厂 63 | BaseHook baseHook = AppFactory.init(param.processName); 64 | // 调用hook方法 65 | hookAttach((context, classLoader) -> { 66 | if (baseHook != null) { 67 | baseHook.hook(context, classLoader); 68 | } 69 | HookUtil.tapTap(context, classLoader); 70 | }); 71 | 72 | } catch (Throwable e) { 73 | XposedBridge.log(e); 74 | } 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/QQLive.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | import android.view.ViewGroup; 6 | 7 | import org.json.JSONObject; 8 | 9 | import java.lang.reflect.Method; 10 | 11 | import de.robv.android.xposed.XC_MethodHook; 12 | import de.robv.android.xposed.XC_MethodReplacement; 13 | import de.robv.android.xposed.XposedBridge; 14 | import de.robv.android.xposed.XposedHelpers; 15 | import xmnh.soulfrog.application.SoulFrog; 16 | import xmnh.soulfrog.interfaces.BaseHook; 17 | import xmnh.soulfrog.utils.AppUtil; 18 | import xmnh.soulfrog.utils.HookUtil; 19 | 20 | public class QQLive implements BaseHook { 21 | 22 | @Override 23 | public void hook(Context context, ClassLoader classLoader) { 24 | Class homeActivity = XposedHelpers.findClass("com.tencent.qqlive.ona.activity.HomeActivity", classLoader); 25 | if (homeActivity != null) { 26 | XposedHelpers.findAndHookMethod(homeActivity, "shouldDelayShowTeenGuardDialog", 27 | XC_MethodReplacement.returnConstant(true)); 28 | } 29 | Class feedAdConfigUtils = XposedHelpers.findClass("com.tencent.qqlive.ad.FeedAdConfigUtils", classLoader); 30 | if (feedAdConfigUtils != null) { 31 | HookUtil.booleAndVoidReplace(feedAdConfigUtils, false); 32 | } 33 | Class adPlayerData = XposedHelpers.findClass("com.tencent.qqlive.qadcore.data.AdPlayerData", classLoader); 34 | if (adPlayerData != null) { 35 | for (Method method : adPlayerData.getDeclaredMethods()) { 36 | if (method.getReturnType() == void.class) { 37 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(null)); 38 | } 39 | } 40 | } 41 | Class watermarkManager = XposedHelpers.findClass("com.tencent.qqlive.ona.player.plugin.watermark.WatermarkManager", classLoader); 42 | if (watermarkManager != null) { 43 | for (Method method : watermarkManager.getDeclaredMethods()) { 44 | if (method.getReturnType() == boolean.class) { 45 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(false)); 46 | } 47 | } 48 | } 49 | Class tVKLogoInfo = XposedHelpers.findClass("com.tencent.qqlive.tvkplayer.api.vinfo.TVKLogoInfo", classLoader); 50 | if (tVKLogoInfo != null) { 51 | XposedHelpers.findAndHookMethod(tVKLogoInfo, "getShow", 52 | XC_MethodReplacement.returnConstant(false)); 53 | } 54 | Class tVideoNetInfo = XposedHelpers.findClass("com.tencent.tavcut.tvkplayer.manager.TVideoNetInfo", classLoader); 55 | if (tVideoNetInfo != null) { 56 | XposedHelpers.findAndHookMethod(tVideoNetInfo, "isHasWatermark", 57 | XC_MethodReplacement.returnConstant(false)); 58 | } 59 | // 暂停广告 60 | Class TVKPlayerManager = XposedHelpers.findClass("com.tencent.qqlive.tvkplayer.logic.TVKPlayerManager", classLoader); 61 | if (TVKPlayerManager != null) { 62 | XposedHelpers.findAndHookMethod(TVKPlayerManager, "pauseWithIsAllowShowPauseAd", 63 | boolean.class, ViewGroup.class, 64 | new XC_MethodHook() { 65 | @Override 66 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 67 | param.args[0] = false; 68 | } 69 | }); 70 | } 71 | AppUtil.finish(context); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/factory/AppFactory.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.factory; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import xmnh.soulfrog.app.APKPure; 7 | import xmnh.soulfrog.app.AbcVPN; 8 | import xmnh.soulfrog.app.AiClips; 9 | import xmnh.soulfrog.app.AiQiYi; 10 | import xmnh.soulfrog.app.AudioClips; 11 | import xmnh.soulfrog.app.BearVCR; 12 | import xmnh.soulfrog.app.BrainWave; 13 | import xmnh.soulfrog.app.RRVideo; 14 | import xmnh.soulfrog.app.DailyTask; 15 | import xmnh.soulfrog.app.DevCheck; 16 | import xmnh.soulfrog.app.ESBrowse; 17 | import xmnh.soulfrog.app.FakeLocation; 18 | import xmnh.soulfrog.app.FastLinkVPN; 19 | import xmnh.soulfrog.app.InfinityAI; 20 | import xmnh.soulfrog.app.Japanese; 21 | import xmnh.soulfrog.app.JuiceSSH; 22 | import xmnh.soulfrog.app.KuWo; 23 | import xmnh.soulfrog.app.Launcher3; 24 | import xmnh.soulfrog.app.NowMuse; 25 | import xmnh.soulfrog.app.QQLive; 26 | import xmnh.soulfrog.app.SDMaid; 27 | import xmnh.soulfrog.app.SaComic; 28 | import xmnh.soulfrog.app.TapTap; 29 | import xmnh.soulfrog.app.Tarot; 30 | import xmnh.soulfrog.app.Termius; 31 | import xmnh.soulfrog.app.Tick; 32 | import xmnh.soulfrog.app.TikTok; 33 | import xmnh.soulfrog.enums.AppEnum; 34 | import xmnh.soulfrog.interfaces.BaseHook; 35 | 36 | public class AppFactory { 37 | private static final Map HOOKS = new HashMap<>(); 38 | 39 | static { 40 | HOOKS.put(AppEnum.FAKE_LOCATION.getPackageName(), new FakeLocation()); 41 | HOOKS.put(AppEnum.DAILY_TASK.getPackageName(), new DailyTask()); 42 | HOOKS.put(AppEnum.KU_WO.getPackageName(), new KuWo()); 43 | HOOKS.put(AppEnum.AI_CLIPS.getPackageName(), new AiClips()); 44 | HOOKS.put(AppEnum.JUICE_SSH.getPackageName(), new JuiceSSH()); 45 | HOOKS.put(AppEnum.QQ_LIVE.getPackageName(), new QQLive()); 46 | HOOKS.put(AppEnum.DEV_CHECK.getPackageName(), new DevCheck()); 47 | HOOKS.put(AppEnum.BRAIN_WAVE.getPackageName(), new BrainWave()); 48 | HOOKS.put(AppEnum.ES_BROWSE.getPackageName(), new ESBrowse()); 49 | HOOKS.put(AppEnum.NOW_MUSE.getPackageName(), new NowMuse()); 50 | HOOKS.put(AppEnum.SD_MAID.getPackageName(), new SDMaid()); 51 | HOOKS.put(AppEnum.SD_MAID_SE.getPackageName(), new SDMaid.SDMaidSe()); 52 | HOOKS.put(AppEnum.TAROT.getPackageName(), new Tarot()); 53 | HOOKS.put(AppEnum.AUDIO_CLIPS.getPackageName(), new AudioClips()); 54 | HOOKS.put(AppEnum.BEAR_VCR.getPackageName(), new BearVCR()); 55 | HOOKS.put(AppEnum.TICK.getPackageName(), new Tick()); 56 | HOOKS.put(AppEnum.AI_QI_YI.getPackageName(), new AiQiYi()); 57 | HOOKS.put(AppEnum.RR_VIDEO.getPackageName(), new RRVideo()); 58 | HOOKS.put(AppEnum.LAUNCHER3.getPackageName(), new Launcher3()); 59 | // HOOKS.put(AppEnum.LAUNCHER2.getPackageName(), new Launcher2()); 60 | HOOKS.put(AppEnum.JAPANESE.getPackageName(), new Japanese()); 61 | HOOKS.put(AppEnum.ABC_VPN.getPackageName(), new AbcVPN()); 62 | HOOKS.put(AppEnum.TERMIUS.getPackageName(), new Termius()); 63 | HOOKS.put(AppEnum.FAST_LINK_VPN.getPackageName(), new FastLinkVPN()); 64 | HOOKS.put(AppEnum.SA_COMIC.getPackageName(), new SaComic()); 65 | HOOKS.put(AppEnum.APK_PURE.getPackageName(), new APKPure()); 66 | HOOKS.put(AppEnum.INFINITY_AI.getPackageName(), new InfinityAI()); 67 | HOOKS.put(AppEnum.TIKTOK.getPackageName(), new TikTok()); 68 | HOOKS.put(AppEnum.TAP_TAP.getPackageName(), new TapTap()); 69 | 70 | // TODO 待填写需要hook的实例 71 | } 72 | 73 | public static BaseHook init(String packageName) { 74 | return HOOKS.getOrDefault(packageName, null); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/utils/AppUtil.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.utils; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.util.Log; 6 | import android.widget.Toast; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | 11 | import xmnh.soulfrog.application.SoulFrog; 12 | 13 | public class AppUtil { 14 | private static Toast toast; 15 | public static SharedPreferences sp; 16 | 17 | /** 18 | * 获取app版本名称 19 | * 20 | * @return 返回版本名称 21 | */ 22 | public static String getAppVersionName(Context context) { 23 | try { 24 | return context.getPackageManager() 25 | .getPackageInfo(context.getPackageName(), Context.MODE_PRIVATE) 26 | .versionName; 27 | } catch (Exception e) { 28 | Log.e(SoulFrog.TAG, "getAppVersionName error" + e); 29 | } 30 | return ""; 31 | } 32 | 33 | /** 34 | * 获取app版本号 35 | * 36 | * @return 返回版本号 37 | */ 38 | public static int getAppVersionCode(Context context) { 39 | try { 40 | return context.getPackageManager() 41 | .getPackageInfo(context.getPackageName(), Context.MODE_PRIVATE) 42 | .versionCode; 43 | } catch (Exception e) { 44 | Log.e(SoulFrog.TAG, "getAppVersionCode error" + e); 45 | } 46 | return 0; 47 | } 48 | 49 | /** 50 | * 吐司弹窗 51 | * 52 | * @param str 内容 53 | */ 54 | public static void finish(Context context, String str) { 55 | if (toast == null) { 56 | toast = Toast.makeText(context, str, Toast.LENGTH_SHORT); 57 | } else { 58 | toast.setText(str); 59 | } 60 | toast.show(); 61 | } 62 | 63 | public static void finish(Context context) { 64 | String text = context.getPackageName() + " : ~ start running ~"; 65 | if (toast == null) { 66 | toast = Toast.makeText(context, text, Toast.LENGTH_SHORT); 67 | } else { 68 | toast.setText(text); 69 | } 70 | toast.show(); 71 | } 72 | 73 | /** 74 | * 检查sp 75 | * 76 | * @param deviceId 设备id 77 | * @param time 加减时间 78 | * @return true/false 79 | */ 80 | public static boolean checkSp(String deviceId, long time) { 81 | // 默认加时间为40分钟 82 | long expireTime = 2_400_000; 83 | long currentTime = System.currentTimeMillis(); 84 | // 不包含键或当前时间大于等于过期时间,则进行put操作 85 | if (!sp.contains("expire_time") || currentTime >= sp.getLong("expire_time", 0)) { 86 | SharedPreferences.Editor editor = sp.edit(); 87 | editor.putString("device_id", deviceId); 88 | editor.putLong("expire_time", currentTime + expireTime + time); 89 | editor.apply(); 90 | return true; 91 | } 92 | return false; 93 | } 94 | 95 | public static void resetApp(String packageName) { 96 | try { 97 | Runtime.getRuntime().exec("pm clear " + packageName); 98 | } catch (IOException e) { 99 | Log.e(SoulFrog.TAG, "resetApp error" + e); 100 | } 101 | 102 | } 103 | 104 | public static void resetDataDir(Context context, String packageName) { 105 | if (StringUtil.isEmpty(packageName)) return; 106 | File dataDir = context.getDataDir(); 107 | File filesDir = context.getFilesDir(); 108 | // File externalFilesDir = context.getExternalFilesDir(""); 109 | // File cacheDir = context.getCacheDir(); 110 | if (packageName.equals(context.getPackageName())) { 111 | deleteDirectory(dataDir); 112 | deleteDirectory(filesDir); 113 | // deleteDirectory(externalFilesDir); 114 | // deleteDirectory(cacheDir); 115 | } 116 | } 117 | 118 | private static void deleteDirectory(File file) { 119 | if (!file.exists()) return; 120 | if (file.isDirectory()) { 121 | File[] files = file.listFiles(); 122 | if (files != null) { 123 | for (File subFile : files) { 124 | deleteDirectory(subFile); 125 | } 126 | } 127 | } 128 | boolean delete = file.delete(); 129 | Log.d(SoulFrog.TAG, delete ? "删除成功" : "删除失败"); 130 | } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/AiQiYi.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | 5 | import java.lang.reflect.Method; 6 | import java.lang.reflect.Modifier; 7 | 8 | import de.robv.android.xposed.XC_MethodHook; 9 | import de.robv.android.xposed.XC_MethodReplacement; 10 | import de.robv.android.xposed.XposedBridge; 11 | import de.robv.android.xposed.XposedHelpers; 12 | import xmnh.soulfrog.interfaces.BaseHook; 13 | import xmnh.soulfrog.utils.AppUtil; 14 | 15 | public class AiQiYi implements BaseHook { 16 | 17 | @Override 18 | public void hook(Context context, ClassLoader classLoader) { 19 | Class playerAlbumInfo = XposedHelpers.findClassIfExists("com.iqiyi.video.qyplayersdk.model.PlayerAlbumInfo", classLoader); 20 | if (playerAlbumInfo != null) { 21 | XposedHelpers.findAndHookMethod(playerAlbumInfo, "isShowWaterMark", 22 | XC_MethodReplacement.returnConstant(false)); 23 | } 24 | Class PlayerAlbumInfo = XposedHelpers.findClassIfExists("com.qiyi.shortplayer.player.model.PlayerAlbumInfo", classLoader); 25 | if (PlayerAlbumInfo != null) { 26 | XposedHelpers.findAndHookMethod(PlayerAlbumInfo, "isShowWaterMark", 27 | XC_MethodReplacement.returnConstant(false)); 28 | } 29 | Class QYPlayerControlConfig = XposedHelpers.findClassIfExists("com.iqiyi.video.qyplayersdk.model.QYPlayerControlConfig", classLoader); 30 | if (QYPlayerControlConfig != null) { 31 | XposedHelpers.findAndHookMethod(QYPlayerControlConfig, "isShowWaterMark", 32 | XC_MethodReplacement.returnConstant(false)); 33 | } 34 | Class QYPlayerADConfig = XposedHelpers.findClassIfExists("com.iqiyi.video.qyplayersdk.model.QYPlayerADConfig", classLoader); 35 | if (QYPlayerADConfig != null) { 36 | XposedHelpers.findAndHookMethod(QYPlayerADConfig, "isShowPause", 37 | XC_MethodReplacement.returnConstant(false)); 38 | XposedHelpers.findAndHookMethod(QYPlayerADConfig, "needCheckHalfPauseAdShow", 39 | XC_MethodReplacement.returnConstant(false)); 40 | } 41 | Class adDefaultListener = XposedHelpers.findClassIfExists("com.iqiyi.video.qyplayersdk.cupid.listener.AdDefaultListener", classLoader); 42 | if (adDefaultListener != null) { 43 | XposedHelpers.findAndHookMethod(adDefaultListener, "isNeedRequestPauseAds", 44 | XC_MethodReplacement.returnConstant(false)); 45 | } 46 | Class AdsController = XposedHelpers.findClassIfExists("com.iqiyi.video.qyplayersdk.cupid.AdsController", classLoader); 47 | if (AdsController != null) { 48 | XposedHelpers.findAndHookMethod(AdsController, "isNeedRequestPauseAds", 49 | XC_MethodReplacement.returnConstant(false)); 50 | XposedHelpers.findAndHookMethod(AdsController, "showOrHideAdView", 51 | int.class, boolean.class, 52 | new XC_MethodHook() { 53 | @Override 54 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 55 | param.args[0] = 17; 56 | param.args[1] = false; 57 | } 58 | }); 59 | } 60 | Class d = XposedHelpers.findClassIfExists("com.qiyi.video.qysplashscreen.d", classLoader); 61 | if (d != null) { 62 | XposedHelpers.findAndHookMethod(d, "showHotLaunchSplashAd", 63 | String.class, 64 | XC_MethodReplacement.returnConstant(false)); 65 | } 66 | Class sdkAdapterInitor = XposedHelpers.findClassIfExists("org.iqiyi.video.adapter.sdk.SdkAdapterInitor", classLoader); 67 | if (sdkAdapterInitor != null) { 68 | XposedBridge.hookAllMethods(sdkAdapterInitor, "initAd", XC_MethodReplacement.returnConstant(null)); 69 | } 70 | 71 | Class adPlayerCondition = XposedHelpers.findClassIfExists("org.qiyi.cast.ui.ad.AdPlayerCondition", classLoader); 72 | if (adPlayerCondition != null) { 73 | XposedHelpers.findAndHookMethod(adPlayerCondition, "isAllowPlay", XC_MethodReplacement.returnConstant(false)); 74 | } 75 | Class mainActivity = XposedHelpers.findClassIfExists("org.qiyi.android.video.MainActivity", classLoader); 76 | if (mainActivity != null) { 77 | for (Method method : mainActivity.getDeclaredMethods()) { 78 | if (method.getModifiers() == Modifier.PRIVATE && method.getReturnType() == boolean.class 79 | && method.getParameterTypes().length == 1) { 80 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(false)); 81 | } 82 | } 83 | } 84 | AppUtil.finish(context); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/utils/KillAdsUtil.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.utils; 2 | 3 | import android.content.res.AssetManager; 4 | import android.util.Log; 5 | 6 | import java.io.IOException; 7 | import java.lang.reflect.Method; 8 | import java.lang.reflect.Modifier; 9 | import java.util.ArrayList; 10 | import java.util.HashMap; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | import de.robv.android.xposed.XC_MethodHook; 15 | import de.robv.android.xposed.XC_MethodReplacement; 16 | import de.robv.android.xposed.XposedBridge; 17 | import de.robv.android.xposed.XposedHelpers; 18 | import xmnh.soulfrog.application.SoulFrog; 19 | 20 | public class KillAdsUtil { 21 | private static final Map> CLASS_CACHE = new HashMap<>(); 22 | private static final Map, Boolean> CACHE_FLAG = new HashMap<>(); 23 | private static final List ADS = new ArrayList<>(); 24 | private static boolean finish; 25 | 26 | static { 27 | // 优量汇 28 | ADS.add("com.qq.e.comm.managers.GDTADManager"); 29 | // 广点通 30 | ADS.add("com.qq.e.comm.managers.b"); 31 | // 穿山甲 32 | ADS.add("com.bytedance.sdk.openadsdk.TTAdSdk"); 33 | ADS.add("com.bytedance.sdk.openadsdk.TTAdManager"); 34 | // 游可赢 35 | ADS.add("com.tencent.klevin.KlevinManager"); 36 | // ADS.add("com.bytedance.sdk.openadsdk.TTAdBridge"); 37 | // ADS.add("com.bytedance.sdk.openadsdk.AdSlot$Builder"); 38 | // ADS.add("com.bytedance.pangle.Zeus"); 39 | // 友盟 40 | ADS.add("com.umeng.commonsdk.UMConfigure"); 41 | // bugly 42 | ADS.add("com.tencent.bugly.crashreport.CrashReport"); 43 | // ADS.add("com.tencent.bugly.Bugly"); 44 | ADS.add("com.tencent.ams.xsad.rewarded.RewardedAd"); 45 | // google 46 | ADS.add("com.google.android.gms.ads.MobileAds"); 47 | // ADS.add("com.google.ads.mediation.admob.AdMobAdapter"); 48 | // 百青藤 49 | ADS.add("com.baidu.mobads.sdk.api.BDAdConfig"); 50 | // ADS.add("com.baidu.mobads.sdk.api.AdView"); 51 | // ADS.add("com.baidu.mobads.sdk.api.NovelSDKConfig"); 52 | // ADS.add("com.baidu.mobads.sdk.internal.bo"); 53 | // bigo 54 | ADS.add("sg.bigo.ads.BigoAdSdk"); 55 | // sigmob 56 | ADS.add("com.sigmob.windad.WindAds"); 57 | ADS.add("com.sigmob.sdk.Sigmob"); 58 | // 有米 59 | ADS.add("net.youmi.overseas.android.YoumiOffersWallSdk"); 60 | // 快手 61 | ADS.add("com.kwad.sdk.api.KsAdSDK"); 62 | // ADS.add("com.kwad.sdk.core.network.BaseResultData"); 63 | // ADS.add("com.kwad.components.offline.api.core.network.model.BaseOfflineCompoResultData"); 64 | // ADS.add("com.kwad.sdk.KsAdSDKImpl"); 65 | // ADS.add("com.kuaishou.pushad.PushAdManager"); 66 | // ADS.add("com.kuaishou.pushad.KsAdGlobalWatcher"); 67 | // ADS.add("com.tencentmusic.ad.TMEAds"); 68 | // unity 69 | ADS.add("com.unity3d.ads.UnityAds"); 70 | // Vungle 71 | ADS.add("com.vungle.warren.Vungle"); 72 | // yomob 73 | ADS.add("com.yomob.tgsdklib.TGADSDK"); 74 | ADS.add("com.mbridge.msdk.MBridgeSDK"); 75 | // ADS.add("com.jd.ad.sdk.JadAdNative"); 76 | // 京准通 77 | ADS.add("com.jd.ad.sdk.JadYunSdk"); 78 | // 倍孜 79 | ADS.add("com.beizi.ad.BeiZi"); 80 | ADS.add("com.beizi.fusion.BeiZis"); 81 | // 小米 82 | ADS.add("com.xiaomi.ad.AdSdk"); 83 | // ADS.add("com.tianmu.TianmuSDK"); 84 | // ADS.add("com.tencent.qqmini.sdk.utils.AdUtil"); 85 | // ADS.add("com.tencent.qqmini.sdk.plugins.BannerAdPlugin"); 86 | // ADS.add("com.tencent.qqmini.minigame.plugins.BlockAdPlugin"); 87 | // ADS.add("com.tencent.ads.AdManager"); 88 | // ADS.add("com.tencent.ad.tangram.AdManagerForQQ"); 89 | // ADS.add("com.tencent.ad.tangram.settings.AdSettingsManager"); 90 | // ADS.add("com.tencent.gdtad.aditem.GdtAd"); 91 | // ADS.add("com.tencent.gdtad.api.GdtAd"); 92 | // ADS.add("com.anythink.splashad.api.ATSplashAd"); 93 | // 米盟 94 | ADS.add("com.miui.zeus.mimo.sdk.MimoSdk"); 95 | // 极光推送 96 | ADS.add("cn.jpush.android.api.JPushInterface"); 97 | // ADS.add("cn.jiguang.union.ads.base.api.JAdApi"); 98 | // ADS.add("cn.jiguang.ads.nativ.api.JNativeAdApi"); 99 | // ADS.add("cn.jiguang.ads.notify.api.JNotifyAdApi"); 100 | // inmobi 101 | ADS.add("com.inmobi.sdk.InMobiSdk"); 102 | // oppo联盟 103 | ADS.add("com.heytap.msp.mobad.api.MobAdManager"); 104 | // 脸书 105 | ADS.add("com.facebook.ads.AudienceNetworkAds"); 106 | // smaato 107 | ADS.add("com.smaato.sdk.core.SmaatoSdk"); 108 | // applovin 109 | ADS.add("com.applovin.sdk.AppLovinSdk"); 110 | // mopub 111 | ADS.add("com.mopub.common.MoPub"); 112 | // 华为 113 | ADS.add("com.huawei.hms.ads.HwAds"); 114 | // verve 115 | ADS.add("net.pubnative.lite.sdk.HyBid"); 116 | // yandex 117 | ADS.add("com.yandex.mobile.ads.common.MobileAds"); 118 | // VerizonAds 119 | ADS.add("com.yahoo.ads.YASAds"); 120 | // inmobi 121 | ADS.add("com.inmobi.sdk.InMobiSdk"); 122 | // maio 123 | ADS.add("jp.maio.sdk.android.MaioAds"); 124 | // verve 125 | ADS.add("net.pubnative.lite.sdk.HyBid"); 126 | } 127 | 128 | public static void killAds(ClassLoader classLoader) { 129 | if (finish) return; 130 | for (String ad : ADS) { 131 | try { 132 | Class cls = CLASS_CACHE.get(ad); 133 | if (cls == null) { 134 | cls = XposedHelpers.findClassIfExists(ad, classLoader); 135 | if (cls != null) { 136 | CLASS_CACHE.put(ad, cls); 137 | } 138 | } 139 | replace(cls); 140 | } catch (Throwable e) { 141 | XposedBridge.log(e); 142 | } 143 | } 144 | Runtime.getRuntime().gc(); 145 | finish = true; 146 | } 147 | 148 | private static void replace(Class cls) { 149 | if (cls == null) return; 150 | if (CACHE_FLAG.containsKey(cls)) return; 151 | for (Method method : cls.getDeclaredMethods()) { 152 | if (Modifier.isNative(method.getModifiers())) continue; 153 | if (method.getReturnType() == boolean.class 154 | || method.getReturnType() == Boolean.class) { 155 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(false)); 156 | } else if (method.getReturnType() == void.class 157 | || method.getReturnType() == cls) { 158 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(null)); 159 | } else if (method.getReturnType() == String.class) { 160 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant("")); 161 | } 162 | } 163 | CACHE_FLAG.put(cls, Boolean.TRUE); 164 | Log.d(SoulFrog.TAG,"killAd => " + cls.getName()); 165 | } 166 | 167 | public static void assets() { 168 | XposedHelpers.findAndHookMethod(AssetManager.class, "open", 169 | String.class, 170 | int.class, 171 | new XC_MethodHook() { 172 | @Override 173 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 174 | // 获取要打开的文件名 175 | String fileName = (String) param.args[0]; 176 | // 判断是否是广告插件 177 | if (fileName.contains("xadsdk") 178 | || StringUtil.isMD5(fileName) 179 | || (StringUtil.isNumeric(fileName) && fileName.length() >= 9) 180 | || fileName.contains("gdtadv2")) { 181 | XposedBridge.log("assets ad plugin => " + fileName); 182 | // 如果是广告插件,则返回一个空的 InputStream,从而阻止文件的加载 183 | param.args[0] = ""; 184 | // 更改为抛FileNotFoundException异常 185 | // param.setThrowable(new Exception()); 186 | } 187 | } 188 | }); 189 | } 190 | 191 | public static void killAdPrecise(ClassLoader classLoader) { 192 | try { 193 | byteDanceAd(classLoader); 194 | tencentAd(classLoader); 195 | } catch (Throwable e) { 196 | XposedBridge.log(e); 197 | } 198 | } 199 | 200 | private static void byteDanceAd(ClassLoader classLoader) { 201 | try { 202 | Class ttAdSdk = XposedHelpers.findClass("com.bytedance.sdk.openadsdk.TTAdSdk", classLoader); 203 | if (ttAdSdk != null) { 204 | XposedHelpers.findAndHookMethod(ttAdSdk, "getAdManager", 205 | XC_MethodReplacement.returnConstant(null)); 206 | } 207 | } catch (Throwable e) { 208 | XposedBridge.log(e); 209 | } 210 | } 211 | 212 | private static void tencentAd(ClassLoader classLoader) { 213 | try { 214 | Class splashAD = XposedHelpers.findClass("com.qq.e.ads.splash.SplashAD", classLoader); 215 | if (splashAD != null) { 216 | XposedBridge.hookAllConstructors(splashAD, XC_MethodReplacement.returnConstant(null)); 217 | } 218 | Class rewardVideoAD = XposedHelpers.findClass("com.qq.e.ads.rewardvideo.RewardVideoAD", classLoader); 219 | if (rewardVideoAD != null) { 220 | XposedHelpers.findAndHookMethod(rewardVideoAD, "loadAD", XC_MethodReplacement.returnConstant(null)); 221 | } 222 | Class unifiedInterstitialAD = XposedHelpers.findClass("com.qq.e.ads.interstitial2.UnifiedInterstitialAD", classLoader); 223 | if (unifiedInterstitialAD != null) { 224 | XposedHelpers.findAndHookMethod(unifiedInterstitialAD, "loadAD", XC_MethodReplacement.returnConstant(null)); 225 | } 226 | Class unifiedBannerView = XposedHelpers.findClass("com.qq.e.ads.banner2.UnifiedBannerView", classLoader); 227 | if (unifiedBannerView != null) { 228 | XposedHelpers.findAndHookMethod(unifiedBannerView, "loadAD", XC_MethodReplacement.returnConstant(null)); 229 | } 230 | Class nativeExpressAD = XposedHelpers.findClass("com.qq.e.ads.nativ.NativeExpressAD", classLoader); 231 | if (nativeExpressAD != null) { 232 | XposedBridge.hookAllMethods(nativeExpressAD, "loadAD", XC_MethodReplacement.returnConstant(null)); 233 | } 234 | Class nativeUnifiedAD = XposedHelpers.findClass("com.qq.e.ads.nativ.NativeUnifiedAD", classLoader); 235 | if (nativeUnifiedAD != null) { 236 | XposedBridge.hookAllMethods(nativeUnifiedAD, "loadData", XC_MethodReplacement.returnConstant(null)); 237 | } 238 | } catch (Throwable e) { 239 | XposedBridge.log(e); 240 | } 241 | } 242 | 243 | } 244 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/utils/HookUtil.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.utils; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import org.json.JSONObject; 7 | 8 | import java.lang.reflect.Method; 9 | import java.lang.reflect.Modifier; 10 | import java.util.function.Consumer; 11 | 12 | import de.robv.android.xposed.XC_MethodHook; 13 | import de.robv.android.xposed.XC_MethodReplacement; 14 | import de.robv.android.xposed.XposedBridge; 15 | import de.robv.android.xposed.XposedHelpers; 16 | import xmnh.soulfrog.application.SoulFrog; 17 | 18 | public class HookUtil { 19 | /** 20 | * 通过反射类,找到方法返回类型为void和boolean的所有方法 21 | * 22 | * @param cls 类 23 | * @param bool true/false 24 | */ 25 | public static void booleAndVoidReplace(Class cls, boolean bool) { 26 | if (cls == null) return; 27 | for (Method method : cls.getDeclaredMethods()) { 28 | if (Modifier.isNative(method.getModifiers())) return; 29 | if (method.getReturnType() == boolean.class 30 | || method.getReturnType() == Boolean.class) { 31 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(bool)); 32 | } else if (method.getReturnType() == void.class) { 33 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(null)); 34 | } 35 | } 36 | } 37 | 38 | 39 | /** 40 | * 通过反射类,找到方法返回类型为boolean的所有方法 41 | * 42 | * @param cls 类 43 | * @param bool true/false 44 | */ 45 | public static void booleReplace(Class cls, boolean bool) { 46 | if (cls == null) return; 47 | for (Method method : cls.getDeclaredMethods()) { 48 | if (method.getModifiers() != Modifier.NATIVE) { 49 | if (method.getReturnType() == boolean.class || method.getReturnType() == Boolean.class) { 50 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(bool)); 51 | } 52 | } 53 | } 54 | } 55 | 56 | /** 57 | * 查找okhttp3 58 | */ 59 | public static void findOkHttpResponseBody(ClassLoader classLoader, Consumer consumer) { 60 | Class cls = XposedHelpers.findClass("okhttp3.Response", classLoader); 61 | if (cls != null) { 62 | XposedHelpers.findAndHookMethod(cls, "isSuccessful", XC_MethodReplacement.returnConstant(true)); 63 | } 64 | Class cls2 = XposedHelpers.findClass("okhttp3.ResponseBody", classLoader); 65 | if (cls != null) { 66 | XposedHelpers.findAndHookMethod(cls2, "string", new XC_MethodHook() { 67 | @Override 68 | protected void beforeHookedMethod(MethodHookParam param) { 69 | consumer.accept(param); 70 | } 71 | }); 72 | } 73 | } 74 | 75 | public static void findOkhttpRequest(ClassLoader classLoader, String url) { 76 | Class cls = XposedHelpers.findClass("okhttp3.Request$Builder", classLoader); 77 | Class httpUrl = XposedHelpers.findClass("okhttp3.HttpUrl", classLoader); 78 | if (cls != null) { 79 | XposedHelpers.findAndHookMethod(cls, "url", httpUrl, new XC_MethodHook() { 80 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 81 | if (url != null && httpUrl != null) { 82 | param.args[0] = url; 83 | Object getUrl = XposedHelpers.callMethod(param.args[0], "get", String.class); 84 | 85 | } 86 | 87 | } 88 | 89 | @Override 90 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 91 | if (url != null && httpUrl != null) { 92 | // param.args[0] = url; 93 | // if () 94 | // Object getUrl = XposedHelpers.callMethod(param.args[0], "get", String.class); 95 | 96 | } 97 | } 98 | }); 99 | } 100 | Class cls2 = XposedHelpers.findClass("okhttp3.ResponseBody", classLoader); 101 | if (cls != null) { 102 | XposedHelpers.findAndHookMethod(cls2, "string", new XC_MethodHook() { 103 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 104 | Log.d(SoulFrog.TAG + " find okhttp3 ", param.getResult().toString()); 105 | } 106 | }); 107 | } 108 | } 109 | 110 | /** 111 | * 查找原生jsonObject 112 | */ 113 | public static void findJsonObject(ClassLoader classLoader) { 114 | Class cls = XposedHelpers.findClass("org.json.JSONObject", classLoader); 115 | if (null == cls) return; 116 | XposedHelpers.findAndHookConstructor(JSONObject.class, String.class, new XC_MethodHook() { 117 | @Override 118 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 119 | Log.d(SoulFrog.TAG + " find constructor ", param.args[0].toString()); 120 | } 121 | }); 122 | XposedHelpers.findAndHookMethod(JSONObject.class, "toString", new XC_MethodHook() { 123 | @Override 124 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 125 | if (StringUtil.containsIgnoreCase(param.getResult().toString(), "vip")) { 126 | Log.d(SoulFrog.TAG + " find vip json ", param.getResult().toString()); 127 | } 128 | } 129 | }); 130 | } 131 | 132 | /** 133 | * 查找gson 134 | */ 135 | public static void findGson(ClassLoader classLoader) { 136 | Class cls = XposedHelpers.findClass("com.google.gson.Gson", classLoader); 137 | if (cls != null) { 138 | XposedHelpers.findAndHookMethod(cls, "fromJson", String.class, Class.class, new XC_MethodHook() { 139 | @Override 140 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 141 | Log.d(SoulFrog.TAG + " find gson ", param.args[0].toString()); 142 | } 143 | }); 144 | } 145 | } 146 | 147 | /** 148 | * 查找fastjson 149 | */ 150 | public static void findFastjson(ClassLoader classLoader) { 151 | Class cls = XposedHelpers.findClass("com.alibaba.fastjson.JSONObject", classLoader); 152 | if (cls != null) { 153 | XposedHelpers.findAndHookMethod(cls, "toJavaObject", Class.class, new XC_MethodHook() { 154 | @Override 155 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 156 | Log.d(SoulFrog.TAG + " find fastjson ", param.args[0].toString()); 157 | } 158 | }); 159 | } 160 | } 161 | 162 | /** 163 | * param.args[0]为String.class , param.args[1]Class.class 164 | * 165 | * @param consumer MethodHookParam 166 | */ 167 | public static void gsonFromJson(ClassLoader classLoader, Consumer consumer) { 168 | Class cls = XposedHelpers.findClass("com.google.gson.Gson", classLoader); 169 | if (null == cls) return; 170 | try { 171 | XposedHelpers.findAndHookMethod(cls, "fromJson", String.class, Class.class, new XC_MethodHook() { 172 | @Override 173 | protected void beforeHookedMethod(MethodHookParam param) { 174 | consumer.accept(param); 175 | } 176 | }); 177 | } catch (Throwable e) { 178 | // public T fromJson(String json, Class classOfT) 179 | // 找到类了但方法名被混淆了,会抛出NoSuchMethodError则进行动态查找 180 | for (Method method : cls.getDeclaredMethods()) { 181 | if (method.getReturnType() == Object.class 182 | && method.getParameterTypes().length == 2 183 | && method.getParameterTypes()[0] == String.class 184 | && method.getParameterTypes()[1] == Class.class) { 185 | XposedBridge.hookMethod(method, new XC_MethodHook() { 186 | @Override 187 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 188 | consumer.accept(param); 189 | } 190 | }); 191 | } 192 | } 193 | } 194 | } 195 | 196 | public static void gsonToJson(ClassLoader classLoader, Consumer consumer) { 197 | Class cls = XposedHelpers.findClass("com.google.gson.Gson", classLoader); 198 | if (null == cls) return; 199 | try { 200 | XposedHelpers.findAndHookMethod(cls, "toJson", Object.class, new XC_MethodHook() { 201 | @Override 202 | protected void beforeHookedMethod(MethodHookParam param) { 203 | consumer.accept(param); 204 | } 205 | }); 206 | } catch (Throwable e) { 207 | // public String toJson(Object src) 208 | // 找到类了但方法名被混淆了,会抛出NoSuchMethodError则进行动态查找 209 | for (Method method : cls.getDeclaredMethods()) { 210 | if (method.getReturnType() == String.class 211 | && method.getParameterTypes().length == 1 212 | && method.getParameterTypes()[0] == Object.class) { 213 | XposedBridge.hookMethod(method, new XC_MethodHook() { 214 | @Override 215 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 216 | consumer.accept(param); 217 | } 218 | }); 219 | } 220 | } 221 | } 222 | } 223 | 224 | public static String printStackTrace() { 225 | StringBuilder sb = new StringBuilder(); 226 | Throwable throwable = new Throwable(); 227 | StackTraceElement[] stackElements = throwable.getStackTrace(); 228 | for (StackTraceElement element : stackElements) { 229 | sb.append("at ") 230 | .append(element.getClassName()).append(".").append(element.getMethodName()) 231 | .append("(") 232 | .append(element.getFileName()).append(":").append(element.getLineNumber()) 233 | .append(")") 234 | .append("\n"); 235 | } 236 | return sb.toString(); 237 | } 238 | 239 | public static void tapTap(Context context, ClassLoader classLoader) { 240 | Class profile = XposedHelpers.findClassIfExists("com.taptap.sdk.Profile", classLoader); 241 | if (profile == null) { 242 | return; 243 | } 244 | context.getSharedPreferences("tap_license", 0) 245 | .edit() 246 | .putLong("last_license_date", 1754611688000L) 247 | .putLong("last_license_date_second", 1754611688000L) 248 | .apply(); 249 | Class tapPurchase = XposedHelpers.findClass("com.taptap.pay.sdk.library.TapPurchase", classLoader); 250 | if (tapPurchase != null) { 251 | XposedBridge.hookAllConstructors(tapPurchase, new XC_MethodHook() { 252 | public void afterHookedMethod(XC_MethodHook.MethodHookParam param) { 253 | Log.d("SoulFrog", "tapPurchase hookAllConstructors => " + param.thisObject); 254 | XposedHelpers.setBooleanField(param.thisObject, "isBought", true); 255 | } 256 | }); 257 | } 258 | Class userInfo = XposedHelpers.findClass("com.tapsdk.antiaddiction.entities.UserInfo", classLoader); 259 | if (userInfo != null) { 260 | XposedHelpers.findAndHookMethod(userInfo, "isAdult", XC_MethodReplacement.returnConstant(true)); 261 | XposedBridge.hookAllConstructors(userInfo, new XC_MethodHook() { 262 | public void afterHookedMethod(XC_MethodHook.MethodHookParam param) { 263 | XposedHelpers.setIntField(param.thisObject, "ageLimit", 18); 264 | XposedHelpers.setIntField(param.thisObject, "remainTime", 9999); 265 | } 266 | }); 267 | } 268 | AppUtil.finish(context); 269 | } 270 | 271 | } 272 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/utils/ObjectionUtil.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.utils; 2 | 3 | import static de.robv.android.xposed.XposedHelpers.findConstructorExact; 4 | 5 | import android.content.ContentResolver; 6 | import android.net.NetworkCapabilities; 7 | import android.os.Build; 8 | import android.os.Debug; 9 | import android.provider.Settings; 10 | import android.telephony.TelephonyManager; 11 | import android.util.Log; 12 | 13 | import java.io.BufferedReader; 14 | import java.io.File; 15 | import java.lang.reflect.Modifier; 16 | import java.net.NetworkInterface; 17 | import java.util.ArrayList; 18 | import java.util.Arrays; 19 | import java.util.List; 20 | import java.util.Locale; 21 | import java.util.TimeZone; 22 | 23 | import de.robv.android.xposed.XC_MethodHook; 24 | import de.robv.android.xposed.XC_MethodReplacement; 25 | import de.robv.android.xposed.XposedBridge; 26 | import de.robv.android.xposed.XposedHelpers; 27 | import xmnh.soulfrog.context.XpContext; 28 | 29 | public class ObjectionUtil { 30 | 31 | public static void hideXp() { 32 | try { 33 | XposedHelpers.findAndHookMethod(Class.class, "forName", 34 | String.class, 35 | boolean.class, 36 | ClassLoader.class, 37 | new XC_MethodHook() { 38 | @Override 39 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 40 | String result = (String) param.args[0]; 41 | if (result.contains("posed")) { 42 | param.setThrowable(new ClassNotFoundException()); 43 | } 44 | } 45 | } 46 | ); 47 | XposedHelpers.findAndHookMethod(Throwable.class, "getOurStackTrace", 48 | new XC_MethodHook() { 49 | @Override 50 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 51 | StackTraceElement[] stackTrace = (StackTraceElement[]) param.getResult(); 52 | if (stackTrace != null) { 53 | StackTraceElement[] stackTraceElements = Arrays.stream(stackTrace) 54 | .filter(i -> !i.getClassName().contains("posed") 55 | && !i.getClassName().contains("Zygote") 56 | ).toArray(StackTraceElement[]::new); 57 | param.setResult(stackTraceElements); 58 | } 59 | } 60 | } 61 | ); 62 | XposedHelpers.findAndHookMethod(Thread.class, "getStackTrace", 63 | new XC_MethodHook() { 64 | @Override 65 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 66 | StackTraceElement[] stackTrace = (StackTraceElement[]) param.getResult(); 67 | if (stackTrace != null) { 68 | List filteredStack = new ArrayList<>(); 69 | for (StackTraceElement element : stackTrace) { 70 | String className = element.getClassName(); 71 | if (!className.contains("posed") && !className.contains("Zygote")) { 72 | filteredStack.add(element); 73 | } 74 | } 75 | param.setResult(filteredStack.toArray(new StackTraceElement[0])); 76 | } 77 | 78 | } 79 | } 80 | ); 81 | XposedHelpers.findAndHookMethod(BufferedReader.class, "readLine", 82 | boolean.class, 83 | new XC_MethodHook() { 84 | @Override 85 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 86 | String result = (String) param.getResult(); 87 | if (result != null) { 88 | match(result, param); 89 | } 90 | } 91 | } 92 | ); 93 | // XposedHelpers.findAndHookMethod(StackTraceElement.class, "isNativeMethod", 94 | // XC_MethodReplacement.returnConstant(false)); 95 | // XposedHelpers.findAndHookMethod(Modifier.class, "isNative", int.class, 96 | // XC_MethodReplacement.returnConstant(false)); 97 | // XposedHelpers.findAndHookMethod(System.class, "getenv", String.class, 98 | // new XC_MethodHook() { 99 | // @Override 100 | // protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 101 | // String property = (String) param.args[0]; 102 | // if (property.contains("CLASSPATH")) { 103 | // param.setResult(""); 104 | // } 105 | // } 106 | // } 107 | // ); 108 | } catch (Throwable e) { 109 | XposedBridge.log(e); 110 | } 111 | } 112 | 113 | public static void hideRoot() { 114 | try { 115 | XposedHelpers.findAndHookMethod(Runtime.class, "exec", 116 | String[].class, 117 | String[].class, 118 | File.class, 119 | new XC_MethodHook() { 120 | @Override 121 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 122 | String[] cmdArray = (String[]) param.args[0]; 123 | List filteredCmd = new ArrayList<>(); 124 | for (String cmd : cmdArray) { 125 | if (cmd != null && !"su".equals(cmd) && !cmd.endsWith("su") && !cmd.contains("xbin") 126 | && !cmd.contains("busybox")) { 127 | filteredCmd.add(cmd); 128 | } 129 | } 130 | param.args[0] = filteredCmd.toArray(new String[0]); 131 | } 132 | } 133 | ); 134 | XposedHelpers.findAndHookConstructor(File.class, String.class, new XC_MethodHook() { 135 | @Override 136 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 137 | String result = (String) param.args[0]; 138 | if (result != null && result.endsWith("/su")) { 139 | param.args[0] = ""; 140 | } 141 | } 142 | }); 143 | 144 | // XposedHelpers.findAndHookMethod(Debug.class, "isDebuggerConnected", 145 | // XC_MethodReplacement.returnConstant(false)); 146 | if (!"release-keys".equals(Build.TAGS)) { 147 | XposedHelpers.setStaticObjectField(android.os.Build.class, "TAGS", "release-keys"); 148 | } 149 | // XposedHelpers.findAndHookMethod("android.os.SystemProperties", 150 | // XpContext.classLoader, 151 | // "get", 152 | // String.class, 153 | // new XC_MethodHook() { 154 | // @Override 155 | // protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 156 | // if ("ro.build.selinux".equals(param.args[0])) { 157 | // param.setResult("1"); 158 | // } 159 | // } 160 | // } 161 | // ); 162 | // XposedHelpers.findAndHookMethod(Settings.Global.class, "getInt", 163 | // ContentResolver.class, 164 | // String.class, 165 | // int.class, 166 | // new XC_MethodHook() { 167 | // @Override 168 | // protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 169 | // String arg = (String) param.args[1]; 170 | // if (Settings.Global.ADB_ENABLED.equals(arg)) { 171 | // param.setResult(0); 172 | // } 173 | // } 174 | // } 175 | // ); 176 | } catch (Throwable e) { 177 | XposedBridge.log(e); 178 | } 179 | } 180 | 181 | public static void hideProxy() { 182 | try { 183 | XposedHelpers.findAndHookMethod(NetworkInterface.class, 184 | "getName", XC_MethodReplacement.returnConstant("rmnet_data1")); 185 | XposedHelpers.findAndHookMethod(NetworkCapabilities.class, "hasTransport", 186 | int.class, XC_MethodReplacement.returnConstant(false)); 187 | XposedHelpers.findAndHookMethod(System.class, 188 | "getProperty", 189 | String.class, 190 | new XC_MethodHook() { 191 | @Override 192 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 193 | String result = (String) param.args[0]; 194 | if ("http.proxyHost".equals(result) || "http.proxyPort".equals(result) 195 | || "vxp".equals(result)) { 196 | param.setResult(""); 197 | } 198 | // if ("ro.secure".equals(result) 199 | // || "ro.debuggable".equals(result) 200 | // ) { 201 | // param.setResult("1"); 202 | // } 203 | } 204 | } 205 | ); 206 | } catch (Throwable e) { 207 | XposedBridge.log(e); 208 | } 209 | } 210 | 211 | public static void hideAll() { 212 | try { 213 | hideXp(); 214 | hideRoot(); 215 | hideProxy(); 216 | } catch (Throwable e) { 217 | XposedBridge.log(e); 218 | } 219 | } 220 | 221 | public static void ChangeRegion(ClassLoader classLoader) { 222 | XposedHelpers.findAndHookMethod(TelephonyManager.class, "getNetworkCountryIso", new Object[]{new XC_MethodHook() { // from class: xmnh.soulfrog.utils.ObjectionUtil.9 223 | public void afterHookedMethod(XC_MethodHook.MethodHookParam param) { 224 | String result = param.getResult().toString(); 225 | Log.d("SoulFrog", "getNetworkCountryIso: " + result); 226 | param.setResult("us"); 227 | Log.d("SoulFrog", "getNetworkCountryIso replace: " + param.getResult()); 228 | } 229 | }}); 230 | XposedHelpers.findAndHookMethod(TelephonyManager.class, "getSimCountryIso", new Object[]{new XC_MethodHook() { // from class: xmnh.soulfrog.utils.ObjectionUtil.10 231 | public void afterHookedMethod(XC_MethodHook.MethodHookParam param) { 232 | String result = param.getResult().toString(); 233 | Log.d("SoulFrog", "getSimCountryIso: " + result); 234 | param.setResult("us"); 235 | Log.d("SoulFrog", "getSimCountryIso replace: " + param.getResult()); 236 | } 237 | }}); 238 | XposedHelpers.findAndHookMethod(TimeZone.class, "getDefaultRef", new Object[]{XC_MethodReplacement.returnConstant(TimeZone.getTimeZone("America/Los_Angeles"))}); 239 | XposedHelpers.findAndHookMethod(Locale.class, "getLanguage", new Object[]{XC_MethodReplacement.returnConstant("en")}); 240 | XposedHelpers.findAndHookMethod(Locale.class, "getCountry", new Object[]{XC_MethodReplacement.returnConstant("us")}); 241 | } 242 | 243 | 244 | private static void match(String str, XC_MethodHook.MethodHookParam param) { 245 | if (str != null) { 246 | if (str.contains("/su") || str.contains("posed")) { 247 | param.setResult(""); 248 | } 249 | } 250 | } 251 | } 252 | -------------------------------------------------------------------------------- /app/src/main/java/xmnh/soulfrog/app/KuWo.java: -------------------------------------------------------------------------------- 1 | package xmnh.soulfrog.app; 2 | 3 | import android.content.Context; 4 | import android.view.ViewGroup; 5 | 6 | import org.json.JSONObject; 7 | 8 | import java.lang.reflect.Method; 9 | import java.lang.reflect.Modifier; 10 | import java.util.List; 11 | 12 | import de.robv.android.xposed.XC_MethodHook; 13 | import de.robv.android.xposed.XC_MethodReplacement; 14 | import de.robv.android.xposed.XposedBridge; 15 | import de.robv.android.xposed.XposedHelpers; 16 | import xmnh.soulfrog.interfaces.BaseHook; 17 | import xmnh.soulfrog.utils.AppUtil; 18 | import xmnh.soulfrog.utils.HookUtil; 19 | 20 | public class KuWo implements BaseHook { 21 | 22 | private int appVersionCode; 23 | 24 | @Override 25 | public void hook(Context context, ClassLoader classLoader) { 26 | appVersionCode = AppUtil.getAppVersionCode(context); 27 | // Class appInfo = XposedHelpers.findClass("cn.kuwo.base.utils.AppInfo", classLoader); 28 | // if (appInfo != null) { 29 | // Field field = XposedHelpers.findField(appInfo, "INSTALL_CHANNEL"); 30 | // Log.e(SoulFrog.TAG, field.toString()); 31 | //// XposedHelpers.setStaticObjectField(appInfo,"INSTALL_CHANNEL", "tunknown"); 32 | // } else { 33 | // Class cls = XposedHelpers.findClass("cn.kuwo.base.utils.b", classLoader); 34 | // if (cls != null) { 35 | // Field field = XposedHelpers.findField(cls, "h"); 36 | // Log.e(SoulFrog.TAG, field.toString()); 37 | // XposedHelpers.setStaticObjectField(cls, "h", "tunknown"); 38 | // } 39 | // } 40 | // if (appVersionCode >= 10050) { 41 | // book(classLoader); 42 | // } 43 | //// vip(); 44 | // download(classLoader); 45 | theme(classLoader); 46 | ad(classLoader); 47 | //// privilege(); 48 | //// config(); 49 | //// pay(); 50 | menu(classLoader); 51 | ui(classLoader); 52 | // kuWo(classLoader); 53 | //// HookUtil.okhttp(); 54 | 55 | AppUtil.finish(context); 56 | } 57 | 58 | private void download(ClassLoader classLoader) { 59 | Class vipConfigMgr = XposedHelpers.findClass("cn.kuwo.peculiar.specialdialogconfig.VipConfigMgr", classLoader); 60 | if (vipConfigMgr != null) { 61 | XposedHelpers.findAndHookMethod(vipConfigMgr, "isEncryptDownOpen", XC_MethodReplacement.returnConstant(false)); 62 | } 63 | } 64 | 65 | private void book(ClassLoader classLoader) { 66 | // 看小说 67 | Class bookAdMgr = XposedHelpers.findClass("cn.kuwo.ui.book.ad.BookAdMgr", classLoader); 68 | if (bookAdMgr != null) { 69 | HookUtil.booleAndVoidReplace(bookAdMgr, false); 70 | } 71 | } 72 | 73 | private void kuWo(ClassLoader classLoader) { 74 | Class specialRealInfo = XposedHelpers.findClass("cn.kuwo.peculiar.specialinfo.SpecialRealInfo", classLoader); 75 | if (specialRealInfo != null) { 76 | XposedHelpers.findAndHookMethod(specialRealInfo, "getState", new XC_MethodHook() { 77 | @Override 78 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 79 | XposedHelpers.setIntField(param.thisObject, "state", 1); 80 | XposedHelpers.setLongField(param.thisObject, "leftDays", 666666L); 81 | XposedHelpers.setLongField(param.thisObject, "endTime", 218330035688000L); 82 | } 83 | 84 | @Override 85 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 86 | XposedHelpers.setIntField(param.thisObject, "state", 1); 87 | XposedHelpers.setLongField(param.thisObject, "leftDays", 666666L); 88 | XposedHelpers.setLongField(param.thisObject, "endTime", 218330035688000L); 89 | param.setResult(1); 90 | } 91 | }); 92 | } 93 | Class specialInfoUtil = XposedHelpers.findClass("cn.kuwo.peculiar.specialinfo.SpecialInfoUtil", classLoader); 94 | if (specialInfoUtil != null) { 95 | XposedHelpers.findAndHookMethod(specialInfoUtil, "isSuperVipUser", XC_MethodReplacement.returnConstant(true)); 96 | XposedHelpers.findAndHookMethod(specialInfoUtil, "isTingshuVipUser", XC_MethodReplacement.returnConstant(true)); 97 | XposedHelpers.findAndHookMethod(specialInfoUtil, "isVipUser", XC_MethodReplacement.returnConstant(true)); 98 | XposedHelpers.findAndHookMethod(specialInfoUtil, "isLuxuryVipUser", XC_MethodReplacement.returnConstant(true)); 99 | XposedHelpers.findAndHookMethod(specialInfoUtil, "isMusicPayUser", XC_MethodReplacement.returnConstant(true)); 100 | XposedHelpers.findAndHookMethod(specialInfoUtil, "isLuxuryVipInvalid", XC_MethodReplacement.returnConstant(false)); 101 | } 102 | Class music = XposedHelpers.findClass("cn.kuwo.base.bean.Music", classLoader); 103 | if (music != null) { 104 | XposedHelpers.findAndHookMethod(music, "isSpPrivilege", new XC_MethodHook() { 105 | @Override 106 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 107 | XposedHelpers.setIntField(param.thisObject, "spPrivilege", 1); 108 | XposedHelpers.setBooleanField(param.thisObject, "disable", false); 109 | XposedHelpers.setBooleanField(param.thisObject, "isNewPay", false); 110 | XposedHelpers.setBooleanField(param.thisObject, "canDownload", true); 111 | XposedHelpers.setBooleanField(param.thisObject, "canOnlinePlay", true); 112 | XposedHelpers.setBooleanField(param.thisObject, "isLimitFree", true); 113 | XposedHelpers.setBooleanField(param.thisObject, "isVipPay", true); 114 | XposedHelpers.setBooleanField(param.thisObject, "isSongPay", true); 115 | XposedHelpers.setBooleanField(param.thisObject, "isAlbumPay", true); 116 | XposedHelpers.setBooleanField(param.thisObject, "isTingshuVipPay", true); 117 | param.setResult(true); 118 | } 119 | }); 120 | // XposedHelpers.findAndHookMethod(music, "getSpPrivilege", XC_MethodReplacement.returnConstant(1)); 121 | XposedHelpers.findAndHookMethod(music, "isListenVip", XC_MethodReplacement.returnConstant(true)); 122 | XposedHelpers.findAndHookMethod(music, "vaild", XC_MethodReplacement.returnConstant(true)); 123 | XposedHelpers.findAndHookMethod(music, "isDownloadVip", XC_MethodReplacement.returnConstant(true)); 124 | Class payInfoBean = XposedHelpers.findClass("cn.kuwo.base.bean.Music$PayInfoBean", classLoader); 125 | if (payInfoBean != null) { 126 | XposedHelpers.findAndHookMethod(payInfoBean, "getCannotOnlinePlay", XC_MethodReplacement.returnConstant(0)); 127 | XposedHelpers.findAndHookMethod(payInfoBean, "getCannotDownload", XC_MethodReplacement.returnConstant(0)); 128 | } 129 | Class musicChargeManager = XposedHelpers.findClass("cn.kuwo.peculiar.speciallogic.MusicChargeManager", classLoader); 130 | if (musicChargeManager != null) { 131 | XposedHelpers.findAndHookMethod(musicChargeManager, "checkMusicBeforeSingleBuy", music, 132 | XC_MethodReplacement.returnConstant(true)); 133 | } 134 | } 135 | Class consumptionQueryUtil = XposedHelpers.findClass("cn.kuwo.peculiar.speciallogic.ConsumptionQueryUtil", classLoader); 136 | if (consumptionQueryUtil != null) { 137 | XposedHelpers.findAndHookMethod(consumptionQueryUtil, "onwLimited", long.class, List.class, 138 | XC_MethodReplacement.returnConstant(true)); 139 | } 140 | } 141 | 142 | private void vip(ClassLoader classLoader) { 143 | Class specialInfoUtil = XposedHelpers.findClass("cn.kuwo.peculiar.specialinfo.SpecialInfoUtil", classLoader); 144 | if (specialInfoUtil != null) { 145 | for (Method method : specialInfoUtil.getDeclaredMethods()) { 146 | if (method.getReturnType() == int.class) { 147 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(1)); 148 | } 149 | if (method.getReturnType() == boolean.class) { 150 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(true)); 151 | } 152 | } 153 | if (appVersionCode >= 10200) { 154 | XposedHelpers.findAndHookMethod(specialInfoUtil, "getSuperVipGrade", XC_MethodReplacement.returnConstant(7)); 155 | XposedHelpers.findAndHookMethod(specialInfoUtil, "getVipGrade", XC_MethodReplacement.returnConstant(7)); 156 | XposedHelpers.findAndHookMethod(specialInfoUtil, "isLuxuryVipInvalid", XC_MethodReplacement.returnConstant(false)); 157 | } 158 | // XposedHelpers.findAndHookMethod(specialInfoUtil, "isSuperVipUser", XC_MethodReplacement.returnConstant(true)); 159 | // XposedHelpers.findAndHookMethod(specialInfoUtil, "isTingshuVipUser", XC_MethodReplacement.returnConstant(true)); 160 | // XposedHelpers.findAndHookMethod(specialInfoUtil, "isVipUser", XC_MethodReplacement.returnConstant(true)); 161 | // XposedHelpers.findAndHookMethod(specialInfoUtil, "isLuxuryVipUser", XC_MethodReplacement.returnConstant(true)); 162 | // XposedHelpers.findAndHookMethod(specialInfoUtil, "isMusicPayUser", XC_MethodReplacement.returnConstant(true)); 163 | } 164 | Class music = XposedHelpers.findClass("cn.kuwo.base.bean.Music", classLoader); 165 | if (music != null) { 166 | XposedHelpers.findAndHookMethod(music, "hasAd", int.class, XC_MethodReplacement.returnConstant(false)); 167 | XposedHelpers.findAndHookMethod(music, "isSpPrivilege", new XC_MethodHook() { 168 | @Override 169 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 170 | XposedHelpers.setIntField(param.thisObject, "spPrivilege", 1); 171 | XposedHelpers.setBooleanField(param.thisObject, "disable", false); 172 | XposedHelpers.setBooleanField(param.thisObject, "isNewPay", false); 173 | XposedHelpers.setBooleanField(param.thisObject, "canDownload", true); 174 | XposedHelpers.setBooleanField(param.thisObject, "canOnlinePlay", true); 175 | XposedHelpers.setBooleanField(param.thisObject, "isLimitFree", true); 176 | XposedHelpers.setBooleanField(param.thisObject, "isVipPay", true); 177 | XposedHelpers.setBooleanField(param.thisObject, "isSongPay", true); 178 | XposedHelpers.setBooleanField(param.thisObject, "isAlbumPay", true); 179 | XposedHelpers.setBooleanField(param.thisObject, "isTingshuVipPay", true); 180 | param.setResult(true); 181 | } 182 | }); 183 | XposedHelpers.findAndHookMethod(music, "getSpPrivilege", XC_MethodReplacement.returnConstant(1)); 184 | XposedHelpers.findAndHookMethod(music, "isListenVip", XC_MethodReplacement.returnConstant(true)); 185 | XposedHelpers.findAndHookMethod(music, "vaild", XC_MethodReplacement.returnConstant(true)); 186 | XposedHelpers.findAndHookMethod(music, "isDownloadVip", XC_MethodReplacement.returnConstant(true)); 187 | XposedHelpers.findAndHookMethod(music, "isPlayFree", XC_MethodReplacement.returnConstant(true)); 188 | XposedHelpers.findAndHookMethod(music, "isOverseasPlayFree", XC_MethodReplacement.returnConstant(true)); 189 | XposedHelpers.findAndHookMethod(music, "isOverseasDownloadFree", XC_MethodReplacement.returnConstant(true)); 190 | } 191 | Class userBgResItem = XposedHelpers.findClass("cn.kuwo.ui.mine.usercenter.UserBgResItem", classLoader); 192 | if (userBgResItem != null) { 193 | XposedHelpers.findAndHookMethod(userBgResItem, "isSuperVipRight", XC_MethodReplacement.returnConstant(true)); 194 | XposedHelpers.findAndHookMethod(userBgResItem, "isVipRight", XC_MethodReplacement.returnConstant(true)); 195 | XposedHelpers.findAndHookMethod(userBgResItem, "isVipRenewRight", XC_MethodReplacement.returnConstant(true)); 196 | XposedHelpers.findAndHookMethod(userBgResItem, "isLimitFree", XC_MethodReplacement.returnConstant(true)); 197 | } 198 | // Class loginListUtils = XposedHelpers.findClass("cn.kuwo.ui.userinfo.utils.LoginListUtils", classLoader); 199 | // if (userBgResItem != null) { 200 | // XposedHelpers.findAndHookMethod(loginListUtils, "getVipTypeIcon", int.class, new XC_MethodHook() { 201 | // @Override 202 | // protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 203 | // param.args[0] = 7; 204 | // } 205 | // }); 206 | // XposedHelpers.findAndHookMethod(loginListUtils, "getVipTypeString", int.class, new XC_MethodHook() { 207 | // @Override 208 | // protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 209 | // param.args[0] = 7; 210 | // } 211 | // }); 212 | // } 213 | Class vipInfo = XposedHelpers.findClass("cn.kuwo.base.bean.VipInfo", classLoader); 214 | if (vipInfo != null) { 215 | XposedHelpers.findAndHookMethod(vipInfo, "getVipType", XC_MethodReplacement.returnConstant(2)); 216 | XposedHelpers.findAndHookMethod(vipInfo, "getVipExpire", XC_MethodReplacement.returnConstant(Integer.MAX_VALUE)); 217 | } 218 | } 219 | 220 | private void theme(ClassLoader classLoader) { 221 | Class starTheme = XposedHelpers.findClass("cn.kuwo.mod.theme.bean.star.StarTheme", classLoader); 222 | Class starThemeDetailPresenter; 223 | // 主题 224 | try { 225 | starThemeDetailPresenter = XposedHelpers.findClass("cn.kuwo.mod.theme.detail.star.StarThemeDetailPresenter", classLoader); 226 | } catch (Exception e) { 227 | starThemeDetailPresenter = XposedHelpers.findClass("cn.kuwo.mod.theme.detail.star.c", classLoader); 228 | } 229 | if (starThemeDetailPresenter != null) { 230 | for (Method method : starThemeDetailPresenter.getDeclaredMethods()) { 231 | if (method.getModifiers() == Modifier.PRIVATE && method.getReturnType() == boolean.class 232 | && method.getParameterTypes().length == 1 && method.getParameterTypes()[0] == starTheme) { 233 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(true)); 234 | } 235 | } 236 | // XposedHelpers.findAndHookMethod(starThemeDetailPresenter, "checkStarThemeFree", 237 | // XposedHelpers.findClass("cn.kuwo.mod.theme.bean.star.StarTheme", classLoader), 238 | // XC_MethodReplacement.returnConstant(true)); 239 | } 240 | } 241 | 242 | private void ad(ClassLoader classLoader) { 243 | // 开屏ad 244 | Class entryActivity = XposedHelpers.findClass("cn.kuwo.player.activities.EntryActivity", classLoader); 245 | if (entryActivity != null) { 246 | for (Method method : entryActivity.getDeclaredMethods()) { 247 | if (method.getModifiers() == Modifier.PRIVATE && method.getReturnType() == boolean.class 248 | && method.getParameterTypes().length == 0) { 249 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(true)); 250 | } 251 | } 252 | } 253 | Class screenAdUtils = XposedHelpers.findClass("cn.kuwo.player.screen.ScreenAdUtils", classLoader); 254 | if (screenAdUtils != null) { 255 | HookUtil.booleReplace(screenAdUtils, false); 256 | } 257 | Class competitiveAdMgr = XposedHelpers.findClass("cn.kuwo.mod.mobilead.tmead.competitive.CompetitiveAdMgr", classLoader); 258 | if (competitiveAdMgr != null) { 259 | HookUtil.booleAndVoidReplace(competitiveAdMgr, false); 260 | } 261 | Class kuWoAdUrl = XposedHelpers.findClass("cn.kuwo.mod.mobilead.KuwoAdUrl", classLoader); 262 | if (kuWoAdUrl != null) { 263 | for (Method method : kuWoAdUrl.getDeclaredMethods()) { 264 | if (method.getReturnType() == String.class) { 265 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant("")); 266 | } 267 | } 268 | XposedHelpers.findAndHookMethod("cn.kuwo.mod.mobilead.KuwoAdUrl$AdUrlDef", classLoader, 269 | "getUrl", String.class, XC_MethodReplacement.returnConstant("")); 270 | } 271 | } 272 | 273 | private void privilege(ClassLoader classLoader) { 274 | Class specialRealInfo = XposedHelpers.findClass("cn.kuwo.peculiar.specialinfo.SpecialRealInfo", classLoader); 275 | if (specialRealInfo != null) { 276 | for (Method method : specialRealInfo.getDeclaredMethods()) { 277 | if (method.getReturnType() == int.class) { 278 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(1)); 279 | } 280 | if (method.getReturnType() == long.class) { 281 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(218330035688000L)); 282 | } 283 | } 284 | } 285 | Class songPrivilegeHelper = XposedHelpers.findClass("com.kugou.fanxing.allinone.watch.mobilelive.user.helper.SongPrivilegeHelper", classLoader); 286 | if (songPrivilegeHelper != null) { 287 | XposedHelpers.findAndHookMethod(songPrivilegeHelper, "verifyPrivilege", int.class, 288 | XC_MethodReplacement.returnConstant(1)); 289 | } 290 | Class consumptionQueryUtil = XposedHelpers.findClass("cn.kuwo.peculiar.speciallogic.ConsumptionQueryUtil", classLoader); 291 | if (consumptionQueryUtil != null) { 292 | XposedHelpers.findAndHookMethod(consumptionQueryUtil, "onwLimited", long.class, List.class, 293 | XC_MethodReplacement.returnConstant(true)); 294 | } 295 | Class privilegeManager = XposedHelpers.findClass("cn.kuwo.peculiar.speciallogic.PrivilegeManager", classLoader); 296 | if (privilegeManager != null) { 297 | for (Method method : privilegeManager.getDeclaredMethods()) { 298 | if (method.getReturnType() == int.class) { 299 | XposedBridge.hookMethod(method, XC_MethodReplacement.returnConstant(1)); 300 | } 301 | if (method.getReturnType() == boolean.class) { 302 | XposedBridge.hookMethod(method, new XC_MethodReplacement() { 303 | @Override 304 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { 305 | XposedHelpers.setIntField(param.thisObject, "searchLimit", 666666); 306 | return false; 307 | } 308 | }); 309 | } 310 | } 311 | } 312 | Class digitAlbum = XposedHelpers.findClass("cn.kuwo.mod.search.DigitAlbum", classLoader); 313 | if (digitAlbum != null) { 314 | XposedHelpers.findAndHookMethod(digitAlbum, "isHadBought", XC_MethodReplacement.returnConstant(true)); 315 | } 316 | } 317 | 318 | private void config(ClassLoader classLoader) { 319 | Class vipConfigMgr = XposedHelpers.findClass("cn.kuwo.peculiar.specialdialogconfig.VipConfigMgr", classLoader); 320 | if (vipConfigMgr != null) { 321 | XposedHelpers.findAndHookMethod(vipConfigMgr, "isShowClickListen30Dialog", XC_MethodReplacement.returnConstant(false)); 322 | XposedHelpers.findAndHookMethod(vipConfigMgr, "isZhizhenOnTrial", XC_MethodReplacement.returnConstant(true)); 323 | 324 | } 325 | Class confMgr = XposedHelpers.findClass("cn.kuwo.base.config.ConfMgr", classLoader); 326 | if (confMgr != null) { 327 | Class specialInfoMgr = XposedHelpers.findClass("cn.kuwo.peculiar.specialinfo.SpecialInfoMgr", classLoader); 328 | if (specialInfoMgr != null) { 329 | /* XposedHelpers.findAndHookMethod(specialInfoMgr, "getVipIconUrl", new XC_MethodHook() { 330 | @Override 331 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 332 | XposedBridge.log("vipUrl: " + param.getResult().toString()); 333 | } 334 | });*/ 335 | } 336 | } 337 | } 338 | 339 | private void pay(ClassLoader classLoader) { 340 | XposedHelpers.findAndHookMethod(JSONObject.class, "optString", String.class, new XC_MethodHook() { 341 | @Override 342 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 343 | String str = param.args[0].toString(); 344 | JSONObject jsonObject = (JSONObject) param.thisObject; 345 | if (jsonObject.has("playright")) { 346 | jsonObject.put("playright", "1"); 347 | } 348 | if ("playright".equals(str) || "downright".equals(str)) { 349 | param.setResult("1"); 350 | } 351 | // if ("vip".equals(str) || "song".equals(str) || "album".equals(str) || "bookvip".equals(str)) { 352 | // param.setResult("0"); 353 | // } 354 | } 355 | }); 356 | } 357 | 358 | private void ui(ClassLoader classLoader) { 359 | Class mainController = XposedHelpers.findClass("cn.kuwo.ui.fragment.MainController", classLoader); 360 | if (mainController != null) { 361 | XposedHelpers.findAndHookMethod(mainController, "onCreate", 362 | new XC_MethodHook() { 363 | @Override 364 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 365 | ViewGroup viewGroup = (ViewGroup) XposedHelpers.getObjectField(param.thisObject, "mBottomTab"); 366 | viewGroup.removeViewAt(1);// 视频 367 | viewGroup.removeViewAt(2);// 会员 368 | } 369 | }); 370 | } 371 | Class app = XposedHelpers.findClass("cn.kuwo.player.App", classLoader); 372 | if (app != null) { 373 | XposedHelpers.findAndHookMethod(app, "initKuGou", XC_MethodReplacement.returnConstant(false)); 374 | } 375 | } 376 | 377 | private void menu(ClassLoader classLoader) { 378 | Class menuController = XposedHelpers.findClass("cn.kuwo.ui.fragment.menu.MenuController", classLoader); 379 | if (menuController != null) { 380 | XposedHelpers.findAndHookMethod(menuController, "refreshFlowItem", new XC_MethodHook() { 381 | @Override 382 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 383 | XposedHelpers.callMethod(param.thisObject, "hideMenuItem", 7); 384 | XposedHelpers.callMethod(param.thisObject, "hideMenuItem", 12); 385 | XposedHelpers.callMethod(param.thisObject, "hideMenuItem", 13); 386 | XposedHelpers.callMethod(param.thisObject, "hideMenuItem", 20); 387 | XposedHelpers.callMethod(param.thisObject, "hideMenuItem", 32); 388 | XposedHelpers.callMethod(param.thisObject, "hideMenuItem", 33); 389 | XposedHelpers.callMethod(param.thisObject, "hideMenuItem", 35); 390 | } 391 | }); 392 | } 393 | } 394 | 395 | } 396 | --------------------------------------------------------------------------------