mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-04 09:45:19 +08:00
Modify move hookModuleAppStatus to AppParasitics and renamed hookModuleAppRelated
This commit is contained in:
@@ -168,11 +168,10 @@ object CodeSourceFileTemplate {
|
||||
" private const val modulePackageName = " +
|
||||
(if (customMPackageName.isNotBlank()) "\"$customMPackageName\"" else "BuildConfig.APPLICATION_ID") + "\n" +
|
||||
"\n" +
|
||||
" private val hookEntry = $entryClassName()\n" +
|
||||
"\n" +
|
||||
" private var moduleClassLoader: ClassLoader? = null\n" +
|
||||
" private var isZygoteBinded = false\n" +
|
||||
"\n" +
|
||||
" private val hookEntry = $entryClassName()\n" +
|
||||
"\n" +
|
||||
" private fun callXposedLoaded(\n" +
|
||||
" isZygoteLoaded: Boolean = false,\n" +
|
||||
" lpparam: XC_LoadPackage.LoadPackageParam? = null,\n" +
|
||||
@@ -192,11 +191,6 @@ object CodeSourceFileTemplate {
|
||||
" YukiHookBridge.callXposedLoaded(isZygoteLoaded, lpparam, resparam)\n" +
|
||||
" }\n" +
|
||||
"\n" +
|
||||
" private fun hookModuleAppStatus(loader: ClassLoader? = null, isHookResourcesStatus: Boolean = false) {\n" +
|
||||
" loader?.let { moduleClassLoader = it }\n" +
|
||||
" runCatching { YukiHookBridge.hookModuleAppStatus(moduleClassLoader, isHookResourcesStatus) }\n" +
|
||||
" }\n" +
|
||||
"\n" +
|
||||
" @YukiGenerateApi\n" +
|
||||
" fun callInitZygote(sparam: IXposedHookZygoteInit.StartupParam?) {\n" +
|
||||
" if (sparam == null) return\n" +
|
||||
@@ -209,16 +203,12 @@ object CodeSourceFileTemplate {
|
||||
"\n" +
|
||||
" @YukiGenerateApi\n" +
|
||||
" fun callHandleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {\n" +
|
||||
" if (lpparam == null) return\n" +
|
||||
" if (lpparam.packageName == modulePackageName) hookModuleAppStatus(lpparam.classLoader)\n" +
|
||||
" callXposedLoaded(lpparam = lpparam)\n" +
|
||||
" if (lpparam != null) callXposedLoaded(lpparam = lpparam)\n" +
|
||||
" }\n" +
|
||||
"\n" +
|
||||
" @YukiGenerateApi\n" +
|
||||
" fun callHandleInitPackageResources(resparam: XC_InitPackageResources.InitPackageResourcesParam?) {\n" +
|
||||
" if (resparam == null) return\n" +
|
||||
" if (resparam.packageName == modulePackageName) hookModuleAppStatus(isHookResourcesStatus = true)\n" +
|
||||
" callXposedLoaded(resparam = resparam)\n" +
|
||||
" if (resparam != null) callXposedLoaded(resparam = resparam)\n" +
|
||||
" }\n" +
|
||||
"}").toByteArray()
|
||||
}
|
@@ -48,6 +48,7 @@ import com.highcapable.yukihookapi.hook.factory.hasClass
|
||||
import com.highcapable.yukihookapi.hook.param.type.HookEntryType
|
||||
import com.highcapable.yukihookapi.hook.param.wrapper.PackageParamWrapper
|
||||
import com.highcapable.yukihookapi.hook.utils.value
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookBridge
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.dummy.YukiModuleResources
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.dummy.YukiResources
|
||||
import com.highcapable.yukihookapi.hook.xposed.channel.YukiHookDataChannel
|
||||
@@ -244,13 +245,13 @@ open class PackageParam internal constructor(@PublishedApi internal var wrapper:
|
||||
* 装载并 Hook 系统框架
|
||||
* @param initiate 方法体
|
||||
*/
|
||||
inline fun loadSystem(initiate: PackageParam.() -> Unit) = loadApp(AppParasitics.SYSTEM_FRAMEWORK_NAME, initiate)
|
||||
inline fun loadSystem(initiate: PackageParam.() -> Unit) = loadApp(YukiHookBridge.SYSTEM_FRAMEWORK_NAME, initiate)
|
||||
|
||||
/**
|
||||
* 装载并 Hook 系统框架
|
||||
* @param hooker Hook 子类
|
||||
*/
|
||||
fun loadSystem(hooker: YukiBaseHooker) = loadApp(AppParasitics.SYSTEM_FRAMEWORK_NAME, hooker)
|
||||
fun loadSystem(hooker: YukiBaseHooker) = loadApp(YukiHookBridge.SYSTEM_FRAMEWORK_NAME, hooker)
|
||||
|
||||
/**
|
||||
* 装载 APP Zygote 事件
|
||||
|
@@ -35,18 +35,11 @@ import com.highcapable.yukihookapi.annotation.YukiGenerateApi
|
||||
import com.highcapable.yukihookapi.hook.factory.classOf
|
||||
import com.highcapable.yukihookapi.hook.factory.field
|
||||
import com.highcapable.yukihookapi.hook.factory.hasClass
|
||||
import com.highcapable.yukihookapi.hook.factory.method
|
||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||
import com.highcapable.yukihookapi.hook.param.type.HookEntryType
|
||||
import com.highcapable.yukihookapi.hook.param.wrapper.HookParamWrapper
|
||||
import com.highcapable.yukihookapi.hook.param.wrapper.PackageParamWrapper
|
||||
import com.highcapable.yukihookapi.hook.type.android.ContextImplClass
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.dummy.YukiResources
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiHookHelper
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiMemberHook
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiMemberReplacement
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.inject.YukiHookBridge_Injector
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.status.YukiHookModuleStatus
|
||||
import com.highcapable.yukihookapi.hook.xposed.helper.YukiHookAppHelper
|
||||
import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics
|
||||
import dalvik.system.PathClassLoader
|
||||
@@ -67,6 +60,10 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||
@YukiGenerateApi
|
||||
object YukiHookBridge {
|
||||
|
||||
/** Android 系统框架名称 */
|
||||
@PublishedApi
|
||||
internal const val SYSTEM_FRAMEWORK_NAME = "android"
|
||||
|
||||
/** Xposed 是否装载完成 */
|
||||
private var isXposedInitialized = false
|
||||
|
||||
@@ -186,12 +183,12 @@ object YukiHookBridge {
|
||||
if (type == HookEntryType.ZYGOTE || appClassLoader != null)
|
||||
PackageParamWrapper(
|
||||
type = type,
|
||||
packageName = packageName ?: AppParasitics.SYSTEM_FRAMEWORK_NAME,
|
||||
processName = processName ?: AppParasitics.SYSTEM_FRAMEWORK_NAME,
|
||||
packageName = packageName ?: SYSTEM_FRAMEWORK_NAME,
|
||||
processName = processName ?: SYSTEM_FRAMEWORK_NAME,
|
||||
appClassLoader = appClassLoader ?: XposedBridge.BOOTCLASSLOADER,
|
||||
appInfo = appInfo,
|
||||
appResources = appResources
|
||||
).also { packageParamWrappers[packageName ?: AppParasitics.SYSTEM_FRAMEWORK_NAME] = it }
|
||||
).also { packageParamWrappers[packageName ?: SYSTEM_FRAMEWORK_NAME] = it }
|
||||
else null
|
||||
else packageParamWrappers[packageName]?.also {
|
||||
it.type = type
|
||||
@@ -203,39 +200,6 @@ object YukiHookBridge {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook 模块自身激活状态和 Resources Hook 支持状态
|
||||
*
|
||||
* - ❗装载代码将自动生成 - 你不应该手动使用此方法装载 Xposed 模块事件
|
||||
* @param loader 模块的 [ClassLoader]
|
||||
* @param isHookResourcesStatus 是否 Hook Resources 支持状态
|
||||
*/
|
||||
@YukiGenerateApi
|
||||
fun hookModuleAppStatus(loader: ClassLoader?, isHookResourcesStatus: Boolean = false) {
|
||||
if (YukiHookAPI.Configs.isEnableHookSharedPreferences)
|
||||
YukiHookHelper.hook(ContextImplClass.method { name = "setFilePermissionsFromMode" }, object : YukiMemberHook() {
|
||||
override fun beforeHookedMember(wrapper: HookParamWrapper) {
|
||||
if ((wrapper.args?.get(0) as? String?)?.endsWith(suffix = "preferences.xml") == true) wrapper.args?.set(1, 1)
|
||||
}
|
||||
})
|
||||
if (YukiHookAPI.Configs.isEnableHookModuleStatus) classOf<YukiHookModuleStatus>(loader).apply {
|
||||
if (isHookResourcesStatus.not()) {
|
||||
YukiHookHelper.hook(method { name = YukiHookModuleStatus.IS_ACTIVE_METHOD_NAME }, object : YukiMemberReplacement() {
|
||||
override fun replaceHookedMember(wrapper: HookParamWrapper) = true
|
||||
})
|
||||
YukiHookHelper.hook(method { name = YukiHookModuleStatus.GET_XPOSED_TAG_METHOD_NAME }, object : YukiMemberReplacement() {
|
||||
override fun replaceHookedMember(wrapper: HookParamWrapper) = executorName
|
||||
})
|
||||
YukiHookHelper.hook(method { name = YukiHookModuleStatus.GET_XPOSED_VERSION_METHOD_NAME }, object : YukiMemberReplacement() {
|
||||
override fun replaceHookedMember(wrapper: HookParamWrapper) = executorVersion
|
||||
})
|
||||
} else
|
||||
YukiHookHelper.hook(method { name = YukiHookModuleStatus.HAS_RESOURCES_HOOK_METHOD_NAME }, object : YukiMemberReplacement() {
|
||||
override fun replaceHookedMember(wrapper: HookParamWrapper) = true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 标识 Xposed API 装载完成
|
||||
*
|
||||
@@ -281,7 +245,7 @@ object YukiHookBridge {
|
||||
resparam: XC_InitPackageResources.InitPackageResourcesParam? = null
|
||||
) {
|
||||
if (isMiuiCatcherPatch(packageName = lpparam?.packageName ?: resparam?.packageName).not()) when {
|
||||
isZygoteLoaded -> assignWrapper(HookEntryType.ZYGOTE, AppParasitics.SYSTEM_FRAMEWORK_NAME, AppParasitics.SYSTEM_FRAMEWORK_NAME)
|
||||
isZygoteLoaded -> assignWrapper(HookEntryType.ZYGOTE, SYSTEM_FRAMEWORK_NAME, SYSTEM_FRAMEWORK_NAME)
|
||||
lpparam != null ->
|
||||
if (isPackageLoaded(lpparam.packageName, HookEntryType.PACKAGE).not())
|
||||
assignWrapper(HookEntryType.PACKAGE, lpparam.packageName, lpparam.processName, lpparam.classLoader, lpparam.appInfo)
|
||||
@@ -293,8 +257,9 @@ object YukiHookBridge {
|
||||
else -> null
|
||||
}?.also {
|
||||
YukiHookAPI.onXposedLoaded(it)
|
||||
if (it.type != HookEntryType.ZYGOTE && it.packageName == modulePackageName)
|
||||
AppParasitics.hookModuleAppRelated(it.appClassLoader, it.type)
|
||||
if (it.type == HookEntryType.PACKAGE) AppParasitics.registerToAppLifecycle(it.packageName)
|
||||
if (it.type == HookEntryType.RESOURCES) isSupportResourcesHook = true
|
||||
}
|
||||
}
|
||||
}
|
@@ -34,10 +34,7 @@ import android.app.Activity
|
||||
import android.app.ActivityManager
|
||||
import android.app.Application
|
||||
import android.app.Instrumentation
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.*
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Configuration
|
||||
import android.content.res.Resources
|
||||
@@ -46,6 +43,7 @@ import com.highcapable.yukihookapi.YukiHookAPI
|
||||
import com.highcapable.yukihookapi.hook.factory.*
|
||||
import com.highcapable.yukihookapi.hook.log.yLoggerE
|
||||
import com.highcapable.yukihookapi.hook.log.yLoggerW
|
||||
import com.highcapable.yukihookapi.hook.param.type.HookEntryType
|
||||
import com.highcapable.yukihookapi.hook.param.wrapper.HookParamWrapper
|
||||
import com.highcapable.yukihookapi.hook.type.android.*
|
||||
import com.highcapable.yukihookapi.hook.type.java.BooleanType
|
||||
@@ -56,6 +54,8 @@ import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookBridge
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.dummy.YukiModuleResources
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiHookHelper
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiMemberHook
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiMemberReplacement
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.status.YukiHookModuleStatus
|
||||
import com.highcapable.yukihookapi.hook.xposed.channel.YukiHookDataChannel
|
||||
import com.highcapable.yukihookapi.hook.xposed.parasitic.activity.config.ActivityProxyConfig
|
||||
import com.highcapable.yukihookapi.hook.xposed.parasitic.activity.delegate.HandlerDelegate
|
||||
@@ -67,13 +67,8 @@ import com.highcapable.yukihookapi.hook.xposed.parasitic.activity.delegate.Instr
|
||||
*
|
||||
* 通过这些功能即可轻松实现对 (Xposed) 宿主环境的 [Resources] 注入以及 [Activity] 代理
|
||||
*/
|
||||
@PublishedApi
|
||||
internal object AppParasitics {
|
||||
|
||||
/** Android 系统框架名称 */
|
||||
@PublishedApi
|
||||
internal const val SYSTEM_FRAMEWORK_NAME = "android"
|
||||
|
||||
/** [YukiHookDataChannel] 是否已经注册 */
|
||||
private var isDataChannelRegister = false
|
||||
|
||||
@@ -134,6 +129,38 @@ internal object AppParasitics {
|
||||
param(IntType)
|
||||
}.ignored().get().int(systemContext.packageManager.getApplicationInfo(packageName, PackageManager.GET_ACTIVITIES).uid)
|
||||
|
||||
/**
|
||||
* Hook 模块 APP 相关功能 - 包括自身激活状态、Resources Hook 支持状态以及 [SharedPreferences]
|
||||
*
|
||||
* - ❗装载代码将自动生成 - 你不应该手动使用此方法装载 Xposed 模块事件
|
||||
* @param loader 模块的 [ClassLoader]
|
||||
* @param type 当前正在进行的 Hook 类型
|
||||
*/
|
||||
internal fun hookModuleAppRelated(loader: ClassLoader?, type: HookEntryType) {
|
||||
if (YukiHookAPI.Configs.isEnableHookSharedPreferences && type == HookEntryType.PACKAGE)
|
||||
YukiHookHelper.hook(ContextImplClass.method { name = "setFilePermissionsFromMode" }, object : YukiMemberHook() {
|
||||
override fun beforeHookedMember(wrapper: HookParamWrapper) {
|
||||
if ((wrapper.args?.get(0) as? String?)?.endsWith(suffix = "preferences.xml") == true) wrapper.args?.set(1, 1)
|
||||
}
|
||||
})
|
||||
if (YukiHookAPI.Configs.isEnableHookModuleStatus) classOf<YukiHookModuleStatus>(loader).apply {
|
||||
if (type != HookEntryType.RESOURCES) {
|
||||
YukiHookHelper.hook(method { name = YukiHookModuleStatus.IS_ACTIVE_METHOD_NAME }, object : YukiMemberReplacement() {
|
||||
override fun replaceHookedMember(wrapper: HookParamWrapper) = true
|
||||
})
|
||||
YukiHookHelper.hook(method { name = YukiHookModuleStatus.GET_XPOSED_TAG_METHOD_NAME }, object : YukiMemberReplacement() {
|
||||
override fun replaceHookedMember(wrapper: HookParamWrapper) = YukiHookBridge.executorName
|
||||
})
|
||||
YukiHookHelper.hook(method { name = YukiHookModuleStatus.GET_XPOSED_VERSION_METHOD_NAME }, object : YukiMemberReplacement() {
|
||||
override fun replaceHookedMember(wrapper: HookParamWrapper) = YukiHookBridge.executorVersion
|
||||
})
|
||||
} else
|
||||
YukiHookHelper.hook(method { name = YukiHookModuleStatus.HAS_RESOURCES_HOOK_METHOD_NAME }, object : YukiMemberReplacement() {
|
||||
override fun replaceHookedMember(wrapper: HookParamWrapper) = true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注入当前 Hook APP (宿主) 全局生命周期
|
||||
* @param packageName 包名
|
||||
|
Reference in New Issue
Block a user