From f62a80f6276569b57204e406ddc71180ffbdd739 Mon Sep 17 00:00:00 2001 From: Jorrit Jongma Date: Mon, 13 May 2019 16:52:37 +0200 Subject: [PATCH] Fix ProGuard issue Closes #1 This fix worked for the same issue in a different project, not sure why the issue shows up only for some projects, and even only for some people cloning the same git. Signed-off-by: rabbit2190 --- .../eu/chainfire/librootjava/AppProcess.java | 46 +++++++--------- .../eu/chainfire/librootjava/Debugger.java | 1 - .../java/eu/chainfire/librootjava/Linker.java | 17 +++--- .../java/eu/chainfire/librootjava/Logger.java | 37 +++++++------ .../eu/chainfire/librootjava/Policies.java | 2 +- .../eu/chainfire/librootjava/Reflection.java | 40 ++++++++------ .../eu/chainfire/librootjava/RootIPC.java | 14 +++-- .../librootjava/RootIPCReceiver.java | 18 +++--- .../eu/chainfire/librootjava/RootJava.java | 53 +++++++++--------- librootjava_example/build.gradle | 1 + .../librootjava_example/MainActivity.java | 2 +- .../root/RemoteInputStream.java | 14 ++--- .../librootjava_example/root/RootMain.java | 4 +- .../librootjavadaemon/RootDaemon.java | 55 ++++++++++++------- librootjavadaemon_example/build.gradle | 1 + .../MainActivity.java | 2 +- .../root/RootMain.java | 2 +- 17 files changed, 160 insertions(+), 149 deletions(-) diff --git a/librootjava/src/main/java/eu/chainfire/librootjava/AppProcess.java b/librootjava/src/main/java/eu/chainfire/librootjava/AppProcess.java index 4698b13..777d7e0 100644 --- a/librootjava/src/main/java/eu/chainfire/librootjava/AppProcess.java +++ b/librootjava/src/main/java/eu/chainfire/librootjava/AppProcess.java @@ -134,12 +134,11 @@ private static boolean isRunningAs32BitOn64BitArch() { * Note that app_process_original and app_process_init are checked to cope with root on * older Android versions and Xposed installations. * - * @see #getAppProcess() - * * @return Path to app_process binary with unspecified bits or null + * @see #getAppProcess() */ public static String getAppProcessNoBit() { - for (String candidate : new String[] { + for (String candidate : new String[]{ "/system/bin/app_process_original", "/system/bin/app_process_init", "/system/bin/app_process" @@ -154,10 +153,9 @@ public static String getAppProcessNoBit() { *
* It is unlikely you will need to call this method. * + * @return Path to 32-bit app_process or app_process with unspecified bits or null * @see #getAppProcess() * @see #getAppProcess32Bit(boolean) - * - * @return Path to 32-bit app_process or app_process with unspecified bits or null */ public static String getAppProcess32Bit() { return getAppProcess32Bit(true); @@ -168,15 +166,14 @@ public static String getAppProcess32Bit() { *
* It is unlikely you will need to call this method. * - * @see #getAppProcess() - * * @param orDefault Whether to return the app_process with unspecified bits if a specific 32-bit binary isn't found * @return Path to 32-bit app_process or optionally app_process with unspecified bits or null + * @see #getAppProcess() */ public static String getAppProcess32Bit(boolean orDefault) { // app_process32 or null if not 32-bit // if >32bit, app_process32 will always exist, if ==32bit, default is 32bit - for (String candidate : new String[] { + for (String candidate : new String[]{ "/system/bin/app_process32_original", "/system/bin/app_process32_init", "/system/bin/app_process32" @@ -192,13 +189,12 @@ public static String getAppProcess32Bit(boolean orDefault) { *
* It is unlikely you will need to call this method. * - * @see #getAppProcess() - * * @return Path to 64-bit app_process or null + * @see #getAppProcess() */ public static String getAppProcess64Bit() { // app_process64 or null if not 64-bit - for (String candidate : new String[] { + for (String candidate : new String[]{ "/system/bin/app_process64_original", "/system/bin/app_process64_init", "/system/bin/app_process64" @@ -213,9 +209,8 @@ public static String getAppProcess64Bit() { *
* It is unlikely you will need to call this method. * - * @see #getAppProcess() - * * @return Path to most-bits app_process or null + * @see #getAppProcess() */ public static String getAppProcessMaxBit() { String ret = getAppProcess64Bit(); @@ -291,18 +286,17 @@ public static boolean guessIfAppProcessIs64Bits(String app_process) { * "Error finding namespace of apex: no namespace called runtime". However, at least * on the first preview release of Q, running straight from /system/bin works and does * not give us a restricted SELinux context, so we skip relocation. - * + *

* TODO: Revisit on new Q preview and production releases. Maybe spend some time figuring out what causes the namespace error and if we can fix it. * - * @see #getAppProcessRelocate(Context, String, List, List, String) - * * @return should app_process be relocated ? + * @see #getAppProcessRelocate(Context, String, List, List, String) */ @TargetApi(Build.VERSION_CODES.M) public static boolean shouldAppProcessBeRelocated() { return !( - (Build.VERSION.SDK_INT >= 29) || - ((Build.VERSION.SDK_INT == 28) && (Build.VERSION.PREVIEW_SDK_INT != 0)) + (Build.VERSION.SDK_INT >= 29) || + ((Build.VERSION.SDK_INT == 28) && (Build.VERSION.PREVIEW_SDK_INT != 0)) ); } @@ -312,15 +306,14 @@ public static boolean shouldAppProcessBeRelocated() { * On many Android versions and roots, executing app_process directly will force an * SELinux context that we do not want. Relocating it bypasses that.
* - * @see #getAppProcess() - * @see #shouldAppProcessBeRelocated() - * - * @param context Application or activity context + * @param context Application or activity context * @param appProcessBase Path to original app_process or null for default - * @param preLaunch List that retrieves commands to execute to perform the relocation - * @param postExecution List that retrieves commands to execute to clean-up after execution - * @param path Path to relocate to - must exist prior to script execution - or null for default + * @param preLaunch List that retrieves commands to execute to perform the relocation + * @param postExecution List that retrieves commands to execute to clean-up after execution + * @param path Path to relocate to - must exist prior to script execution - or null for default * @return Path to relocated app_process + * @see #getAppProcess() + * @see #shouldAppProcessBeRelocated() */ public static String getAppProcessRelocate(Context context, String appProcessBase, List preLaunch, List postExecution, String path) { if (appProcessBase == null) appProcessBase = getAppProcess(); @@ -358,7 +351,8 @@ public static String getAppProcessRelocate(Context context, String appProcessBas } preLaunch.add(String.format(Locale.ENGLISH, "%s cp %s %s >/dev/null 2>/dev/null", BOX, appProcessBase, appProcessCopy)); preLaunch.add(String.format(Locale.ENGLISH, "%s chmod %s %s >/dev/null 2>/dev/null", BOX, onData ? "0766" : "0700", appProcessCopy)); - if (onData) preLaunch.add(String.format(Locale.ENGLISH, "restorecon %s >/dev/null 2>/dev/null", appProcessCopy)); + if (onData) + preLaunch.add(String.format(Locale.ENGLISH, "restorecon %s >/dev/null 2>/dev/null", appProcessCopy)); postExecution.add(String.format(Locale.ENGLISH, "%s rm %s >/dev/null 2>/dev/null", BOX, appProcessCopy)); return appProcessCopy; } diff --git a/librootjava/src/main/java/eu/chainfire/librootjava/Debugger.java b/librootjava/src/main/java/eu/chainfire/librootjava/Debugger.java index 27e2a31..94d234e 100644 --- a/librootjava/src/main/java/eu/chainfire/librootjava/Debugger.java +++ b/librootjava/src/main/java/eu/chainfire/librootjava/Debugger.java @@ -70,7 +70,6 @@ public static void setEnabled(boolean enabled) { * check. * * @param name Name to present to debugger, or null to use process name - * * @see #waitFor(boolean) */ public static void setName(String name) { diff --git a/librootjava/src/main/java/eu/chainfire/librootjava/Linker.java b/librootjava/src/main/java/eu/chainfire/librootjava/Linker.java index 0401133..8b60c27 100644 --- a/librootjava/src/main/java/eu/chainfire/librootjava/Linker.java +++ b/librootjava/src/main/java/eu/chainfire/librootjava/Linker.java @@ -50,7 +50,7 @@ private static String getenv(String name) { * The updated value is set at OS level, but System.getenv() calls may still return * the old values, as those are cached at JVM startup. * - * @param name Name of variable + * @param name Name of variable * @param value Value of variable */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) @@ -75,17 +75,16 @@ private static void setenv(String name, String value) { * Android 7.0 (API level 24) and up use linker namespaces, which prevent apps from loading * native libraries outside of that namespace.
* - * @see #getPatchedLdLibraryPath(boolean, String[]) - * * @return If linker namespaces are used + * @see #getPatchedLdLibraryPath(boolean, String[]) */ @TargetApi(23) private static boolean haveLinkerNamespaces() { return ( (Build.VERSION.SDK_INT >= 24) || - // 7.0 preview - ((Build.VERSION.SDK_INT == 23) && (Build.VERSION.PREVIEW_SDK_INT != 0)) + // 7.0 preview + ((Build.VERSION.SDK_INT == 23) && (Build.VERSION.PREVIEW_SDK_INT != 0)) ); } @@ -104,11 +103,10 @@ private static boolean haveLinkerNamespaces() { * We also add a marker and include the original LD_LIBRARY_PATH, so it's value may be * restored after load. Otherwise, executing other binaries may fail. * - * @see #restoreOriginalLdLibraryPath() - * - * @param use64bit Use 64-bit paths + * @param use64bit Use 64-bit paths * @param extraPaths Additional paths to include * @return Patched value for LD_LIBRARY_PATH + * @see #restoreOriginalLdLibraryPath() */ static String getPatchedLdLibraryPath(boolean use64bit, String[] extraPaths) { String LD_LIBRARY_PATH = getenv("LD_LIBRARY_PATH"); @@ -190,9 +188,8 @@ static String getPatchedLdLibraryPath(boolean use64bit, String[] extraPaths) { /** * Retrieve the pre-patched value of LD_LIBRARY_PATH. * - * @see #getPatchedLdLibraryPath(boolean, String[]) - * * @return Original value of LD_LIBRARY_PATH + * @see #getPatchedLdLibraryPath(boolean, String[]) */ private static String getOriginalLdLibraryPath() { String LD_LIBRARY_PATH = System.getenv("LD_LIBRARY_PATH"); diff --git a/librootjava/src/main/java/eu/chainfire/librootjava/Logger.java b/librootjava/src/main/java/eu/chainfire/librootjava/Logger.java index 5ad1ee0..fb37c99 100644 --- a/librootjava/src/main/java/eu/chainfire/librootjava/Logger.java +++ b/librootjava/src/main/java/eu/chainfire/librootjava/Logger.java @@ -22,7 +22,7 @@ */ @SuppressWarnings({"unused", "WeakerAccess"}) public class Logger { - private static String getDefaultLogTag(){ + private static String getDefaultLogTag() { String tag = BuildConfig.APPLICATION_ID; int p; while ((p = tag.indexOf('.')) >= 0) { @@ -34,15 +34,16 @@ private static String getDefaultLogTag(){ private static String LOG_TAG = getDefaultLogTag(); private static boolean log = false; - + /** * Set LOG_TAG + * * @param logTag LOG_TAG to use */ public static void setLogTag(String logTag) { LOG_TAG = logTag; } - + /** * @return LOG_TAG */ @@ -61,7 +62,7 @@ public static void setDebugLogging(boolean enabled) { * Log on debug level * * @param message Message to format - * @param args Format arguments + * @param args Format arguments */ public static void d(String message, Object... args) { if (log) { @@ -75,9 +76,9 @@ public static void d(String message, Object... args) { /** * Log on debug level with prefix * - * @param prefix Prefix to prepend + * @param prefix Prefix to prepend * @param message Message to format - * @param args Format arguments + * @param args Format arguments */ public static void dp(String prefix, String message, Object... args) { if (log) { @@ -105,7 +106,7 @@ public static void ex(Exception e) { * Log on verbose level * * @param message Message to format - * @param args Format arguments + * @param args Format arguments */ public static void v(String message, Object... args) { android.util.Log.v(LOG_TAG, String.format(Locale.ENGLISH, message, args)); @@ -114,9 +115,9 @@ public static void v(String message, Object... args) { /** * Log on verbose level with prefix * - * @param prefix Prefix to prepend + * @param prefix Prefix to prepend * @param message Message to format - * @param args Format arguments + * @param args Format arguments */ public static void vp(String prefix, String message, Object... args) { message = String.format(Locale.ENGLISH, message, args); @@ -128,7 +129,7 @@ public static void vp(String prefix, String message, Object... args) { * Log on info level * * @param message Message to format - * @param args Format arguments + * @param args Format arguments */ public static void i(String message, Object... args) { android.util.Log.i(LOG_TAG, String.format(Locale.ENGLISH, message, args)); @@ -137,9 +138,9 @@ public static void i(String message, Object... args) { /** * Log on info level with prefix * - * @param prefix Prefix to prepend + * @param prefix Prefix to prepend * @param message Message to format - * @param args Format arguments + * @param args Format arguments */ public static void ip(String prefix, String message, Object... args) { message = String.format(Locale.ENGLISH, message, args); @@ -151,7 +152,7 @@ public static void ip(String prefix, String message, Object... args) { * Log on warning level * * @param message Message to format - * @param args Format arguments + * @param args Format arguments */ public static void w(String message, Object... args) { android.util.Log.w(LOG_TAG, String.format(Locale.ENGLISH, message, args)); @@ -160,9 +161,9 @@ public static void w(String message, Object... args) { /** * Log on warning level with prefix * - * @param prefix Prefix to prepend + * @param prefix Prefix to prepend * @param message Message to format - * @param args Format arguments + * @param args Format arguments */ public static void wp(String prefix, String message, Object... args) { message = String.format(Locale.ENGLISH, message, args); @@ -174,7 +175,7 @@ public static void wp(String prefix, String message, Object... args) { * Log on error level * * @param message Message to format - * @param args Format arguments + * @param args Format arguments */ public static void e(String message, Object... args) { android.util.Log.e(LOG_TAG, String.format(Locale.ENGLISH, message, args)); @@ -183,9 +184,9 @@ public static void e(String message, Object... args) { /** * Log on error level with prefix * - * @param prefix Prefix to prepend + * @param prefix Prefix to prepend * @param message Message to format - * @param args Format arguments + * @param args Format arguments */ public static void ep(String prefix, String message, Object... args) { message = String.format(Locale.ENGLISH, message, args); diff --git a/librootjava/src/main/java/eu/chainfire/librootjava/Policies.java b/librootjava/src/main/java/eu/chainfire/librootjava/Policies.java index 70a1505..b4afa12 100644 --- a/librootjava/src/main/java/eu/chainfire/librootjava/Policies.java +++ b/librootjava/src/main/java/eu/chainfire/librootjava/Policies.java @@ -26,7 +26,7 @@ public class Policies { * SELinux policies that require patching for the Binder calls to work on newer Android * versions. Failing to do this may cause Binder transactions to fail. */ - private static String[] required = new String[] { + private static String[] required = new String[]{ /* We skip the init context used in older SuperSU versions, as that is potentially dangerous, and Android versions that actually require this policy modification are likely to run a SuperSU version that uses it's own SELinux context or Magisk */ diff --git a/librootjava/src/main/java/eu/chainfire/librootjava/Reflection.java b/librootjava/src/main/java/eu/chainfire/librootjava/Reflection.java index 077d35b..0dd74e3 100644 --- a/librootjava/src/main/java/eu/chainfire/librootjava/Reflection.java +++ b/librootjava/src/main/java/eu/chainfire/librootjava/Reflection.java @@ -18,7 +18,9 @@ class Reflection { private static final Object lock = new Object(); - /** Cache for getSystemContext() */ + /** + * Cache for getSystemContext() + */ @SuppressLint("StaticFieldLeak") private static Context systemContext = null; @@ -27,9 +29,8 @@ class Reflection { *
* Stability: unlikely to change, this implementation works from 1.6 through 9.0
* - * @see RootJava#getSystemContext() - * * @return system context + * @see RootJava#getSystemContext() */ @SuppressLint("PrivateApi") static Context getSystemContext() { @@ -55,7 +56,7 @@ static Context getSystemContext() { Object oActivityThread = mSystemMain.invoke(null); Object oContext = mGetSystemContext.invoke(oActivityThread); - systemContext = (Context)oContext; + systemContext = (Context) oContext; return systemContext; } catch (Exception e) { Logger.ex(e); @@ -64,7 +65,9 @@ static Context getSystemContext() { } } - /** Cache for getActivityManager() */ + /** + * Cache for getActivityManager() + */ private static Object oActivityManager = null; /** @@ -108,7 +111,9 @@ private static Object getActivityManager() { } } - /** Cache for getFlagReceiverFromShell() */ + /** + * Cache for getFlagReceiverFromShell() + */ private static Integer FLAG_RECEIVER_FROM_SHELL = null; /** @@ -140,7 +145,9 @@ private static int getFlagReceiverFromShell() { } } - /** Cache for getBroadcastIntent() */ + /** + * Cache for getBroadcastIntent() + */ private static Method mBroadcastIntent = null; /** @@ -179,10 +186,9 @@ private static Method getBroadcastIntent(Class cActivityManager) { *
* This implementation does not require us to have a context * + * @param intent Intent to broadcast * @see RootJava#sendBroadcast(Intent) * @see RootIPC#broadcastIPC() - * - * @param intent Intent to broadcast */ @SuppressLint("PrivateApi") static void sendBroadcast(Intent intent) { @@ -216,16 +222,15 @@ static void sendBroadcast(Intent intent) { *
* Stability: unlikely to change, this implementation works from 1.6 through 9.0
* - * @see Debugger#isEnabled() - * * @return Debugging enabled + * @see Debugger#isEnabled() */ @SuppressLint("PrivateApi") static boolean isDebuggingEnabled() { try { Class cVMDebug = Class.forName("dalvik.system.VMDebug"); Method mIsDebuggingEnabled = cVMDebug.getDeclaredMethod("isDebuggingEnabled"); - return (Boolean)mIsDebuggingEnabled.invoke(null); + return (Boolean) mIsDebuggingEnabled.invoke(null); } catch (Exception e) { Logger.ex(e); return false; @@ -261,11 +266,10 @@ static class InterfaceRetriever { * Stability: stable, as changes to this pattern in AOSP would probably require all * AIDL-using apps to be recompiled. * - * @see RootIPCReceiver#getInterfaceFromBinder(IBinder) - * - * @param clazz Class of T + * @param clazz Class of T * @param binder Binder proxy to retrieve interface from * @return T (proxy) instance or null + * @see RootIPCReceiver#getInterfaceFromBinder(IBinder) */ T getInterfaceFromBinder(Class clazz, IBinder binder) { // There does not appear to be a nice way to do this without reflection, @@ -276,17 +280,17 @@ T getInterfaceFromBinder(Class clazz, IBinder binder) { Field fDescriptor = cStub.getDeclaredField("DESCRIPTOR"); fDescriptor.setAccessible(true); - String descriptor = (String)fDescriptor.get(binder); + String descriptor = (String) fDescriptor.get(binder); IInterface intf = binder.queryLocalInterface(descriptor); if (clazz.isInstance(intf)) { // local - return (T)intf; + return (T) intf; } else { // remote Class cProxy = Class.forName(clazz.getName() + "$Stub$Proxy"); Constructor ctorProxy = cProxy.getDeclaredConstructor(IBinder.class); ctorProxy.setAccessible(true); - return (T)ctorProxy.newInstance(binder); + return (T) ctorProxy.newInstance(binder); } } catch (Exception e) { Logger.ex(e); diff --git a/librootjava/src/main/java/eu/chainfire/librootjava/RootIPC.java b/librootjava/src/main/java/eu/chainfire/librootjava/RootIPC.java index 3d6fab6..bd6aac5 100644 --- a/librootjava/src/main/java/eu/chainfire/librootjava/RootIPC.java +++ b/librootjava/src/main/java/eu/chainfire/librootjava/RootIPC.java @@ -73,11 +73,11 @@ public IBinder.DeathRecipient getDeathRecipient() { /** * Wrap the supplied Binder, send it to the target package, and optionally wait until a session is connected and completed * - * @param packageName Package name of process to send Binder to. Use BuildConfig.APPLICATION_ID (double check you're importing the correct BuildConfig!) for convenience - * @param ipc Binder object to wrap and send out - * @param code User-value, should be unique per Binder + * @param packageName Package name of process to send Binder to. Use BuildConfig.APPLICATION_ID (double check you're importing the correct BuildConfig!) for convenience + * @param ipc Binder object to wrap and send out + * @param code User-value, should be unique per Binder * @param connection_timeout_ms How long to wait for the other process to initiate the connection, -1 for default, 0 to wait forever (if blocking) - * @param blocking If a connection is made, do not return until the other process disconnects or dies, + * @param blocking If a connection is made, do not return until the other process disconnects or dies, * @throws TimeoutException If the connection times out */ public RootIPC(String packageName, IBinder ipc, int code, int connection_timeout_ms, boolean blocking) throws TimeoutException { @@ -140,9 +140,9 @@ public boolean haveAllClientsDisconnected() { /** * Wrap the binder in an intent and broadcast it to packageName - * + *

* Uses the reflected sendBroadcast method that doesn't require us to have a context - * + *

* You may call this manually to re-broadcast the interface */ public void broadcastIPC() { @@ -203,6 +203,7 @@ private void pruneConnections() { /** * Get Connection based on IBinder + * * @param binder IBinder to find Connection for * @return Connection or null */ @@ -220,6 +221,7 @@ private Connection getConnection(IBinder binder) { /** * Get Connection based on DeathRecipient + * * @param deathRecipient DeathRecipient to find Connection for * @return Connection or null */ diff --git a/librootjava/src/main/java/eu/chainfire/librootjava/RootIPCReceiver.java b/librootjava/src/main/java/eu/chainfire/librootjava/RootIPCReceiver.java index 3f9b9df..74ee85e 100644 --- a/librootjava/src/main/java/eu/chainfire/librootjava/RootIPCReceiver.java +++ b/librootjava/src/main/java/eu/chainfire/librootjava/RootIPCReceiver.java @@ -37,9 +37,8 @@ * This class handles receiving the (wrapped) Binder interface, casting it to your own interface, * and handling connection state. * - * @see RootIPC - * * @param Your IPC interface + * @see RootIPC */ @SuppressWarnings({"unused", "WeakerAccess", "Convert2Diamond", "TryWithIdenticalCatches"}) public abstract class RootIPCReceiver { @@ -165,10 +164,9 @@ public void run() { /** * Convenience constructor that calls the proper constructor. * - * @see #RootIPCReceiver(Context, int, Class) - * * @param context Context to attach receiver to - * @param code User-value, should be unique per Binder + * @param code User-value, should be unique per Binder + * @see #RootIPCReceiver(Context, int, Class) */ public RootIPCReceiver(Context context, int code) { this(context, code, null); @@ -204,8 +202,8 @@ public RootIPCReceiver(Context context, int code) { * * * @param context Context to attach receiver to - * @param code User-value, should be unique per Binder - * @param clazz Class of the IPC interface, or null to attempt to determine + * @param code User-value, should be unique per Binder + * @param clazz Class of the IPC interface, or null to attempt to determine */ @SuppressWarnings("unchecked") public RootIPCReceiver(Context context, int code, Class clazz) { @@ -214,8 +212,8 @@ public RootIPCReceiver(Context context, int code, Class clazz) { // Not inside the Reflection class because this is a well known Java trick that // doesn't depend on Android-specific classes. Type superClass = getClass().getGenericSuperclass(); - Type tType = ((ParameterizedType)superClass).getActualTypeArguments()[0]; - this.clazz = (Class)tType; + Type tType = ((ParameterizedType) superClass).getActualTypeArguments()[0]; + this.clazz = (Class) tType; } else { this.clazz = clazz; } @@ -242,7 +240,7 @@ public void setContext(Context context) { if (context != null) { if (context instanceof ContextWrapper) { // prevent NPE if constructed in activity class definition - if (((ContextWrapper)context).getBaseContext() == null) return; + if (((ContextWrapper) context).getBaseContext() == null) return; } this.context = new WeakReference(context); context.registerReceiver(receiver, filter, null, handler); diff --git a/librootjava/src/main/java/eu/chainfire/librootjava/RootJava.java b/librootjava/src/main/java/eu/chainfire/librootjava/RootJava.java index 826d7c8..523b3d6 100644 --- a/librootjava/src/main/java/eu/chainfire/librootjava/RootJava.java +++ b/librootjava/src/main/java/eu/chainfire/librootjava/RootJava.java @@ -72,7 +72,7 @@ public class RootJava { * String libpath = RootJava.getLibraryPath(context, "mynativecode"); * } * - * + *

* NOTE: This is not compatible with using extractNativeLibs="false" in your manifest! * * @param context Application or activity context @@ -97,7 +97,7 @@ public static String getLibraryPath(Context context, String libname) { // try nativeLibraryDir ApplicationInfo appInfo = context.getApplicationInfo(); - for (String candidate : new String[] { + for (String candidate : new String[]{ appInfo.nativeLibraryDir + File.separator + "lib" + libname + ".so", appInfo.nativeLibraryDir + File.separator + libname + ".so" // unlikely but not impossible }) { @@ -109,7 +109,7 @@ public static String getLibraryPath(Context context, String libname) { // try BaseDexClassLoader if (context.getClassLoader() instanceof BaseDexClassLoader) { try { - BaseDexClassLoader bdcl = (BaseDexClassLoader)context.getClassLoader(); + BaseDexClassLoader bdcl = (BaseDexClassLoader) context.getClassLoader(); return bdcl.findLibrary(libname); } catch (Throwable t) { // not a standard call: catch Errors and Violations too aside from Exceptions @@ -117,7 +117,7 @@ public static String getLibraryPath(Context context, String libname) { } // try (old) default location - for (String candidate : new String[] { + for (String candidate : new String[]{ String.format(Locale.ENGLISH, "/data/data/%s/lib/lib%s.so", packageName, libname), String.format(Locale.ENGLISH, "/data/data/%s/lib/%s.so", packageName, libname) }) { @@ -131,14 +131,14 @@ public static String getLibraryPath(Context context, String libname) { /** * Get string to be executed (in a root shell) to launch the Java code as root. - * + *

* You would normally use {@link #getLaunchScript(Context, Class, String, String, String[], String)} * - * @param context Application or activity context - * @param clazz Class containing "main" method + * @param context Application or activity context + * @param clazz Class containing "main" method * @param app_process Specific app_process binary to use, or null for default - * @param params Parameters to supply to Java code, or null - * @param niceName Process name to use (ps) instead of app_process (should be unique to your app), or null + * @param params Parameters to supply to Java code, or null + * @param niceName Process name to use (ps) instead of app_process (should be unique to your app), or null * @return Script */ public static String getLaunchString(Context context, Class clazz, String app_process, String[] params, String niceName) { @@ -148,15 +148,15 @@ public static String getLaunchString(Context context, Class clazz, String app /** * Get string to be executed (in a root shell) to launch the Java code as root. - * + *

* You would normally use {@link #getLaunchScript(Context, Class, String, String, String[], String)} * * @param packageCodePath Path to APK - * @param clazz Class containing "main" method - * @param app_process Specific app_process binary to use - * @param is64Bit Is specific app_process binary 64-bit? - * @param params Parameters to supply to Java code, or null - * @param niceName Process name to use (ps) instead of app_process (should be unique to your app), or null + * @param clazz Class containing "main" method + * @param app_process Specific app_process binary to use + * @param is64Bit Is specific app_process binary 64-bit? + * @param params Parameters to supply to Java code, or null + * @param niceName Process name to use (ps) instead of app_process (should be unique to your app), or null * @return Script */ public static String getLaunchString(String packageCodePath, String clazz, String app_process, boolean is64Bit, String[] params, String niceName) { @@ -171,7 +171,7 @@ public static String getLaunchString(String packageCodePath, String clazz, Strin int p; String[] extraPaths = null; if ((p = app_process.lastIndexOf('/')) >= 0) { - extraPaths = new String[] { app_process.substring(0, p) }; + extraPaths = new String[]{app_process.substring(0, p)}; } String LD_LIBRARY_PATH = Linker.getPatchedLdLibraryPath(is64Bit, extraPaths); if (LD_LIBRARY_PATH != null) { @@ -221,12 +221,12 @@ public static String getLaunchString(String packageCodePath, String clazz, Strin * you may consider passing true to {@link Policies#setPatched(Boolean)} and prevent the * patching altogether. * - * @param context Application or activity context - * @param clazz Class containing "main" method - * @param app_process Specific app_process binary to use, or null for default + * @param context Application or activity context + * @param clazz Class containing "main" method + * @param app_process Specific app_process binary to use, or null for default * @param relocate_path Path to relocate app_process to (must exist), or null for default - * @param params Parameters to supply to Java code, or null - * @param niceName Process name to use (ps) instead of app_process (should be unique to your app), or null + * @param params Parameters to supply to Java code, or null + * @param niceName Process name to use (ps) instead of app_process (should be unique to your app), or null * @return Script */ public static List getLaunchScript(Context context, Class clazz, String app_process, String relocate_path, String[] params, String niceName) { @@ -249,8 +249,10 @@ public static List getLaunchScript(Context context, Class clazz, Stri return script; } - /** Prefixes of filename to remove from the app's cache directory */ - public static final String[] CLEANUP_CACHE_PREFIXES = new String[] { ".app_process32_", ".app_process64_" }; + /** + * Prefixes of filename to remove from the app's cache directory + */ + public static final String[] CLEANUP_CACHE_PREFIXES = new String[]{".app_process32_", ".app_process64_"}; /** * Clean up leftover files from our cache directory.
@@ -276,7 +278,7 @@ public static void cleanupCache(Context context) { *
* This version is for internal use, see {@link #cleanupCache(Context)} instead. * - * @param context Context to retrieve cache directory from + * @param context Context to retrieve cache directory from * @param prefixes List of prefixes to scrub */ public static void cleanupCache(Context context, final String[] prefixes) { @@ -351,11 +353,10 @@ public static Context getSystemContext() { * limited in many of the same ways the context returned by {@link #getSystemContext()} is, as * we still do not have an active ProcessRecord. * - * @see #getSystemContext() - * * @param packageName Name of the package to create Context for. Use BuildConfig.APPLICATION_ID (double check you're importing the correct BuildConfig!) to access our own package. * @return Package context * @throws PackageManager.NameNotFoundException If package could not be found + * @see #getSystemContext() */ public static Context getPackageContext(String packageName) throws PackageManager.NameNotFoundException { return getSystemContext().createPackageContext(packageName, 0); diff --git a/librootjava_example/build.gradle b/librootjava_example/build.gradle index 6a58f6d..9a34f77 100644 --- a/librootjava_example/build.gradle +++ b/librootjava_example/build.gradle @@ -15,6 +15,7 @@ android { buildTypes { release { minifyEnabled true + useProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } diff --git a/librootjava_example/src/main/java/eu/chainfire/librootjava_example/MainActivity.java b/librootjava_example/src/main/java/eu/chainfire/librootjava_example/MainActivity.java index 9a3a59d..758e92c 100644 --- a/librootjava_example/src/main/java/eu/chainfire/librootjava_example/MainActivity.java +++ b/librootjava_example/src/main/java/eu/chainfire/librootjava_example/MainActivity.java @@ -16,9 +16,9 @@ package eu.chainfire.librootjava_example; import android.graphics.Bitmap; +import android.os.Bundle; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; import android.text.method.ScrollingMovementMethod; import android.view.View; import android.widget.Button; diff --git a/librootjava_example/src/main/java/eu/chainfire/librootjava_example/root/RemoteInputStream.java b/librootjava_example/src/main/java/eu/chainfire/librootjava_example/root/RemoteInputStream.java index c09e530..43ae395 100644 --- a/librootjava_example/src/main/java/eu/chainfire/librootjava_example/root/RemoteInputStream.java +++ b/librootjava_example/src/main/java/eu/chainfire/librootjava_example/root/RemoteInputStream.java @@ -26,14 +26,14 @@ /** * Example helper class to pass InputStreams through Binder - * + *

* InputStream is a pretty basic class that is easily wrapped, because it really only requires * a handful of base methods. - * + *

* We cannot make an InputStream into a Binder-passable interface directly, because its definitions * includes throwing IOExceptions. It also defines multiple methods with the same name and a * different parameter list, which is not supported in aidl. - * + *

* You should never throw an exception in your Binder interface. We catch the exceptions and * return -2 instead, because conveniently all the methods we override should return values >= -1. * More complex classes would require more complex solutions. @@ -42,7 +42,7 @@ public class RemoteInputStream { /** * Wraps an InputStream in an IRemoteInputStream - * + *

* Use this on the root side * * @param is InputStream @@ -95,15 +95,15 @@ public void close() { /** * Wraps an IRemoteInputStream in an InputStream - * + *

* We throw an IOException if we receive a -2 result, because we know we caught one on the * other end in that case. The logcat output will obviously not show the real reason for the * exception. - * + *

* We also wrap the InputStream we create inside a BufferedInputStream, to potentially reduce * the number of calls made. We increase the buffer size to 64kb in case this is ever used * to actually read large files, which is quite a bit faster than the default 8kb. - * + *

* Use this on the non-root side. * * @param ris IRemoteInputStream received through Binder diff --git a/librootjava_example/src/main/java/eu/chainfire/librootjava_example/root/RootMain.java b/librootjava_example/src/main/java/eu/chainfire/librootjava_example/root/RootMain.java index ea3052f..3fd8c05 100644 --- a/librootjava_example/src/main/java/eu/chainfire/librootjava_example/root/RootMain.java +++ b/librootjava_example/src/main/java/eu/chainfire/librootjava_example/root/RootMain.java @@ -49,8 +49,8 @@ public class RootMain { * Call this from non-root code to generate the script to launch the root code * * @param context Application or activity context - * @param params Parameters to pass - * @param libs Native libraries to pass (no extension), for example libmynativecode + * @param params Parameters to pass + * @param libs Native libraries to pass (no extension), for example libmynativecode * @return Script */ public static List getLaunchScript(Context context, String[] params, String[] libs) { diff --git a/librootjavadaemon/src/main/java/eu/chainfire/librootjavadaemon/RootDaemon.java b/librootjavadaemon/src/main/java/eu/chainfire/librootjavadaemon/RootDaemon.java index ac625bb..c107573 100644 --- a/librootjavadaemon/src/main/java/eu/chainfire/librootjavadaemon/RootDaemon.java +++ b/librootjavadaemon/src/main/java/eu/chainfire/librootjavadaemon/RootDaemon.java @@ -43,7 +43,9 @@ @SuppressWarnings({"unused", "WeakerAccess", "Convert2Diamond"}) public class RootDaemon { - /** Used for logging */ + /** + * Used for logging + */ private static String LOG_PREFIX = "daemon"; // ------------------------ calls for non-root ------------------------ @@ -57,7 +59,7 @@ public class RootDaemon { * NOTE: This is not compatible with using extractNativeLibs="false" in your manifest! * * @param context Application or activity context - * @param script Script from RootJava.getLaunchScript() + * @param script Script from RootJava.getLaunchScript() * @return Patched script */ public static List patchLaunchScript(Context context, List script) { @@ -88,7 +90,8 @@ public static List patchLaunchScript(Context context, List scrip ret.add(String.format(Locale.ENGLISH, "%s cp %s %s >/dev/null 2>/dev/null", AppProcess.BOX, libSource, libExec)); ret.add(String.format(Locale.ENGLISH, "%s chmod %s %s >/dev/null 2>/dev/null", AppProcess.BOX, onData ? "0766" : "0700", libExec)); - if (onData) ret.add(String.format(Locale.ENGLISH, "restorecon %s >/dev/null 2>/dev/null", libExec)); + if (onData) + ret.add(String.format(Locale.ENGLISH, "restorecon %s >/dev/null 2>/dev/null", libExec)); } // inject executable into command @@ -114,20 +117,22 @@ public static List patchLaunchScript(Context context, List scrip *
* NOTE: This is not compatible with using extractNativeLibs="false" in your manifest! * - * @param context Application or activity context - * @param clazz Class containing "main" method - * @param app_process Specific app_process binary to use, or null for default + * @param context Application or activity context + * @param clazz Class containing "main" method + * @param app_process Specific app_process binary to use, or null for default * @param relocate_path Path to relocate app_process to (must exist), or null for default - * @param params Parameters to supply to Java code, or null - * @param niceName Process name to use (ps) instead of app_process (should be unique to your app), or null + * @param params Parameters to supply to Java code, or null + * @param niceName Process name to use (ps) instead of app_process (should be unique to your app), or null * @return Script */ public static List getLaunchScript(Context context, Class clazz, String app_process, String relocate_path, String[] params, String niceName) { return patchLaunchScript(context, RootJava.getLaunchScript(context, clazz, app_process, relocate_path, params, niceName)); } - /** Prefixes of filename to remove from the app's cache directory */ - public static final String[] CLEANUP_CACHE_PREFIXES = new String[] { ".daemonize_" }; + /** + * Prefixes of filename to remove from the app's cache directory + */ + public static final String[] CLEANUP_CACHE_PREFIXES = new String[]{".daemonize_"}; /** * Clean up leftover files from our cache directory.
@@ -145,15 +150,21 @@ public static void cleanupCache(Context context) { // ------------------------ calls for root ------------------------ - /** Registered interfaces */ + /** + * Registered interfaces + */ private static final List ipcs = new ArrayList(); - /** Called before termination */ + /** + * Called before termination + */ public interface OnExitListener { void onExit(); } - /** Stored by daemonize(), called by exit() */ + /** + * Stored by daemonize(), called by exit() + */ private static volatile OnExitListener onExitListener = null; /** @@ -177,10 +188,10 @@ public interface OnExitListener { * are closed, we are running as a child of pid 1 (init), and no longer tied to the lifecycle of * the process that started us. * - * @param packageName Package name of the app. BuildConfig.APPLICATION_ID can generally be used. - * @param code User-value, should be unique per daemon process + * @param packageName Package name of the app. BuildConfig.APPLICATION_ID can generally be used. + * @param code User-value, should be unique per daemon process * @param surviveFrameworkRestart If false (recommended), automatically terminate if the Android framework restarts - * @param exitListener Callback called before the daemon exists either due to a newer daemon version being started or {@link #exit()} being called, or null + * @param exitListener Callback called before the daemon exists either due to a newer daemon version being started or {@link #exit()} being called, or null */ @SuppressLint("PrivateApi") public static void daemonize(String packageName, int code, boolean surviveFrameworkRestart, OnExitListener exitListener) { @@ -195,7 +206,7 @@ public static void daemonize(String packageName, int code, boolean surviveFramew Method mGetService = cServiceManager.getDeclaredMethod("getService", String.class); Method mAddService = cServiceManager.getDeclaredMethod("addService", String.class, IBinder.class); - IBinder svc = (IBinder)mGetService.invoke(null, id); + IBinder svc = (IBinder) mGetService.invoke(null, id); if (svc != null) { IRootDaemonIPC ipc = IRootDaemonIPC.Stub.asInterface(svc); if (!ipc.getVersion().equals(version)) { @@ -226,7 +237,7 @@ public static void daemonize(String packageName, int code, boolean surviveFramew your own code may still cause this process to terminate when the framework dies, we're just not doing it automatically. */ - IBinder activityService = (IBinder)mGetService.invoke(null, Context.ACTIVITY_SERVICE); + IBinder activityService = (IBinder) mGetService.invoke(null, Context.ACTIVITY_SERVICE); if (activityService != null) { try { activityService.linkToDeath(new IBinder.DeathRecipient() { @@ -275,8 +286,8 @@ public void broadcast() { * Use this method instead of librootjava's 'new RootIPC()' constructor when running as daemon. * * @param packageName Package name of the app. Use the same value as used when calling {@link #daemonize(String, int, boolean, OnExitListener)}. - * @param ipc Binder object to wrap and send out - * @param code User-value, should be unique per Binder + * @param ipc Binder object to wrap and send out + * @param code User-value, should be unique per Binder * @return RootIPC instance */ public static RootIPC register(String packageName, IBinder ipc, int code) { @@ -292,7 +303,9 @@ public static RootIPC register(String packageName, IBinder ipc, int code) { } } - /** Used to suspend the thread on which {@link #run()} is called */ + /** + * Used to suspend the thread on which {@link #run()} is called + */ private static final Object runWaiter = new Object(); /** diff --git a/librootjavadaemon_example/build.gradle b/librootjavadaemon_example/build.gradle index 1019acc..017d4b8 100644 --- a/librootjavadaemon_example/build.gradle +++ b/librootjavadaemon_example/build.gradle @@ -15,6 +15,7 @@ android { buildTypes { release { minifyEnabled true + useProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } diff --git a/librootjavadaemon_example/src/main/java/eu/chainfire/librootjavadaemon_example/MainActivity.java b/librootjavadaemon_example/src/main/java/eu/chainfire/librootjavadaemon_example/MainActivity.java index 85fa712..5a1c3db 100644 --- a/librootjavadaemon_example/src/main/java/eu/chainfire/librootjavadaemon_example/MainActivity.java +++ b/librootjavadaemon_example/src/main/java/eu/chainfire/librootjavadaemon_example/MainActivity.java @@ -15,9 +15,9 @@ package eu.chainfire.librootjavadaemon_example; +import android.os.Bundle; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; import android.text.method.ScrollingMovementMethod; import android.view.View; import android.widget.Button; diff --git a/librootjavadaemon_example/src/main/java/eu/chainfire/librootjavadaemon_example/root/RootMain.java b/librootjavadaemon_example/src/main/java/eu/chainfire/librootjavadaemon_example/root/RootMain.java index d2db3fa..65ed43a 100644 --- a/librootjavadaemon_example/src/main/java/eu/chainfire/librootjavadaemon_example/root/RootMain.java +++ b/librootjavadaemon_example/src/main/java/eu/chainfire/librootjavadaemon_example/root/RootMain.java @@ -39,7 +39,7 @@ public class RootMain { */ public static List getLaunchScript(Context context) { // We pass the daemon our PID so we know which process started it - String[] params = new String[] { + String[] params = new String[]{ String.valueOf(android.os.Process.myPid()) };