mirror of
https://github.com/fankes/TSBattery.git
synced 2025-09-04 17:55:30 +08:00
Fix change hook entry inject function try fix some Non-Root Hook Framework not work, such as TaiChi
This commit is contained in:
@@ -24,15 +24,11 @@
|
||||
package com.fankes.tsbattery.hook
|
||||
|
||||
import com.fankes.tsbattery.const.PackageName
|
||||
import com.fankes.tsbattery.data.ConfigData
|
||||
import com.fankes.tsbattery.hook.entity.QQTIMHooker
|
||||
import com.fankes.tsbattery.hook.entity.WeChatHooker
|
||||
import com.fankes.tsbattery.utils.factory.versionName
|
||||
import com.highcapable.yukihookapi.annotation.xposed.InjectYukiHookWithXposed
|
||||
import com.highcapable.yukihookapi.hook.factory.configs
|
||||
import com.highcapable.yukihookapi.hook.factory.encase
|
||||
import com.highcapable.yukihookapi.hook.factory.registerModuleAppActivities
|
||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||
import com.highcapable.yukihookapi.hook.xposed.proxy.IYukiHookXposedInit
|
||||
|
||||
@InjectYukiHookWithXposed(isUsingResourcesHook = false)
|
||||
@@ -50,31 +46,9 @@ class HookEntry : IYukiHookXposedInit {
|
||||
isEnableDataChannel = false
|
||||
}
|
||||
|
||||
/**
|
||||
* 装载对象是否为 QQ、TIM、微信
|
||||
* @return [Boolean]
|
||||
*/
|
||||
private fun PackageParam.isCurrentScope() = packageName.let { it == PackageName.QQ || it == PackageName.TIM || it == PackageName.WECHAT }
|
||||
|
||||
override fun onHook() = encase {
|
||||
loadApp {
|
||||
if (isCurrentScope()) onAppLifecycle {
|
||||
attachBaseContext { baseContext, hasCalledSuper ->
|
||||
if (hasCalledSuper) return@attachBaseContext
|
||||
ConfigData.init(baseContext)
|
||||
when (baseContext.packageName) {
|
||||
PackageName.QQ, PackageName.TIM -> loadHooker(QQTIMHooker.apply { appVersionName = baseContext.versionName })
|
||||
PackageName.WECHAT -> loadHooker(WeChatHooker)
|
||||
}
|
||||
}
|
||||
onCreate {
|
||||
when (packageName) {
|
||||
PackageName.QQ, PackageName.TIM ->
|
||||
registerModuleAppActivities(proxy = "${PackageName.QQ}.activity.QQSettingSettingActivity")
|
||||
PackageName.WECHAT -> registerModuleAppActivities(proxy = "${PackageName.WECHAT}.plugin.welab.ui.WelabMainUI")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
loadApp(PackageName.QQ) { loadHooker(QQTIMHooker) }
|
||||
loadApp(PackageName.TIM) { loadHooker(QQTIMHooker) }
|
||||
loadApp(PackageName.WECHAT) { loadHooker(WeChatHooker) }
|
||||
}
|
||||
}
|
||||
|
@@ -35,13 +35,13 @@ import com.fankes.tsbattery.hook.factory.hookSystemWakeLock
|
||||
import com.fankes.tsbattery.hook.factory.jumpToModuleSettings
|
||||
import com.fankes.tsbattery.hook.factory.startModuleSettings
|
||||
import com.fankes.tsbattery.utils.factory.dp
|
||||
import com.fankes.tsbattery.utils.factory.versionName
|
||||
import com.highcapable.yukihookapi.hook.bean.VariousClass
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
import com.highcapable.yukihookapi.hook.factory.buildOf
|
||||
import com.highcapable.yukihookapi.hook.factory.current
|
||||
import com.highcapable.yukihookapi.hook.factory.field
|
||||
import com.highcapable.yukihookapi.hook.factory.*
|
||||
import com.highcapable.yukihookapi.hook.log.loggerD
|
||||
import com.highcapable.yukihookapi.hook.log.loggerE
|
||||
import com.highcapable.yukihookapi.hook.log.loggerI
|
||||
import com.highcapable.yukihookapi.hook.type.android.*
|
||||
import com.highcapable.yukihookapi.hook.type.java.*
|
||||
|
||||
@@ -79,7 +79,7 @@ object QQTIMHooker : YukiBaseHooker() {
|
||||
private val isQQ get() = packageName == PackageName.QQ
|
||||
|
||||
/** 当前宿主的版本 */
|
||||
var appVersionName = "<unknown>"
|
||||
private var appVersionName = "<unknown>"
|
||||
|
||||
/**
|
||||
* 这个类 QQ 的 BaseChatPie 是控制聊天界面的
|
||||
@@ -500,67 +500,74 @@ object QQTIMHooker : YukiBaseHooker() {
|
||||
}
|
||||
|
||||
override fun onHook() {
|
||||
/** Hook 跳转事件 */
|
||||
JumpActivityClass.hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "doOnCreate"
|
||||
param(BundleClass)
|
||||
}
|
||||
afterHook { instance<Activity>().jumpToModuleSettings() }
|
||||
onAppLifecycle {
|
||||
onCreate {
|
||||
appVersionName = versionName
|
||||
ConfigData.init(context = this)
|
||||
registerModuleAppActivities(QQSettingSettingActivityClass)
|
||||
if (ConfigData.isDisableAllHook) return@onCreate
|
||||
hookSystemWakeLock()
|
||||
hookQQBaseChatPie()
|
||||
hookCoreService()
|
||||
hookQQDisgusting()
|
||||
loggerI(msg = "All processes are completed for \"${processName.takeIf { it != packageName } ?: packageName}\"")
|
||||
}
|
||||
}
|
||||
/** 将条目注入设置界面 */
|
||||
QQSettingSettingActivityClass.hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "doOnCreate"
|
||||
param(BundleClass)
|
||||
/** 仅注入主进程 */
|
||||
withProcess(mainProcessName) {
|
||||
/** Hook 跳转事件 */
|
||||
JumpActivityClass.hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "doOnCreate"
|
||||
param(BundleClass)
|
||||
}
|
||||
afterHook { instance<Activity>().jumpToModuleSettings() }
|
||||
}
|
||||
afterHook {
|
||||
/** 当前的顶级 Item 实例 */
|
||||
val formItemRefRoot = field {
|
||||
type(FormSimpleItemClass).index(num = 1)
|
||||
}.ignored().get(instance).cast() ?: field {
|
||||
type(FormCommonSingleLineItemClass).index(num = 1)
|
||||
}.ignored().get(instance).cast<View?>()
|
||||
/** 创建一个新的 Item */
|
||||
FormSimpleItemClass.toClassOrNull()?.buildOf<View>(instance) { param(ContextClass) }?.current {
|
||||
method {
|
||||
name = "setLeftText"
|
||||
param(CharSequenceType)
|
||||
}.call("TSBattery")
|
||||
method {
|
||||
name = "setRightText"
|
||||
param(CharSequenceType)
|
||||
}.call(BuildConfig.VERSION_NAME)
|
||||
method {
|
||||
name = "setBgType"
|
||||
param(IntType)
|
||||
}.call(if (isQQ) 0 else 2)
|
||||
}?.apply { setOnClickListener { instance<Activity>().startModuleSettings() } }?.also { item ->
|
||||
var listGroup = formItemRefRoot?.parent as? ViewGroup?
|
||||
val lparam = (if (listGroup?.childCount == 1) {
|
||||
listGroup = listGroup.parent as? ViewGroup
|
||||
(formItemRefRoot?.parent as? View?)?.layoutParams
|
||||
} else formItemRefRoot?.layoutParams)
|
||||
?: ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
/** 设置圆角和间距 */
|
||||
if (isQQ) (lparam as? ViewGroup.MarginLayoutParams?)?.setMargins(0, 15.dp(item.context), 0, 0)
|
||||
/** 将 Item 添加到设置界面 */
|
||||
listGroup?.also { if (isQQ) it.addView(item, lparam) else it.addView(item, 0, lparam) }
|
||||
}
|
||||
/** 将条目注入设置界面 */
|
||||
QQSettingSettingActivityClass.hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "doOnCreate"
|
||||
param(BundleClass)
|
||||
}
|
||||
afterHook {
|
||||
/** 当前的顶级 Item 实例 */
|
||||
val formItemRefRoot = field {
|
||||
type(FormSimpleItemClass).index(num = 1)
|
||||
}.ignored().get(instance).cast() ?: field {
|
||||
type(FormCommonSingleLineItemClass).index(num = 1)
|
||||
}.ignored().get(instance).cast<View?>()
|
||||
/** 创建一个新的 Item */
|
||||
FormSimpleItemClass.toClassOrNull()?.buildOf<View>(instance) { param(ContextClass) }?.current {
|
||||
method {
|
||||
name = "setLeftText"
|
||||
param(CharSequenceType)
|
||||
}.call("TSBattery")
|
||||
method {
|
||||
name = "setRightText"
|
||||
param(CharSequenceType)
|
||||
}.call(BuildConfig.VERSION_NAME)
|
||||
method {
|
||||
name = "setBgType"
|
||||
param(IntType)
|
||||
}.call(if (isQQ) 0 else 2)
|
||||
}?.apply { setOnClickListener { instance<Activity>().startModuleSettings() } }?.also { item ->
|
||||
var listGroup = formItemRefRoot?.parent as? ViewGroup?
|
||||
val lparam = (if (listGroup?.childCount == 1) {
|
||||
listGroup = listGroup.parent as? ViewGroup
|
||||
(formItemRefRoot?.parent as? View?)?.layoutParams
|
||||
} else formItemRefRoot?.layoutParams)
|
||||
?: ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
/** 设置圆角和间距 */
|
||||
if (isQQ) (lparam as? ViewGroup.MarginLayoutParams?)?.setMargins(0, 15.dp(item.context), 0, 0)
|
||||
/** 将 Item 添加到设置界面 */
|
||||
listGroup?.also { if (isQQ) it.addView(item, lparam) else it.addView(item, 0, lparam) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ConfigData.isDisableAllHook) return
|
||||
/** Hook 系统电源锁 */
|
||||
hookSystemWakeLock()
|
||||
/** Hook 聊天界面 */
|
||||
hookQQBaseChatPie()
|
||||
/** Hook CoreService */
|
||||
hookCoreService()
|
||||
/** Hook QQ 不省电的功能 */
|
||||
hookQQDisgusting()
|
||||
}
|
||||
}
|
@@ -36,10 +36,14 @@ import com.fankes.tsbattery.hook.factory.jumpToModuleSettings
|
||||
import com.fankes.tsbattery.hook.factory.startModuleSettings
|
||||
import com.fankes.tsbattery.utils.factory.absoluteStatusBarHeight
|
||||
import com.fankes.tsbattery.utils.factory.dp
|
||||
import com.fankes.tsbattery.utils.factory.versionCode
|
||||
import com.fankes.tsbattery.utils.factory.versionName
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
import com.highcapable.yukihookapi.hook.factory.current
|
||||
import com.highcapable.yukihookapi.hook.factory.injectModuleAppResources
|
||||
import com.highcapable.yukihookapi.hook.log.loggerD
|
||||
import com.highcapable.yukihookapi.hook.factory.processName
|
||||
import com.highcapable.yukihookapi.hook.factory.registerModuleAppActivities
|
||||
import com.highcapable.yukihookapi.hook.log.loggerI
|
||||
import com.highcapable.yukihookapi.hook.type.android.BundleClass
|
||||
|
||||
/**
|
||||
@@ -52,57 +56,76 @@ object WeChatHooker : YukiBaseHooker() {
|
||||
/** 微信存在的类 - 未测试每个版本是否都存在 */
|
||||
const val LauncherUIClass = "${PackageName.WECHAT}.ui.LauncherUI"
|
||||
|
||||
/** 微信存在的类 - 未测试每个版本是否都存在 */
|
||||
private const val EmptyActivityClass = "${PackageName.WECHAT}.ui.EmptyActivity"
|
||||
|
||||
/** 微信存在的类 - 未测试每个版本是否都存在 */
|
||||
private const val WelabMainUIClass = "${PackageName.WECHAT}.plugin.welab.ui.WelabMainUI"
|
||||
|
||||
/** 微信存在的类 - 未测试每个版本是否都存在 */
|
||||
private const val SettingsUIClass = "${PackageName.WECHAT}.plugin.setting.ui.setting.SettingsUI"
|
||||
|
||||
override fun onHook() {
|
||||
/** Hook 跳转事件 */
|
||||
LauncherUIClass.hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "onResume"
|
||||
emptyParam()
|
||||
}
|
||||
afterHook { instance<Activity>().jumpToModuleSettings(isFinish = false) }
|
||||
onAppLifecycle {
|
||||
onCreate {
|
||||
ConfigData.init(context = this)
|
||||
registerModuleAppActivities(
|
||||
when {
|
||||
EmptyActivityClass.hasClass() -> EmptyActivityClass
|
||||
WelabMainUIClass.hasClass() -> WelabMainUIClass
|
||||
else -> error("Inject WeChat Activity Proxy failed, unsupport version $versionName($versionCode)")
|
||||
}
|
||||
)
|
||||
if (ConfigData.isDisableAllHook) return@onCreate
|
||||
hookSystemWakeLock()
|
||||
loggerI(msg = "All processes are completed for \"${processName.takeIf { it != packageName } ?: packageName}\"")
|
||||
}
|
||||
}
|
||||
/** 向设置界面右上角添加按钮 */
|
||||
SettingsUIClass.hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "onCreate"
|
||||
param(BundleClass)
|
||||
}
|
||||
afterHook {
|
||||
/** 仅注入主进程 */
|
||||
withProcess(mainProcessName) {
|
||||
/** Hook 跳转事件 */
|
||||
LauncherUIClass.hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "get_fragment"
|
||||
name = "onResume"
|
||||
emptyParam()
|
||||
superClass(isOnlySuperClass = true)
|
||||
}.get(instance).call()?.current()
|
||||
?.field { name = "mController" }
|
||||
?.current()?.method { name = "getContentView" }
|
||||
?.invoke<ViewGroup>()?.addView(LinearLayout(instance()).apply {
|
||||
context.injectModuleAppResources()
|
||||
gravity = Gravity.END or Gravity.BOTTOM
|
||||
layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
addView(ImageView(context).apply {
|
||||
layoutParams = ViewGroup.MarginLayoutParams(20.dp(context), 20.dp(context)).apply {
|
||||
topMargin = context.absoluteStatusBarHeight + 15.dp(context)
|
||||
rightMargin = 20.dp(context)
|
||||
}
|
||||
setColorFilter(ResourcesCompat.getColor(resources, R.color.colorTextGray, null))
|
||||
setImageResource(R.drawable.ic_icon)
|
||||
if (Build.VERSION.SDK_INT >= 26) tooltipText = "TSBattery 设置"
|
||||
setOnClickListener { context.startModuleSettings() }
|
||||
}
|
||||
afterHook { instance<Activity>().jumpToModuleSettings(isFinish = false) }
|
||||
}
|
||||
}
|
||||
/** 向设置界面右上角添加按钮 */
|
||||
SettingsUIClass.hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "onCreate"
|
||||
param(BundleClass)
|
||||
}
|
||||
afterHook {
|
||||
method {
|
||||
name = "get_fragment"
|
||||
emptyParam()
|
||||
superClass(isOnlySuperClass = true)
|
||||
}.get(instance).call()?.current()
|
||||
?.field { name = "mController" }
|
||||
?.current()?.method { name = "getContentView" }
|
||||
?.invoke<ViewGroup>()?.addView(LinearLayout(instance()).apply {
|
||||
context.injectModuleAppResources()
|
||||
gravity = Gravity.END or Gravity.BOTTOM
|
||||
layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
addView(ImageView(context).apply {
|
||||
layoutParams = ViewGroup.MarginLayoutParams(20.dp(context), 20.dp(context)).apply {
|
||||
topMargin = context.absoluteStatusBarHeight + 15.dp(context)
|
||||
rightMargin = 20.dp(context)
|
||||
}
|
||||
setColorFilter(ResourcesCompat.getColor(resources, R.color.colorTextGray, null))
|
||||
setImageResource(R.drawable.ic_icon)
|
||||
if (Build.VERSION.SDK_INT >= 26) tooltipText = "TSBattery 设置"
|
||||
setOnClickListener { context.startModuleSettings() }
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ConfigData.isDisableAllHook) return
|
||||
/** Hook 系统电源锁 */
|
||||
hookSystemWakeLock()
|
||||
/** 日志省电大法 */
|
||||
loggerD(msg = "ウイチャット:それが機能するかどうかはわかりませんでした")
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user