Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/src/main/java/me/iacn/biliroaming/BiliBiliPackage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class BiliBiliPackage constructor(private val mClassLoader: ClassLoader, mContex
val bangumiApiResponseClass by Weak { mHookInfo.bangumiApiResponse from mClassLoader }
val rxGeneralResponseClass by Weak { "com.bilibili.okretro.call.rxjava.RxGeneralResponse" from mClassLoader }
val fastJsonClass by Weak { mHookInfo.fastJson.class_ from mClassLoader }
val gsonClass by Weak { "com.google.gson.Gson" from mClassLoader }
val bangumiUniformSeasonClass by Weak { mHookInfo.bangumiSeason from mClassLoader }
val kingPositionComponentClass by Weak { mHookInfo.autoLike.kingPositionComponent.class_ from mClassLoader }
val storyAbsControllerClass by Weak { mHookInfo.autoLike.storyAbsController.class_ from mClassLoader }
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/me/iacn/biliroaming/XposedInit.kt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ class XposedInit : IXposedHookLoadPackage, IXposedHookZygoteInit {
startHook { CustomThemeHook(lpparam.classLoader) }
startHook { TeenagersModeHook(lpparam.classLoader) }
startHook { JsonHook(lpparam.classLoader) }
startHook { GsonHook(lpparam.classLoader) }
startHook { ShareHook(lpparam.classLoader) }
startHook { AutoLikeHook(lpparam.classLoader) }
startHook { SettingHook(lpparam.classLoader) }
Expand Down
52 changes: 52 additions & 0 deletions app/src/main/java/me/iacn/biliroaming/hook/GsonHook.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package me.iacn.biliroaming.hook

import me.iacn.biliroaming.BiliBiliPackage.Companion.instance
import me.iacn.biliroaming.hook.gson.GsonProcessor
import me.iacn.biliroaming.hook.gson.SplashListProcessor
import me.iacn.biliroaming.hook.gson.SplashShowProcessor
import me.iacn.biliroaming.utils.Log
import me.iacn.biliroaming.utils.getObjectField
import me.iacn.biliroaming.utils.hookAfterAllMethods

class GsonHook(classLoader: ClassLoader) : BaseHook(classLoader) {
private val allProcessors = listOf(
SplashListProcessor(),
SplashShowProcessor(),
)

private val enabledProcessors: Map<String, List<GsonProcessor>> by lazy {
allProcessors
.filter { it.shouldEnable() }
.groupBy { it.targetClassName }
}

override fun startHook() {
if (enabledProcessors.isEmpty()) return
Log.d("startHook: Gson")

val gsonClass = instance.gsonClass ?: return
val fromJsonName = instance.gsonFromJson() ?: return

gsonClass.hookAfterAllMethods(fromJsonName) { param ->
dispatchResult(param.result)
}
}

private fun dispatchResult(result: Any?) {
if (result == null) return

// Network path: unwrap GeneralResponse<T> -> T
var target = result
if (result.javaClass == instance.generalResponseClass) {
target = result.getObjectField("data") ?: return
}

enabledProcessors[target.javaClass.name]?.forEach { processor ->
try {
processor.process(target)
} catch (e: Throwable) {
Log.e("GsonHook processor ${processor.targetClassName} error: $e")
}
}
}
}
12 changes: 12 additions & 0 deletions app/src/main/java/me/iacn/biliroaming/hook/gson/GsonProcessor.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package me.iacn.biliroaming.hook.gson

interface GsonProcessor {
/** Full class name of the target deserialized type */
val targetClassName: String

/** Return true if this processor's settings are enabled */
fun shouldEnable(): Boolean

/** Process the deserialized result object */
fun process(result: Any)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package me.iacn.biliroaming.hook.gson

import me.iacn.biliroaming.utils.sPrefs
import me.iacn.biliroaming.utils.getObjectFieldOrNullAs

class SplashListProcessor : GsonProcessor {
override val targetClassName =
"tv.danmaku.bili.splash.ad.model.SplashListResponse"

override fun shouldEnable() =
sPrefs.getBoolean("hidden", false) && sPrefs.getBoolean("purify_splash", false)

override fun process(result: Any) {
result.getObjectFieldOrNullAs<MutableList<*>>("splashList")?.clear()
result.getObjectFieldOrNullAs<MutableList<*>>("strategyList")?.clear()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package me.iacn.biliroaming.hook.gson

import me.iacn.biliroaming.utils.sPrefs
import me.iacn.biliroaming.utils.getObjectFieldOrNullAs

class SplashShowProcessor : GsonProcessor {
override val targetClassName =
"tv.danmaku.bili.splash.ad.model.SplashShowResponse"

override fun shouldEnable() =
sPrefs.getBoolean("hidden", false) && sPrefs.getBoolean("purify_splash", false)

override fun process(result: Any) {
result.getObjectFieldOrNullAs<MutableList<*>>("strategyList")?.clear()
}
}
Loading