...
3
.idea/compiler.xml
generated
@@ -2,7 +2,8 @@
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="1.8">
|
||||
<module name="YukiHookAPI.app" target="11" />
|
||||
<module name="YukiHookAPI.app_demo" target="11" />
|
||||
<module name="YukiHookAPI.module_demo" target="11" />
|
||||
<module name="YukiHookAPI.yukihookapi-yaya" target="11" />
|
||||
</bytecodeTargetLevel>
|
||||
</component>
|
||||
|
3
.idea/gradle.xml
generated
@@ -10,7 +10,8 @@
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
<option value="$PROJECT_DIR$/app_demo" />
|
||||
<option value="$PROJECT_DIR$/module_demo" />
|
||||
<option value="$PROJECT_DIR$/yukihookapi" />
|
||||
<option value="$PROJECT_DIR$/yukihookapi-ksp-xposed" />
|
||||
</set>
|
||||
|
3
.idea/misc.xml
generated
@@ -4,6 +4,9 @@
|
||||
<option name="filePathToZoomLevelMap">
|
||||
<map>
|
||||
<entry key="app/src/main/res/layout/activity_main.xml" value="0.4169230769230769" />
|
||||
<entry key="app_demo/src/main/res/layout/activity_main.xml" value="0.4375" />
|
||||
<entry key="demo/src/main/res/layout/activity_main.xml" value="0.4375" />
|
||||
<entry key="module_demo/src/main/res/layout/activity_main.xml" value="0.4375" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
|
@@ -1,24 +0,0 @@
|
||||
package com.highcapable.yukihookapi
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.highcapable.yukihookapi", appContext.packageName)
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
com.highcapable.yukihookapi.demo.hook.inject.MainInjecter_YukiHookXposedInit
|
@@ -1,52 +0,0 @@
|
||||
/**
|
||||
* 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/7.
|
||||
*/
|
||||
@file:Suppress("unused")
|
||||
|
||||
package com.highcapable.yukihookapi.demo
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import com.highcapable.yukihookapi.YukiHookAPI
|
||||
import com.highcapable.yukihookapi.demo.hook.MainHooker
|
||||
import com.highcapable.yukihookapi.demo.hook.SecondHooker
|
||||
|
||||
class App : Application() {
|
||||
|
||||
override fun attachBaseContext(base: Context?) {
|
||||
////
|
||||
// 装载你的 Hook 框架的代码
|
||||
////
|
||||
// 方式 1
|
||||
YukiHookAPI.encase(base) {
|
||||
// Your code here.
|
||||
}
|
||||
// 方式 2
|
||||
YukiHookAPI.encase(base, MainHooker(), SecondHooker())
|
||||
super.attachBaseContext(base)
|
||||
}
|
||||
}
|
@@ -1,55 +0,0 @@
|
||||
/**
|
||||
* 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/8.
|
||||
*/
|
||||
package com.highcapable.yukihookapi.demo
|
||||
|
||||
import androidx.annotation.Keep
|
||||
|
||||
// for test
|
||||
@Keep
|
||||
class InjectLucky {
|
||||
|
||||
// for test
|
||||
@Keep
|
||||
private var string = "没有"
|
||||
|
||||
// for test
|
||||
@Keep
|
||||
constructor() {
|
||||
string = "原始数据"
|
||||
}
|
||||
|
||||
// for test
|
||||
@Keep
|
||||
constructor(string: String = "原始数据复写") {
|
||||
this.string = string
|
||||
}
|
||||
|
||||
// for test
|
||||
@Keep
|
||||
fun getString() = string
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
/**
|
||||
* 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/8.
|
||||
*/
|
||||
package com.highcapable.yukihookapi.demo
|
||||
|
||||
import androidx.annotation.Keep
|
||||
|
||||
// for test
|
||||
@Keep
|
||||
class InjectNoParamTest {
|
||||
|
||||
@Keep
|
||||
private var test = "没有"
|
||||
|
||||
init {
|
||||
test = "没修改的变量"
|
||||
}
|
||||
|
||||
// for test
|
||||
@Keep
|
||||
fun getString() = test
|
||||
}
|
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* 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/3.
|
||||
*/
|
||||
package com.highcapable.yukihookapi.demo
|
||||
|
||||
import androidx.annotation.Keep
|
||||
|
||||
// for test
|
||||
@Keep
|
||||
class InjectTestName(private val string: String) {
|
||||
|
||||
// for test
|
||||
@Keep
|
||||
fun getString() = string
|
||||
}
|
@@ -1,111 +0,0 @@
|
||||
/**
|
||||
* 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/1/29.
|
||||
*/
|
||||
@file:Suppress("SameParameterValue")
|
||||
|
||||
package com.highcapable.yukihookapi.demo
|
||||
|
||||
import android.os.Bundle
|
||||
import android.widget.Button
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.Keep
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.highcapable.yukihookapi.hook.factory.modulePrefs
|
||||
import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus
|
||||
|
||||
@Keep
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
@Keep
|
||||
private var a = "没更改的变量"
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
// for test
|
||||
findViewById<Button>(R.id.main_button).setOnClickListener {
|
||||
modulePrefs.apply {
|
||||
putString("data", "这是存储的数据")
|
||||
putBoolean("test_key", true)
|
||||
putString("test_key_name", "存储数据成功,包名:$packageName")
|
||||
}
|
||||
Toast.makeText(this, "存储完成", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
// for test
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle("Hook 方法返回值测试")
|
||||
.setMessage(test() + "\n变量:$a\n模块数据:${xptest()}\n模块是否已激活:${YukiHookModuleStatus.isActive()}")
|
||||
.setPositiveButton("下一个") { _, _ ->
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle("Hook 方法参数测试")
|
||||
.setMessage(test("这是没有更改的文字") + "\n${a(content = "这是原文")}\n模块是否已激活:${YukiHookModuleStatus.isActive()}")
|
||||
.setPositiveButton("下一个") { _, _ ->
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle("Hook 构造方法测试(stub)")
|
||||
.setMessage(InjectTest("文字未更改").getString() + "\n模块是否已激活:${YukiHookModuleStatus.isActive()}")
|
||||
.setPositiveButton("下一个") { _, _ ->
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle("Hook 构造方法测试(多个)")
|
||||
.setMessage(InjectLucky().getString() + "\n" + InjectLucky(string = "没更改的文字").getString() + "\n模块是否已激活:${YukiHookModuleStatus.isActive()}")
|
||||
.setPositiveButton("下一个") { _, _ ->
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle("Hook 构造方法测试(无参)")
|
||||
.setMessage(InjectNoParamTest().getString() + "\n模块是否已激活:${YukiHookModuleStatus.isActive()}")
|
||||
.setPositiveButton("下一个") { _, _ ->
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle("Hook 构造方法测试(名称)")
|
||||
.setMessage(InjectTestName("文字没更改").getString() + "\n模块是否已激活:${YukiHookModuleStatus.isActive()}")
|
||||
.setPositiveButton("完成") { _, _ -> toast() }
|
||||
.show()
|
||||
}.show()
|
||||
}.show()
|
||||
}.show()
|
||||
}.show()
|
||||
}.show()
|
||||
}
|
||||
|
||||
// for test
|
||||
@Keep
|
||||
private fun toast() = Toast.makeText(this, "我弹出来了,没有 Hook", Toast.LENGTH_SHORT).show()
|
||||
|
||||
// for test
|
||||
@Keep
|
||||
private fun a(content1: String = "前缀", content: String) = "$content1${content}_后面加了一段文字"
|
||||
|
||||
// for test
|
||||
@Keep
|
||||
private fun test() = "正常显示的一行文字"
|
||||
|
||||
// for test
|
||||
@Keep
|
||||
private fun xptest() = "这里是正常的文字"
|
||||
|
||||
// for test
|
||||
@Keep
|
||||
private fun test(string: String) = string
|
||||
}
|
@@ -1,100 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@file:Suppress("unused")
|
||||
|
||||
package com.highcapable.yukihookapi.demo.hook
|
||||
|
||||
import com.highcapable.yukihookapi.demo.BuildConfig
|
||||
import com.highcapable.yukihookapi.demo.InjectTest
|
||||
import com.highcapable.yukihookapi.demo.MainActivity
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
import com.highcapable.yukihookapi.hook.type.BundleClass
|
||||
import com.highcapable.yukihookapi.hook.type.StringType
|
||||
import com.highcapable.yukihookapi.hook.type.UnitType
|
||||
|
||||
// for test
|
||||
class MainHooker : YukiBaseHooker() {
|
||||
|
||||
override fun onHook() =
|
||||
loadApp(name = BuildConfig.APPLICATION_ID) {
|
||||
MainActivity::class.java.hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "onCreate"
|
||||
param(BundleClass)
|
||||
}
|
||||
beforeHook {
|
||||
field {
|
||||
name = "a"
|
||||
type = StringType
|
||||
}.set(instance, "这段文字被修改成功了")
|
||||
}
|
||||
}
|
||||
injectMember {
|
||||
method {
|
||||
name = "toast"
|
||||
returnType = UnitType
|
||||
}
|
||||
intercept()
|
||||
}
|
||||
injectMember {
|
||||
method {
|
||||
name = "a"
|
||||
param(StringType, StringType)
|
||||
returnType = StringType
|
||||
}
|
||||
beforeHook {
|
||||
args(index = 0).set("改了前面的")
|
||||
args(index = 1).set("改了后面的")
|
||||
}
|
||||
}
|
||||
injectMember {
|
||||
method {
|
||||
name = "test"
|
||||
returnType = StringType
|
||||
}
|
||||
replaceTo("这段文字已被 Hook 成功")
|
||||
}
|
||||
injectMember {
|
||||
method {
|
||||
name = "test"
|
||||
param(StringType)
|
||||
returnType = StringType
|
||||
}
|
||||
beforeHook { args().set("方法参数已被 Hook 成功") }
|
||||
}
|
||||
}
|
||||
InjectTest::class.java.hook {
|
||||
injectMember {
|
||||
constructor { param(StringType) }
|
||||
beforeHook { args().set("构造方法已被 Hook 成功") }
|
||||
}
|
||||
}
|
||||
loadHooker(hooker = TestChildHooker())
|
||||
}
|
||||
}
|
@@ -1,66 +0,0 @@
|
||||
/**
|
||||
* 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/3.
|
||||
*/
|
||||
package com.highcapable.yukihookapi.demo.hook
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.widget.Toast
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
import com.highcapable.yukihookapi.hook.factory.findMethod
|
||||
import com.highcapable.yukihookapi.hook.type.ActivityClass
|
||||
import com.highcapable.yukihookapi.hook.type.BundleClass
|
||||
|
||||
// for test
|
||||
class SecondHooker : YukiBaseHooker() {
|
||||
|
||||
override fun onHook() =
|
||||
loadApp(name = "com.android.browser") {
|
||||
ActivityClass.hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "onCreate"
|
||||
param(BundleClass)
|
||||
}
|
||||
afterHook {
|
||||
AlertDialog.Builder(instance())
|
||||
.setCancelable(false)
|
||||
.setTitle("测试 Hook")
|
||||
.setMessage("Hook 已成功")
|
||||
.setPositiveButton("OK") { _, _ ->
|
||||
Toast.makeText(instance(), "Hook Success", Toast.LENGTH_SHORT).show()
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
injectMember {
|
||||
member = hookClass.findMethod(name = "onStart")
|
||||
afterHook {
|
||||
Toast.makeText(instance(), "手动 Hook", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,43 +0,0 @@
|
||||
/**
|
||||
* 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/4.
|
||||
*/
|
||||
package com.highcapable.yukihookapi.demo.hook
|
||||
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
import com.highcapable.yukihookapi.hook.type.StringType
|
||||
|
||||
// for test
|
||||
class TestChildHooker : YukiBaseHooker() {
|
||||
|
||||
override fun onHook() =
|
||||
findClass(name = "$packageName.InjectTestName").hook {
|
||||
injectMember {
|
||||
constructor { param(StringType) }
|
||||
beforeHook { args().set("构造方法已被 Hook 成功 [2]") }
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,187 +0,0 @@
|
||||
/**
|
||||
* 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/4.
|
||||
*/
|
||||
@file:Suppress("unused")
|
||||
|
||||
package com.highcapable.yukihookapi.demo.hook.inject
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.widget.Toast
|
||||
import com.highcapable.yukihookapi.YukiHookAPI
|
||||
import com.highcapable.yukihookapi.annotation.xposed.InjectYukiHookWithXposed
|
||||
import com.highcapable.yukihookapi.demo.*
|
||||
import com.highcapable.yukihookapi.hook.factory.encase
|
||||
import com.highcapable.yukihookapi.hook.factory.findMethod
|
||||
import com.highcapable.yukihookapi.hook.type.ActivityClass
|
||||
import com.highcapable.yukihookapi.hook.type.BundleClass
|
||||
import com.highcapable.yukihookapi.hook.type.StringType
|
||||
import com.highcapable.yukihookapi.hook.type.UnitType
|
||||
import com.highcapable.yukihookapi.hook.xposed.proxy.YukiHookXposedInitProxy
|
||||
|
||||
// for test
|
||||
@InjectYukiHookWithXposed
|
||||
class MainInjecter : YukiHookXposedInitProxy {
|
||||
|
||||
override fun onHook() {
|
||||
// 设置模式
|
||||
YukiHookAPI.configs {
|
||||
debugTag = "YukiSuki"
|
||||
isDebug = true
|
||||
}
|
||||
// 方案 1
|
||||
// encase(MainHooker(), SecondHooker())
|
||||
// 方案 2
|
||||
encase {
|
||||
loadApp(name = BuildConfig.APPLICATION_ID) {
|
||||
MainActivity::class.java.hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "onCreate"
|
||||
param(BundleClass)
|
||||
}
|
||||
beforeHook {
|
||||
field {
|
||||
name = "a"
|
||||
type = StringType
|
||||
}.set(instance, "这段文字被修改成功了")
|
||||
}
|
||||
}
|
||||
injectMember {
|
||||
method {
|
||||
name = "xptest"
|
||||
returnType = StringType
|
||||
}
|
||||
replaceTo(prefs.getString(key = "data", default = "获取 Hook:没数据"))
|
||||
}
|
||||
injectMember {
|
||||
method {
|
||||
name = "toast"
|
||||
returnType = UnitType
|
||||
}
|
||||
intercept()
|
||||
}
|
||||
injectMember {
|
||||
method {
|
||||
name = "a"
|
||||
param(StringType, StringType)
|
||||
returnType = StringType
|
||||
}
|
||||
beforeHook {
|
||||
args(index = 0).set("✌️改了前面的")
|
||||
args(index = 1).set("✌️改了后面的")
|
||||
}
|
||||
}
|
||||
injectMember {
|
||||
method {
|
||||
name = "test"
|
||||
returnType = StringType
|
||||
}
|
||||
replaceTo("这段文字已被 Hook 成功")
|
||||
}
|
||||
injectMember {
|
||||
method {
|
||||
name = "test"
|
||||
param(StringType)
|
||||
returnType = StringType
|
||||
}
|
||||
beforeHook { args().set("方法参数已被 Hook 成功") }
|
||||
}
|
||||
}
|
||||
InjectLucky::class.java.hook {
|
||||
injectMember {
|
||||
allConstructors()
|
||||
afterHook {
|
||||
field {
|
||||
name = "string"
|
||||
type = StringType
|
||||
}.set(instance, "内容被改掉了")
|
||||
}
|
||||
}
|
||||
}
|
||||
InjectTest::class.java.hook {
|
||||
injectMember {
|
||||
constructor { param(StringType) }
|
||||
beforeHook { args().set("构造方法已被 Hook 成功") }
|
||||
}
|
||||
}
|
||||
InjectNoParamTest::class.java.hook {
|
||||
injectMember {
|
||||
constructor()
|
||||
afterHook {
|
||||
field {
|
||||
name = "test"
|
||||
type = StringType
|
||||
}.set(instance, "内容被改掉了")
|
||||
}
|
||||
}
|
||||
}
|
||||
findClass(name = "$packageName.InjectTestName").hook {
|
||||
injectMember {
|
||||
constructor { param(StringType) }
|
||||
beforeHook { args().set("构造方法已被 Hook 成功 [2]") }
|
||||
}
|
||||
}
|
||||
}
|
||||
loadApp(name = "com.android.browser") {
|
||||
ActivityClass.hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "onCreate"
|
||||
param(BundleClass)
|
||||
}
|
||||
afterHook {
|
||||
AlertDialog.Builder(instance())
|
||||
.setCancelable(false)
|
||||
.setTitle("测试 Hook")
|
||||
.setMessage(
|
||||
"Hook 已成功\n" +
|
||||
"test_key:${prefs.getBoolean("test_key")}\n" +
|
||||
"test_key_name:${prefs.getString("test_key_name", "默认值")}"
|
||||
)
|
||||
.setPositiveButton("OK") { _, _ ->
|
||||
Toast.makeText(instance(), "Hook Success", Toast.LENGTH_SHORT).show()
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
injectMember {
|
||||
member = hookClass.findMethod(name = "onStart")
|
||||
afterHook {
|
||||
Toast.makeText(instance(), "手动 Hook", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}.failures {
|
||||
onConductFailure { _, _ -> }
|
||||
onHookingFailure {}
|
||||
onAllFailure {}
|
||||
ignoredConductFailure()
|
||||
ignoredHookingFailure()
|
||||
ignoredAllFailure()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
tools:context=".MainActivity"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="Hello World!" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/main_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="存储模块数据" />
|
||||
</LinearLayout>
|
@@ -1,3 +0,0 @@
|
||||
<resources>
|
||||
<string name="app_name">YukiHookAPI</string>
|
||||
</resources>
|
@@ -1,17 +0,0 @@
|
||||
package com.highcapable.yukihookapi
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
0
app/.gitignore → app_demo/.gitignore
vendored
54
app_demo/build.gradle
Normal file
@@ -0,0 +1,54 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
}
|
||||
|
||||
android {
|
||||
signingConfigs {
|
||||
debug {
|
||||
storeFile file('../keystore/public')
|
||||
storePassword '123456'
|
||||
keyAlias 'public'
|
||||
keyPassword '123456'
|
||||
v1SigningEnabled true
|
||||
v2SigningEnabled true
|
||||
}
|
||||
}
|
||||
|
||||
compileSdk 31
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.highcapable.yukihookapi.app_demo"
|
||||
minSdk 22
|
||||
targetSdk 31
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
signingConfig signingConfigs.debug
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.core:core-ktx:1.7.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
implementation 'com.google.android.material:material:1.5.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
}
|
23
app_demo/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.highcapable.yukihookapi.app_demo">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Default">
|
||||
|
||||
<activity
|
||||
android:name=".ui.MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* 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/9.
|
||||
*/
|
||||
@file:Suppress("SameParameterValue")
|
||||
|
||||
package com.highcapable.yukihookapi.app_demo.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.widget.Button
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.highcapable.yukihookapi.app_demo.R
|
||||
import com.highcapable.yukihookapi.app_demo.utils.Main
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
findViewById<TextView>(R.id.app_demo_first_text).text = getFirstText()
|
||||
findViewById<TextView>(R.id.app_demo_second_text).text = secondText
|
||||
findViewById<TextView>(R.id.app_demo_third_text).text = Main("Feel real").getString()
|
||||
findViewById<TextView>(R.id.app_demo_fourth_text).text = getRegularText("Have fun day")
|
||||
findViewById<TextView>(R.id.app_demo_fifth_text).text = getDataText()
|
||||
findViewById<Button>(R.id.app_demo_button).setOnClickListener { toast() }
|
||||
}
|
||||
|
||||
private val secondText = "This is a miracle"
|
||||
|
||||
private fun getFirstText() = "Hello World!"
|
||||
|
||||
private fun getRegularText(string: String) = string
|
||||
|
||||
private fun getDataText() = "No data found"
|
||||
|
||||
private fun toast() = Toast.makeText(this, "Nothing to show", Toast.LENGTH_SHORT).show()
|
||||
}
|
@@ -23,17 +23,11 @@
|
||||
* 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/3.
|
||||
* This file is Created by fankes on 2022/2/9.
|
||||
*/
|
||||
package com.highcapable.yukihookapi.demo
|
||||
package com.highcapable.yukihookapi.app_demo.utils
|
||||
|
||||
import androidx.annotation.Keep
|
||||
class Main(private val string: String) {
|
||||
|
||||
// for test
|
||||
@Keep
|
||||
class InjectTest(private val string: String) {
|
||||
|
||||
// for test
|
||||
@Keep
|
||||
fun getString() = string
|
||||
}
|
56
app_demo/src/main/res/layout/activity_main.xml
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/app_demo_first_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:text="sample"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/app_demo_second_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:text="sample"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/app_demo_third_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:text="sample"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/app_demo_fourth_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:text="sample"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/app_demo_fifth_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:text="sample"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/app_demo_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Click Me!"
|
||||
android:textAllCaps="false" />
|
||||
</LinearLayout>
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 982 B After Width: | Height: | Size: 982 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
@@ -1,6 +1,6 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.YukiHookAPI" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<style name="Theme.Default" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_200</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
3
app_demo/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">YukiHookAppDemo</string>
|
||||
</resources>
|
@@ -1,6 +1,6 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.YukiHookAPI" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<style name="Theme.Default" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_500</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
1
module_demo/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
@@ -19,7 +19,7 @@ android {
|
||||
compileSdk 31
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.highcapable.yukihookapi.demo"
|
||||
applicationId "com.highcapable.yukihookapi.module_demo"
|
||||
minSdk 22
|
||||
targetSdk 31
|
||||
versionCode 1
|
||||
@@ -55,12 +55,12 @@ dependencies {
|
||||
compileOnly 'de.robv.android.xposed:api:82'
|
||||
// Implementation API
|
||||
implementation project(':yukihookapi')
|
||||
// Implementation Processor
|
||||
ksp project(':yukihookapi-ksp-xposed')
|
||||
implementation 'androidx.core:core-ktx:1.7.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
implementation 'com.google.android.material:material:1.5.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
||||
implementation project(path: ':yukihookapi')
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
41
module_demo/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
|
||||
-dontwarn
|
||||
-ignorewarnings
|
||||
|
||||
-optimizationpasses 10
|
||||
-dontusemixedcaseclassnames
|
||||
|
||||
-dontoptimize
|
||||
-verbose
|
||||
-overloadaggressively
|
||||
-repackageclasses i
|
||||
-allowaccessmodification
|
||||
|
||||
-adaptclassstrings
|
||||
-adaptresourcefilenames
|
||||
-adaptresourcefilecontents
|
||||
|
||||
# -optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
|
||||
-renamesourcefileattribute P
|
||||
-keepattributes SourceFile,LineNumberTable
|
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.highcapable.yukihookapi.demo">
|
||||
package="com.highcapable.yukihookapi.module_demo">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
@@ -8,25 +8,25 @@
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.YukiHookAPI">
|
||||
android:theme="@style/Theme.Default">
|
||||
|
||||
<!-- 是否是xposed模块 -->
|
||||
<!-- 设置为 Xposed 模块 -->
|
||||
<meta-data
|
||||
android:name="xposedmodule"
|
||||
android:value="true" />
|
||||
|
||||
<!-- 模块描述 -->
|
||||
<!-- 设置你的模块描述 -->
|
||||
<meta-data
|
||||
android:name="xposeddescription"
|
||||
android:value="YukiHookAPI Xposed Module Test" />
|
||||
|
||||
<!-- 最低xposed版本号 -->
|
||||
<!-- 最低 Xposed 版本号 -->
|
||||
<meta-data
|
||||
android:name="xposedminversion"
|
||||
android:value="93" />
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:name=".ui.MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
1
module_demo/src/main/assets/xposed_init
Normal file
@@ -0,0 +1 @@
|
||||
com.highcapable.yukihookapi.module_demo.hook.MainHook_YukiHookXposedInit
|
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* 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/9.
|
||||
*/
|
||||
@file:Suppress("unused")
|
||||
|
||||
package com.highcapable.yukihookapi.module_demo.hook
|
||||
|
||||
import android.app.AlertDialog
|
||||
import com.highcapable.yukihookapi.YukiHookAPI
|
||||
import com.highcapable.yukihookapi.annotation.xposed.InjectYukiHookWithXposed
|
||||
import com.highcapable.yukihookapi.hook.type.BundleClass
|
||||
import com.highcapable.yukihookapi.hook.type.StringType
|
||||
import com.highcapable.yukihookapi.hook.type.UnitType
|
||||
import com.highcapable.yukihookapi.hook.xposed.proxy.YukiHookXposedInitProxy
|
||||
|
||||
@InjectYukiHookWithXposed
|
||||
class MainHook : YukiHookXposedInitProxy {
|
||||
|
||||
override fun onHook() {
|
||||
// 配置 YuKiHookAPI
|
||||
YukiHookAPI.configs {
|
||||
// 全局调试用的 TAG
|
||||
debugTag = "YukiHookAPI"
|
||||
// 是否开启全局调试日志输出功能
|
||||
isDebug = true
|
||||
}
|
||||
// 开始你的 Hook
|
||||
YukiHookAPI.encase {
|
||||
// 装载需要 Hook 的 APP
|
||||
loadApp(name = "com.highcapable.yukihookapi.app_demo") {
|
||||
// 得到需要 Hook 的 Class
|
||||
findClass(name = "$packageName.ui.MainActivity").hook {
|
||||
// 注入要 Hook 的方法
|
||||
injectMember {
|
||||
method {
|
||||
name = "getFirstText"
|
||||
returnType = StringType
|
||||
}
|
||||
// 执行替换 Hook
|
||||
replaceTo(any = "Hello YukiHookAPI!")
|
||||
}
|
||||
// 注入要 Hook 的方法
|
||||
injectMember {
|
||||
method {
|
||||
name = "onCreate"
|
||||
param(BundleClass)
|
||||
}
|
||||
// 在方法执行之前拦截
|
||||
beforeHook {
|
||||
field {
|
||||
name = "secondText"
|
||||
type = StringType
|
||||
}.set(instance, "I am hook result")
|
||||
}
|
||||
}
|
||||
// 注入要 Hook 的方法
|
||||
injectMember {
|
||||
method {
|
||||
name = "getRegularText"
|
||||
param(StringType)
|
||||
returnType = StringType
|
||||
}
|
||||
// 在方法执行之前拦截
|
||||
beforeHook {
|
||||
// 设置 0 号 param
|
||||
args().set("I am hook method param")
|
||||
}
|
||||
}
|
||||
// 注入要 Hook 的方法
|
||||
injectMember {
|
||||
method {
|
||||
name = "toast"
|
||||
returnType = UnitType
|
||||
}
|
||||
// 拦截整个方法
|
||||
replaceUnit {
|
||||
AlertDialog.Builder(instance())
|
||||
.setTitle("Hooked")
|
||||
.setMessage("I am hook your toast showing")
|
||||
.setPositiveButton("OK", null)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
// 注入要 Hook 的方法
|
||||
injectMember {
|
||||
method {
|
||||
name = "getDataText"
|
||||
returnType = StringType
|
||||
}
|
||||
// 执行替换 Hook
|
||||
replaceTo(prefs.getString(key = "test_data", default = "Test data is nothing"))
|
||||
}
|
||||
}
|
||||
// 得到需要 Hook 的 Class
|
||||
findClass(name = "$packageName.utils.Main").hook {
|
||||
// 注入要 Hook 的方法
|
||||
injectMember {
|
||||
constructor { param(StringType) }
|
||||
// 在方法执行之前拦截
|
||||
beforeHook {
|
||||
// 设置 0 号 param
|
||||
args().set("I am hook constructor param")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 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/1/29.
|
||||
*/
|
||||
@file:Suppress("SetTextI18n")
|
||||
|
||||
package com.highcapable.yukihookapi.module_demo.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.widget.Button
|
||||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.highcapable.yukihookapi.hook.factory.modulePrefs
|
||||
import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus
|
||||
import com.highcapable.yukihookapi.module_demo.R
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
findViewById<TextView>(R.id.module_demo_text).text = "Module is Active -> ${YukiHookModuleStatus.isActive()}"
|
||||
findViewById<EditText>(R.id.module_demo_edit_text).also {
|
||||
it.setText(modulePrefs.getString(key = "test_data"))
|
||||
findViewById<Button>(R.id.module_demo_button).setOnClickListener { _ ->
|
||||
if (it.text.toString().isNotEmpty()) {
|
||||
modulePrefs.putString(key = "test_data", value = it.text.toString())
|
||||
Toast.makeText(applicationContext, "Saved", Toast.LENGTH_SHORT).show()
|
||||
} else Toast.makeText(applicationContext, "Please enter the text", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
170
module_demo/src/main/res/drawable/ic_launcher_background.xml
Normal file
@@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
34
module_demo/src/main/res/layout/activity_main.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/module_demo_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:text="sample"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/module_demo_edit_text"
|
||||
android:layout_width="250dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:hint="Please enter the text"
|
||||
android:singleLine="true"
|
||||
android:textSize="20sp"
|
||||
tools:ignore="Autofill,LabelFor,TextFields" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/module_demo_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Save Test Data"
|
||||
android:textAllCaps="false" />
|
||||
</LinearLayout>
|
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
BIN
module_demo/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
module_demo/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
module_demo/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 982 B |
BIN
module_demo/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
module_demo/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
module_demo/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
module_demo/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
module_demo/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
module_demo/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
module_demo/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 7.6 KiB |
16
module_demo/src/main/res/values-night/themes.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.Default" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_200</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/black</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_200</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
10
module_demo/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="purple_200">#FFBB86FC</color>
|
||||
<color name="purple_500">#FF6200EE</color>
|
||||
<color name="purple_700">#FF3700B3</color>
|
||||
<color name="teal_200">#FF03DAC5</color>
|
||||
<color name="teal_700">#FF018786</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
</resources>
|
3
module_demo/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">YukiHookModuleDemo</string>
|
||||
</resources>
|
16
module_demo/src/main/res/values/themes.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.Default" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_500</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/white</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_700</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
@@ -1,4 +1,5 @@
|
||||
rootProject.name = "YukiHookAPI"
|
||||
include ':app'
|
||||
include ':app_demo'
|
||||
include ':module_demo'
|
||||
include ':yukihookapi'
|
||||
include ':yukihookapi-ksp-xposed'
|
||||
|
@@ -174,8 +174,8 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
|
||||
if (modulePackageName.isNotBlank()) logger.warn(message = "You set the customize module package name to \"$modulePackageName\",please check for yourself if it is correct")
|
||||
val realPackageName =
|
||||
modulePackageName.ifBlank {
|
||||
if (packageName.contains(".hook."))
|
||||
packageName.split(".hook.")[0]
|
||||
if (packageName.contains(".hook.") || packageName.endsWith(".hook"))
|
||||
packageName.split(".hook")[0]
|
||||
else error(msg = "YukiHookAPI cannot identify your App's package name,please refer to the wiki https://github.com/fankes/YukiHookAPI/wiki to fix the package name or manually configure the package name")
|
||||
}
|
||||
codeGenerator.createNewFile(
|
||||
|