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) ~ 10.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.
Add dependencies in build.gradle (like this):
dependencies {
implementation 'top.canyie.pine:core:<version>'
}
Basic configuration:
PineConfig.debug = true; // Need to print more detailed log?
PineConfig.debuggable = BuildConfig.DEBUG; // Is this process debuggable?
Example 1: monitor the creation of activities
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
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:
Method checkThread = Class.forName("android.view.ViewRootImpl").getDeclaredMethod("checkThread");
Pine.hook(checkThread, MethodReplacement.DO_NOTHING);
Pine supports hooking methods in Xposed-style and loading Xposd modules. (Only supports java method hook now.)
implementation 'top.canyie.pine:xposed:<version>'
Direct hook methods in Xposed-style:
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:
XposedBridge.hookMethod(target, callback);
and you can load xposed modules (resources hook is not supported now):
// 1. load modules
PineXposed.loadModule(new File(moudlePath));
// 2. call all 'IXposedHookLoadPackage' callback
PineXposed.onPackageLoad(packageName, processName, appInfo, isFirstApp, classLoader);
AndroidELF Copyright (c) Swift Gan
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