...
1
.idea/compiler.xml
generated
@@ -2,6 +2,7 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CompilerConfiguration">
|
<component name="CompilerConfiguration">
|
||||||
<bytecodeTargetLevel target="1.8">
|
<bytecodeTargetLevel target="1.8">
|
||||||
|
<module name="YukiHookAPI.app" target="11" />
|
||||||
<module name="YukiHookAPI.demo-app" target="11" />
|
<module name="YukiHookAPI.demo-app" target="11" />
|
||||||
<module name="YukiHookAPI.demo-module" target="11" />
|
<module name="YukiHookAPI.demo-module" target="11" />
|
||||||
<module name="YukiHookAPI.yukihookapi-yaya" target="11" />
|
<module name="YukiHookAPI.yukihookapi-yaya" target="11" />
|
||||||
|
3
.idea/gradle.xml
generated
@@ -10,8 +10,7 @@
|
|||||||
<option name="modules">
|
<option name="modules">
|
||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
<option value="$PROJECT_DIR$/demo-app" />
|
<option value="$PROJECT_DIR$/app" />
|
||||||
<option value="$PROJECT_DIR$/demo-module" />
|
|
||||||
<option value="$PROJECT_DIR$/yukihookapi" />
|
<option value="$PROJECT_DIR$/yukihookapi" />
|
||||||
<option value="$PROJECT_DIR$/yukihookapi-ksp-xposed" />
|
<option value="$PROJECT_DIR$/yukihookapi-ksp-xposed" />
|
||||||
</set>
|
</set>
|
||||||
|
0
demo-app/.gitignore → app/.gitignore
vendored
@@ -4,21 +4,10 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
signingConfigs {
|
|
||||||
debug {
|
|
||||||
storeFile file('../keystore/public')
|
|
||||||
storePassword '123456'
|
|
||||||
keyAlias 'public'
|
|
||||||
keyPassword '123456'
|
|
||||||
v1SigningEnabled true
|
|
||||||
v2SigningEnabled true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compileSdk 31
|
compileSdk 31
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.highcapable.yukihookapi.demo_app"
|
applicationId "com.highcapable.yukihookapi.demo"
|
||||||
minSdk 22
|
minSdk 22
|
||||||
targetSdk 31
|
targetSdk 31
|
||||||
versionCode 1
|
versionCode 1
|
||||||
@@ -30,7 +19,6 @@ android {
|
|||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
signingConfig signingConfigs.debug
|
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,6 +32,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
implementation 'androidx.core:core-ktx:1.7.0'
|
implementation 'androidx.core:core-ktx:1.7.0'
|
||||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||||
implementation 'com.google.android.material:material:1.5.0'
|
implementation 'com.google.android.material:material:1.5.0'
|
@@ -18,24 +18,4 @@
|
|||||||
|
|
||||||
# If you keep the line number information, uncomment this to
|
# If you keep the line number information, uncomment this to
|
||||||
# hide the original source file name.
|
# hide the original source file name.
|
||||||
#-renamesourcefileattribute SourceFile
|
#-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
|
|
@@ -0,0 +1,24 @@
|
|||||||
|
package com.highcapable.yukihookapi.demo
|
||||||
|
|
||||||
|
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.demo", appContext.packageName)
|
||||||
|
}
|
||||||
|
}
|
@@ -1,17 +1,17 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.highcapable.yukihookapi.demo_app">
|
package="com.highcapable.yukihookapi.demo">
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_icon"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_icon"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.Default">
|
android:theme="@style/Theme.MyApplication">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
@@ -0,0 +1,12 @@
|
|||||||
|
package com.highcapable.yukihookapi.demo
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
|
||||||
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.activity_main)
|
||||||
|
}
|
||||||
|
}
|
18
app/src/main/res/layout/activity_main.xml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Hello World!"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
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">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<!-- Base application theme. -->
|
<!-- Base application theme. -->
|
||||||
<style name="Theme.Default" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
<style name="Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||||
<!-- Primary brand color. -->
|
<!-- Primary brand color. -->
|
||||||
<item name="colorPrimary">@color/purple_200</item>
|
<item name="colorPrimary">@color/purple_200</item>
|
||||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
<item name="colorPrimaryVariant">@color/purple_700</item>
|
3
app/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">YukiHookAPI</string>
|
||||||
|
</resources>
|
@@ -1,6 +1,6 @@
|
|||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<!-- Base application theme. -->
|
<!-- Base application theme. -->
|
||||||
<style name="Theme.Default" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
<style name="Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||||
<!-- Primary brand color. -->
|
<!-- Primary brand color. -->
|
||||||
<item name="colorPrimary">@color/purple_500</item>
|
<item name="colorPrimary">@color/purple_500</item>
|
||||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
<item name="colorPrimaryVariant">@color/purple_700</item>
|
@@ -0,0 +1,17 @@
|
|||||||
|
package com.highcapable.yukihookapi.demo
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
@@ -1,62 +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/2/9.
|
|
||||||
*/
|
|
||||||
@file:Suppress("SameParameterValue")
|
|
||||||
|
|
||||||
package com.highcapable.yukihookapi.demo_app.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.demo_app.R
|
|
||||||
import com.highcapable.yukihookapi.demo_app.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()
|
|
||||||
}
|
|
@@ -1,33 +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/2/9.
|
|
||||||
*/
|
|
||||||
package com.highcapable.yukihookapi.demo_app.utils
|
|
||||||
|
|
||||||
class Main(private val string: String) {
|
|
||||||
|
|
||||||
fun getString() = string
|
|
||||||
}
|
|
@@ -1,56 +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: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: 24 KiB |
@@ -1,3 +0,0 @@
|
|||||||
<resources>
|
|
||||||
<string name="app_name">YukiHookAppDemo</string>
|
|
||||||
</resources>
|
|
1
demo-module/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
/build
|
|
@@ -1,61 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id 'com.android.application'
|
|
||||||
id 'org.jetbrains.kotlin.android'
|
|
||||||
id 'com.google.devtools.ksp' version '1.6.10-1.0.2'
|
|
||||||
}
|
|
||||||
|
|
||||||
android {
|
|
||||||
signingConfigs {
|
|
||||||
debug {
|
|
||||||
storeFile file('../keystore/public')
|
|
||||||
storePassword '123456'
|
|
||||||
keyAlias 'public'
|
|
||||||
keyPassword '123456'
|
|
||||||
v1SigningEnabled true
|
|
||||||
v2SigningEnabled true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compileSdk 31
|
|
||||||
|
|
||||||
defaultConfig {
|
|
||||||
applicationId "com.highcapable.yukihookapi.demo_module"
|
|
||||||
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 {
|
|
||||||
// Used 82 API Version
|
|
||||||
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'
|
|
||||||
testImplementation 'junit:junit:4.13.2'
|
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
|
||||||
}
|
|
41
demo-module/proguard-rules.pro
vendored
@@ -1,41 +0,0 @@
|
|||||||
# 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,38 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
package="com.highcapable.yukihookapi.demo_module">
|
|
||||||
|
|
||||||
<application
|
|
||||||
android:allowBackup="true"
|
|
||||||
android:icon="@mipmap/ic_icon"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:roundIcon="@mipmap/ic_icon"
|
|
||||||
android:supportsRtl="true"
|
|
||||||
android:theme="@style/Theme.Default">
|
|
||||||
|
|
||||||
<!-- 设置为 Xposed 模块 -->
|
|
||||||
<meta-data
|
|
||||||
android:name="xposedmodule"
|
|
||||||
android:value="true" />
|
|
||||||
|
|
||||||
<!-- 设置你的模块描述 -->
|
|
||||||
<meta-data
|
|
||||||
android:name="xposeddescription"
|
|
||||||
android:value="YukiHookAPI Xposed Module Test" />
|
|
||||||
|
|
||||||
<!-- 最低 Xposed 版本号 -->
|
|
||||||
<meta-data
|
|
||||||
android:name="xposedminversion"
|
|
||||||
android:value="93" />
|
|
||||||
|
|
||||||
<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>
|
|
@@ -1 +0,0 @@
|
|||||||
com.highcapable.yukihookapi.demo_module.hook.MainHook_YukiHookXposedInit
|
|
@@ -1 +0,0 @@
|
|||||||
com.highcapable.yukihookapi.demo_module.hook.MainHook
|
|
@@ -1,131 +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/2/9.
|
|
||||||
*/
|
|
||||||
package com.highcapable.yukihookapi.demo_module.hook
|
|
||||||
|
|
||||||
import android.app.AlertDialog
|
|
||||||
import com.highcapable.yukihookapi.YukiHookAPI
|
|
||||||
import com.highcapable.yukihookapi.annotation.xposed.InjectYukiHookWithXposed
|
|
||||||
import com.highcapable.yukihookapi.hook.type.android.BundleClass
|
|
||||||
import com.highcapable.yukihookapi.hook.type.java.StringType
|
|
||||||
import com.highcapable.yukihookapi.hook.type.java.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.demo_app") {
|
|
||||||
// 得到需要 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
|
|
||||||
}.get(instance).set("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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,58 +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/1/29.
|
|
||||||
*/
|
|
||||||
@file:Suppress("SetTextI18n")
|
|
||||||
|
|
||||||
package com.highcapable.yukihookapi.demo_module.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.demo_module.R
|
|
||||||
import com.highcapable.yukihookapi.hook.factory.modulePrefs
|
|
||||||
import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus
|
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,30 +0,0 @@
|
|||||||
<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>
|
|
@@ -1,170 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,34 +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: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>
|
|
@@ -1,5 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,5 +0,0 @@
|
|||||||
<?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>
|
|
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 982 B |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 7.6 KiB |
@@ -1,16 +0,0 @@
|
|||||||
<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>
|
|
@@ -1,10 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,3 +0,0 @@
|
|||||||
<resources>
|
|
||||||
<string name="app_name">YukiHookModuleDemo</string>
|
|
||||||
</resources>
|
|
@@ -1,16 +0,0 @@
|
|||||||
<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,5 +1,4 @@
|
|||||||
rootProject.name = "YukiHookAPI"
|
rootProject.name = "YukiHookAPI"
|
||||||
include ':demo-app'
|
include ':app'
|
||||||
include ':demo-module'
|
|
||||||
include ':yukihookapi'
|
include ':yukihookapi'
|
||||||
include ':yukihookapi-ksp-xposed'
|
include ':yukihookapi-ksp-xposed'
|
||||||
|
@@ -9,15 +9,9 @@ java {
|
|||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
sourceSets.main { java.srcDir("src/api/kotlin") }
|
sourceSets.main { java.srcDir("src/api/kotlin") }
|
||||||
withJavadocJar()
|
|
||||||
withSourcesJar()
|
withSourcesJar()
|
||||||
}
|
}
|
||||||
|
|
||||||
javadoc {
|
|
||||||
options.addStringOption("charset", "UTF-8")
|
|
||||||
if (JavaVersion.current().isJava9Compatible()) options.addBooleanOption("html5", true)
|
|
||||||
}
|
|
||||||
|
|
||||||
kotlin { sourceSets.main { kotlin.srcDir("src/api/kotlin") } }
|
kotlin { sourceSets.main { kotlin.srcDir("src/api/kotlin") } }
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@@ -41,11 +41,18 @@ import de.robv.android.xposed.XposedHelpers;
|
|||||||
|
|
||||||
@SuppressWarnings("ALL")
|
@SuppressWarnings("ALL")
|
||||||
@DoNotUseClass
|
@DoNotUseClass
|
||||||
|
/**
|
||||||
|
* ReflectionUtils
|
||||||
|
*/
|
||||||
public class ReflectionUtils {
|
public class ReflectionUtils {
|
||||||
|
|
||||||
private static final HashMap<String, Field> fieldCache = new HashMap<>();
|
private static final HashMap<String, Field> fieldCache = new HashMap<>();
|
||||||
private static final HashMap<String, Method> methodCache = new HashMap<>();
|
private static final HashMap<String, Method> methodCache = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param clazzes
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
private static String getParametersString(Class<?>... clazzes) {
|
private static String getParametersString(Class<?>... clazzes) {
|
||||||
StringBuilder sb = new StringBuilder("(");
|
StringBuilder sb = new StringBuilder("(");
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
@@ -64,12 +71,26 @@ public class ReflectionUtils {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param clazz
|
||||||
|
* @param fieldType
|
||||||
|
* @param fieldName
|
||||||
|
* @param value
|
||||||
|
* @return Field
|
||||||
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static void setStaticObjectField(Class<?> clazz, Class<?> fieldType, String fieldName, Object value)
|
public static void setStaticObjectField(Class<?> clazz, Class<?> fieldType, String fieldName, Object value)
|
||||||
throws NoSuchFieldException, IllegalAccessException {
|
throws NoSuchFieldException, IllegalAccessException {
|
||||||
findFieldIfExists(clazz, fieldType, fieldName).set(null, value);
|
findFieldIfExists(clazz, fieldType, fieldName).set(null, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fieldType
|
||||||
|
* @param fieldName
|
||||||
|
* @param value
|
||||||
|
* @param obj
|
||||||
|
* @return Field
|
||||||
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static void setObjectField(Object obj, Class<?> fieldType, String fieldName, Object value)
|
public static void setObjectField(Object obj, Class<?> fieldType, String fieldName, Object value)
|
||||||
throws NoSuchFieldException, IllegalAccessException {
|
throws NoSuchFieldException, IllegalAccessException {
|
||||||
@@ -81,12 +102,12 @@ public class ReflectionUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Field findFieldIfExists(Class<?> clazz, Class<?> fieldType, String fieldName)
|
private static Field findFieldIfExists(Class<?> clazz, Class<?> fieldType, String fieldName)
|
||||||
throws NoSuchFieldException {
|
throws NoSuchFieldException {
|
||||||
return findFieldIfExists(clazz, fieldType.getName(), fieldName);
|
return findFieldIfExists(clazz, fieldType.getName(), fieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isCallingFrom(String className) {
|
private static boolean isCallingFrom(String className) {
|
||||||
StackTraceElement[] stackTraceElements = Thread.currentThread()
|
StackTraceElement[] stackTraceElements = Thread.currentThread()
|
||||||
.getStackTrace();
|
.getStackTrace();
|
||||||
for (StackTraceElement element : stackTraceElements) {
|
for (StackTraceElement element : stackTraceElements) {
|
||||||
@@ -98,7 +119,7 @@ public class ReflectionUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isCallingFromEither(String... classname) {
|
private static boolean isCallingFromEither(String... classname) {
|
||||||
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
|
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
|
||||||
for (StackTraceElement element : stackTraceElements) {
|
for (StackTraceElement element : stackTraceElements) {
|
||||||
for (String name : classname) {
|
for (String name : classname) {
|
||||||
@@ -110,6 +131,12 @@ public class ReflectionUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param clazz
|
||||||
|
* @param typeName
|
||||||
|
* @param fieldName
|
||||||
|
* @return Field
|
||||||
|
*/
|
||||||
public static Field findFieldIfExists(Class<?> clazz, String typeName, String fieldName) throws NoSuchFieldException {
|
public static Field findFieldIfExists(Class<?> clazz, String typeName, String fieldName) throws NoSuchFieldException {
|
||||||
String fullFieldName = "name:[" + fieldName + "] type:[" + typeName + "] in Class [" + clazz.getName() + "] by YukiHookAPI#finder";
|
String fullFieldName = "name:[" + fieldName + "] type:[" + typeName + "] in Class [" + clazz.getName() + "] by YukiHookAPI#finder";
|
||||||
if (!fieldCache.containsKey(fullFieldName)) {
|
if (!fieldCache.containsKey(fullFieldName)) {
|
||||||
@@ -144,6 +171,7 @@ public class ReflectionUtils {
|
|||||||
* @param clazz 方法所在类
|
* @param clazz 方法所在类
|
||||||
* @param returnType 返回类型
|
* @param returnType 返回类型
|
||||||
* @param methodName 方法名
|
* @param methodName 方法名
|
||||||
|
* @return Method
|
||||||
*/
|
*/
|
||||||
public static Method findMethodNoParam(Class<?> clazz, Class<?> returnType, String methodName) {
|
public static Method findMethodNoParam(Class<?> clazz, Class<?> returnType, String methodName) {
|
||||||
String fullMethodName = "name:[" + methodName + "] in Class [" + clazz.getName() + "] by YukiHookAPI#finder";
|
String fullMethodName = "name:[" + methodName + "] in Class [" + clazz.getName() + "] by YukiHookAPI#finder";
|
||||||
@@ -163,6 +191,7 @@ public class ReflectionUtils {
|
|||||||
* @param returnType 返回类型
|
* @param returnType 返回类型
|
||||||
* @param methodName 方法名
|
* @param methodName 方法名
|
||||||
* @param parameterTypes 方法参数类型数组
|
* @param parameterTypes 方法参数类型数组
|
||||||
|
* @return Method
|
||||||
*/
|
*/
|
||||||
public static Method findMethodBestMatch(Class<?> clazz, Class<?> returnType, String methodName, Class<?>... parameterTypes) {
|
public static Method findMethodBestMatch(Class<?> clazz, Class<?> returnType, String methodName, Class<?>... parameterTypes) {
|
||||||
String fullMethodName = "name:[" + methodName + "] paramType:[" + getParametersString(parameterTypes) + "] in Class [" + clazz.getName() + "] by YukiHookAPI#finder";
|
String fullMethodName = "name:[" + methodName + "] paramType:[" + getParametersString(parameterTypes) + "] in Class [" + clazz.getName() + "] by YukiHookAPI#finder";
|
||||||
@@ -180,6 +209,7 @@ public class ReflectionUtils {
|
|||||||
*
|
*
|
||||||
* @param clazz 构造类所在类
|
* @param clazz 构造类所在类
|
||||||
* @param parameterTypes 构造类方法参数类型数组
|
* @param parameterTypes 构造类方法参数类型数组
|
||||||
|
* @return Constructor
|
||||||
*/
|
*/
|
||||||
public static Constructor<?> findConstructorExact(Class<?> clazz, Class<?>... parameterTypes) {
|
public static Constructor<?> findConstructorExact(Class<?> clazz, Class<?>... parameterTypes) {
|
||||||
String fullConstructorName = "paramType:[" + getParametersString(parameterTypes) + "in Class [" + clazz.getName() + "] by YukiHookAPI#finder";
|
String fullConstructorName = "paramType:[" + getParametersString(parameterTypes) + "in Class [" + clazz.getName() + "] by YukiHookAPI#finder";
|
||||||
|