Need help with pine?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

canyie
252 Stars 55 Forks 160 Commits 5 Opened issues

Description

Dynamic java method hook framework on ART.

Services available

!
?

Need anything else?

Contributors list

Pine Download LICENSE

中文版本

Introduction

Pine is a dynamic java method hook framework on ART runtime, it can intercept almost all java method calls in this process.

Currently it supports Android 4.4(ART only) ~ 11.0 with thumb-2/arm64 architecture.

About its working principle, you can refer to this Chinese article.

Note: For Android 6.0 and 32-bit mode, the arguments may be wrong; and for Android 9.0+, pine will disable the hidden api restriction policy.

Usage

JCenter seems to have stopped receiving new packages. Please add the following line to your root build.gradle:

groovy
repositories {
    maven {
        url  "https://dl.bintray.com/canyie/pine"
    }
}
Bintray and JCenter will be sunset. We are looking for an alternative; but before that, please use bintray.

Basic Usage

Add dependencies in build.gradle (like this):

groovy
dependencies {
    implementation 'top.canyie.pine:core:'
}
Basic configuration:
java
PineConfig.debug = true; // Do we need to print more detailed logs?
PineConfig.debuggable = BuildConfig.DEBUG; // Is this process debuggable?

Example 1: monitor the creation of activities ```java Pine.hook(Activity.class.getDeclaredMethod("onCreate", Bundle.class), new MethodHook() { @Override public void beforeCall(Pine.CallFrame callFrame) { Log.i(TAG, "Before " + callFrame.thisObject + " onCreate()"); }

@Override public void afterCall(Pine.CallFrame callFrame) {
    Log.i(TAG, "After " + callFrame.thisObject + " onCreate()");
}

}); ```

Example 2: monitor the creation and destroy of all java threads ```java final MethodHook runHook = new MethodHook() { @Override public void beforeCall(Pine.CallFrame callFrame) throws Throwable { Log.i(TAG, "Thread " + callFrame.thisObject + " started..."); }

@Override public void afterCall(Pine.CallFrame callFrame) throws Throwable {
    Log.i(TAG, "Thread " + callFrame.thisObject + " exit...");
}

};

Pine.hook(Thread.class.getDeclaredMethod("start"), new MethodHook() { @Override public void beforeCall(Pine.CallFrame callFrame) { Pine.hook(ReflectionHelper.getMethod(callFrame.thisObject.getClass(), "run"), runHook); } }); ```

Example 3: force allow any threads to modify the ui:

java
Method checkThread = Class.forName("android.view.ViewRootImpl").getDeclaredMethod("checkThread");
Pine.hook(checkThread, MethodReplacement.DO_NOTHING);

Xposed Support

Download

Pine supports hooking methods in Xposed-style and loading Xposd modules. (Only supports java method hook now.)

groovy
implementation 'top.canyie.pine:xposed:'
Direct hook methods in Xposed-style: ```java XposedHelpers.findAndHookMethod(TextView.class, "setText", CharSequence.class, TextView.BufferType.class, boolean.class, int.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { Log.e(TAG, "Before TextView.setText"); param.args[0] = "hooked"; }
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    Log.e(TAG, "After TextView.setText");
                }
            });
or like this:
```java
XposedBridge.hookMethod(target, callback);

and you can load xposed modules (resources hook is not supported now): ```java // 1. load modules PineXposed.loadModule(new File(modulePath));

// 2. call all 'IXposedHookLoadPackage' callback PineXposed.onPackageLoad(packageName, processName, appInfo, isFirstApp, classLoader); ```

Enhanced Features

With Dobby, you can use some enhancements of Pine:

groovy
implementation 'top.canyie.pine:enhances:0.0.1'
  • Delay hook (aka pending hook) support, hooking static methods without initialize its declaring class now:
    java
    PineEnhances.enableDelayHook();
    

Known issues

  • May not be compatible with some devices/systems.

  • Due to #11, we recommend hooking methods with less concurrency as much as possible, for example: ```java public static void method() { synchronized (sLock) { methodLocked(); } }

private static void methodLocked() { // ... } ``

In the example, we recommend that the hook method is
methodLocked
instead of
method`.

Discussion

QQ Group:949888394

Credits

License

Pine Copyright (c) canyie

AndroidELF Copyright (c) Swift Gan

Dobby Copyright (c) jmpews

Licensed under the Anti 996 License, Version 1.0 (the "License");

you may not use this "Pine" project except in compliance with the License.

You may obtain a copy of the License at

https://github.com/996icu/996.ICU/blob/master/LICENSE

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.