mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-06 10:45:47 +08:00
Modify change injection process to GenerateData and integrate into the new code file
This commit is contained in:
@@ -34,7 +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 com.highcapable.yukihookapi_ksp_xposed.bean.GenerateData
|
||||||
|
import com.highcapable.yukihookapi_ksp_xposed.factory.sources
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import org.w3c.dom.Node
|
import org.w3c.dom.Node
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -68,11 +69,11 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建一个环境方法体方便调用
|
* 创建一个环境方法体方便调用
|
||||||
* @param ignoredError 是否忽略错误 - 默认否
|
* @param ignored 是否忽略错误 - 默认否
|
||||||
* @param env 方法体
|
* @param env 方法体
|
||||||
*/
|
*/
|
||||||
private fun environment(ignoredError: Boolean = false, env: SymbolProcessorEnvironment.() -> Unit) {
|
private fun environment(ignored: Boolean = false, env: SymbolProcessorEnvironment.() -> Unit) {
|
||||||
if (ignoredError) runCatching { environment.apply(env) }
|
if (ignored) runCatching { environment.apply(env) }
|
||||||
else environment.apply(env)
|
else environment.apply(env)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,6 +87,18 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
|
|||||||
throw RuntimeException("[$TAG] $msg\n$helpMsg")
|
throw RuntimeException("[$TAG] $msg\n$helpMsg")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建代码文件 - 类型 kt
|
||||||
|
* @param fileName 文件名
|
||||||
|
* @param packageName 包名
|
||||||
|
* @param content 代码内容
|
||||||
|
*/
|
||||||
|
private fun SymbolProcessorEnvironment.createCodeFile(fileName: String, packageName: String, content: String?) =
|
||||||
|
codeGenerator.createNewFile(
|
||||||
|
dependencies = Dependencies.ALL_FILES,
|
||||||
|
packageName, fileName
|
||||||
|
).apply { content?.toByteArray()?.let { write(it) }; flush() }.close()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发出警告
|
* 发出警告
|
||||||
* @param msg 错误消息
|
* @param msg 错误消息
|
||||||
@@ -98,10 +111,7 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
|
|||||||
*/
|
*/
|
||||||
private fun String.removeSpecialChars() = replace("\\s*|\t|\r|\n".toRegex(), replacement = "").replace(oldValue = "\"", newValue = "'")
|
private fun String.removeSpecialChars() = replace("\\s*|\t|\r|\n".toRegex(), replacement = "").replace(oldValue = "\"", newValue = "'")
|
||||||
|
|
||||||
override fun process(resolver: Resolver) = emptyList<KSAnnotated>().let {
|
override fun process(resolver: Resolver) = emptyList<KSAnnotated>().let { startProcess(resolver); it }
|
||||||
startProcess(resolver)
|
|
||||||
it
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开始作业入口
|
* 开始作业入口
|
||||||
@@ -109,40 +119,28 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
|
|||||||
*/
|
*/
|
||||||
private fun startProcess(resolver: Resolver) = environment {
|
private fun startProcess(resolver: Resolver) = environment {
|
||||||
var isInjectOnce = true
|
var isInjectOnce = true
|
||||||
|
val data = GenerateData()
|
||||||
resolver.getSymbolsWithAnnotation(annotationName).apply {
|
resolver.getSymbolsWithAnnotation(annotationName).apply {
|
||||||
/**
|
/**
|
||||||
* 检索需要注入的类
|
* 检索需要注入的类
|
||||||
* @param sourcePath 指定的 source 路径
|
* @param sourcePath 指定的 source 路径
|
||||||
* @param custMPackageName 自定义模块包名
|
|
||||||
* @param xInitClassName xposed_init 入口类名
|
|
||||||
* @param isUsingResourcesHook 是否启用 Resources Hook
|
|
||||||
*/
|
*/
|
||||||
fun fetchKSClassDeclaration(
|
fun fetchKSClassDeclaration(sourcePath: String) {
|
||||||
sourcePath: String,
|
|
||||||
custMPackageName: String,
|
|
||||||
xInitClassName: String,
|
|
||||||
isUsingResourcesHook: Boolean
|
|
||||||
) {
|
|
||||||
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 xInitPatchName = xInitClassName.ifBlank { "${it.simpleName.asString()}$xposedClassShortName" }
|
val xInitPatchName = data.xInitClassName.ifBlank { "${it.simpleName.asString()}$xposedClassShortName" }
|
||||||
if (xInitClassName == it.simpleName.asString()) problem(msg = "Duplicate entryClassName \"$xInitClassName\"")
|
if (data.xInitClassName == it.simpleName.asString())
|
||||||
generateAssetsFile(
|
problem(msg = "Duplicate entryClassName \"${data.xInitClassName}\"")
|
||||||
codePath = (it.location as? FileLocation?)?.filePath ?: "",
|
data.entryPackageName = it.packageName.asString()
|
||||||
sourcePath = sourcePath,
|
data.entryClassName = it.simpleName.asString()
|
||||||
packageName = it.packageName.asString(),
|
data.xInitClassName = xInitPatchName
|
||||||
custMPackageName = custMPackageName,
|
generateAssetsFile(codePath = (it.location as? FileLocation?)?.filePath ?: "", sourcePath = sourcePath, data)
|
||||||
entryClassName = it.simpleName.asString(),
|
|
||||||
xInitClassName = xInitPatchName,
|
|
||||||
isUsingResourcesHook = isUsingResourcesHook
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
it.superTypes.any { type -> type.element.toString() == "YukiHookXposedInitProxy" } ->
|
it.superTypes.any { type -> type.element.toString() == "YukiHookXposedInitProxy" } ->
|
||||||
problem(msg = "\"YukiHookXposedInitProxy\" was deprecated, please replace to \"IYukiHookXposedInit\"")
|
problem(msg = "\"YukiHookXposedInitProxy\" was deprecated, please replace to \"IYukiHookXposedInit\"")
|
||||||
else -> problem(msg = "HookEntryClass \"${it.simpleName.asString()}\" must be implements \"IYukiHookXposedInit\"")
|
else -> problem(msg = "HookEntryClass \"${it.simpleName.asString()}\" must be implements \"IYukiHookXposedInit\"")
|
||||||
}
|
} else problem(msg = "\"@InjectYukiHookWithXposed\" only can be use in once times")
|
||||||
else problem(msg = "\"@InjectYukiHookWithXposed\" only can be use in once times")
|
|
||||||
/** 仅处理第一个标记的类 - 再次处理将拦截并报错 */
|
/** 仅处理第一个标记的类 - 再次处理将拦截并报错 */
|
||||||
isInjectOnce = false
|
isInjectOnce = false
|
||||||
}
|
}
|
||||||
@@ -150,30 +148,27 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
|
|||||||
forEach {
|
forEach {
|
||||||
it.annotations.forEach { annotation ->
|
it.annotations.forEach { annotation ->
|
||||||
var sourcePath = "" // 项目相对路径
|
var sourcePath = "" // 项目相对路径
|
||||||
var custMPackageName = "" // 自定义模块包名
|
|
||||||
var entryClassName = "" // xposed_init 入口类名
|
|
||||||
var isUsingResourcesHook = false // 是否启用 Resources Hook
|
|
||||||
annotation.arguments.forEach { args ->
|
annotation.arguments.forEach { args ->
|
||||||
if (args.name?.asString() == "sourcePath")
|
if (args.name?.asString() == "sourcePath")
|
||||||
sourcePath = args.value.toString().trim()
|
sourcePath = args.value.toString().trim()
|
||||||
if (args.name?.asString() == "modulePackageName")
|
if (args.name?.asString() == "modulePackageName")
|
||||||
custMPackageName = args.value.toString().trim()
|
data.customMPackageName = args.value.toString().trim()
|
||||||
if (args.name?.asString() == "entryClassName")
|
if (args.name?.asString() == "entryClassName")
|
||||||
entryClassName = args.value.toString().trim()
|
data.entryClassName = args.value.toString().trim()
|
||||||
if (args.name?.asString() == "isUsingResourcesHook")
|
if (args.name?.asString() == "isUsingResourcesHook")
|
||||||
isUsingResourcesHook = args.value as? Boolean ?: true
|
data.isUsingResourcesHook = args.value as? Boolean ?: true
|
||||||
}
|
}
|
||||||
if ((custMPackageName.startsWith(".") ||
|
if ((data.customMPackageName.startsWith(".") ||
|
||||||
custMPackageName.endsWith(".") ||
|
data.customMPackageName.endsWith(".") ||
|
||||||
custMPackageName.contains(".").not() ||
|
data.customMPackageName.contains(".").not() ||
|
||||||
custMPackageName.contains("..")) &&
|
data.customMPackageName.contains("..")) &&
|
||||||
custMPackageName.isNotEmpty()
|
data.customMPackageName.isNotEmpty()
|
||||||
) problem(msg = "Invalid modulePackageName \"$custMPackageName\"")
|
) problem(msg = "Invalid modulePackageName \"${data.customMPackageName}\"")
|
||||||
if ((Pattern.compile("[*,.:~`'\"|/\\\\?!^()\\[\\]{}%@#$&\\-+=<>]").matcher(entryClassName).find() ||
|
if ((Pattern.compile("[*,.:~`'\"|/\\\\?!^()\\[\\]{}%@#$&\\-+=<>]").matcher(data.entryClassName).find() ||
|
||||||
true.let { for (i in 0..9) if (entryClassName.startsWith(i.toString())) return@let true;false })
|
true.let { for (i in 0..9) if (data.entryClassName.startsWith(i.toString())) return@let true; false })
|
||||||
&& entryClassName.isNotEmpty()
|
&& data.entryClassName.isNotEmpty()
|
||||||
) problem(msg = "Invalid entryClassName \"$entryClassName\"")
|
) problem(msg = "Invalid entryClassName \"${data.entryClassName}\"")
|
||||||
else fetchKSClassDeclaration(sourcePath, custMPackageName, entryClassName, isUsingResourcesHook)
|
else fetchKSClassDeclaration(sourcePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,21 +178,9 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
|
|||||||
* 自动生成 Xposed assets 入口文件
|
* 自动生成 Xposed assets 入口文件
|
||||||
* @param codePath 注解类的完整代码文件路径
|
* @param codePath 注解类的完整代码文件路径
|
||||||
* @param sourcePath 指定的 source 路径
|
* @param sourcePath 指定的 source 路径
|
||||||
* @param packageName 包名
|
* @param data 生成的模板数据
|
||||||
* @param custMPackageName 自定义模块包名
|
|
||||||
* @param entryClassName 入口类名
|
|
||||||
* @param xInitClassName xposed_init 入口类名
|
|
||||||
* @param isUsingResourcesHook 是否启用 Resources Hook
|
|
||||||
*/
|
*/
|
||||||
private fun generateAssetsFile(
|
private fun generateAssetsFile(codePath: String, sourcePath: String, data: GenerateData) = environment {
|
||||||
codePath: String,
|
|
||||||
sourcePath: String,
|
|
||||||
packageName: String,
|
|
||||||
custMPackageName: String,
|
|
||||||
entryClassName: String,
|
|
||||||
xInitClassName: String,
|
|
||||||
isUsingResourcesHook: Boolean
|
|
||||||
) = environment {
|
|
||||||
if (codePath.isBlank()) problem(msg = "Project CodePath not available")
|
if (codePath.isBlank()) problem(msg = "Project CodePath not available")
|
||||||
if (sourcePath.isBlank()) problem(msg = "Project SourcePath not available")
|
if (sourcePath.isBlank()) problem(msg = "Project SourcePath not available")
|
||||||
/**
|
/**
|
||||||
@@ -214,7 +197,7 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
|
|||||||
val projectPath = when {
|
val projectPath = when {
|
||||||
codePath.contains("\\") -> sourcePath.replace("/", "\\")
|
codePath.contains("\\") -> sourcePath.replace("/", "\\")
|
||||||
codePath.contains("/") -> sourcePath.replace("\\", "/")
|
codePath.contains("/") -> sourcePath.replace("\\", "/")
|
||||||
else -> error("Unix File Separator unknown")
|
else -> error("Unknown Unix File Separator")
|
||||||
}.let {
|
}.let {
|
||||||
if (codePath.contains(it))
|
if (codePath.contains(it))
|
||||||
codePath.split(it)[0].apply { rootPath = this } + it
|
codePath.split(it)[0].apply { rootPath = this } + it
|
||||||
@@ -226,78 +209,52 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
|
|||||||
val manifestFile = File("$projectPath${separator}AndroidManifest.xml")
|
val manifestFile = File("$projectPath${separator}AndroidManifest.xml")
|
||||||
if (manifestFile.exists()) {
|
if (manifestFile.exists()) {
|
||||||
if (assetsFile.exists().not() || assetsFile.isDirectory.not()) assetsFile.apply { delete(); mkdirs() }
|
if (assetsFile.exists().not() || assetsFile.isDirectory.not()) assetsFile.apply { delete(); mkdirs() }
|
||||||
val modulePackageName = parseModulePackageName(manifestFile, gradleFile, gradleKtsFile)
|
data.modulePackageName = parseModulePackageName(manifestFile, gradleFile, gradleKtsFile)
|
||||||
if (modulePackageName.isBlank() && custMPackageName.isBlank())
|
if (data.modulePackageName.isBlank() && data.customMPackageName.isBlank())
|
||||||
problem(msg = "Cannot identify your Module App's package name, tried AndroidManifest.xml, build.gradle and build.gradle.kts")
|
problem(msg = "Cannot identify your Module App's package name, tried AndroidManifest.xml, build.gradle and build.gradle.kts")
|
||||||
File("${assetsFile.absolutePath}${separator}xposed_init")
|
File("${assetsFile.absolutePath}${separator}xposed_init")
|
||||||
.writeText(text = "$packageName.$xInitClassName")
|
.writeText(text = "${data.entryPackageName}.${data.xInitClassName}")
|
||||||
File("${assetsFile.absolutePath}${separator}yukihookapi_init")
|
File("${assetsFile.absolutePath}${separator}yukihookapi_init")
|
||||||
.writeText(text = "$packageName.$entryClassName")
|
.writeText(text = "${data.entryPackageName}.${data.entryClassName}")
|
||||||
generateClassFile(packageName, modulePackageName, custMPackageName, entryClassName, xInitClassName, isUsingResourcesHook)
|
generateClassFile(data)
|
||||||
} else problem(msg = "Project Source Path \"$sourcePath\" verify failed! Is this an Android Project?")
|
} else problem(msg = "Project Source Path \"$sourcePath\" verify failed! Is this an Android Project?")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自动生成指定类文件
|
* 自动生成指定类文件
|
||||||
* @param packageName 包名
|
* @param data 生成的模板数据
|
||||||
* @param modulePackageName 模块包名
|
|
||||||
* @param customMPackageName 自定义模块包名
|
|
||||||
* @param entryClassName 入口类名
|
|
||||||
* @param xInitClassName xposed_init 入口类名
|
|
||||||
* @param isUsingResourcesHook 是否启用 Resources Hook
|
|
||||||
*/
|
*/
|
||||||
private fun generateClassFile(
|
private fun generateClassFile(data: GenerateData) = environment(ignored = true) {
|
||||||
packageName: String,
|
if (data.customMPackageName.isNotBlank()) warn(
|
||||||
modulePackageName: String,
|
msg = "You set the customize module package name to \"${data.customMPackageName}\", " +
|
||||||
customMPackageName: String,
|
"please check for yourself if it is correct"
|
||||||
entryClassName: String,
|
)
|
||||||
xInitClassName: String,
|
|
||||||
isUsingResourcesHook: Boolean
|
|
||||||
) = environment(ignoredError = true) {
|
|
||||||
if (customMPackageName.isNotBlank())
|
|
||||||
warn(msg = "You set the customize module package name to \"$customMPackageName\", please check for yourself if it is correct")
|
|
||||||
val mdAppInjectPackageName = "com.highcapable.yukihookapi.hook.xposed.application.inject"
|
val mdAppInjectPackageName = "com.highcapable.yukihookapi.hook.xposed.application.inject"
|
||||||
val ykBridgeInjectPackageName = "com.highcapable.yukihookapi.hook.xposed.bridge.inject"
|
val ykBridgeInjectPackageName = "com.highcapable.yukihookapi.hook.xposed.bridge.inject"
|
||||||
/** 插入 ModuleApplication_Injector 代码 */
|
/** 插入 ModuleApplication_Injector 代码 */
|
||||||
codeGenerator.createNewFile(
|
createCodeFile(
|
||||||
dependencies = Dependencies.ALL_FILES,
|
fileName = "ModuleApplication_Injector",
|
||||||
packageName = mdAppInjectPackageName,
|
packageName = mdAppInjectPackageName,
|
||||||
fileName = "ModuleApplication_Injector"
|
content = data.apply { injectPackageName = mdAppInjectPackageName }.sources()["ModuleApplication_Injector"]
|
||||||
).apply {
|
)
|
||||||
write(CodeSourceFileTemplate.getModuleApplicationInjectorFileByteArray(mdAppInjectPackageName, packageName, entryClassName))
|
|
||||||
flush()
|
|
||||||
close()
|
|
||||||
}
|
|
||||||
/** 插入 YukiHookBridge_Injector 代码 */
|
/** 插入 YukiHookBridge_Injector 代码 */
|
||||||
codeGenerator.createNewFile(
|
createCodeFile(
|
||||||
dependencies = Dependencies.ALL_FILES,
|
fileName = "YukiHookBridge_Injector",
|
||||||
packageName = ykBridgeInjectPackageName,
|
packageName = ykBridgeInjectPackageName,
|
||||||
fileName = "YukiHookBridge_Injector"
|
content = data.apply { injectPackageName = ykBridgeInjectPackageName }.sources()["YukiHookBridge_Injector"]
|
||||||
).apply {
|
)
|
||||||
write(CodeSourceFileTemplate.getYukiHookBridgeInjectorFileByteArray(ykBridgeInjectPackageName))
|
|
||||||
flush()
|
|
||||||
close()
|
|
||||||
}
|
|
||||||
/** 插入 xposed_init 代码 */
|
/** 插入 xposed_init 代码 */
|
||||||
codeGenerator.createNewFile(
|
createCodeFile(
|
||||||
dependencies = Dependencies.ALL_FILES,
|
fileName = data.xInitClassName,
|
||||||
packageName = packageName,
|
packageName = data.entryPackageName,
|
||||||
fileName = xInitClassName
|
content = data.sources()["xposed_init"]
|
||||||
).apply {
|
)
|
||||||
write(CodeSourceFileTemplate.getXposedInitFileByteArray(packageName, entryClassName, xInitClassName, isUsingResourcesHook))
|
|
||||||
flush()
|
|
||||||
close()
|
|
||||||
}
|
|
||||||
/** 插入 xposed_init_Impl 代码 */
|
/** 插入 xposed_init_Impl 代码 */
|
||||||
codeGenerator.createNewFile(
|
createCodeFile(
|
||||||
dependencies = Dependencies.ALL_FILES,
|
fileName = "${data.entryClassName}_Impl",
|
||||||
packageName = packageName,
|
packageName = data.entryPackageName,
|
||||||
fileName = "${entryClassName}_Impl"
|
content = data.sources()["xposed_init_Impl"]
|
||||||
).apply {
|
)
|
||||||
write(CodeSourceFileTemplate.getXposedInitImplFileByteArray(packageName, modulePackageName, customMPackageName, entryClassName))
|
|
||||||
flush()
|
|
||||||
close()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* 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/9/20.
|
||||||
|
*/
|
||||||
|
package com.highcapable.yukihookapi_ksp_xposed.bean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成的模板数据实例
|
||||||
|
* @param entryPackageName 入口类包名
|
||||||
|
* @param injectPackageName 注入类包名
|
||||||
|
* @param modulePackageName 模块包名 (命名空间)
|
||||||
|
* @param customMPackageName 自定义模块包名
|
||||||
|
* @param entryClassName 入口类名
|
||||||
|
* @param xInitClassName xposed_init 入口类名
|
||||||
|
* @param isUsingResourcesHook 是否启用 Resources Hook
|
||||||
|
*/
|
||||||
|
data class GenerateData(
|
||||||
|
var entryPackageName: String = "",
|
||||||
|
var injectPackageName: String = "",
|
||||||
|
var modulePackageName: String = "",
|
||||||
|
var customMPackageName: String = "",
|
||||||
|
var entryClassName: String = "",
|
||||||
|
var xInitClassName: String = "",
|
||||||
|
var isUsingResourcesHook: Boolean = true
|
||||||
|
)
|
@@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* 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/9/20.
|
||||||
|
*/
|
||||||
|
package com.highcapable.yukihookapi_ksp_xposed.factory
|
||||||
|
|
||||||
|
import com.highcapable.yukihookapi_ksp_xposed.bean.GenerateData
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建文件注释
|
||||||
|
* @param entryClassName 入口类名 - 空则不生成
|
||||||
|
* @param currrentClassTag 当前注入类标签
|
||||||
|
* @return [String]
|
||||||
|
*/
|
||||||
|
private fun createCommentContent(entryClassName: String = "", currrentClassTag: String) =
|
||||||
|
("/**\n" +
|
||||||
|
" * $currrentClassTag Inject Class\n" +
|
||||||
|
" *\n" +
|
||||||
|
" * Compiled from YukiHookXposedProcessor\n" +
|
||||||
|
" *\n" +
|
||||||
|
(if (entryClassName.isNotBlank()) " * HookEntryClass: [$entryClassName]\n *\n" else "") +
|
||||||
|
" * 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")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得注入文件代码内容
|
||||||
|
* @return [Map]<[String],[String]>
|
||||||
|
*/
|
||||||
|
fun GenerateData.sources() = mapOf(
|
||||||
|
"ModuleApplication_Injector" to ("@file:Suppress(\"ClassName\")\n" +
|
||||||
|
"\n" +
|
||||||
|
"package $entryPackageName\n" +
|
||||||
|
"\n" +
|
||||||
|
"import $entryPackageName.$entryClassName\n" +
|
||||||
|
"\n" +
|
||||||
|
createCommentContent(entryClassName, currrentClassTag = "ModuleApplication") +
|
||||||
|
"object ModuleApplication_Injector {\n" +
|
||||||
|
"\n" +
|
||||||
|
" @JvmStatic\n" +
|
||||||
|
" fun callApiInit() = try {\n" +
|
||||||
|
" $entryClassName().onInit()\n" +
|
||||||
|
" } catch (_: Throwable) {\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}"),
|
||||||
|
"YukiHookBridge_Injector" to ("@file:Suppress(\"ClassName\")\n" +
|
||||||
|
"\n" +
|
||||||
|
"package $entryPackageName\n" +
|
||||||
|
"\n" +
|
||||||
|
createCommentContent(currrentClassTag = "YukiHookBridge") +
|
||||||
|
"object YukiHookBridge_Injector {\n" +
|
||||||
|
"\n" +
|
||||||
|
" @JvmStatic\n" +
|
||||||
|
" fun getModuleGeneratedVersion() = \"${System.currentTimeMillis()}\"\n" +
|
||||||
|
"}"),
|
||||||
|
"xposed_init" to ("@file:Suppress(\"ClassName\")\n" +
|
||||||
|
"\n" +
|
||||||
|
"package $entryPackageName\n" +
|
||||||
|
"\n" +
|
||||||
|
"import androidx.annotation.Keep\n" +
|
||||||
|
"import com.highcapable.yukihookapi.hook.xposed.bridge.event.YukiXposedEvent\n" +
|
||||||
|
"import com.highcapable.yukihookapi.annotation.YukiGenerateApi\n" +
|
||||||
|
(if (isUsingResourcesHook) "import de.robv.android.xposed.IXposedHookInitPackageResources\n" else "") +
|
||||||
|
"import de.robv.android.xposed.IXposedHookLoadPackage\n" +
|
||||||
|
"import de.robv.android.xposed.IXposedHookZygoteInit\n" +
|
||||||
|
(if (isUsingResourcesHook) "import de.robv.android.xposed.callbacks.XC_InitPackageResources\n" else "") +
|
||||||
|
"import de.robv.android.xposed.callbacks.XC_LoadPackage\n" +
|
||||||
|
"\n" +
|
||||||
|
createCommentContent(entryClassName, currrentClassTag = "Xposed Init") +
|
||||||
|
"@Keep\n" +
|
||||||
|
"@YukiGenerateApi\n" +
|
||||||
|
"class $xInitClassName : IXposedHookZygoteInit, IXposedHookLoadPackage" +
|
||||||
|
"${if (isUsingResourcesHook) ", IXposedHookInitPackageResources" else ""} {\n" +
|
||||||
|
"\n" +
|
||||||
|
" override fun initZygote(sparam: IXposedHookZygoteInit.StartupParam?) {\n" +
|
||||||
|
" ${entryClassName}_Impl.callInitZygote(sparam)\n" +
|
||||||
|
" YukiXposedEvent.EventHandler.callInitZygote(sparam)\n" +
|
||||||
|
" }\n" +
|
||||||
|
"\n" +
|
||||||
|
" override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {\n" +
|
||||||
|
" ${entryClassName}_Impl.callHandleLoadPackage(lpparam)\n" +
|
||||||
|
" YukiXposedEvent.EventHandler.callHandleLoadPackage(lpparam)\n" +
|
||||||
|
" }\n" +
|
||||||
|
(if (isUsingResourcesHook)
|
||||||
|
("\n override fun handleInitPackageResources(resparam: XC_InitPackageResources.InitPackageResourcesParam?) {\n" +
|
||||||
|
" ${entryClassName}_Impl.callHandleInitPackageResources(resparam)\n" +
|
||||||
|
" YukiXposedEvent.EventHandler.callHandleInitPackageResources(resparam)\n" +
|
||||||
|
" }\n") else "") +
|
||||||
|
"}"),
|
||||||
|
"xposed_init_Impl" to ("@file:Suppress(\"ClassName\")\n" +
|
||||||
|
"\n" +
|
||||||
|
"package $entryPackageName\n" +
|
||||||
|
"\n" +
|
||||||
|
"import com.highcapable.yukihookapi.annotation.YukiGenerateApi\n" +
|
||||||
|
"import com.highcapable.yukihookapi.hook.log.loggerE\n" +
|
||||||
|
"import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookBridge\n" +
|
||||||
|
"import de.robv.android.xposed.IXposedHookZygoteInit\n" +
|
||||||
|
"import de.robv.android.xposed.callbacks.XC_InitPackageResources\n" +
|
||||||
|
"import de.robv.android.xposed.callbacks.XC_LoadPackage\n" +
|
||||||
|
(if (customMPackageName.isBlank()) "import $modulePackageName.BuildConfig\n" else "") +
|
||||||
|
"\n" +
|
||||||
|
createCommentContent(entryClassName, currrentClassTag = "Xposed Init Impl") +
|
||||||
|
"@YukiGenerateApi\n" +
|
||||||
|
"object ${entryClassName}_Impl {\n" +
|
||||||
|
"\n" +
|
||||||
|
" private const val modulePackageName = " +
|
||||||
|
(if (customMPackageName.isNotBlank()) "\"$customMPackageName\"" else "BuildConfig.APPLICATION_ID") + "\n" +
|
||||||
|
"\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" +
|
||||||
|
" resparam: XC_InitPackageResources.InitPackageResourcesParam? = null\n" +
|
||||||
|
" ) {\n" +
|
||||||
|
" if (isZygoteBinded.not()) runCatching {\n" +
|
||||||
|
" hookEntry.onXposedEvent()\n" +
|
||||||
|
" hookEntry.onInit()\n" +
|
||||||
|
" if (YukiHookBridge.isXposedCallbackSetUp) {\n" +
|
||||||
|
" loggerE(msg = \"You cannot load a hooker in \\\"onInit\\\" or \\\"onXposedEvent\\\" method! Aborted\")\n" +
|
||||||
|
" return\n" +
|
||||||
|
" }\n" +
|
||||||
|
" hookEntry.onHook()\n" +
|
||||||
|
" YukiHookBridge.callXposedInitialized()\n" +
|
||||||
|
" YukiHookBridge.modulePackageName = modulePackageName\n" +
|
||||||
|
" }.onFailure { loggerE(msg = \"YukiHookAPI try to load HookEntryClass failed\", e = it) }\n" +
|
||||||
|
" YukiHookBridge.callXposedLoaded(isZygoteLoaded, lpparam, resparam)\n" +
|
||||||
|
" }\n" +
|
||||||
|
"\n" +
|
||||||
|
" @YukiGenerateApi\n" +
|
||||||
|
" fun callInitZygote(sparam: IXposedHookZygoteInit.StartupParam?) {\n" +
|
||||||
|
" if (sparam == null) return\n" +
|
||||||
|
" runCatching {\n" +
|
||||||
|
" YukiHookBridge.callXposedZygoteLoaded(sparam)\n" +
|
||||||
|
" }.onFailure { loggerE(msg = \"YukiHookAPI bind initZygote failed\", e = it) }\n" +
|
||||||
|
" callXposedLoaded(isZygoteLoaded = true)\n" +
|
||||||
|
" isZygoteBinded = true\n" +
|
||||||
|
" }\n" +
|
||||||
|
"\n" +
|
||||||
|
" @YukiGenerateApi\n" +
|
||||||
|
" fun callHandleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {\n" +
|
||||||
|
" if (lpparam != null) callXposedLoaded(lpparam = lpparam)\n" +
|
||||||
|
" }\n" +
|
||||||
|
"\n" +
|
||||||
|
" @YukiGenerateApi\n" +
|
||||||
|
" fun callHandleInitPackageResources(resparam: XC_InitPackageResources.InitPackageResourcesParam?) {\n" +
|
||||||
|
" if (resparam != null) callXposedLoaded(resparam = resparam)\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}")
|
||||||
|
)
|
@@ -1,214 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得文件注释
|
|
||||||
* @param entryClassName 入口类名 - 空则不生成
|
|
||||||
* @param currrentClassTag 当前注入类标签
|
|
||||||
* @return [String]
|
|
||||||
*/
|
|
||||||
private fun getCommentContent(entryClassName: String = "", currrentClassTag: String) =
|
|
||||||
("/**\n" +
|
|
||||||
" * $currrentClassTag Inject Class\n" +
|
|
||||||
" *\n" +
|
|
||||||
" * Compiled from YukiHookXposedProcessor\n" +
|
|
||||||
" *\n" +
|
|
||||||
(if (entryClassName.isNotBlank()) " * HookEntryClass: [$entryClassName]\n *\n" else "") +
|
|
||||||
" * 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()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得 YukiHookBridge_Injector 注入文件
|
|
||||||
* @param packageName 包名
|
|
||||||
* @return [ByteArray]
|
|
||||||
*/
|
|
||||||
fun getYukiHookBridgeInjectorFileByteArray(packageName: String) =
|
|
||||||
("@file:Suppress(\"ClassName\")\n" +
|
|
||||||
"\n" +
|
|
||||||
"package $packageName\n" +
|
|
||||||
"\n" +
|
|
||||||
getCommentContent(currrentClassTag = "YukiHookBridge") +
|
|
||||||
"object YukiHookBridge_Injector {\n" +
|
|
||||||
"\n" +
|
|
||||||
" @JvmStatic\n" +
|
|
||||||
" fun getModuleGeneratedVersion() = \"${System.currentTimeMillis()}\"\n" +
|
|
||||||
"}").toByteArray()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得 xposed_init 注入文件
|
|
||||||
* @param packageName 包名
|
|
||||||
* @param entryClassName 入口类名
|
|
||||||
* @param xInitClassName xposed_init 入口类名
|
|
||||||
* @param isUsingResourcesHook 是否启用 Resources Hook
|
|
||||||
* @return [ByteArray]
|
|
||||||
*/
|
|
||||||
fun getXposedInitFileByteArray(packageName: String, entryClassName: String, xInitClassName: String, isUsingResourcesHook: Boolean) =
|
|
||||||
("@file:Suppress(\"ClassName\")\n" +
|
|
||||||
"\n" +
|
|
||||||
"package $packageName\n" +
|
|
||||||
"\n" +
|
|
||||||
"import androidx.annotation.Keep\n" +
|
|
||||||
"import com.highcapable.yukihookapi.hook.xposed.bridge.event.YukiXposedEvent\n" +
|
|
||||||
"import com.highcapable.yukihookapi.annotation.YukiGenerateApi\n" +
|
|
||||||
(if (isUsingResourcesHook) "import de.robv.android.xposed.IXposedHookInitPackageResources\n" else "") +
|
|
||||||
"import de.robv.android.xposed.IXposedHookLoadPackage\n" +
|
|
||||||
"import de.robv.android.xposed.IXposedHookZygoteInit\n" +
|
|
||||||
(if (isUsingResourcesHook) "import de.robv.android.xposed.callbacks.XC_InitPackageResources\n" else "") +
|
|
||||||
"import de.robv.android.xposed.callbacks.XC_LoadPackage\n" +
|
|
||||||
"\n" +
|
|
||||||
getCommentContent(entryClassName, currrentClassTag = "Xposed Init") +
|
|
||||||
"@Keep\n" +
|
|
||||||
"@YukiGenerateApi\n" +
|
|
||||||
"class $xInitClassName : IXposedHookZygoteInit, IXposedHookLoadPackage" +
|
|
||||||
"${if (isUsingResourcesHook) ", IXposedHookInitPackageResources" else ""} {\n" +
|
|
||||||
"\n" +
|
|
||||||
" override fun initZygote(sparam: IXposedHookZygoteInit.StartupParam?) {\n" +
|
|
||||||
" ${entryClassName}_Impl.callInitZygote(sparam)\n" +
|
|
||||||
" YukiXposedEvent.EventHandler.callInitZygote(sparam)\n" +
|
|
||||||
" }\n" +
|
|
||||||
"\n" +
|
|
||||||
" override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {\n" +
|
|
||||||
" ${entryClassName}_Impl.callHandleLoadPackage(lpparam)\n" +
|
|
||||||
" YukiXposedEvent.EventHandler.callHandleLoadPackage(lpparam)\n" +
|
|
||||||
" }\n" +
|
|
||||||
(if (isUsingResourcesHook)
|
|
||||||
("\n override fun handleInitPackageResources(resparam: XC_InitPackageResources.InitPackageResourcesParam?) {\n" +
|
|
||||||
" ${entryClassName}_Impl.callHandleInitPackageResources(resparam)\n" +
|
|
||||||
" YukiXposedEvent.EventHandler.callHandleInitPackageResources(resparam)\n" +
|
|
||||||
" }\n") else "") +
|
|
||||||
"}").toByteArray()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得 xposed_init_Impl 注入文件
|
|
||||||
* @param packageName 包名
|
|
||||||
* @param modulePackageName 模块包名
|
|
||||||
* @param customMPackageName 自定义模块包名
|
|
||||||
* @param entryClassName 入口类名
|
|
||||||
* @return [ByteArray]
|
|
||||||
*/
|
|
||||||
fun getXposedInitImplFileByteArray(packageName: String, modulePackageName: String, customMPackageName: String, entryClassName: String) =
|
|
||||||
("@file:Suppress(\"ClassName\")\n" +
|
|
||||||
"\n" +
|
|
||||||
"package $packageName\n" +
|
|
||||||
"\n" +
|
|
||||||
"import com.highcapable.yukihookapi.annotation.YukiGenerateApi\n" +
|
|
||||||
"import com.highcapable.yukihookapi.hook.log.loggerE\n" +
|
|
||||||
"import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookBridge\n" +
|
|
||||||
"import de.robv.android.xposed.IXposedHookZygoteInit\n" +
|
|
||||||
"import de.robv.android.xposed.callbacks.XC_InitPackageResources\n" +
|
|
||||||
"import de.robv.android.xposed.callbacks.XC_LoadPackage\n" +
|
|
||||||
(if (customMPackageName.isBlank()) "import $modulePackageName.BuildConfig\n" else "") +
|
|
||||||
"\n" +
|
|
||||||
getCommentContent(entryClassName, currrentClassTag = "Xposed Init Impl") +
|
|
||||||
"@YukiGenerateApi\n" +
|
|
||||||
"object ${entryClassName}_Impl {\n" +
|
|
||||||
"\n" +
|
|
||||||
" private const val modulePackageName = " +
|
|
||||||
(if (customMPackageName.isNotBlank()) "\"$customMPackageName\"" else "BuildConfig.APPLICATION_ID") + "\n" +
|
|
||||||
"\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" +
|
|
||||||
" resparam: XC_InitPackageResources.InitPackageResourcesParam? = null\n" +
|
|
||||||
" ) {\n" +
|
|
||||||
" if (isZygoteBinded.not()) runCatching {\n" +
|
|
||||||
" hookEntry.onXposedEvent()\n" +
|
|
||||||
" hookEntry.onInit()\n" +
|
|
||||||
" if (YukiHookBridge.isXposedCallbackSetUp) {\n" +
|
|
||||||
" loggerE(msg = \"You cannot load a hooker in \\\"onInit\\\" or \\\"onXposedEvent\\\" method! Aborted\")\n" +
|
|
||||||
" return\n" +
|
|
||||||
" }\n" +
|
|
||||||
" hookEntry.onHook()\n" +
|
|
||||||
" YukiHookBridge.callXposedInitialized()\n" +
|
|
||||||
" YukiHookBridge.modulePackageName = modulePackageName\n" +
|
|
||||||
" }.onFailure { loggerE(msg = \"YukiHookAPI try to load HookEntryClass failed\", e = it) }\n" +
|
|
||||||
" YukiHookBridge.callXposedLoaded(isZygoteLoaded, lpparam, resparam)\n" +
|
|
||||||
" }\n" +
|
|
||||||
"\n" +
|
|
||||||
" @YukiGenerateApi\n" +
|
|
||||||
" fun callInitZygote(sparam: IXposedHookZygoteInit.StartupParam?) {\n" +
|
|
||||||
" if (sparam == null) return\n" +
|
|
||||||
" runCatching {\n" +
|
|
||||||
" YukiHookBridge.callXposedZygoteLoaded(sparam)\n" +
|
|
||||||
" }.onFailure { loggerE(msg = \"YukiHookAPI bind initZygote failed\", e = it) }\n" +
|
|
||||||
" callXposedLoaded(isZygoteLoaded = true)\n" +
|
|
||||||
" isZygoteBinded = true\n" +
|
|
||||||
" }\n" +
|
|
||||||
"\n" +
|
|
||||||
" @YukiGenerateApi\n" +
|
|
||||||
" fun callHandleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {\n" +
|
|
||||||
" if (lpparam != null) callXposedLoaded(lpparam = lpparam)\n" +
|
|
||||||
" }\n" +
|
|
||||||
"\n" +
|
|
||||||
" @YukiGenerateApi\n" +
|
|
||||||
" fun callHandleInitPackageResources(resparam: XC_InitPackageResources.InitPackageResourcesParam?) {\n" +
|
|
||||||
" if (resparam != null) callXposedLoaded(resparam = resparam)\n" +
|
|
||||||
" }\n" +
|
|
||||||
"}").toByteArray()
|
|
||||||
}
|
|
Reference in New Issue
Block a user