Modify move hookModuleAppStatus to AppParasitics and renamed hookModuleAppRelated

This commit is contained in:
2022-08-19 21:56:08 +08:00
parent 554e6ba1bb
commit 809d2d20da
4 changed files with 53 additions and 70 deletions

View File

@@ -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()
}

View File

@@ -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 事件

View File

@@ -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
}
}
}

View File

@@ -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 包名