@@ -10,6 +10,11 @@ import de.robv.android.xposed.XposedBridge
1010import de.robv.android.xposed.XposedHelpers
1111import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam
1212import io.github.chsbuffer.revancedxposed.BuildConfig.DEBUG
13+ import kotlinx.serialization.ExperimentalSerializationApi
14+ import kotlinx.serialization.Serializable
15+ import kotlinx.serialization.decodeFromByteArray
16+ import kotlinx.serialization.encodeToByteArray
17+ import kotlinx.serialization.protobuf.ProtoBuf
1318import org.luckypray.dexkit.DexKitBridge
1419import org.luckypray.dexkit.DexKitCacheBridge
1520import org.luckypray.dexkit.result.ClassData
@@ -18,6 +23,7 @@ import org.luckypray.dexkit.result.MethodData
1823import org.luckypray.dexkit.wrap.DexClass
1924import org.luckypray.dexkit.wrap.DexField
2025import org.luckypray.dexkit.wrap.DexMethod
26+ import java.io.File
2127import java.lang.reflect.Constructor
2228import java.lang.reflect.Member
2329import java.lang.reflect.Method
@@ -69,9 +75,29 @@ interface IHook {
6975 fun DexField.toField () = getFieldInstance(classLoader)
7076}
7177
78+ fun String.toSha256 (): String {
79+ val bytes = this .toByteArray()
80+ val md = java.security.MessageDigest .getInstance(" SHA-256" )
81+ val digest = md.digest(bytes)
82+ return digest.toHexString()
83+ }
84+
85+ @Serializable
86+ data class Pairs (
87+ val map : MutableMap <String , String ?>
88+ )
89+
7290@Suppress(" UNCHECKED_CAST" )
91+ @OptIn(ExperimentalSerializationApi ::class )
7392class SharedPrefCache (app : Application ) : DexKitCacheBridge.Cache {
74- private val map = mutableMapOf<String , String >()
93+ val file = File (app.cacheDir.path, BuildConfig .BUILD_TYPE .toSha256())
94+
95+ val pref = runCatching { ProtoBuf .decodeFromByteArray<Pairs >(file.readBytes()) }.getOrElse {
96+ Pairs (mutableMapOf ())
97+ }
98+
99+ val map get() = pref.map
100+
75101 override fun clearAll () {
76102 map.clear()
77103 }
@@ -82,7 +108,8 @@ class SharedPrefCache(app: Application) : DexKitCacheBridge.Cache {
82108
83109 override fun getList (
84110 key : String , default : List <String >?
85- ): List <String >? = map.getOrDefault(key, null )?.takeIf (String ::isNotBlank)?.split(' |' ) ? : default
111+ ): List <String >? =
112+ map.getOrDefault(key, null )?.takeIf (String ::isNotBlank)?.split(' |' ) ? : default
86113
87114 override fun put (key : String , value : String ) {
88115 map.put(key, value)
@@ -95,6 +122,10 @@ class SharedPrefCache(app: Application) : DexKitCacheBridge.Cache {
95122 override fun remove (key : String ) {
96123 map.remove(key)
97124 }
125+
126+ fun saveCache () {
127+ file.writeBytes(ProtoBuf .encodeToByteArray(pref))
128+ }
98129}
99130
100131class DependedHookFailedException (
@@ -121,6 +152,7 @@ abstract class BaseHook(private val app: Application, val lpparam: LoadPackagePa
121152
122153 override fun Hook () {
123154 val t = measureTimeMillis {
155+ tryLoadCache()
124156 try {
125157 applyHooks()
126158 handleResult()
@@ -166,6 +198,7 @@ abstract class BaseHook(private val app: Application, val lpparam: LoadPackagePa
166198 }
167199
168200 private fun handleResult () {
201+ cache.saveCache()
169202 val success = failedHooks.isEmpty()
170203 if (! success) {
171204 XposedBridge .log(" ${lpparam.appInfo.packageName} version: ${getAppVersion()} " )
0 commit comments