diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 248fc390..25ec9e94 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -10,6 +10,21 @@
android:supportsRtl="true"
android:theme="@style/Theme.YukiHookAPI">
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/com/highcapable/yukihookapi/demo/Yuu.kt b/app/src/main/java/com/highcapable/yukihookapi/demo/Yuu.kt
new file mode 100644
index 00000000..3107dcad
--- /dev/null
+++ b/app/src/main/java/com/highcapable/yukihookapi/demo/Yuu.kt
@@ -0,0 +1,9 @@
+package com.highcapable.yukihookapi.demo
+
+import com.highcapable.yukihookapi.hook.init.YukiHookLoadPackage
+
+class Yuu : YukiHookLoadPackage() {
+
+ override fun onHookStart() {
+ }
+}
\ No newline at end of file
diff --git a/yukihookapi/build.gradle b/yukihookapi/build.gradle
index f89d6544..da80ad4e 100644
--- a/yukihookapi/build.gradle
+++ b/yukihookapi/build.gradle
@@ -32,6 +32,7 @@ android {
dependencies {
// Used 82 API Version
compileOnly fileTree(include: ['api-82.jar'], dir: 'libs')
+ implementation 'androidx.appcompat:appcompat:1.4.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
diff --git a/yukihookapi/src/main/assets/xposed_init b/yukihookapi/src/main/assets/xposed_init
new file mode 100644
index 00000000..1d697fdd
--- /dev/null
+++ b/yukihookapi/src/main/assets/xposed_init
@@ -0,0 +1 @@
+com.highcapable.yukihookapi.hook.init.YukiHookLoadPackage
\ No newline at end of file
diff --git a/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/YukiHookCreater.kt b/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/YukiHookCreater.kt
new file mode 100644
index 00000000..0fdb6a9c
--- /dev/null
+++ b/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/YukiHookCreater.kt
@@ -0,0 +1,63 @@
+/**
+ * MIT License
+ *
+ * Copyright (C) 2022 HighCapable
+ *
+ * This file is part of YukiHookAPI.
+ *
+ * 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/2/2.
+ */
+package com.highcapable.yukihookapi.hook
+
+import com.highcapable.yukihookapi.param.HookParam
+import com.highcapable.yukihookapi.param.PackageParam
+import java.lang.reflect.Constructor
+import java.lang.reflect.Method
+
+class YukiHookCreater(private val param: PackageParam) {
+
+ var grabMethod: Method? = null
+ var grabConstructor: Constructor<*>? = null
+
+ fun beforeHook(initiate: HookParam.() -> Unit) {
+
+ }
+
+ fun afterHook(initiate: HookParam.() -> Unit) {
+
+ }
+
+ fun replaceHook(initiate: HookParam.() -> Any?) {
+
+ }
+
+ fun replaceTo(any: Any?) {
+
+ }
+
+ fun intercept() {
+
+ }
+
+ fun hook() {
+
+ }
+}
\ No newline at end of file
diff --git a/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/factory/ReflectFactory.kt b/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/factory/ReflectFactory.kt
new file mode 100644
index 00000000..2bfc85e5
--- /dev/null
+++ b/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/factory/ReflectFactory.kt
@@ -0,0 +1,32 @@
+/**
+ * MIT License
+ *
+ * Copyright (C) 2022 HighCapable
+ *
+ * This file is part of YukiHookAPI.
+ *
+ * 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/2/2.
+ */
+package com.highcapable.yukihookapi.hook.factory
+
+import com.highcapable.yukihookapi.hook.YukiHookCreater
+
+fun Class<*>.hook(it: YukiHookCreater.() -> Unit) = YukiHookCreater().apply(it).hook()
\ No newline at end of file
diff --git a/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/helper/YukiHookHelper.kt b/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/helper/YukiHookHelper.kt
new file mode 100644
index 00000000..dc694b21
--- /dev/null
+++ b/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/helper/YukiHookHelper.kt
@@ -0,0 +1,52 @@
+/**
+ * MIT License
+ *
+ * Copyright (C) 2022 HighCapable
+ *
+ * This file is part of YukiHookAPI.
+ *
+ * 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/2/2.
+ */
+package com.highcapable.yukihookapi.hook.helper
+
+import com.highcapable.yukihookapi.param.PackageParam
+
+/**
+ * YukiHook 的装载 API 调用类
+ * 可以实现作为模块装载和 Hook 自身 APP 两种方式
+ */
+object YukiHookHelper {
+
+ /**
+ * 自身作为模块装载调用入口方法
+ * @param initiate Hook 方法体
+ */
+ fun onHookApp(initiate: PackageParam.() -> Unit) {
+
+ }
+
+ /**
+ * 作为侵入式 Hook 自身装载调用入口方法
+ * 正在开发敬请期待。
+ * @param initiate Hook 方法体
+ */
+ fun onHookSelf(initiate: PackageParam.() -> Unit) {}
+}
\ No newline at end of file
diff --git a/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/init/YukiHookLoadPackage.kt b/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/init/YukiHookLoadPackage.kt
new file mode 100644
index 00000000..be8b86af
--- /dev/null
+++ b/yukihookapi/src/main/java/com/highcapable/yukihookapi/hook/init/YukiHookLoadPackage.kt
@@ -0,0 +1,46 @@
+/**
+ * MIT License
+ *
+ * Copyright (C) 2022 HighCapable
+ *
+ * This file is part of YukiHookAPI.
+ *
+ * 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/2/2.
+ */
+package com.highcapable.yukihookapi.hook.init
+
+import androidx.annotation.Keep
+import com.highcapable.yukihookapi.hook.helper.YukiHookHelper
+import de.robv.android.xposed.IXposedHookLoadPackage
+import de.robv.android.xposed.callbacks.XC_LoadPackage
+
+/**
+ * 接管 Xposed 的 [IXposedHookLoadPackage] 入口
+ * 你可以使用 [YukiHookHelper] 来监听模块开始装载
+ */
+@Keep
+class YukiHookLoadPackage : IXposedHookLoadPackage {
+
+ override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {
+ if (lpparam == null) return
+
+ }
+}
\ No newline at end of file
diff --git a/yukihookapi/src/main/java/com/highcapable/yukihookapi/param/HookParam.kt b/yukihookapi/src/main/java/com/highcapable/yukihookapi/param/HookParam.kt
index 64b5684c..3ecd686b 100644
--- a/yukihookapi/src/main/java/com/highcapable/yukihookapi/param/HookParam.kt
+++ b/yukihookapi/src/main/java/com/highcapable/yukihookapi/param/HookParam.kt
@@ -25,7 +25,132 @@
*
* This file is Created by fankes on 2022/2/2.
*/
+@file:Suppress("unused", "MemberVisibilityCanBePrivate")
+
package com.highcapable.yukihookapi.param
-class HookParam {
+import de.robv.android.xposed.XC_MethodHook
+import java.lang.reflect.Constructor
+import java.lang.reflect.Method
+
+/**
+ * Hook 方法、构造类的目标对象实现类
+ * @param instance 对接 Xposed API 的 [XC_MethodHook.MethodHookParam]
+ */
+class HookParam(private val instance: XC_MethodHook.MethodHookParam) {
+
+ /**
+ * 获取 Hook 方法的参数对象数组
+ * @return [Array]
+ */
+ val args get() = instance.args ?: arrayOf(0)
+
+ /**
+ * 获取 Hook 方法的参数对象数组第一位
+ * @return [Array]
+ * @throws IllegalStateException 如果数组为空或对象为空
+ */
+ val firstArgs get() = args[0] ?: error("HookParam args[0] with a non-null object")
+
+ /**
+ * 获取 Hook 方法的参数对象数组最后一位
+ * @return [Array]
+ * @throws IllegalStateException 如果数组为空或对象为空
+ */
+ val lastArgs get() = args[args.lastIndex] ?: error("HookParam args[lastIndex] with a non-null object")
+
+ /**
+ * 获取 Hook 实例的 Class
+ * @return [Class]
+ */
+ val thisClass get() = instance.thisObject.javaClass
+
+ /**
+ * 获取 Hook 实例的对象
+ * @return [Any]
+ * @throws IllegalStateException 如果对象为空
+ */
+ val thisAny get() = instance.thisObject ?: error("HookParam must with a non-null object")
+
+ /**
+ * 获取 Hook 当前普通方法
+ * @return [Method]
+ * @throws IllegalStateException 如果方法为空或方法类型不是 [Method]
+ */
+ val method get() = instance.method as? Method? ?: error("Current hook method type is wrong or null")
+
+ /**
+ * 获取 Hook 当前构造方法
+ * @return [Constructor]
+ * @throws IllegalStateException 如果方法为空或方法类型不是 [Constructor]
+ */
+ val constructor get() = instance.method as? Constructor<*>? ?: error("Current hook constructor type is wrong or null")
+
+ /**
+ * 获取、设置 Hook 方法的返回值
+ * @return [Any] or null
+ */
+ var result: Any?
+ get() = instance.result
+ set(value) {
+ instance.result = value
+ }
+
+ /**
+ * 获取 Hook 实例的对象 [T]
+ * @return [Any]
+ * @throws IllegalStateException 如果对象为空或对象类型不是 [T]
+ */
+ inline fun thisAny() = thisAny as? T? ?: error("HookParam object cannot cast to ${T::class.java.name}")
+
+ /**
+ * 获取 Hook 方法的参数实例化对象类
+ * @param index 参数对象数组下标 - 默认是 0
+ * @return [Array]
+ */
+ fun args(index: Int = 0) = ArgsModifyer(index)
+
+ /**
+ * 拦截整个方法体
+ * 此方法将强制设置方法体的 [result] 为 null
+ */
+ fun intercept() {
+ result = null
+ }
+
+ /**
+ * 对方法参数的修改进行实例化类
+ * @param index 参数对象数组下标
+ */
+ inner class ArgsModifyer(private val index: Int) {
+
+ /**
+ * 设置方法参数的实例对象
+ * @param any 实例对象
+ * @throws IllegalStateException 如果目标方法参数对象数组为空或 [index] 下标不存在
+ */
+ fun set(any: T?) {
+ if (args.isEmpty()) error("HookParam method args is empty,mabe not has args")
+ if (index > args.lastIndex) error("HookParam method args index out of bounds,max is ${args.lastIndex}")
+ instance.args[index] = any
+ }
+
+ /**
+ * 设置方法参数的实例对象为 null
+ * 此方法可以将任何被 Hook 的目标对象设置为空
+ */
+ fun setNull() = set(null)
+
+ /**
+ * 设置方法参数的实例对象为 true
+ * 请确保目标对象的类型是 [Boolean] 不然会出错
+ */
+ fun setTrue() = set(true)
+
+ /**
+ * 设置方法参数的实例对象为 false
+ * 请确保目标对象的类型是 [Boolean] 不然会出错
+ */
+ fun setFalse() = set(false)
+ }
}
\ No newline at end of file
diff --git a/yukihookapi/src/main/java/com/highcapable/yukihookapi/param/PackageParam.kt b/yukihookapi/src/main/java/com/highcapable/yukihookapi/param/PackageParam.kt
new file mode 100644
index 00000000..b9d6f03d
--- /dev/null
+++ b/yukihookapi/src/main/java/com/highcapable/yukihookapi/param/PackageParam.kt
@@ -0,0 +1,52 @@
+@file:Suppress("unused", "MemberVisibilityCanBePrivate")
+
+package com.highcapable.yukihookapi.param
+
+import android.content.pm.ApplicationInfo
+import de.robv.android.xposed.callbacks.XC_LoadPackage
+
+/**
+ * 装载 Hook 的目标 APP 入口对象实现类
+ * 如果是侵入式 Hook 自身 APP 可将参数 [instance] 置空获得当前类的 [ClassLoader]
+ * @param instance 对接 Xposed API 的 [XC_LoadPackage.LoadPackageParam]
+ */
+class PackageParam(private val instance: XC_LoadPackage.LoadPackageParam? = null) {
+
+ /** 当前 classLoader */
+ private var privateClassLoader = instance?.classLoader ?: javaClass.classLoader
+
+ /**
+ * 获取、设置当前 APP 的 [ClassLoader]
+ * @return [ClassLoader]
+ */
+ var appClassLoader: ClassLoader
+ get() = privateClassLoader
+ set(value) {
+ privateClassLoader = value
+ }
+
+ /**
+ * 获取当前 APP 的 [ApplicationInfo]
+ * @return [ApplicationInfo]
+ */
+ val appInfo get() = instance?.appInfo ?: ApplicationInfo()
+
+ /**
+ * 获取当前 APP 的进程名称
+ * 默认的进程名称是 [packageName]
+ * @return [String]
+ */
+ val processName get() = instance?.processName ?: ""
+
+ /**
+ * 获取当前 APP 的包名
+ * @return [String]
+ */
+ val packageName get() = instance?.packageName ?: ""
+
+ /**
+ * 获取当前 APP 是否为第一个 Application
+ * @return [Boolean]
+ */
+ val isFirstApplication get() = instance?.isFirstApplication ?: true
+}
\ No newline at end of file