Package 

Class Pine


  • 
    public final class Pine
    
                        

    The bridge class provides main APIs for you.

    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      public interface Pine.HookListener

      Interface definition for a callback to be invoked when a method is hooked.

      public interface Pine.LibLoader

      Interface definition for an implementation to be invoked when load our native library (libpine.so)

      public interface Pine.HookMode

      Enum definition for how to hook method.

      public interface Pine.HookHandler

      Internal API. Implement the hook logic by implementing this interface.

      public final class Pine.HookRecord

      Internal API. Record hook info about a method.

      public class Pine.CallFrame

      A Holder that holds the method, "this" object, arguments, result or exception of a method call.

    • Method Summary

      Modifier and Type Method Description
      static int getHookMode() Return the current hook mode.
      static void setHookMode(int newHookMode) Set the way how Pine hook method.
      static void ensureInitialized() Initialize the Pine library if not initialized.
      static boolean isInitialized() Check whether Pine library is initialized.
      static void setHookHandler(Pine.HookHandler h) Set a handler that will be used when Pine hooking a method.
      static Pine.HookHandler getHookHandler() Get the handler that will be used when Pine hooking a method.Internal API, use the returned handler only when you are implementing your own handlerand want to continue hooking.
      static void setHookListener(Pine.HookListener l) Set a listener that will be called before/after hooking a method.
      static Pine.HookListener getHookListener() Get the listener that will be called before/after hooking method.
      static boolean is64Bit() Return whether the system is 64-bit.Note that this method will initialize Pine library if uninitialized.
      static MethodHook.Unhook hook(Member method, MethodHook callback) Register a hook that will be invoked when the {@code method} is invoked.Note that this will initialize Pine library if uninitialized.
      static MethodHook.Unhook hook(Member method, MethodHook callback, boolean canInitDeclaringClass) Register a hook that will be invoked when the {@code method} is invoked.Note that this will initialize Pine library if uninitialized.
      static Method hookReplace(Pine.HookRecord hookRecord, Method replacement, Method backup, boolean canInitDeclaringClass)
      static boolean isHooked(Member method) Return whether the given method has been hooked before.
      static Pine.HookRecord getHookRecord(long artMethod)
      static Object getObject(long thread, long address)
      static long getAddress(long thread, Object o)
      static Object invokeOriginalMethod(Member method, Object thisObject, Array<Object> args) Invoke the original implementation of the given method.If the method is not hooked, the behavior is undefined.
      static boolean compile(Member method) Compile the given method.
      static boolean decompile(Member method, boolean disableJit) Decompile the given method.
      static boolean disableJitInline() Prevent any JIT inlining in the current process.
      static void setJitCompilationAllowed(boolean allowed) Set whether we can manually JIT compile a method.
      static void setJitCompilationAllowed(boolean allowed, boolean autoCompileBridge) Set whether we can manually JIT compile a method.
      static boolean disableProfileSaver() Prevent art recording our method call profile.
      static void setDebuggable(boolean debuggable) Set whether the current process is debuggable, like {@code PineConfig#debuggable} but allowsyou set the value after Pine library is initialized.
      static void disableHiddenApiPolicy(boolean application, boolean platform) Disable the hidden api restriction policy in the current process.
      static Object handleCall(Pine.HookRecord hookRecord, Object thisObject, Array<Object> args)
      static void log(String message) Print a log with "Pine" tag if {@code PineConfig#debug} is set, or do nothing.
      static void log(String fmt, Array<Object> args) Print a log with "Pine" tag if {@code PineConfig#debug} is set, or do nothing.
      static native long getArtMethod(Member method)
      static native void getArgsArm32(int extras, int sp, Array<int> crOut, Array<int> stack, Array<float> fpOut)
      static native void getArgsArm64(long extras, long sp, Array<boolean> typeWides, Array<long> crOut, Array<long> stack, Array<double> fpOut)
      static native void getArgsX86(int extras, Array<int> out, int ebx)
      static native long currentArtThread0()
      static native long cloneExtras(long origin)
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • getHookMode

         static int getHookMode()

        Return the current hook mode.

      • setHookMode

         static void setHookMode(int newHookMode)

        Set the way how Pine hook method.

        Parameters:
        newHookMode - One of {@code Pine.HookMode.AUTO}, {@code Pine.HookMode.INLINE},{@code Pine.HookMode.REPLACEMENT} or {@code Pine.HookMode.INLINE_WITHOUT_JIT}.
      • ensureInitialized

         static void ensureInitialized()

        Initialize the Pine library if not initialized.WARNING: Calling this API will disable hidden api policy when {@code PineConfig.disableHiddenApiPolicy} or {@code PineConfig.disableHiddenApiPolicyForPlatformDomain}.Due to an ART bug, if a thread changes hidden api policy while another thread is callinga API that lists members of a class, a out-of-bounds write may occur and causes crashes.See ... for more details.

      • isInitialized

         static boolean isInitialized()

        Check whether Pine library is initialized.

      • setHookHandler

         static void setHookHandler(Pine.HookHandler h)

        Set a handler that will be used when Pine hooking a method.Internal API, use {@code HookListener} instead if you just want to be notified when hooking.Note that only one handler can exist at a time, so setting a new handler will overridethe old one. Save the old handler if yours don't know how to properly hook a method!

        Parameters:
        h - The handler you want to register.
      • getHookHandler

         static Pine.HookHandler getHookHandler()

        Get the handler that will be used when Pine hooking a method.Internal API, use the returned handler only when you are implementing your own handlerand want to continue hooking. Do NOT use the returned hook handler if you just want to hook.

      • setHookListener

         static void setHookListener(Pine.HookListener l)

        Set a listener that will be called before/after hooking a method.

        Parameters:
        l - The listener you want to set.
      • is64Bit

         static boolean is64Bit()

        Return whether the system is 64-bit.Note that this method will initialize Pine library if uninitialized.

      • hook

         static MethodHook.Unhook hook(Member method, MethodHook callback)

        Register a hook that will be invoked when the {@code method} is invoked.Note that this will initialize Pine library if uninitialized.

        Parameters:
        method - The method want to control.
        callback - The callback that will be invoked when the {@code method} is invoked.
      • hook

         static MethodHook.Unhook hook(Member method, MethodHook callback, boolean canInitDeclaringClass)

        Register a hook that will be invoked when the {@code method} is invoked.Note that this will initialize Pine library if uninitialized.

        Parameters:
        method - The method want to control.
        callback - The callback that will be invoked when the {@code method} is invoked.
        canInitDeclaringClass - {@code true} if initializing the class is allowed, {@code false} otherwise.
      • isHooked

         static boolean isHooked(Member method)

        Return whether the given method has been hooked before.Note that once the method is hooked, this will return {@code true}, even it has been unhooked.

        Parameters:
        method - the method you want to check.
      • invokeOriginalMethod

         static Object invokeOriginalMethod(Member method, Object thisObject, Array<Object> args)

        Invoke the original implementation of the given method.If the method is not hooked, the behavior is undefined. Now Pine will try to directly invoke it,but if other threads hooked the given method between we check if the method is hookedand invoke it directly, this call will be intercepted and the registered hooks will betriggered. DO NOT RELY ON THIS UNRELIABLE INTERNAL BEHAVIOR.

        Parameters:
        method - The method you want to invoke its original implementation.
        thisObject - The object the underlying method is invoked from
        args - The arguments used for the method call
      • compile

         static boolean compile(Member method)

        Compile the given method. Note that this will always do nothing on Android R+,and may crash if JIT compilation is not allowed the current process,like some system process. Make sure you really need this before use!

        Parameters:
        method - The method you want to compile.
      • decompile

         static boolean decompile(Member method, boolean disableJit)

        Decompile the given method. Force the given method executes by interpreter.This may be very useful when hooking a method that is inlined into caller.Note that in that case, you should decompile the caller rather than the callee.

        Parameters:
        method - The method you want to decompile.
        disableJit - {@code true} if you want to prevent the method gets JIT compiled again
      • disableJitInline

        @Deprecated() static boolean disableJitInline()

        Prevent any JIT inlining in the current process. DOES NOT WORK FOR NOW.

      • setJitCompilationAllowed

         static void setJitCompilationAllowed(boolean allowed)

        Set whether we can manually JIT compile a method.

        Parameters:
        allowed - {@code true} if allowed, {@code false} otherwise.
      • setJitCompilationAllowed

         static void setJitCompilationAllowed(boolean allowed, boolean autoCompileBridge)

        Set whether we can manually JIT compile a method.

        Parameters:
        allowed - {@code true} if allowed, {@code false} otherwise.
        autoCompileBridge - {@code true} if try to automatically compile bridge methods for better performance
      • disableProfileSaver

         static boolean disableProfileSaver()

        Prevent art recording our method call profile. This can prevent methods being AOT-compiled,so can avoid some hook invalidation caused by optimization, but will cause performance problems.

      • setDebuggable

         static void setDebuggable(boolean debuggable)

        Set whether the current process is debuggable, like {@code PineConfig#debuggable} but allowsyou set the value after Pine library is initialized.

        Parameters:
        debuggable - whether the current process is debuggable.
      • disableHiddenApiPolicy

         static void disableHiddenApiPolicy(boolean application, boolean platform)

        Disable the hidden api restriction policy in the current process.

        Parameters:
        application - whether the restriction policy for application domain should be disabled
        platform - whether the restriction policy for platform domain should be disabled
      • log

         static void log(String message)

        Print a log with "Pine" tag if {@code PineConfig#debug} is set, or do nothing.

        Parameters:
        message - The message you want print.
      • log

         static void log(String fmt, Array<Object> args)

        Print a log with "Pine" tag if {@code PineConfig#debug} is set, or do nothing.

        Parameters:
        fmt - The message format you want print.
        args - The args used to format {@code format}.
      • getArgsX86

         static native void getArgsX86(int extras, Array<int> out, int ebx)
      • cloneExtras

         static native long cloneExtras(long origin)