YukiHookAPI - An efficient Kotlin version of the Xposed Hook API

Related tags

App YukiHookAPI
Overview

Yuki Hook API

Eclipse Marketplace Eclipse Marketplace Eclipse Marketplace
🔥 An efficient Kotlin version of the Xposed Hook API.

Introduce

Get Startted

  • 敬请期待...

License

MIT License

Copyright (C) 2022 HighCapable

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.
Comments
  • Prefs相关问题

    Prefs相关问题

    在Activity中,使用以下代码保存配置。

    val strongMode = sharedPreferences.getBoolean("strong_mode", false)
    modulePrefs.putBoolean("strong_mode", strongMode)
    

    保存后,在Activity中再使用modulePrefsgetBoolean方法进行检查,发现设置已经保存。

    但是在hook中,prefs.getBoolean始终返回默认值false,perfs.all返回为空。

    Target API 32,运行系统API 31,已经按照文档中说明进行配置,也参考了demo中的代码,使用PrefsData问题依然出现,使用String进行数据保存问题依旧。

    请问是我用法不对,还是这是一个bug。

    bug fixed 
    opened by mahoshojoHCG 24
  • Some problems about logger

    Some problems about logger

    I manually use method loggerI in beforehook, but it seems that it does not work properly and I can’t find log in LSPosed. Could I use it in beforehook?

    invalid 
    opened by ZQDesigned 15
  • Simply support initZygote

    Simply support initZygote

    The data structure of IXposedHookZygoteInit.StartupParam is very simple, therefor data wrapper is not created.

    Been handled together, relax superclass restriction of proxy class (hook entry) to meet the complex customization needs of users.

    opened by ApeaSuperz 7
  • 在hook ClassLoader时,有一定概率会有原因不明的app卡死现象或代码执行中断

    在hook ClassLoader时,有一定概率会有原因不明的app卡死现象或代码执行中断

    为了hook动态加载的class,我使用了hook ClassLoader.loadClass(String)的方法,此方法在原生Xposed API上生效,但在Yuki上会有app卡死或代码执行中断的问题。 以下是原生Xposed API正常使用的代码:

    public class ZuoyebangHook implements IXposedHookLoadPackage {
        public String LOG_TAG = "ZuoyebangHook: ";
        @Override
        public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
            XposedBridge.log("Loaded app: " + lpparam.packageName);
            if (lpparam.packageName.equals("com.baidu.homework")){
                XposedBridge.log(LOG_TAG + "作业帮已启动");
                findAndHookMethod(ClassLoader.class, "loadClass", String.class, new XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        if (param.hasThrowable()) return;
                        super.afterHookedMethod(param);
                        //下面一行代码可以查看动态加载的类
                        XposedBridge.log(LOG_TAG + "已加载类:" + param.args[0]);
                        hook(lpparam, (String)param.args[0]);
                    }
                });
            }
        }
    
        public void hook(XC_LoadPackage.LoadPackageParam lpparam, String className) {
            switch (className){
                case "com.baidu.homework.activity.search.whole.PicManySearchActivity":
                    XposedBridge.log(LOG_TAG + "已加载" + className + ",并捕捉");
                    findAndHookMethod(
                            "com.baidu.homework.activity.search.whole.PicManySearchActivity",
                            lpparam.classLoader,
                            "onCreate",
                            Bundle.class,
                            new XC_MethodHook() {
                                @Override
                                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                                    super.beforeHookedMethod(param);
                                    XposedBridge.log(LOG_TAG + "PicManySearchActivity.onCreate已调用");
                                }
                                @Override
                                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                                    super.afterHookedMethod(param);
                                }
                            });
        }
    }
    

    以下是使用Yuki不能正常工作的代码:

    @InjectYukiHookWithXposed
    class HookEntry : IYukiHookXposedInit {
    
        override fun onInit() {
            // 配置 YuKiHookAPI
            // 可简写为 configs {}
            YukiHookAPI.configs {
                // 全局调试用的 TAG
                // 在 Logcat 控制台过滤此 TAG 可找到详细日志
                debugTag = "HomeworkKiller"
                // 是否开启调试模式
                // 请注意 - 若作为发布版本请务必关闭调试功能防止对用户设备造成大量日志填充
                isDebug = true
                // 是否启用调试日志的输出功能
                // 一旦关闭后除手动日志外 API 将停止全部日志的输出 - 建议不要随意关掉这个选项
                // 虽然说对用户的设备写入大量日志是不正确的 - 但是没有日志你将无法调试
                // 关于日志是否会影响设备的流畅度一直是一个伪命题
                // 但是不设置这个选项可能会引起一些非议 - 建议不要关闭就是了
                isAllowPrintingLogs = true
                // 是否启用 [YukiHookModulePrefs] 的键值缓存功能
                // 若无和模块频繁交互数据在宿主重新启动之前建议开启
                // 若需要实时交互数据建议关闭或从 [YukiHookModulePrefs] 中进行动态配置
                isEnableModulePrefsCache = true
                // 是否启用当前 Xposed 模块自身 [Resources] 缓存功能
                // 一般情况下模块的 Resources 是不会改变的 - 但是在语言区域更改、分辨率更改等情况下 - 就需要刷新缓存
                // 若无上述需求 - 在宿主重新启动之前建议开启
                // 你可以手动调用 [PackageParam.refreshModuleAppResources] 来刷新缓存
                isEnableModuleAppResourcesCache = true
                // 是否启用 Hook Xposed 模块激活等状态功能
                // 为原生支持 Xposed 模块激活状态检测 - 此功能默认启用
                // 关闭后你将不能再在模块环境中使用 [YukiHookAPI.Status] 中的功能
                // 功能启用后 - 将会在宿主启动时自动 Hook [YukiHookModuleStatus]
                isEnableHookModuleStatus = true
                // 是否启用当前 Xposed 模块与宿主交互的 [YukiHookDataChannel] 功能
                // 请确保 Xposed 模块的 [Application] 继承于 [ModuleApplication] 才能有效
                // 此功能默认启用 - 关闭后将不会在功能初始化的时候装载 [YukiHookDataChannel]
                // 功能启用后 - 将会在宿主启动时自动 Hook [Application] 的生命周期方法进行注册
                isEnableDataChannel = true
                // 是否启用 [Member] 缓存功能
                // 为防止 [Member] 复用过高造成的系统 GC 问题 - 此功能默认启用
                // 除非缓存的 [Member] 发生了混淆的问题 - 否则建议启用
                isEnableMemberCache = true
            }
        }
        override fun onHook(){
            YukiHookAPI.encase {
                loadApp( APP_NAME ){
    
                    ClassLoader::class.java.hook {
                        injectMember {
                            method {
                                name = "loadClass"
                                //param(String::class.java)
                            }
                            afterHook {
                                val className = args[0] as String
                                //loggerI(msg = "loaded class:${className}")
                                loggerI(msg = "result:${hook_classes.contains(className)}")//正常打印,后面的代码不会运行
                                loggerI(msg = "现在要加载hooker")//不能打印
                                loadHooker(MethodHooks(className))
                            }
    
    
                        }
                    }
                    "com.baidu.homework.activity.search.whole.PicManySearchActivity".hook {
                        injectMember {
                            method {
                                name = "onCreate"
                                param(BundleClass)
                            }
                            beforeHook {
                                loggerI(msg = "Has hooked method:PicManySearchActivity.onCreate")
                            }
                        }
                    }
                }
            }
        }
    }
    
    val hook_classes  = listOf(
        "com.baidu.homework.activity.search.whole.PicManySearchActivity",
    )
    
    class MethodHooks(className : String) : MyBaseHooker(className){
        override fun onHook() {
    
            loadApp(APP_NAME){
                loggerI(msg = "loaded class:${className}")
                //若执行以下代码,则app直接卡死
                //loggerI(msg = hook_classes.contains(className) as String)
    
            }
        }
    }
    
    abstract class MyBaseHooker(class_name : String) : YukiBaseHooker() {
        var className : String = "";
        init {
            className = class_name
        }
        abstract override fun onHook()
    }
    
    bug fixed 
    opened by Saiyinfu 4
  • `method` 能否以多个条件查找方法呢?

    `method` 能否以多个条件查找方法呢?

    大概有这么一个场景,需要 Hook 的目标 App 在旧版本和新版本中存在同名但参数列表不同的方法:

    // 这是旧版本 App 的方法
    public static String methodName(Context context, boolean z, boolean z2)
    
    // 这是新版本 App 的方法
    public static String methodName(Context context, View view, boolean z, boolean z2, Intent intent, int i2)
    

    我需要在目标 App 原本的 methodName 方法执行前进行一些操作。尽管新版本增加了几个参数,但这些并不是我需要用到的。也就是说除了需要 Hook 的方法签名不同之外,我不需要对我自行实现的模块中的方法进行修改。

    YukiHookAPI 的文档中指出“存在多个 BaseFinder.IndexTypeCondition 时除了 order 只会生效最后一个”,这样的话我就需要将完全相同的代码复制两遍,比较繁琐。

    因此,不知道能否允许通过多个 IndexTypeCondition 来查找方法呢?或者我的这个需求有其他的实现方法吗?

    opened by Robotxm 2
  • Added getField & setField function

    Added getField & setField function

    假如需要修改自定义类型实例(innerClassInstance)中的变量(testString)

    class HookedClass {
        inner class TestClass(){
            val testString = "String Content"
        }
        private val innerClassInstance = TestClass()
    }
    

    根据我已了解到的YukiHookAPI用法,我会这样写:

    val innerClassInstance = field { name = "innerClassInstance" }.get(instance).any()
    innerClassInstance.javaclass.field { name = "testString" }.get(innerClassInstance).set("another String")
    

    如果需要设置innerClassInstance中的很多变量就会感觉很麻烦,要写多个innerClassInstance.javaclass,加上这个commit后就可以写成:

    val mField =  instance.getField("innerClassInstance").any()
    mField.setField("testString", "another String")
    

    这样如果需要设置innerClassInstance中的多个变量,就可以多写几个mField.setField()。而且直接对实例操作也会看起来更直观。 按照这个commit的写法,只能对 field 名称这个单一条件进行搜索,不过这个可以后续优化 我是YukiHookAPI的新手,如果已有类似简便的写法,也请麻烦告诉我一下 :-)

    opened by GSWXXN 2
  • [bug]在windows下无法识别路径,无法正常编译

    [bug]在windows下无法识别路径,无法正常编译

    在win下无法识别路径,编译失败。在linux下可正常编译。

    test项目 MIUINativeNotifyIcon

    > Task :app:kspDebugKotlin FAILED
    e: [ksp] [YukiHookAPI] Project Source Path "src\main" not matched
    Looking for help? see https://github.com/fankes/YukiHookAPI/wiki/%E4%BD%9C%E4%B8%BA-Xposed-%E6%A8%A1%E5%9D%97%E4%BD%BF%E7%94%A8%E7%9A%84%E7%9B%B8%E5%85%B3%E9%85%8D%E7%BD%AE
    e: [ksp] java.lang.RuntimeException: [YukiHookAPI] Project Source Path "src\main" not matched
    Looking for help? see https://github.com/fankes/YukiHookAPI/wiki/%E4%BD%9C%E4%B8%BA-Xposed-%E6%A8%A1%E5%9D%97%E4%BD%BF%E7%94%A8%E7%9A%84%E7%9B%B8%E5%85%B3%E9%85%8D%E7%BD%AE
            at com.highcapable.yukihookapi_ksp_xposed.YukiHookXposedProcessor$create$1.error(YukiHookXposedProcessor.kt:89)
            at com.highcapable.yukihookapi_ksp_xposed.YukiHookXposedProcessor$create$1.access$error(YukiHookXposedProcessor.kt:49)
            at com.highcapable.yukihookapi_ksp_xposed.YukiHookXposedProcessor$create$1$injectAssets$1.invoke(YukiHookXposedProcessor.kt:172)
            at com.highcapable.yukihookapi_ksp_xposed.YukiHookXposedProcessor$create$1$injectAssets$1.invoke(YukiHookXposedProcessor.kt:162)
            at com.highcapable.yukihookapi_ksp_xposed.YukiHookXposedProcessor$create$1.environment(YukiHookXposedProcessor.kt:78)
            at com.highcapable.yukihookapi_ksp_xposed.YukiHookXposedProcessor$create$1.environment$default(YukiHookXposedProcessor.kt:76)
            at com.highcapable.yukihookapi_ksp_xposed.YukiHookXposedProcessor$create$1.injectAssets(YukiHookXposedProcessor.kt:162)
            at com.highcapable.yukihookapi_ksp_xposed.YukiHookXposedProcessor$create$1.access$injectAssets(YukiHookXposedProcessor.kt:49)
            at com.highcapable.yukihookapi_ksp_xposed.YukiHookXposedProcessor$create$1$injectProcess$1.invoke$lambda-4$fetchKSClassDeclaration(YukiHookXposedProcessor.kt:119)
            at com.highcapable.yukihookapi_ksp_xposed.YukiHookXposedProcessor$create$1$injectProcess$1.invoke(YukiHookXposedProcessor.kt:148)
            at com.highcapable.yukihookapi_ksp_xposed.YukiHookXposedProcessor$create$1$injectProcess$1.invoke(YukiHookXposedProcessor.kt:107)
            at com.highcapable.yukihookapi_ksp_xposed.YukiHookXposedProcessor$create$1.environment(YukiHookXposedProcessor.kt:78)
            at com.highcapable.yukihookapi_ksp_xposed.YukiHookXposedProcessor$create$1.environment$default(YukiHookXposedProcessor.kt:76)
            at com.highcapable.yukihookapi_ksp_xposed.YukiHookXposedProcessor$create$1.injectProcess(YukiHookXposedProcessor.kt:107)
            at com.highcapable.yukihookapi_ksp_xposed.YukiHookXposedProcessor$create$1.process(YukiHookXposedProcessor.kt:99)
            at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$4$1.invoke(KotlinSymbolProcessingExtension.kt:195)
            at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$4$1.invoke(KotlinSymbolProcessingExtension.kt:193)
            at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.handleException(KotlinSymbolProcessingExtension.kt:287)
            at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.doAnalysis(KotlinSymbolProcessingExtension.kt:193)
            at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:120)
            at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:96)
            at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:262)
            at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:53)
            at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:113)
            at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:253)
            at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:100)
            at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli$default(KotlinToJVMBytecodeCompiler.kt:58)
            at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:170)
            at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:52)
            at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:92)
            at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:44)
            at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:98)
            at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1618)
            at jdk.internal.reflect.GeneratedMethodAccessor97.invoke(Unknown Source)
            at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.base/java.lang.reflect.Method.invoke(Method.java:564)
            at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:359)
            at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
            at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
            at java.base/java.security.AccessController.doPrivileged(AccessController.java:691)
            at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
            at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)
            at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
            at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)
            at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
            at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)
            at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
            at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
            at java.base/java.lang.Thread.run(Thread.java:832)
    
    e: Error occurred in KSP, check log for detail
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Execution failed for task ':app:kspDebugKotlin'.
    > Compilation error. See log for more details
    
    * Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
    
    * Get more help at https://help.gradle.org
    
    BUILD FAILED in 1s
    14 actionable tasks: 1 executed, 13 up-to-date
    
    bug fixed 
    opened by naicfeng 2
Owner
Fankesyooni
Salted Fish
Fankesyooni
AnyText - An Xposed module trying to hook TextView in any activities

AnyText What's this This application provides features to modify any TextView in

Leonardo 41 Nov 30, 2022
An inline hook library for Android apps.

android-inline-hook README 中文版 shadowhook is an inline hook library for Android apps. shadowhook is a module of "the android-inline-hook project". Fea

Bytedance Inc. 818 Dec 30, 2022
Android Package Inspector - dynamic analysis with api hooks, start unexported activities and more. (Xposed Module)

Inspeckage - Android Package Inspector Inspeckage is a tool developed to offer dynamic analysis of Android applications. By applying hooks to function

acpm 2.5k Jan 8, 2023
A general purpose kotlin library that use kotlin coroutines, flows and channels to provide timer features with the most easy and efficient way

Timer Timer is a general purpose kotlin library that use kotlin coroutines, flows and channels to provide timer features with the most easy and effici

Amr Saraya 3 Jul 11, 2022
A simple xposed module that helps you use your AdGuard subscription in multiple devices

DualGuard A simple xposed module that helps you use your AdGuard subscription in multiple (>3) devices. Monstor ahead! / 警告 This is NOT a module that

null 7 Oct 2, 2022
SIMNumberSetter - A small Xposed module to set the SIM card's phone subscriber number

SIM Number Setter SIM Number Setter is a small Xposed module that invokes normal

Kieron Quinn 99 Dec 30, 2022
Xposed module for Snapchat.

SnapMod Xposed module for Snapchat. Setup To set SnapMod up, download and install the latest apk from here. When you open it, it will ask to install s

Rodi 141 Jan 5, 2023
Media Provider Manager - An Xposed module intended to prevent media storage abuse

Media Provider Manager - An Xposed module intended to prevent media storage abuse

null 104 Dec 26, 2022
Mixed Xposed+Magisk module for customization of AOSP-based Android 12+

This is a mixed Xposed+Magisk module, which is made to allow customizations that are not originally designed in AOSP (Android Open Source Project).

Siavash 654 Jan 4, 2023
Xposed module which will set location where you want without effect mock location.

GPS Setter Support/Discussion: XDA thread As most of GPS spoof app not working anymore coz some are old and some are not proper implement with current

Android1500 73 Dec 28, 2022
Xposed module to set the Signature Scheme for Android 30 >= to 1. This allows system apps to be modified

SetSignatureSchemeV1 Xposed module to set the Signature Scheme for Android 30+ to 1. This allows system apps to be modified. This module makes the met

null 4 Sep 20, 2022
Xposed-based motion simulator with sensor support.

This project is under active development MotionEmulator Android motion simulator with sensor support. Scenarios If you study in universities in China,

ZhuFu 26 Dec 24, 2022
An efficient GitHub profile app, written in Kotlin!

GitPositive An efficient GitHub profile app, written in Kotlin! GitPositive aims to be a simple and efficient GitHub profile app, following the princi

ACM VIT 14 Oct 12, 2022
This project is focused on the sample using the API's new preview version of Android-L, use of transitions, shadows etc...

Android L preview example Description This project is focused on the sample using the API's new preview version of Android-L, use of transitions, shad

Saul Molinero 165 Nov 10, 2022
New version of my Android app that shows you popular movies using themoviedb.org API.

New version of my Android app that shows you popular movies using themoviedb.org API. Using Modern Android Develpment skills like Kotlin, Room, Retrofit, Hilt, coroutines, Flow and Jetpack Compose.

Gemma Lara Savill 0 Apr 21, 2022
An library to help android developers working easly with activities and fragments (Kotlin version)

AFM An library to help android developer working easly with activities and fragments (Kotlin) Motivation Accelerate the process and abstract the logic

Massive Disaster 12 Oct 3, 2022
Freegemas libGDX is an Android and Java desktop port of Freegemas, which in turn is an open source version of the well known Bejeweled.

freegemas-gdx Freegemas libGDX is an Android, HTML 5 and Java desktop port of Freegemas, which in turn is an open source version of the well known Bej

David Saltares 144 Jun 21, 2022
Freegemas libGDX is an Android and Java desktop port of Freegemas, which in turn is an open source version of the well known Bejeweled.

freegemas-gdx Freegemas libGDX is an Android, HTML 5 and Java desktop port of Freegemas, which in turn is an open source version of the well known Bej

David Saltares 144 Jun 21, 2022
An unofficial version of the Android library for the Muse EEG headset

libmuse NOTE: This is an unofficial version of the Android library for interfacing with the Muse EEG headset. The Muse headset is a research-grade, lo

Siddhant Attavar 2 Dec 19, 2022