mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-07 11:10:04 +08:00
Merge XposedProcessor code source files to template
This commit is contained in:
@@ -34,8 +34,8 @@ import com.google.devtools.ksp.processing.*
|
|||||||
import com.google.devtools.ksp.symbol.FileLocation
|
import com.google.devtools.ksp.symbol.FileLocation
|
||||||
import com.google.devtools.ksp.symbol.KSAnnotated
|
import com.google.devtools.ksp.symbol.KSAnnotated
|
||||||
import com.google.devtools.ksp.symbol.KSClassDeclaration
|
import com.google.devtools.ksp.symbol.KSClassDeclaration
|
||||||
|
import com.highcapable.yukihookapi_ksp_xposed.sources.CodeSourceFileTemplate
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
@@ -49,18 +49,6 @@ import java.util.regex.Pattern
|
|||||||
@AutoService(SymbolProcessorProvider::class)
|
@AutoService(SymbolProcessorProvider::class)
|
||||||
class YukiHookXposedProcessor : SymbolProcessorProvider {
|
class YukiHookXposedProcessor : SymbolProcessorProvider {
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
/** 定义 Jvm 方法名 */
|
|
||||||
private const val IS_ACTIVE_METHOD_NAME = "__--"
|
|
||||||
|
|
||||||
/** 定义 Jvm 方法名 */
|
|
||||||
private const val GET_XPOSED_VERSION_METHOD_NAME = "--__"
|
|
||||||
|
|
||||||
/** 定义 Jvm 方法名 */
|
|
||||||
private const val GET_XPOSED_TAG_METHOD_NAME = "_-_-"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun create(environment: SymbolProcessorEnvironment) = object : SymbolProcessor {
|
override fun create(environment: SymbolProcessorEnvironment) = object : SymbolProcessor {
|
||||||
|
|
||||||
/** 自动处理程序的 TAG */
|
/** 自动处理程序的 TAG */
|
||||||
@@ -114,22 +102,22 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
|
|||||||
* 检索需要注入的类
|
* 检索需要注入的类
|
||||||
* @param sourcePath 指定的 source 路径
|
* @param sourcePath 指定的 source 路径
|
||||||
* @param modulePackageName 模块包名
|
* @param modulePackageName 模块包名
|
||||||
* @param entryClassName 入口类名
|
* @param xInitClassName xposed_init 入口类名
|
||||||
*/
|
*/
|
||||||
fun fetchKSClassDeclaration(sourcePath: String, modulePackageName: String, entryClassName: String) {
|
fun fetchKSClassDeclaration(sourcePath: String, modulePackageName: String, xInitClassName: String) {
|
||||||
asSequence().filterIsInstance<KSClassDeclaration>().forEach {
|
asSequence().filterIsInstance<KSClassDeclaration>().forEach {
|
||||||
if (isInjectOnce) when {
|
if (isInjectOnce) when {
|
||||||
it.superTypes.any { type -> type.element.toString() == "IYukiHookXposedInit" } -> {
|
it.superTypes.any { type -> type.element.toString() == "IYukiHookXposedInit" } -> {
|
||||||
val ecName = entryClassName.ifBlank { "${it.simpleName.asString()}$xposedClassShortName" }
|
val xcName = xInitClassName.ifBlank { "${it.simpleName.asString()}$xposedClassShortName" }
|
||||||
if (entryClassName == it.simpleName.asString()) error(msg = "Duplicate entryClassName \"$entryClassName\"")
|
if (xInitClassName == it.simpleName.asString()) error(msg = "Duplicate entryClassName \"$xInitClassName\"")
|
||||||
injectAssets(
|
injectAssets(
|
||||||
codePath = (it.location as? FileLocation?)?.filePath ?: "",
|
codePath = (it.location as? FileLocation?)?.filePath ?: "",
|
||||||
sourcePath = sourcePath,
|
sourcePath = sourcePath,
|
||||||
packageName = it.packageName.asString(),
|
packageName = it.packageName.asString(),
|
||||||
className = it.simpleName.asString(),
|
entryClassName = it.simpleName.asString(),
|
||||||
entryClassName = ecName
|
xInitClassName = xcName
|
||||||
)
|
)
|
||||||
injectClass(it.packageName.asString(), it.simpleName.asString(), modulePackageName, ecName)
|
injectClass(it.packageName.asString(), modulePackageName, it.simpleName.asString(), xcName)
|
||||||
}
|
}
|
||||||
it.superTypes.any { type -> type.element.toString() == "YukiHookXposedInitProxy" } ->
|
it.superTypes.any { type -> type.element.toString() == "YukiHookXposedInitProxy" } ->
|
||||||
error(msg = "\"YukiHookXposedInitProxy\" was deprecated, please replace to \"IYukiHookXposedInit\"")
|
error(msg = "\"YukiHookXposedInitProxy\" was deprecated, please replace to \"IYukiHookXposedInit\"")
|
||||||
@@ -142,9 +130,9 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
|
|||||||
}
|
}
|
||||||
forEach {
|
forEach {
|
||||||
it.annotations.forEach { e ->
|
it.annotations.forEach { e ->
|
||||||
var sourcePath = ""
|
var sourcePath = "" // 项目相对路径
|
||||||
var modulePackageName = ""
|
var modulePackageName = "" // 模块包名
|
||||||
var entryClassName = ""
|
var entryClassName = "" // xposed_init 入口类名
|
||||||
e.arguments.forEach { pease ->
|
e.arguments.forEach { pease ->
|
||||||
if (pease.name?.asString() == "sourcePath")
|
if (pease.name?.asString() == "sourcePath")
|
||||||
sourcePath = pease.value.toString().trim()
|
sourcePath = pease.value.toString().trim()
|
||||||
@@ -174,10 +162,10 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
|
|||||||
* @param codePath 注解类的完整代码文件路径
|
* @param codePath 注解类的完整代码文件路径
|
||||||
* @param sourcePath 指定的 source 路径
|
* @param sourcePath 指定的 source 路径
|
||||||
* @param packageName 包名
|
* @param packageName 包名
|
||||||
* @param className 类名
|
|
||||||
* @param entryClassName 入口类名
|
* @param entryClassName 入口类名
|
||||||
|
* @param xInitClassName xposed_init 入口类名
|
||||||
*/
|
*/
|
||||||
private fun injectAssets(codePath: String, sourcePath: String, packageName: String, className: String, entryClassName: String) =
|
private fun injectAssets(codePath: String, sourcePath: String, packageName: String, entryClassName: String, xInitClassName: String) =
|
||||||
environment {
|
environment {
|
||||||
if (codePath.isBlank()) error(msg = "Project CodePath not available")
|
if (codePath.isBlank()) error(msg = "Project CodePath not available")
|
||||||
if (sourcePath.isBlank()) error(msg = "Project SourcePath not available")
|
if (sourcePath.isBlank()) error(msg = "Project SourcePath not available")
|
||||||
@@ -206,9 +194,9 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
|
|||||||
assFile.mkdirs()
|
assFile.mkdirs()
|
||||||
}
|
}
|
||||||
File("${assFile.absolutePath}${separator}xposed_init")
|
File("${assFile.absolutePath}${separator}xposed_init")
|
||||||
.writeText(text = "$packageName.$entryClassName")
|
.writeText(text = "$packageName.$xInitClassName")
|
||||||
File("${assFile.absolutePath}${separator}yukihookapi_init")
|
File("${assFile.absolutePath}${separator}yukihookapi_init")
|
||||||
.writeText(text = "$packageName.$className")
|
.writeText(text = "$packageName.$entryClassName")
|
||||||
} else error(msg = "Project Source Path \"$sourcePath\" verify failed! Is this an Android Project?")
|
} else error(msg = "Project Source Path \"$sourcePath\" verify failed! Is this an Android Project?")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,137 +204,39 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
|
|||||||
/**
|
/**
|
||||||
* 注入并生成指定类
|
* 注入并生成指定类
|
||||||
* @param packageName 包名
|
* @param packageName 包名
|
||||||
* @param className 类名
|
|
||||||
* @param modulePackageName 模块包名
|
* @param modulePackageName 模块包名
|
||||||
* @param entryClassName 入口类名
|
* @param entryClassName 入口类名
|
||||||
|
* @param xInitClassName xposed_init 入口类名
|
||||||
*/
|
*/
|
||||||
private fun injectClass(packageName: String, className: String, modulePackageName: String, entryClassName: String) =
|
private fun injectClass(packageName: String, modulePackageName: String, entryClassName: String, xInitClassName: String) =
|
||||||
environment(ignoredError = true) {
|
environment(ignoredError = true) {
|
||||||
if (modulePackageName.isNotBlank()) warn(msg = "You set the customize module package name to \"$modulePackageName\", please check for yourself if it is correct")
|
if (modulePackageName.isNotBlank())
|
||||||
val realPackageName =
|
warn(msg = "You set the customize module package name to \"$modulePackageName\", please check for yourself if it is correct")
|
||||||
|
val fModulePackageName =
|
||||||
modulePackageName.ifBlank {
|
modulePackageName.ifBlank {
|
||||||
if (packageName.contains(".hook.") || packageName.endsWith(".hook"))
|
if (packageName.contains(other = ".hook.") || packageName.endsWith(suffix = ".hook"))
|
||||||
packageName.split(".hook")[0]
|
packageName.split(".hook")[0]
|
||||||
else error(msg = "Cannot identify your App's package name, please manually configure the package name")
|
else error(msg = "Cannot identify your Module App's package name, please manually configure the package name")
|
||||||
|
modulePackageName
|
||||||
}
|
}
|
||||||
val injectPackageName = "com.highcapable.yukihookapi.hook.xposed.application.inject"
|
val injectPackageName = "com.highcapable.yukihookapi.hook.xposed.application.inject"
|
||||||
fun commentContent(name: String) = ("/**\n" +
|
/** 插入 ModuleApplication_Injector 代码 */
|
||||||
" * $name Inject Class\n" +
|
|
||||||
" *\n" +
|
|
||||||
" * Compiled from YukiHookXposedProcessor\n" +
|
|
||||||
" *\n" +
|
|
||||||
" * HookEntryClass: [$className]\n" +
|
|
||||||
" *\n" +
|
|
||||||
" * Generate Date: ${SimpleDateFormat.getDateTimeInstance().format(Date())}\n" +
|
|
||||||
" *\n" +
|
|
||||||
" * Powered by YukiHookAPI (C) HighCapable 2022\n" +
|
|
||||||
" *\n" +
|
|
||||||
" * Project Address: [YukiHookAPI](https://github.com/fankes/YukiHookAPI)\n" +
|
|
||||||
" */\n")
|
|
||||||
codeGenerator.createNewFile(
|
codeGenerator.createNewFile(
|
||||||
dependencies = Dependencies.ALL_FILES,
|
dependencies = Dependencies.ALL_FILES,
|
||||||
packageName = injectPackageName,
|
packageName = injectPackageName,
|
||||||
fileName = "ModuleApplication_Injector"
|
fileName = "ModuleApplication_Injector"
|
||||||
).apply {
|
).apply {
|
||||||
/** 插入 ModuleApplication_Injector 代码 */
|
write(CodeSourceFileTemplate.getModuleApplicationInjectorFileByteArray(injectPackageName, packageName, entryClassName))
|
||||||
write(
|
|
||||||
("@file:Suppress(\"ClassName\")\n" +
|
|
||||||
"\n" +
|
|
||||||
"package $injectPackageName\n" +
|
|
||||||
"\n" +
|
|
||||||
"import $packageName.$className\n" +
|
|
||||||
"\n" +
|
|
||||||
commentContent(name = "ModuleApplication") +
|
|
||||||
"object ModuleApplication_Injector {\n" +
|
|
||||||
"\n" +
|
|
||||||
" @JvmStatic\n" +
|
|
||||||
" fun callApiInit() = try {\n" +
|
|
||||||
" $className().onInit()\n" +
|
|
||||||
" } catch (_: Throwable) {\n" +
|
|
||||||
" }\n" +
|
|
||||||
"}").toByteArray()
|
|
||||||
)
|
|
||||||
flush()
|
flush()
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
|
/** 插入 xposed_init 代码 */
|
||||||
codeGenerator.createNewFile(
|
codeGenerator.createNewFile(
|
||||||
dependencies = Dependencies.ALL_FILES,
|
dependencies = Dependencies.ALL_FILES,
|
||||||
packageName = packageName,
|
packageName = packageName,
|
||||||
fileName = entryClassName
|
fileName = xInitClassName
|
||||||
).apply {
|
).apply {
|
||||||
/** 插入 xposed_init 代码 */
|
write(CodeSourceFileTemplate.getXposedInitFileByteArray(packageName, fModulePackageName, entryClassName, xInitClassName))
|
||||||
write(
|
|
||||||
("package $packageName\n" +
|
|
||||||
"\n" +
|
|
||||||
"import androidx.annotation.Keep\n" +
|
|
||||||
"import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookXposedBridge\n" +
|
|
||||||
"import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus\n" +
|
|
||||||
"import com.highcapable.yukihookapi.hook.log.loggerE\n" +
|
|
||||||
"import de.robv.android.xposed.IXposedHookLoadPackage\n" +
|
|
||||||
"import de.robv.android.xposed.XC_MethodReplacement\n" +
|
|
||||||
"import de.robv.android.xposed.XposedHelpers\n" +
|
|
||||||
"import de.robv.android.xposed.XposedBridge\n" +
|
|
||||||
"import de.robv.android.xposed.callbacks.XC_LoadPackage\n" +
|
|
||||||
"import com.highcapable.yukihookapi.annotation.YukiGenerateApi\n" +
|
|
||||||
"import $packageName.$className\n" +
|
|
||||||
"\n" +
|
|
||||||
commentContent(name = "XposedInit") +
|
|
||||||
"@Keep\n" +
|
|
||||||
"@YukiGenerateApi\n" +
|
|
||||||
"class $entryClassName : IXposedHookLoadPackage {\n" +
|
|
||||||
"\n" +
|
|
||||||
" override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {\n" +
|
|
||||||
" if (lpparam == null) return\n" +
|
|
||||||
" try {\n" +
|
|
||||||
" $className().apply {\n" +
|
|
||||||
" onInit()\n" +
|
|
||||||
" if (YukiHookXposedBridge.isXposedCallbackSetUp) {\n" +
|
|
||||||
" loggerE(tag = \"YukiHookAPI\", msg = \"You cannot loading a hooker in \\\"onInit\\\" method! Aborted\")\n" +
|
|
||||||
" return\n" +
|
|
||||||
" }\n" +
|
|
||||||
" onHook()\n" +
|
|
||||||
" }\n" +
|
|
||||||
" YukiHookXposedBridge.callXposedInitialized()\n" +
|
|
||||||
" } catch (e: Throwable) {\n" +
|
|
||||||
" loggerE(tag = \"YukiHookAPI\", msg = \"YukiHookAPI try to load HookEntryClass failed\", e = e)\n" +
|
|
||||||
" }\n" +
|
|
||||||
" if (lpparam.packageName == \"$realPackageName\") {\n" +
|
|
||||||
" XposedHelpers.findAndHookMethod(\n" +
|
|
||||||
" YukiHookModuleStatus::class.java.name,\n" +
|
|
||||||
" lpparam.classLoader,\n" +
|
|
||||||
" \"$IS_ACTIVE_METHOD_NAME\",\n" +
|
|
||||||
" object : XC_MethodReplacement() {\n" +
|
|
||||||
" override fun replaceHookedMethod(param: MethodHookParam?) = true\n" +
|
|
||||||
" })\n" +
|
|
||||||
" XposedHelpers.findAndHookMethod(\n" +
|
|
||||||
" YukiHookModuleStatus::class.java.name,\n" +
|
|
||||||
" lpparam.classLoader,\n" +
|
|
||||||
" \"$GET_XPOSED_TAG_METHOD_NAME\",\n" +
|
|
||||||
" object : XC_MethodReplacement() {\n" +
|
|
||||||
" override fun replaceHookedMethod(param: MethodHookParam?) = try {\n" +
|
|
||||||
" XposedBridge::class.java.getDeclaredField(\"TAG\").apply { isAccessible = true }.get(null) as String\n" +
|
|
||||||
" } catch (_: Throwable) {\n" +
|
|
||||||
" \"invalid\"\n" +
|
|
||||||
" }\n" +
|
|
||||||
" })\n" +
|
|
||||||
" XposedHelpers.findAndHookMethod(\n" +
|
|
||||||
" YukiHookModuleStatus::class.java.name,\n" +
|
|
||||||
" lpparam.classLoader,\n" +
|
|
||||||
" \"$GET_XPOSED_VERSION_METHOD_NAME\",\n" +
|
|
||||||
" object : XC_MethodReplacement() {\n" +
|
|
||||||
" override fun replaceHookedMethod(param: MethodHookParam?) = try {\n" +
|
|
||||||
" XposedBridge.getXposedVersion()\n" +
|
|
||||||
" } catch (_: Throwable) {\n" +
|
|
||||||
" -1\n" +
|
|
||||||
" }\n" +
|
|
||||||
" })\n" +
|
|
||||||
" YukiHookXposedBridge.isModulePackageXposedEnv = true\n" +
|
|
||||||
" }\n" +
|
|
||||||
" YukiHookXposedBridge.modulePackageName = \"$realPackageName\"\n" +
|
|
||||||
" YukiHookXposedBridge.callXposedLoaded(lpparam)\n" +
|
|
||||||
" }\n" +
|
|
||||||
"}").toByteArray()
|
|
||||||
)
|
|
||||||
flush()
|
flush()
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
* YukiHookAPI - An efficient Kotlin version of the Xposed Hook API.
|
||||||
|
* Copyright (C) 2019-2022 HighCapable
|
||||||
|
* https://github.com/fankes/YukiHookAPI
|
||||||
|
*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is Created by fankes on 2022/4/27.
|
||||||
|
*/
|
||||||
|
package com.highcapable.yukihookapi_ksp_xposed.sources
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代码文件注入器
|
||||||
|
*/
|
||||||
|
object CodeSourceFileTemplate {
|
||||||
|
|
||||||
|
/** 定义 Jvm 方法名 */
|
||||||
|
private const val IS_ACTIVE_METHOD_NAME = "__--"
|
||||||
|
|
||||||
|
/** 定义 Jvm 方法名 */
|
||||||
|
private const val GET_XPOSED_VERSION_METHOD_NAME = "--__"
|
||||||
|
|
||||||
|
/** 定义 Jvm 方法名 */
|
||||||
|
private const val GET_XPOSED_TAG_METHOD_NAME = "_-_-"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得文件注释
|
||||||
|
* @param entryClassName 入口类名
|
||||||
|
* @param currrentClassTag 当前注入类标签
|
||||||
|
* @return [String]
|
||||||
|
*/
|
||||||
|
private fun getCommentContent(entryClassName: String, currrentClassTag: String) =
|
||||||
|
("/**\n" +
|
||||||
|
" * $currrentClassTag Inject Class\n" +
|
||||||
|
" *\n" +
|
||||||
|
" * Compiled from YukiHookXposedProcessor\n" +
|
||||||
|
" *\n" +
|
||||||
|
" * HookEntryClass: [$entryClassName]\n" +
|
||||||
|
" *\n" +
|
||||||
|
" * Generate Date: ${SimpleDateFormat.getDateTimeInstance().format(Date())}\n" +
|
||||||
|
" *\n" +
|
||||||
|
" * Powered by YukiHookAPI (C) HighCapable 2022\n" +
|
||||||
|
" *\n" +
|
||||||
|
" * Project Address: [YukiHookAPI](https://github.com/fankes/YukiHookAPI)\n" +
|
||||||
|
" */\n")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得 ModuleApplication_Injector 注入文件
|
||||||
|
* @param packageName 包名
|
||||||
|
* @param entryPackageName 入口类包名
|
||||||
|
* @param entryClassName 入口类名
|
||||||
|
* @return [ByteArray]
|
||||||
|
*/
|
||||||
|
fun getModuleApplicationInjectorFileByteArray(packageName: String, entryPackageName: String, entryClassName: String) =
|
||||||
|
("@file:Suppress(\"ClassName\")\n" +
|
||||||
|
"\n" +
|
||||||
|
"package $packageName\n" +
|
||||||
|
"\n" +
|
||||||
|
"import $entryPackageName.$entryClassName\n" +
|
||||||
|
"\n" +
|
||||||
|
getCommentContent(entryClassName, currrentClassTag = "ModuleApplication") +
|
||||||
|
"object ModuleApplication_Injector {\n" +
|
||||||
|
"\n" +
|
||||||
|
" @JvmStatic\n" +
|
||||||
|
" fun callApiInit() = try {\n" +
|
||||||
|
" $entryClassName().onInit()\n" +
|
||||||
|
" } catch (_: Throwable) {\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}").toByteArray()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得 xposed_init 注入文件
|
||||||
|
* @param packageName 包名
|
||||||
|
* @param modulePackageName 模块包名
|
||||||
|
* @param entryClassName 入口类名
|
||||||
|
* @param xInitClassName xposed_init 入口类名
|
||||||
|
* @return [ByteArray]
|
||||||
|
*/
|
||||||
|
fun getXposedInitFileByteArray(packageName: String, modulePackageName: String, entryClassName: String, xInitClassName: String) =
|
||||||
|
("package $packageName\n" +
|
||||||
|
"\n" +
|
||||||
|
"import androidx.annotation.Keep\n" +
|
||||||
|
"import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookXposedBridge\n" +
|
||||||
|
"import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus\n" +
|
||||||
|
"import com.highcapable.yukihookapi.hook.log.loggerE\n" +
|
||||||
|
"import de.robv.android.xposed.IXposedHookLoadPackage\n" +
|
||||||
|
"import de.robv.android.xposed.XC_MethodReplacement\n" +
|
||||||
|
"import de.robv.android.xposed.XposedHelpers\n" +
|
||||||
|
"import de.robv.android.xposed.XposedBridge\n" +
|
||||||
|
"import de.robv.android.xposed.callbacks.XC_LoadPackage\n" +
|
||||||
|
"import com.highcapable.yukihookapi.annotation.YukiGenerateApi\n" +
|
||||||
|
"import $packageName.$entryClassName\n" +
|
||||||
|
"\n" +
|
||||||
|
getCommentContent(entryClassName, currrentClassTag = "XposedInit") +
|
||||||
|
"@Keep\n" +
|
||||||
|
"@YukiGenerateApi\n" +
|
||||||
|
"class $xInitClassName : IXposedHookLoadPackage {\n" +
|
||||||
|
"\n" +
|
||||||
|
" override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {\n" +
|
||||||
|
" if (lpparam == null) return\n" +
|
||||||
|
" try {\n" +
|
||||||
|
" $entryClassName().apply {\n" +
|
||||||
|
" onInit()\n" +
|
||||||
|
" if (YukiHookXposedBridge.isXposedCallbackSetUp) {\n" +
|
||||||
|
" loggerE(tag = \"YukiHookAPI\", msg = \"You cannot loading a hooker in \\\"onInit\\\" method! Aborted\")\n" +
|
||||||
|
" return\n" +
|
||||||
|
" }\n" +
|
||||||
|
" onHook()\n" +
|
||||||
|
" }\n" +
|
||||||
|
" YukiHookXposedBridge.callXposedInitialized()\n" +
|
||||||
|
" } catch (e: Throwable) {\n" +
|
||||||
|
" loggerE(tag = \"YukiHookAPI\", msg = \"YukiHookAPI try to load HookEntryClass failed\", e = e)\n" +
|
||||||
|
" }\n" +
|
||||||
|
" if (lpparam.packageName == \"$modulePackageName\") {\n" +
|
||||||
|
" XposedHelpers.findAndHookMethod(\n" +
|
||||||
|
" YukiHookModuleStatus::class.java.name,\n" +
|
||||||
|
" lpparam.classLoader,\n" +
|
||||||
|
" \"$IS_ACTIVE_METHOD_NAME\",\n" +
|
||||||
|
" object : XC_MethodReplacement() {\n" +
|
||||||
|
" override fun replaceHookedMethod(param: MethodHookParam?) = true\n" +
|
||||||
|
" })\n" +
|
||||||
|
" XposedHelpers.findAndHookMethod(\n" +
|
||||||
|
" YukiHookModuleStatus::class.java.name,\n" +
|
||||||
|
" lpparam.classLoader,\n" +
|
||||||
|
" \"$GET_XPOSED_TAG_METHOD_NAME\",\n" +
|
||||||
|
" object : XC_MethodReplacement() {\n" +
|
||||||
|
" override fun replaceHookedMethod(param: MethodHookParam?) = try {\n" +
|
||||||
|
" XposedBridge::class.java.getDeclaredField(\"TAG\").apply { isAccessible = true }.get(null) as String\n" +
|
||||||
|
" } catch (_: Throwable) {\n" +
|
||||||
|
" \"invalid\"\n" +
|
||||||
|
" }\n" +
|
||||||
|
" })\n" +
|
||||||
|
" XposedHelpers.findAndHookMethod(\n" +
|
||||||
|
" YukiHookModuleStatus::class.java.name,\n" +
|
||||||
|
" lpparam.classLoader,\n" +
|
||||||
|
" \"$GET_XPOSED_VERSION_METHOD_NAME\",\n" +
|
||||||
|
" object : XC_MethodReplacement() {\n" +
|
||||||
|
" override fun replaceHookedMethod(param: MethodHookParam?) = try {\n" +
|
||||||
|
" XposedBridge.getXposedVersion()\n" +
|
||||||
|
" } catch (_: Throwable) {\n" +
|
||||||
|
" -1\n" +
|
||||||
|
" }\n" +
|
||||||
|
" })\n" +
|
||||||
|
" YukiHookXposedBridge.isModulePackageXposedEnv = true\n" +
|
||||||
|
" }\n" +
|
||||||
|
" YukiHookXposedBridge.modulePackageName = \"$modulePackageName\"\n" +
|
||||||
|
" YukiHookXposedBridge.callXposedLoaded(lpparam)\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}").toByteArray()
|
||||||
|
}
|
Reference in New Issue
Block a user