diff --git a/app/build/bin/aapt_rules.txt b/app/build/bin/aapt_rules.txt deleted file mode 100644 index cfe2364..0000000 --- a/app/build/bin/aapt_rules.txt +++ /dev/null @@ -1,10 +0,0 @@ -# view AndroidManifest.xml #generated:19 --keep class acessor.droidfrida.MainActivity { (...); } - -# onClick res/layout/main.xml #generated:38 --keepclassmembers class * { *** launchClicked(...); } - -# onClick res/layout/main.xml #generated:55 -# onClick res/layout/main.xml #generated:64 --keepclassmembers class * { *** tabClicked(...); } - diff --git a/app/build/bin/classes.dex b/app/build/bin/classes.dex deleted file mode 100644 index d8e0764..0000000 Binary files a/app/build/bin/classes.dex and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/BuildConfig$0$debug.class b/app/build/bin/classesdebug/acessor/droidfrida/BuildConfig$0$debug.class deleted file mode 100644 index 326450b..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/BuildConfig$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/BuildConfig.class b/app/build/bin/classesdebug/acessor/droidfrida/BuildConfig.class deleted file mode 100644 index f806024..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/BuildConfig.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/MainActivity$0$debug.class b/app/build/bin/classesdebug/acessor/droidfrida/MainActivity$0$debug.class deleted file mode 100644 index 654040a..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/MainActivity$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/MainActivity$100000000$0$debug.class b/app/build/bin/classesdebug/acessor/droidfrida/MainActivity$100000000$0$debug.class deleted file mode 100644 index 3c6c7d1..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/MainActivity$100000000$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/MainActivity$100000000.class b/app/build/bin/classesdebug/acessor/droidfrida/MainActivity$100000000.class deleted file mode 100644 index 325aa89..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/MainActivity$100000000.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/MainActivity$100000001$0$debug.class b/app/build/bin/classesdebug/acessor/droidfrida/MainActivity$100000001$0$debug.class deleted file mode 100644 index ddee1e1..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/MainActivity$100000001$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/MainActivity$100000001.class b/app/build/bin/classesdebug/acessor/droidfrida/MainActivity$100000001.class deleted file mode 100644 index e57bb94..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/MainActivity$100000001.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/MainActivity.class b/app/build/bin/classesdebug/acessor/droidfrida/MainActivity.class deleted file mode 100644 index 1a3cb2f..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/MainActivity.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/R$0$debug.class b/app/build/bin/classesdebug/acessor/droidfrida/R$0$debug.class deleted file mode 100644 index 4279356..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/R$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/R$attr$0$debug.class b/app/build/bin/classesdebug/acessor/droidfrida/R$attr$0$debug.class deleted file mode 100644 index ae26d2a..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/R$attr$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/R$attr.class b/app/build/bin/classesdebug/acessor/droidfrida/R$attr.class deleted file mode 100644 index ab49dda..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/R$attr.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/R$drawable$0$debug.class b/app/build/bin/classesdebug/acessor/droidfrida/R$drawable$0$debug.class deleted file mode 100644 index 80dc175..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/R$drawable$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/R$drawable.class b/app/build/bin/classesdebug/acessor/droidfrida/R$drawable.class deleted file mode 100644 index 3a4537a..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/R$drawable.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/R$id$0$debug.class b/app/build/bin/classesdebug/acessor/droidfrida/R$id$0$debug.class deleted file mode 100644 index d61b562..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/R$id$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/R$id.class b/app/build/bin/classesdebug/acessor/droidfrida/R$id.class deleted file mode 100644 index eaa90ef..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/R$id.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/R$layout$0$debug.class b/app/build/bin/classesdebug/acessor/droidfrida/R$layout$0$debug.class deleted file mode 100644 index be0bea6..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/R$layout$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/R$layout.class b/app/build/bin/classesdebug/acessor/droidfrida/R$layout.class deleted file mode 100644 index d86c514..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/R$layout.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/R$mipmap$0$debug.class b/app/build/bin/classesdebug/acessor/droidfrida/R$mipmap$0$debug.class deleted file mode 100644 index ec0be64..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/R$mipmap$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/R$mipmap.class b/app/build/bin/classesdebug/acessor/droidfrida/R$mipmap.class deleted file mode 100644 index a874e92..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/R$mipmap.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/R$string$0$debug.class b/app/build/bin/classesdebug/acessor/droidfrida/R$string$0$debug.class deleted file mode 100644 index 75aebc7..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/R$string$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/R$string.class b/app/build/bin/classesdebug/acessor/droidfrida/R$string.class deleted file mode 100644 index ce20c02..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/R$string.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/R$style$0$debug.class b/app/build/bin/classesdebug/acessor/droidfrida/R$style$0$debug.class deleted file mode 100644 index a5cca7e..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/R$style$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/R$style.class b/app/build/bin/classesdebug/acessor/droidfrida/R$style.class deleted file mode 100644 index 707f700..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/R$style.class and /dev/null differ diff --git a/app/build/bin/classesdebug/acessor/droidfrida/R.class b/app/build/bin/classesdebug/acessor/droidfrida/R.class deleted file mode 100644 index d09058e..0000000 Binary files a/app/build/bin/classesdebug/acessor/droidfrida/R.class and /dev/null differ diff --git a/app/build/bin/classesdebug/adrt/ADRTMetadata.class b/app/build/bin/classesdebug/adrt/ADRTMetadata.class deleted file mode 100644 index e1e45ae..0000000 Binary files a/app/build/bin/classesdebug/adrt/ADRTMetadata.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$0$debug.class deleted file mode 100644 index 8b2cc77..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000000$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000000$0$debug.class deleted file mode 100644 index 71ff8f3..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000000$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000000.class b/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000000.class deleted file mode 100644 index c895161..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000000.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000001$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000001$0$debug.class deleted file mode 100644 index c41bbf2..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000001$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000001.class b/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000001.class deleted file mode 100644 index ce17029..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000001.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000002$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000002$0$debug.class deleted file mode 100644 index 4dd7604..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000002$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000002.class b/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000002.class deleted file mode 100644 index 9a14450..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000002.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000003$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000003$0$debug.class deleted file mode 100644 index d0ccfb4..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000003$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000003.class b/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000003.class deleted file mode 100644 index d8c6775..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$100000003.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$LogLevel$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$LogLevel$0$debug.class deleted file mode 100644 index a7af569..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$LogLevel$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$LogLevel.class b/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$LogLevel.class deleted file mode 100644 index f2b9934..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell$LogLevel.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell.class b/app/build/bin/classesdebug/com/stericson/RootShell/RootShell.class deleted file mode 100644 index 58f1d8b..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/RootShell.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$0$debug.class deleted file mode 100644 index 3be1a03..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$0$debug.class deleted file mode 100644 index 594e5b0..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000000$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000000$0$debug.class deleted file mode 100644 index 2be59d3..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000000$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000000.class b/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000000.class deleted file mode 100644 index b1d2194..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000000.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000001$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000001$0$debug.class deleted file mode 100644 index fdc240c..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000001$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000001.class b/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000001.class deleted file mode 100644 index 8cbe0f6..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000001.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000002$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000002$0$debug.class deleted file mode 100644 index feefc15..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000002$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000002.class b/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000002.class deleted file mode 100644 index 844212a..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000002.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder.class b/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder.class deleted file mode 100644 index bea19bd..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$AnnotationsFinder.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$Candidate.class b/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$Candidate.class deleted file mode 100644 index c9d8507..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$Candidate.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$READ_STATE$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$READ_STATE$0$debug.class deleted file mode 100644 index 55b9238..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$READ_STATE$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$READ_STATE.class b/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$READ_STATE.class deleted file mode 100644 index e755ba6..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$READ_STATE.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$RootArgs$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$RootArgs$0$debug.class deleted file mode 100644 index 8c44019..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$RootArgs$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$RootArgs.class b/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$RootArgs.class deleted file mode 100644 index 43cfa25..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass$RootArgs.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass.class b/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass.class deleted file mode 100644 index 08be8bf..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/containers/RootClass.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/exceptions/RootDeniedException$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/exceptions/RootDeniedException$0$debug.class deleted file mode 100644 index 2359ade..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/exceptions/RootDeniedException$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/exceptions/RootDeniedException.class b/app/build/bin/classesdebug/com/stericson/RootShell/exceptions/RootDeniedException.class deleted file mode 100644 index 85d4bba..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/exceptions/RootDeniedException.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command$0$debug.class deleted file mode 100644 index 66bea74..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command$CommandHandler$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command$CommandHandler$0$debug.class deleted file mode 100644 index 82f2098..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command$CommandHandler$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command$CommandHandler.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command$CommandHandler.class deleted file mode 100644 index c0433d3..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command$CommandHandler.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command$ExecutionMonitor$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command$ExecutionMonitor$0$debug.class deleted file mode 100644 index 71c8235..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command$ExecutionMonitor$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command$ExecutionMonitor.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command$ExecutionMonitor.class deleted file mode 100644 index 68bce6d..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command$ExecutionMonitor.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command.class deleted file mode 100644 index 2395831..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Command.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/JavaCommand$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/JavaCommand$0$debug.class deleted file mode 100644 index 9566060..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/JavaCommand$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/JavaCommand.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/JavaCommand.class deleted file mode 100644 index c700fcc..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/JavaCommand.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$0$debug.class deleted file mode 100644 index b036047..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000000$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000000$0$debug.class deleted file mode 100644 index 2ddfcb2..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000000$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000000.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000000.class deleted file mode 100644 index 973e01a..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000000.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000001$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000001$0$debug.class deleted file mode 100644 index 2233347..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000001$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000001.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000001.class deleted file mode 100644 index 8e78fa6..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000001.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000002$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000002$0$debug.class deleted file mode 100644 index 9171fef..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000002$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000002.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000002.class deleted file mode 100644 index 2f81b78..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$100000002.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$ShellContext$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$ShellContext$0$debug.class deleted file mode 100644 index 1864eb3..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$ShellContext$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$ShellContext.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$ShellContext.class deleted file mode 100644 index 7ffb5b0..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$ShellContext.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$ShellType$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$ShellType$0$debug.class deleted file mode 100644 index e2fea55..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$ShellType$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$ShellType.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$ShellType.class deleted file mode 100644 index 6e9d5ca..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$ShellType.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$Worker$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$Worker$0$debug.class deleted file mode 100644 index 20eb802..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$Worker$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$Worker.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$Worker.class deleted file mode 100644 index 46f79bd..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell$Worker.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell.class b/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell.class deleted file mode 100644 index ec4a7c3..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootShell/execution/Shell.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/Constants$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/Constants$0$debug.class deleted file mode 100644 index 8df79e3..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/Constants$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/Constants.class b/app/build/bin/classesdebug/com/stericson/RootTools/Constants.class deleted file mode 100644 index 19be328..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/Constants.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/RootTools$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/RootTools$0$debug.class deleted file mode 100644 index e63ba72..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/RootTools$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/RootTools.class b/app/build/bin/classesdebug/com/stericson/RootTools/RootTools.class deleted file mode 100644 index c63f974..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/RootTools.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$0$debug.class deleted file mode 100644 index 17e9932..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$100000000$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$100000000$0$debug.class deleted file mode 100644 index 98242df..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$100000000$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$100000000.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$100000000.class deleted file mode 100644 index f41e8d5..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$100000000.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$0$debug.class deleted file mode 100644 index 6f701a8..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000001$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000001$0$debug.class deleted file mode 100644 index d74d4ca..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000001$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000001.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000001.class deleted file mode 100644 index 2fb531b..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000001.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000002$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000002$0$debug.class deleted file mode 100644 index 068a7b9..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000002$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000002.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000002.class deleted file mode 100644 index 295fdc4..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000002.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000003$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000003$0$debug.class deleted file mode 100644 index f7cd7e6..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000003$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000003.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000003.class deleted file mode 100644 index 20a66f3..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000003.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000004$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000004$0$debug.class deleted file mode 100644 index 2e84e52..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000004$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000004.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000004.class deleted file mode 100644 index f60ea02..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000004.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000005$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000005$0$debug.class deleted file mode 100644 index b6e3afc..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000005$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000005.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000005.class deleted file mode 100644 index d567a3a..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000005.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000006$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000006$0$debug.class deleted file mode 100644 index 4d06b97..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000006$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000006.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000006.class deleted file mode 100644 index 469ffd8..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000006.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread.class deleted file mode 100644 index bcc9fb6..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$TestHandler$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$TestHandler$0$debug.class deleted file mode 100644 index 5322cde..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$TestHandler$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$TestHandler.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$TestHandler.class deleted file mode 100644 index 6d1f47e..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools$TestHandler.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools.class b/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools.class deleted file mode 100644 index a251665..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/SanityCheckRootTools.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/containers/Mount$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/containers/Mount$0$debug.class deleted file mode 100644 index 2592434..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/containers/Mount$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/containers/Mount.class b/app/build/bin/classesdebug/com/stericson/RootTools/containers/Mount.class deleted file mode 100644 index 2ab897e..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/containers/Mount.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/containers/Permissions$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/containers/Permissions$0$debug.class deleted file mode 100644 index ea95a9b..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/containers/Permissions$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/containers/Permissions.class b/app/build/bin/classesdebug/com/stericson/RootTools/containers/Permissions.class deleted file mode 100644 index 80ac2d7..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/containers/Permissions.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/containers/Symlink$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/containers/Symlink$0$debug.class deleted file mode 100644 index 4b4837a..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/containers/Symlink$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/containers/Symlink.class b/app/build/bin/classesdebug/com/stericson/RootTools/containers/Symlink.class deleted file mode 100644 index 8045e49..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/containers/Symlink.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/Installer$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/Installer$0$debug.class deleted file mode 100644 index 6aca402..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/Installer$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/Installer.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/Installer.class deleted file mode 100644 index 619de18..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/Installer.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/InternalVariables$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/InternalVariables$0$debug.class deleted file mode 100644 index 05816be..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/InternalVariables$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/InternalVariables.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/InternalVariables.class deleted file mode 100644 index f658916..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/InternalVariables.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/Remounter$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/Remounter$0$debug.class deleted file mode 100644 index 58922bc..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/Remounter$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/Remounter.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/Remounter.class deleted file mode 100644 index bc8598c..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/Remounter.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$0$debug.class deleted file mode 100644 index eac8b09..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000000$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000000$0$debug.class deleted file mode 100644 index d0df662..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000000$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000000.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000000.class deleted file mode 100644 index c4bf4f6..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000000.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000001$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000001$0$debug.class deleted file mode 100644 index eb2a80f..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000001$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000001.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000001.class deleted file mode 100644 index 07bd883..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000001.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000002$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000002$0$debug.class deleted file mode 100644 index 3087c9e..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000002$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000002.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000002.class deleted file mode 100644 index b9e00f9..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000002.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000003$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000003$0$debug.class deleted file mode 100644 index 9f8d0fd..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000003$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000003.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000003.class deleted file mode 100644 index f3cd843..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000003.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000004$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000004$0$debug.class deleted file mode 100644 index c2c387c..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000004$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000004.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000004.class deleted file mode 100644 index 7983871..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000004.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000005$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000005$0$debug.class deleted file mode 100644 index 37d2017..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000005$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000005.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000005.class deleted file mode 100644 index f4ffd54..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000005.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000006$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000006$0$debug.class deleted file mode 100644 index 0718206..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000006$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000006.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000006.class deleted file mode 100644 index 47ed5b7..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000006.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000007$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000007$0$debug.class deleted file mode 100644 index 0d3a5ce..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000007$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000007.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000007.class deleted file mode 100644 index ec0cca3..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000007.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000008$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000008$0$debug.class deleted file mode 100644 index a42972a..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000008$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000008.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000008.class deleted file mode 100644 index b824ca7..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000008.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000009$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000009$0$debug.class deleted file mode 100644 index 9723650..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000009$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000009.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000009.class deleted file mode 100644 index 635b7bd..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000009.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000010$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000010$0$debug.class deleted file mode 100644 index 668a92f..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000010$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000010.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000010.class deleted file mode 100644 index 44ba456..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000010.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000011$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000011$0$debug.class deleted file mode 100644 index 77a47f2..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000011$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000011.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000011.class deleted file mode 100644 index a46a65c..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000011.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000012$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000012$0$debug.class deleted file mode 100644 index 5221083..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000012$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000012.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000012.class deleted file mode 100644 index 6a8b2f8..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods$100000012.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods.class deleted file mode 100644 index b749436..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/RootToolsInternalMethods.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/Runner$0$debug.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/Runner$0$debug.class deleted file mode 100644 index 15583d2..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/Runner$0$debug.class and /dev/null differ diff --git a/app/build/bin/classesdebug/com/stericson/RootTools/internal/Runner.class b/app/build/bin/classesdebug/com/stericson/RootTools/internal/Runner.class deleted file mode 100644 index 38f9d4c..0000000 Binary files a/app/build/bin/classesdebug/com/stericson/RootTools/internal/Runner.class and /dev/null differ diff --git a/app/build/bin/classesdebug/javalangEnum.class b/app/build/bin/classesdebug/javalangEnum.class deleted file mode 100644 index 475f25a..0000000 Binary files a/app/build/bin/classesdebug/javalangEnum.class and /dev/null differ diff --git a/app/build/bin/classesdebug/javalangIterable.class b/app/build/bin/classesdebug/javalangIterable.class deleted file mode 100644 index 54f125e..0000000 Binary files a/app/build/bin/classesdebug/javalangIterable.class and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/BuildConfig.class b/app/build/bin/classesrelease/acessor/droidfrida/BuildConfig.class deleted file mode 100644 index 0f2e0a6..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/BuildConfig.class and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/BuildConfig.dex b/app/build/bin/classesrelease/acessor/droidfrida/BuildConfig.dex deleted file mode 100644 index 499707b..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/BuildConfig.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/MainActivity$100000000.class b/app/build/bin/classesrelease/acessor/droidfrida/MainActivity$100000000.class deleted file mode 100644 index dda4eac..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/MainActivity$100000000.class and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/MainActivity$100000000.dex b/app/build/bin/classesrelease/acessor/droidfrida/MainActivity$100000000.dex deleted file mode 100644 index fbc600d..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/MainActivity$100000000.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/MainActivity$100000001.class b/app/build/bin/classesrelease/acessor/droidfrida/MainActivity$100000001.class deleted file mode 100644 index c2f3275..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/MainActivity$100000001.class and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/MainActivity$100000001.dex b/app/build/bin/classesrelease/acessor/droidfrida/MainActivity$100000001.dex deleted file mode 100644 index aff2d01..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/MainActivity$100000001.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/MainActivity.class b/app/build/bin/classesrelease/acessor/droidfrida/MainActivity.class deleted file mode 100644 index 6b24682..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/MainActivity.class and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/MainActivity.dex b/app/build/bin/classesrelease/acessor/droidfrida/MainActivity.dex deleted file mode 100644 index 8e3a0bd..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/MainActivity.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/R$attr.class b/app/build/bin/classesrelease/acessor/droidfrida/R$attr.class deleted file mode 100644 index d89d92b..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/R$attr.class and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/R$attr.dex b/app/build/bin/classesrelease/acessor/droidfrida/R$attr.dex deleted file mode 100644 index b8e7221..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/R$attr.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/R$drawable.class b/app/build/bin/classesrelease/acessor/droidfrida/R$drawable.class deleted file mode 100644 index 73b37a9..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/R$drawable.class and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/R$drawable.dex b/app/build/bin/classesrelease/acessor/droidfrida/R$drawable.dex deleted file mode 100644 index 9d764c0..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/R$drawable.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/R$id.class b/app/build/bin/classesrelease/acessor/droidfrida/R$id.class deleted file mode 100644 index b06f855..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/R$id.class and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/R$id.dex b/app/build/bin/classesrelease/acessor/droidfrida/R$id.dex deleted file mode 100644 index 5993796..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/R$id.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/R$layout.class b/app/build/bin/classesrelease/acessor/droidfrida/R$layout.class deleted file mode 100644 index bbabdc9..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/R$layout.class and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/R$layout.dex b/app/build/bin/classesrelease/acessor/droidfrida/R$layout.dex deleted file mode 100644 index c241bd4..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/R$layout.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/R$mipmap.class b/app/build/bin/classesrelease/acessor/droidfrida/R$mipmap.class deleted file mode 100644 index 51ef307..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/R$mipmap.class and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/R$mipmap.dex b/app/build/bin/classesrelease/acessor/droidfrida/R$mipmap.dex deleted file mode 100644 index a3d3b82..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/R$mipmap.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/R$string.class b/app/build/bin/classesrelease/acessor/droidfrida/R$string.class deleted file mode 100644 index 9a31e76..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/R$string.class and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/R$string.dex b/app/build/bin/classesrelease/acessor/droidfrida/R$string.dex deleted file mode 100644 index 4342216..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/R$string.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/R$style.class b/app/build/bin/classesrelease/acessor/droidfrida/R$style.class deleted file mode 100644 index 2f1c8f4..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/R$style.class and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/R$style.dex b/app/build/bin/classesrelease/acessor/droidfrida/R$style.dex deleted file mode 100644 index debffeb..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/R$style.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/R.class b/app/build/bin/classesrelease/acessor/droidfrida/R.class deleted file mode 100644 index 347fe6c..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/R.class and /dev/null differ diff --git a/app/build/bin/classesrelease/acessor/droidfrida/R.dex b/app/build/bin/classesrelease/acessor/droidfrida/R.dex deleted file mode 100644 index 8b463d1..0000000 Binary files a/app/build/bin/classesrelease/acessor/droidfrida/R.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000000.class b/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000000.class deleted file mode 100644 index 6f5460f..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000000.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000000.dex b/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000000.dex deleted file mode 100644 index e23d622..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000000.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000001.class b/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000001.class deleted file mode 100644 index 6804527..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000001.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000001.dex b/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000001.dex deleted file mode 100644 index dc579c7..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000001.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000002.class b/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000002.class deleted file mode 100644 index 2db057f..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000002.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000002.dex b/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000002.dex deleted file mode 100644 index 79762fe..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000002.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000003.class b/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000003.class deleted file mode 100644 index e0ff099..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000003.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000003.dex b/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000003.dex deleted file mode 100644 index ae05d02..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$100000003.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$LogLevel.class b/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$LogLevel.class deleted file mode 100644 index 932de44..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$LogLevel.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$LogLevel.dex b/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$LogLevel.dex deleted file mode 100644 index 0304b55..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell$LogLevel.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell.class b/app/build/bin/classesrelease/com/stericson/RootShell/RootShell.class deleted file mode 100644 index 193eb72..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell.dex b/app/build/bin/classesrelease/com/stericson/RootShell/RootShell.dex deleted file mode 100644 index 084749d..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/RootShell.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000000.class b/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000000.class deleted file mode 100644 index 875b601..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000000.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000000.dex b/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000000.dex deleted file mode 100644 index aac26f9..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000000.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000001.class b/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000001.class deleted file mode 100644 index 60c2119..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000001.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000001.dex b/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000001.dex deleted file mode 100644 index 011b7e6..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000001.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000002.class b/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000002.class deleted file mode 100644 index 3e5a4fa..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000002.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000002.dex b/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000002.dex deleted file mode 100644 index 126ed1a..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder$100000002.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder.class b/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder.class deleted file mode 100644 index cd8cdc8..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder.dex b/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder.dex deleted file mode 100644 index 4d27366..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$AnnotationsFinder.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$Candidate.class b/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$Candidate.class deleted file mode 100644 index c9d8507..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$Candidate.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$Candidate.dex b/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$Candidate.dex deleted file mode 100644 index ea33b5e..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$Candidate.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$READ_STATE.class b/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$READ_STATE.class deleted file mode 100644 index 0ecc288..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$READ_STATE.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$READ_STATE.dex b/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$READ_STATE.dex deleted file mode 100644 index 0421856..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$READ_STATE.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$RootArgs.class b/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$RootArgs.class deleted file mode 100644 index 1f0c6a2..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$RootArgs.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$RootArgs.dex b/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$RootArgs.dex deleted file mode 100644 index 22c7952..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass$RootArgs.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass.class b/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass.class deleted file mode 100644 index 451f020..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass.dex b/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass.dex deleted file mode 100644 index 626d82e..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/containers/RootClass.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/exceptions/RootDeniedException.class b/app/build/bin/classesrelease/com/stericson/RootShell/exceptions/RootDeniedException.class deleted file mode 100644 index af079b8..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/exceptions/RootDeniedException.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/exceptions/RootDeniedException.dex b/app/build/bin/classesrelease/com/stericson/RootShell/exceptions/RootDeniedException.dex deleted file mode 100644 index 9cfb1ab..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/exceptions/RootDeniedException.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command$CommandHandler.class b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command$CommandHandler.class deleted file mode 100644 index 0966442..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command$CommandHandler.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command$CommandHandler.dex b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command$CommandHandler.dex deleted file mode 100644 index f8c7d7e..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command$CommandHandler.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command$ExecutionMonitor.class b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command$ExecutionMonitor.class deleted file mode 100644 index 3354fd3..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command$ExecutionMonitor.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command$ExecutionMonitor.dex b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command$ExecutionMonitor.dex deleted file mode 100644 index d6eeca0..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command$ExecutionMonitor.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command.class b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command.class deleted file mode 100644 index da32b81..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command.dex b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command.dex deleted file mode 100644 index cb7c891..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Command.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/JavaCommand.class b/app/build/bin/classesrelease/com/stericson/RootShell/execution/JavaCommand.class deleted file mode 100644 index 261a229..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/JavaCommand.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/JavaCommand.dex b/app/build/bin/classesrelease/com/stericson/RootShell/execution/JavaCommand.dex deleted file mode 100644 index 7512896..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/JavaCommand.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000000.class b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000000.class deleted file mode 100644 index 81c4556..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000000.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000000.dex b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000000.dex deleted file mode 100644 index 3323ca4..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000000.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000001.class b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000001.class deleted file mode 100644 index a5b6bf7..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000001.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000001.dex b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000001.dex deleted file mode 100644 index 5af8a35..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000001.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000002.class b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000002.class deleted file mode 100644 index 9228f3c..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000002.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000002.dex b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000002.dex deleted file mode 100644 index 8061e7a..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$100000002.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$ShellContext.class b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$ShellContext.class deleted file mode 100644 index d7a6308..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$ShellContext.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$ShellContext.dex b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$ShellContext.dex deleted file mode 100644 index f280b8e..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$ShellContext.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$ShellType.class b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$ShellType.class deleted file mode 100644 index 5bb804b..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$ShellType.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$ShellType.dex b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$ShellType.dex deleted file mode 100644 index d23d4a0..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$ShellType.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$Worker.class b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$Worker.class deleted file mode 100644 index e1a23fe..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$Worker.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$Worker.dex b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$Worker.dex deleted file mode 100644 index 2e8e7cd..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell$Worker.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell.class b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell.class deleted file mode 100644 index 4eb0e3e..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell.dex b/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell.dex deleted file mode 100644 index 940f646..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootShell/execution/Shell.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/Constants.class b/app/build/bin/classesrelease/com/stericson/RootTools/Constants.class deleted file mode 100644 index fa80259..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/Constants.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/Constants.dex b/app/build/bin/classesrelease/com/stericson/RootTools/Constants.dex deleted file mode 100644 index e35a4a8..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/Constants.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/RootTools.class b/app/build/bin/classesrelease/com/stericson/RootTools/RootTools.class deleted file mode 100644 index d480e97..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/RootTools.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/RootTools.dex b/app/build/bin/classesrelease/com/stericson/RootTools/RootTools.dex deleted file mode 100644 index 20c45dc..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/RootTools.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$100000000.class b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$100000000.class deleted file mode 100644 index a694f47..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$100000000.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$100000000.dex b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$100000000.dex deleted file mode 100644 index 0ee9d3f..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$100000000.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000001.class b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000001.class deleted file mode 100644 index fdcf6d7..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000001.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000001.dex b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000001.dex deleted file mode 100644 index 283baa2..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000001.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000002.class b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000002.class deleted file mode 100644 index 5944cee..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000002.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000002.dex b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000002.dex deleted file mode 100644 index 66c52a2..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000002.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000003.class b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000003.class deleted file mode 100644 index 9a4c09b..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000003.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000003.dex b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000003.dex deleted file mode 100644 index 0cda405..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000003.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000004.class b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000004.class deleted file mode 100644 index b2e3411..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000004.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000004.dex b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000004.dex deleted file mode 100644 index f483c6b..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000004.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000005.class b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000005.class deleted file mode 100644 index 1f072c9..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000005.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000005.dex b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000005.dex deleted file mode 100644 index fd92ef8..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000005.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000006.class b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000006.class deleted file mode 100644 index afc6935..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000006.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000006.dex b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000006.dex deleted file mode 100644 index 965c6f4..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread$100000006.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread.class b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread.class deleted file mode 100644 index a80d87a..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread.dex b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread.dex deleted file mode 100644 index aa59ddf..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$SanityCheckThread.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$TestHandler.class b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$TestHandler.class deleted file mode 100644 index 729157a..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$TestHandler.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$TestHandler.dex b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$TestHandler.dex deleted file mode 100644 index 69781ed..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools$TestHandler.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools.class b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools.class deleted file mode 100644 index 1706f18..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools.dex b/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools.dex deleted file mode 100644 index 39f8da1..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/SanityCheckRootTools.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/containers/Mount.class b/app/build/bin/classesrelease/com/stericson/RootTools/containers/Mount.class deleted file mode 100644 index 5e92252..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/containers/Mount.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/containers/Mount.dex b/app/build/bin/classesrelease/com/stericson/RootTools/containers/Mount.dex deleted file mode 100644 index 9338e75..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/containers/Mount.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/containers/Permissions.class b/app/build/bin/classesrelease/com/stericson/RootTools/containers/Permissions.class deleted file mode 100644 index fa32d97..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/containers/Permissions.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/containers/Permissions.dex b/app/build/bin/classesrelease/com/stericson/RootTools/containers/Permissions.dex deleted file mode 100644 index 4fa08d5..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/containers/Permissions.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/containers/Symlink.class b/app/build/bin/classesrelease/com/stericson/RootTools/containers/Symlink.class deleted file mode 100644 index eda0775..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/containers/Symlink.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/containers/Symlink.dex b/app/build/bin/classesrelease/com/stericson/RootTools/containers/Symlink.dex deleted file mode 100644 index 0f11d54..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/containers/Symlink.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/Installer.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/Installer.class deleted file mode 100644 index dce5877..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/Installer.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/Installer.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/Installer.dex deleted file mode 100644 index 468b57d..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/Installer.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/InternalVariables.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/InternalVariables.class deleted file mode 100644 index dab4b18..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/InternalVariables.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/InternalVariables.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/InternalVariables.dex deleted file mode 100644 index 1bcf4ea..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/InternalVariables.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/Remounter.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/Remounter.class deleted file mode 100644 index dc04e7a..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/Remounter.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/Remounter.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/Remounter.dex deleted file mode 100644 index 43263f0..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/Remounter.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000000.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000000.class deleted file mode 100644 index ba9c3a9..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000000.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000000.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000000.dex deleted file mode 100644 index 6a3d85b..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000000.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000001.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000001.class deleted file mode 100644 index 76b1b8d..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000001.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000001.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000001.dex deleted file mode 100644 index 3574385..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000001.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000002.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000002.class deleted file mode 100644 index a3a2700..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000002.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000002.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000002.dex deleted file mode 100644 index 4885221..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000002.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000003.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000003.class deleted file mode 100644 index a1ace6d..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000003.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000003.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000003.dex deleted file mode 100644 index d5f1c9b..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000003.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000004.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000004.class deleted file mode 100644 index b0ec5a8..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000004.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000004.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000004.dex deleted file mode 100644 index b293e6f..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000004.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000005.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000005.class deleted file mode 100644 index 2f57f6c..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000005.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000005.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000005.dex deleted file mode 100644 index cc52d77..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000005.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000006.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000006.class deleted file mode 100644 index 1535a5a..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000006.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000006.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000006.dex deleted file mode 100644 index 77c3c95..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000006.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000007.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000007.class deleted file mode 100644 index 4ad8ebb..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000007.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000007.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000007.dex deleted file mode 100644 index a413f4f..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000007.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000008.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000008.class deleted file mode 100644 index 78cfa92..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000008.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000008.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000008.dex deleted file mode 100644 index 26b68dd..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000008.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000009.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000009.class deleted file mode 100644 index c1f577c..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000009.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000009.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000009.dex deleted file mode 100644 index 675c2d2..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000009.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000010.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000010.class deleted file mode 100644 index e054aeb..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000010.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000010.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000010.dex deleted file mode 100644 index 025fd2f..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000010.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000011.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000011.class deleted file mode 100644 index 6a5450d..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000011.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000011.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000011.dex deleted file mode 100644 index 23fd22b..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000011.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000012.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000012.class deleted file mode 100644 index b519c19..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000012.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000012.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000012.dex deleted file mode 100644 index 0525aef..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods$100000012.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods.class deleted file mode 100644 index e766751..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods.dex deleted file mode 100644 index 7a23ae5..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/RootToolsInternalMethods.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/Runner.class b/app/build/bin/classesrelease/com/stericson/RootTools/internal/Runner.class deleted file mode 100644 index 9aa74e2..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/Runner.class and /dev/null differ diff --git a/app/build/bin/classesrelease/com/stericson/RootTools/internal/Runner.dex b/app/build/bin/classesrelease/com/stericson/RootTools/internal/Runner.dex deleted file mode 100644 index 642d3b0..0000000 Binary files a/app/build/bin/classesrelease/com/stericson/RootTools/internal/Runner.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/javalangEnum.class b/app/build/bin/classesrelease/javalangEnum.class deleted file mode 100644 index 475f25a..0000000 Binary files a/app/build/bin/classesrelease/javalangEnum.class and /dev/null differ diff --git a/app/build/bin/classesrelease/javalangEnum.dex b/app/build/bin/classesrelease/javalangEnum.dex deleted file mode 100644 index 9566071..0000000 Binary files a/app/build/bin/classesrelease/javalangEnum.dex and /dev/null differ diff --git a/app/build/bin/classesrelease/javalangIterable.class b/app/build/bin/classesrelease/javalangIterable.class deleted file mode 100644 index 54f125e..0000000 Binary files a/app/build/bin/classesrelease/javalangIterable.class and /dev/null differ diff --git a/app/build/bin/classesrelease/javalangIterable.dex b/app/build/bin/classesrelease/javalangIterable.dex deleted file mode 100644 index 23a2f7c..0000000 Binary files a/app/build/bin/classesrelease/javalangIterable.dex and /dev/null differ diff --git a/app/build/bin/injected/AndroidManifest.xml b/app/build/bin/injected/AndroidManifest.xml deleted file mode 100644 index 3bfbe12..0000000 --- a/app/build/bin/injected/AndroidManifest.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/build/bin/res/mipmap-hdpi/ic_launcher.png b/app/build/bin/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 802d2db..0000000 Binary files a/app/build/bin/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/app/build/bin/res/mipmap-mdpi/ic_launcher.png b/app/build/bin/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 60b041d..0000000 Binary files a/app/build/bin/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/app/build/bin/res/mipmap-xhdpi/ic_launcher.png b/app/build/bin/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index a9907e3..0000000 Binary files a/app/build/bin/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/app/build/bin/res/mipmap-xxhdpi/ic_launcher.png b/app/build/bin/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index f8affce..0000000 Binary files a/app/build/bin/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/app/build/bin/res/mipmap-xxxhdpi/ic_launcher.png b/app/build/bin/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index dde0199..0000000 Binary files a/app/build/bin/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/app/build/bin/resources.ap_ b/app/build/bin/resources.ap_ deleted file mode 100644 index 9cb9f09..0000000 Binary files a/app/build/bin/resources.ap_ and /dev/null differ diff --git a/app/build/gen/acessor/droidfrida/BuildConfig.java b/app/build/gen/acessor/droidfrida/BuildConfig.java deleted file mode 100644 index 37938fb..0000000 --- a/app/build/gen/acessor/droidfrida/BuildConfig.java +++ /dev/null @@ -1,6 +0,0 @@ -/** Automatically generated file. DO NOT MODIFY */ -package acessor.droidfrida; - -public final class BuildConfig { - public final static boolean DEBUG = true; -} \ No newline at end of file diff --git a/app/build/gen/acessor/droidfrida/R.java b/app/build/gen/acessor/droidfrida/R.java deleted file mode 100644 index 40642d2..0000000 --- a/app/build/gen/acessor/droidfrida/R.java +++ /dev/null @@ -1,38 +0,0 @@ -/* AUTO-GENERATED FILE. DO NOT MODIFY. - * - * This class was automatically generated by the - * aapt tool from the resource data it found. It - * should not be modified by hand. - */ - -package acessor.droidfrida; - -public final class R { - public static final class attr { - } - public static final class drawable { - public static final int bordered_view=0x7f020000; - public static final int button=0x7f020001; - } - public static final class id { - public static final int codeTab=0x7f070001; - public static final int outputLog=0x7f070004; - public static final int outputTab=0x7f070002; - public static final int pkgName=0x7f070000; - public static final int scriptInput=0x7f070003; - } - public static final class layout { - public static final int item=0x7f040000; - public static final int main=0x7f040001; - } - public static final class mipmap { - public static final int ic_launcher=0x7f030000; - } - public static final class string { - public static final int app_name=0x7f050000; - public static final int hello_world=0x7f050001; - } - public static final class style { - public static final int AppTheme=0x7f060000; - } -} diff --git a/app/libs/RootTools.jar b/app/libs/RootTools.jar new file mode 100644 index 0000000..73e4ffa Binary files /dev/null and b/app/libs/RootTools.jar differ diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 6b17661..0c05653 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,6 +1,11 @@ --keepattributes SourceFile, LineNumberTable --renamesourcefileattribute SourceFile --repackageclasses --ignorewarnings --dontwarn --dontnote \ No newline at end of file +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class com.android.vending.licensing.ILicensingService diff --git a/app/src/main/assets/frida64.zip b/app/src/main/assets/frida64.zip index ad09fa8..48a5881 100644 Binary files a/app/src/main/assets/frida64.zip and b/app/src/main/assets/frida64.zip differ diff --git a/app/src/main/java/acessor/droidfrida/CodeView.java b/app/src/main/java/acessor/droidfrida/CodeView.java new file mode 100644 index 0000000..ecf75d5 --- /dev/null +++ b/app/src/main/java/acessor/droidfrida/CodeView.java @@ -0,0 +1,155 @@ +package acessor.droidfrida; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.text.Editable; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.TextWatcher; +import android.text.style.ForegroundColorSpan; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.widget.EditText; +import android.widget.Toast; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CodeView extends EditText { + private Paint lineNumberPaint; + + public CodeView(Context context) { + super(context); + init(); + } + + public CodeView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public CodeView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + /* a custom hashsum method is used to avoid + reallocating large strings which may cause lag + */ + public long hashsum(String str) { + final int prime = 31; + long hash = 0; + long multiplier = 1; + for (int i = 0; i < str.length(); i++) { + hash = hash + (str.charAt(i) - 'a' + 1) * multiplier; + multiplier = multiplier * prime; + } + return hash; + } + + private void init() { + lineNumberPaint = new Paint(); + lineNumberPaint.setColor(Color.WHITE); + lineNumberPaint.setTextSize(getTextSize()); + lineNumberPaint.setAntiAlias(true); + addTextChangedListener(new TextWatcher() { + + private long beforeHashsum = -1; + + @Override + public void beforeTextChanged(CharSequence text, int start, int count, int after) { + this.beforeHashsum = hashsum(getText().toString()); + } + + @Override + public void onTextChanged(CharSequence text, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + if (beforeHashsum != hashsum(getText().toString())) { + int cpos = getSelectionStart(), + scrollY = getScrollY(), + scrollX = getScrollX(); + highlightJavaScript(s.toString()); + setSelection(cpos); + scrollTo(scrollX, scrollY); + } + } + }); + } + + private int getTextWidth(String text) { + Paint paint = new Paint(); + paint.setTypeface(getTypeface()); + paint.setTextSize(getTextSize()); + Rect rect = new Rect(); + paint.getTextBounds(text, 0, text.length(), rect); + int widthPixels = rect.width(); + //DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); + int widthDp = widthPixels; + return widthDp; + } + + @Override + protected void onDraw(Canvas canvas) { + int lineCount = getLineCount(); + int lineHeight = getLineHeight(); + float lineNumberX = 10; // draw start + float lineNumberY; + + int borderX = getTextWidth(Integer.toString(getLineCount())) + + (int)lineNumberX + 20; + + for (int i = 0; i < lineCount; i++) { + lineNumberY = lineHeight * (i + 1) - (lineHeight / 2) + getScrollY() + + lineHeight; + canvas.drawText(String.valueOf(i + 1), lineNumberX, lineNumberY, lineNumberPaint); + } + + setPaddingRelative(borderX + 10, + getPaddingTop(), 0, 0); + + canvas.drawLine(borderX, 0, borderX, getHeight(), getPaint()); + + super.onDraw(canvas); + } + + private void highlightJavaScript(String text) { + Spannable spannable = new SpannableString(text); + /*for (ForegroundColorSpan old : spannable.getSpans(0, spannable.length(), ForegroundColorSpan.class)) + spannable.removeSpan(old);*/ + highlightKeywords(spannable, "var|let|const|function|return|if|else|for|while|do|switch|case|break"); + highlightKeywords(spannable, "true|false|null|undefined"); + highlightKeywords(spannable, "new|this|class"); + highlightStrings(spannable); + highlightNumbers(spannable); + + setText(spannable); + } + + private void highlightKeywords(Spannable spannable, String pattern) { + Pattern keywordPattern = Pattern.compile("\\b(" + pattern + ")\\b"); + Matcher keywordMatcher = keywordPattern.matcher(spannable); + while (keywordMatcher.find()) { + spannable.setSpan(new ForegroundColorSpan(Color.BLUE), keywordMatcher.start(), keywordMatcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } + + private void highlightStrings(Spannable spannable) { + Pattern stringPattern = Pattern.compile("(\".*\")|('.*')"); + Matcher stringMatcher = stringPattern.matcher(spannable); + while (stringMatcher.find()) { + spannable.setSpan(new ForegroundColorSpan(Color.MAGENTA), stringMatcher.start(), stringMatcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } + + private void highlightNumbers(Spannable spannable) { + Pattern numberPattern = Pattern.compile("\\b[0-9]+\\b"); + Matcher numberMatcher = numberPattern.matcher(spannable); + while (numberMatcher.find()) { + spannable.setSpan(new ForegroundColorSpan(Color.RED), numberMatcher.start(), numberMatcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } +} diff --git a/app/src/main/java/acessor/droidfrida/JSConfuser.java b/app/src/main/java/acessor/droidfrida/JSConfuser.java new file mode 100644 index 0000000..970e43c --- /dev/null +++ b/app/src/main/java/acessor/droidfrida/JSConfuser.java @@ -0,0 +1,212 @@ +package acessor.droidfrida; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class JSConfuser { + + /* + * This was made using regexps only and should be rewritten to per-char + * processing eventually. The regexp implementation is temprorary and doesn't + * allow to actually analyze the code structure + */ + + public static void main(String[] args) { + String testcode = "function areaOfCircle(e){return Math.PI*e*e}function perimeterOfCircle(e){return 2*Math.PI*e}function volumeOfCube(e){return e*e*e}let radius=5;console.log(\"Area of circle with radius \"+radius+\" is: \"+areaOfCircle(radius)),radius=10,console.log(\"Perimeter of circle with radius \"+radius+\" is: \"+perimeterOfCircle(radius));let side=4;console.log(\"Volume of cube with side \"+side+\" is: \"+volumeOfCube(side));"; + System.out.println(JSConfuser.obfuscate(testcode)); + } + + private static final Random RANDOM = new Random(); + private static final String CHARSET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + private static final String STRDECRYPTOR = "function rot13(t){let r=\"\";for(let e=0;e=97&&o<=122?o=97+(o-97+13)%26:o>=65&&o<=90&&(o=65+(o-65+13)%26),r+=String.fromCharCode(o)}return r}function decryptString(t,r){let e=\"\";for(let o=0;o{setInterval(()=>{ultrasex()},1e3)})();\");"; + + private static final Pattern VARIABLE_PATTERN = Pattern.compile("(?:let|var|const) ([a-zA-Z0-9]+)(?: |=)"); + private static final Pattern STRING_PATTERN = Pattern.compile("((?:\"|')(.*?[^\\\\])(?:\"|'))"); // strings + private static final Pattern INTEGER_PATTERN = Pattern.compile("(?:[^a-zA-Z0-9])(\\d+)(?:[^a-zA-Z0-9])"); + private static final Pattern METHOD_PATTERN = Pattern.compile("function ([a-zA-Z0-9]+)\\("); // functions + private static final Pattern CALL_PATTERN = Pattern.compile("[a-zA-Z0-9\\]](\\.[a-zA-Z0-9]+)\\(.*?\\)"); + // private static final Pattern STATIC_PATTERN = Pattern.compile("(?:[\\n + // ({=]+)((?!this)[a-zA-Z0-9]+?)[\\.\\[]"); // static + + private StringBuffer sb; + + public JSConfuser(String jsCode) { + this.sb = new StringBuffer(); + this.sb.append(jsCode); + } + + public static String obfuscate(String jsCode) { + JSConfuser confuser = new JSConfuser(JSMinifier.minify(jsCode)); + return confuser.obfuscate(); + } + + /* + * This is tricky, the obfuscation is text-based so some of the protections may + * mess up the others if used not in correct order. Just keep that in mind + */ + public String obfuscate() { + + appendModule(ANTIDEBUG); + + applyBlockReplacement(STRING_PATTERN, new MatchEvent() { + @Override + public String onMatch(Matcher matcher, String jsCode) { + String block = jsCode.substring(matcher.start(), matcher.end()); + if (matcher.group(1).length() > 0) { + int shift = getRandomInt(1, 10); + String data = "decryptString(\"" + encryptString(matcher.group(2), shift) + "\"," + shift + ")"; + return block.replace(matcher.group(1), data); + } else + return block; + } + }); + + applyBlockReplacement(CALL_PATTERN, new MatchEvent() { + @Override + public String onMatch(Matcher matcher, String jsCode) { + String block = jsCode.substring(matcher.start(), matcher.end()); + int shift = getRandomInt(1, 10); + String data = "[decryptString(\"" + encryptString(matcher.group(1).substring(1), shift) + "\", " + shift + + ")]"; + return block.replace(matcher.group(1), data); + } + }); + + appendModule(STRDECRYPTOR); + + applyGlobalReplacement(VARIABLE_PATTERN, new MatchEvent() { + @Override + public String onMatch(Matcher matcher, String jsCode) { + if (matcher.group(1).length() > 2) + return jsCode.replaceAll(matcher.group(1), genRandomName()); + else + return jsCode; + } + }); + + applyGlobalReplacement(METHOD_PATTERN, new MatchEvent() { + @Override + public String onMatch(Matcher matcher, String jsCode) { + if (matcher.group(1).length() > 2) + return jsCode.replaceAll(matcher.group(1), genRandomName()); + else + return jsCode; + } + }); + + applyBlockReplacement(INTEGER_PATTERN, new MatchEvent() { + @Override + public String onMatch(Matcher matcher, String jsCode) { + Integer value = Integer.parseInt(matcher.group(1)); + String block = jsCode.substring(matcher.start(), matcher.end()); + if (value > 0) { + return block.replace(matcher.group(1), generateExpression(value, 2)); + } else + return block; + } + }); + + return this.sb.toString(); + } + + public void appendModule(String jsCode) { + sb.insert(0, jsCode); + } + + public void applyBlockReplacement(Pattern pattern, MatchEvent event) { + String jsCode = sb.toString(); + sb.setLength(0); + Matcher matcher = pattern.matcher(jsCode); + while (matcher.find()) { + matcher.appendReplacement(sb, event.onMatch(matcher, jsCode)); + } + matcher.appendTail(sb); + jsCode = sb.toString(); + } + + public void applyGlobalReplacement(Pattern pattern, MatchEvent event) { + String jsCode = sb.toString(); + sb.setLength(0); + Matcher matcher = pattern.matcher(jsCode); + while (matcher.find()) { + jsCode = event.onMatch(matcher, jsCode); + } + sb.append(jsCode); + } + + class MatchEvent { + public String onMatch(Matcher matcher, String jsCode) { + return jsCode.substring(matcher.start(), matcher.end()); + } + } + + public static String encryptString(String input, int key) { + String rotten = rot13(input); + StringBuilder encrypted = new StringBuilder(); + for (int i = 0; i < rotten.length(); i++) { + encrypted.append((char) (rotten.charAt(i) + (key * 256))); + } + return encrypted.toString(); + } + + public static String rot13(String input) { + StringBuilder output = new StringBuilder(); + for (int i = 0; i < input.length(); i++) { + char c = input.charAt(i); + if (c >= 'a' && c <= 'z') { + c = (char) ('a' + (c - 'a' + 13) % 26); + } else if (c >= 'A' && c <= 'Z') { + c = (char) ('A' + (c - 'A' + 13) % 26); + } + output.append(c); + } + return output.toString(); + } + + private static String generateExpression(int target, int depth) { + if (depth == 0 | target < 1) { + return String.valueOf(target); + } + char operator = getRandomOperator(); + int subTarget = getRandomInt(1, Math.abs(target)); + switch (operator) { + case '+': + return "(" + generateExpression(target - subTarget, depth - 1) + operator + subTarget + ")"; + case '-': + return "(" + generateExpression(target + subTarget, depth - 1) + operator + subTarget + ")"; + case '*': + if (target % subTarget == 0) { + return "(" + generateExpression(target / subTarget, depth - 1) + operator + subTarget + ")"; + } else { + return generateExpression(target, depth - 1); + } + case '/': + return "(" + generateExpression(target * subTarget, depth - 1) + operator + subTarget + ")"; + default: + return String.valueOf(target); + } + } + + private static char getRandomOperator() { + char[] operators = { '+', '-', '*', '/' }; + return operators[RANDOM.nextInt(operators.length)]; + } + + private static int getRandomInt(int min, int max) { + return RANDOM.nextInt((max - min) + 1) + min; + } + + private static String genRandomName() { + StringBuilder name = new StringBuilder(); + for (int i = 0; i < 8; i++) { + name.append(CHARSET.charAt(RANDOM.nextInt(CHARSET.length()))); + } + return name.toString(); + } +} diff --git a/app/src/main/java/acessor/droidfrida/JSFormatter.java b/app/src/main/java/acessor/droidfrida/JSFormatter.java new file mode 100644 index 0000000..6f31f88 --- /dev/null +++ b/app/src/main/java/acessor/droidfrida/JSFormatter.java @@ -0,0 +1,143 @@ +package acessor.droidfrida; + +public class JSFormatter { + + /* + * JavaScript formatter by ac3ss0r (per-char processing) + * + * Project homepage - https://github.com/ac3ss0r/jshift + */ + + public static void main(String[] args) { + String testcode = "function tjcHsmAp(n,o){return LZFxABAq(\"\\u0045\",(((((0+2)-1)*1)/1)+1))==o?Math[LZFxABAq(\"wtzsi\", ((((286-49)-87)/10)/3))](((((0+1)*1)*8)+1)*n/(((51-23)/4)-2)+32):Math[LZFxABAq(\"tqwpf\", ((((0+2)*6)/3)/2))](((0+1)+4)*(n-(((13+41)-24)+2))/(((((3/1)-1)-1)*1)+8))}console[LZFxABAq(\"orj\", ((((110/10)-5)/2)/1))](tjcHsmAp((((1*3)+1)+6)));;function LZFxABAq(e,t){let r=\"\";for(let o=0;o=\"A\".charCodeAt(0)&&e<=\"Z\".charCodeAt(0)||e>=\"a\".charCodeAt(0)&&e<=\"z\".charCodeAt(0)}function JZDTxRod(e){return e>=\"a\".charCodeAt(0)&&e<=\"z\".charCodeAt(0)};function AeqfIToO(){}(async()=>{setInterval((()=>{AeqfIToO()}),1e3)})();\n"; + System.out.print(JSFormatter.formatJSCode(testcode)); + } + + private String jsCode; + private StringBuilder sb; + private int indentSize = 4; + + // expressions, comments and strings should be skipped + boolean inString = false; + boolean inComment = false; + boolean inExpression = false; // while, for + + // the "deepness" of ( and { brackets + int expressionLayer = 0; + int indentLevel = 0; + + public JSFormatter(String jsCode, int indent) { + this.sb = new StringBuilder(); + this.indentSize = indent; + this.jsCode = jsCode; + } + + public static String formatJSCode(String jsCode) { + JSFormatter formatter = new JSFormatter(jsCode, 4); + return formatter.format(); + } + + public String format() { + sb.setLength(0); // reset sb + jsCode = jsCode.replace("\t", repeat(" ", indentSize)); // tabs to space + // per-char code processing + for (int i = 0; i < jsCode.length(); i++) { + char c = jsCode.charAt(i); + + if (inComment || inString) { + sb.append(c); + if (c == '\n') + inComment = false; + if (c == '"' && jsCode.charAt(i - 1) != '\\') + inString = false; + } else { + if (peek(jsCode, "function", i)) + sb.append("\n"); + if (peek(jsCode, "for", i) || peek(jsCode, "while", i)) + inExpression = true; + switch (c) { + case '{': + indentLevel++; + sb.append("{\n"); + appendIndent(indentLevel); + break; + case '}': + indentLevel--; + sb.append("\n"); + appendIndent(indentLevel); + sb.append("}\n"); + appendIndent(indentLevel); + break; + case '(': + if (inExpression) + expressionLayer++; + sb.append('('); + break; + case ')': + if (inExpression) + expressionLayer--; + if (expressionLayer == 0) + inExpression = false; + sb.append(')'); + break; + case ';': + if (jsCode.charAt(i - 1) != ';')// we don't want double ; + sb.append(";"); + if (!inExpression) { + sb.append('\n'); + appendIndent(indentLevel); + } + break; + case '\n': + sb.append("\n"); + appendIndent(indentLevel); + break; + case '"': + sb.append('"'); + inString = true; + break; + case '/': + if (jsCode.charAt(i + 1) == '/') { + inComment = true; + sb.append("//"); + i++; + } else if (jsCode.charAt(i + 1) == '*') { + inComment = true; + sb.append("/*"); + i++; + } + break; + case ' ': + if (jsCode.charAt(i - 1) != ' ') + sb.append(' '); + default: + sb.append(c); + break; + } + } + } + return sb.toString(); + } + + // peek into the code and check strings equality + public boolean peek(String str, String val, int index) { + if (val.length() > str.length() - index) + return false; + for (int i = 0; i < val.length(); i++) { + if (str.charAt(index + i) != val.charAt(i)) + return false; + } + return true; + } + + private String repeat(String str, int count) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < count; i++) + sb.append(str); + return sb.toString(); + } + + private void appendIndent(int level) { + sb.append(repeat(" ", indentSize * level)); + } +} diff --git a/app/src/main/java/acessor/droidfrida/JSMinifier.java b/app/src/main/java/acessor/droidfrida/JSMinifier.java new file mode 100644 index 0000000..390e7bd --- /dev/null +++ b/app/src/main/java/acessor/droidfrida/JSMinifier.java @@ -0,0 +1,221 @@ +package acessor.droidfrida; + +import java.io.IOException; +import java.io.PushbackReader; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; + +public class JSMinifier { + + private static final int EOF = -1; + private final PushbackReader in; + private final Writer out; + private int theA; + private int theB; + + public static String minify(String jsCode) { + StringReader reader = new StringReader(jsCode); + StringWriter writer = new StringWriter(); + try { + JSMinifier min = new JSMinifier(reader, writer); + min.jsmin(); + } catch (Exception e) { + System.err.println("Failed to minify"); + } + return writer.toString().trim(); + } + + public JSMinifier(final Reader in, final Writer out) { + this.in = new PushbackReader(in); + this.out = out; + } + + static boolean isAlphanum(final int c) { + return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || c == '_' || c == '$' + || c == '\\' || c > 126); + } + + int get() throws IOException { + int c = in.read(); + if (c >= ' ' || c == '\n' || c == EOF) { + return c; + } + if (c == '\r') { + return '\n'; + } + return ' '; + } + + int peek() throws IOException { + int lookaheadChar = in.read(); + in.unread(lookaheadChar); + return lookaheadChar; + } + + int next() throws IOException, UnterminatedCommentException { + int c = get(); + if (c == '/') { + switch (peek()) { + case '/': + for (;;) { + c = get(); + if (c <= '\n') { + return c; + } + } + case '*': + get(); + for (;;) { + switch (get()) { + case '*': + if (peek() == '/') { + get(); + return ' '; + } + break; + case EOF: + throw new UnterminatedCommentException(); + } + } + default: + return c; + } + + } + return c; + } + + void action(final int d) throws IOException, UnterminatedRegExpLiteralException, UnterminatedCommentException, + UnterminatedStringLiteralException { + switch (d) { + case 1: + out.write(theA); + case 2: + theA = theB; + + if (theA == '\'' || theA == '"') { + for (;;) { + out.write(theA); + theA = get(); + if (theA == theB) { + break; + } + if (theA <= '\n') { + throw new UnterminatedStringLiteralException(); + } + if (theA == '\\') { + out.write(theA); + theA = get(); + } + } + } + + case 3: + theB = next(); + if (theB == '/' && (theA == '(' || theA == ',' || theA == '=' || theA == ':' || theA == '[' || theA == '!' + || theA == '&' || theA == '|' || theA == '?' || theA == '{' || theA == '}' || theA == ';' + || theA == '\n')) { + out.write(theA); + out.write(theB); + for (;;) { + theA = get(); + if (theA == '/') { + break; + } else if (theA == '\\') { + out.write(theA); + theA = get(); + } else if (theA <= '\n') { + throw new UnterminatedRegExpLiteralException(); + } + out.write(theA); + } + theB = next(); + } + } + } + + public void jsmin() throws IOException, UnterminatedRegExpLiteralException, UnterminatedCommentException, + UnterminatedStringLiteralException { + theA = '\n'; + action(3); + while (theA != EOF) { + switch (theA) { + case ' ': + if (isAlphanum(theB)) { + action(1); + } else { + action(2); + } + break; + case '\n': + switch (theB) { + case '{': + case '[': + case '(': + case '+': + case '-': + action(1); + break; + case ' ': + action(3); + break; + default: + if (isAlphanum(theB)) { + action(1); + } else { + action(2); + } + } + break; + default: + switch (theB) { + case ' ': + if (isAlphanum(theA)) { + action(1); + break; + } + action(3); + break; + case '\n': + switch (theA) { + case '}': + case ']': + case ')': + case '+': + case '-': + case '"': + case '\'': + action(1); + break; + default: + if (isAlphanum(theA)) { + action(1); + } else { + action(3); + } + } + break; + default: + action(1); + break; + } + } + } + out.flush(); + } + + class UnterminatedCommentException extends Exception { + private static final long serialVersionUID = -2351947272352605042L; + } + + class UnterminatedStringLiteralException extends Exception { + private static final long serialVersionUID = -5055563551435617689L; + } + + class UnterminatedRegExpLiteralException extends Exception { + private static final long serialVersionUID = 2975193879980704494L; + } + +} diff --git a/app/src/main/java/acessor/droidfrida/JSpinner.java b/app/src/main/java/acessor/droidfrida/JSpinner.java new file mode 100644 index 0000000..3e0766e --- /dev/null +++ b/app/src/main/java/acessor/droidfrida/JSpinner.java @@ -0,0 +1,25 @@ +package acessor.droidfrida; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.Spinner; + +public class JSpinner extends Spinner { + OnItemSelectedListener listener; + + public JSpinner(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public void setSelection(int position) { + super.setSelection(position); + if (listener != null) + listener.onItemSelected(null, null, position, 0); + } + + public void setOnItemSelectedEvenIfUnchangedListener( + OnItemSelectedListener listener) { + this.listener = listener; + } +} diff --git a/app/src/main/java/acessor/droidfrida/MainActivity.java b/app/src/main/java/acessor/droidfrida/MainActivity.java index 0428e5c..bca089c 100644 --- a/app/src/main/java/acessor/droidfrida/MainActivity.java +++ b/app/src/main/java/acessor/droidfrida/MainActivity.java @@ -1,22 +1,33 @@ package acessor.droidfrida; + import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.graphics.Color; import android.os.Bundle; +import android.text.Editable; +import android.text.InputType; +import android.text.TextWatcher; import android.view.View; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; +import android.widget.ListView; +import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import com.stericson.RootShell.RootShell; import com.stericson.RootShell.execution.Command; import com.stericson.RootShell.execution.Shell; import com.stericson.RootTools.RootTools; +import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; +import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; @@ -29,180 +40,275 @@ public class MainActivity extends Activity { - private HashMap tabs = new HashMap(); - private TextView scriptInput; - private TextView scriptOutput; - private AutoCompleteTextView pkgName; - private Shell rootShell; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.main); - scriptInput = findViewById(R.id.scriptInput); - scriptOutput = findViewById(R.id.outputLog); - tabs.put(findViewById(R.id.codeTab), findViewById(R.id.scriptInput)); - tabs.put(findViewById(R.id.outputTab), findViewById(R.id.outputLog)); - pkgName = findViewById(R.id.pkgName); - pkgName.setAdapter(getInstalledAppNames()); - if (RootTools.isRootAvailable() && RootTools.isAccessGiven()) { - String basePath = "/data/data/" + getPackageName().toString(); - try { - File fridaBin = new File(basePath + "/frida64"); - if (!fridaBin.exists()) - extractAsset("frida64.zip", fridaBin.getPath()); - if (!fridaBin.canExecute()) - rootShell.runRootCommand(new Command(0, "chmod +x " + fridaBin.getPath())); - } catch (Exception e) { - showToast(e.toString()); - } - } else { - ShowDialog("Error", "Your device should be rooted in order to use DroidFrida.", true); + private HashMap tabs = new HashMap(); + private AutoCompleteTextView pkgName; + private TextView scriptInput; + private TextView scriptOutput; + private JSpinner jsOptionMenu; + private Shell rootShell; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + scriptInput = findViewById(R.id.scriptInput); + String initScriptPath = "/data/data/" + getPackageName() + "/script.js"; + if (new File(initScriptPath).exists()) { + try { + scriptInput.setText(readTextFile(initScriptPath)); + } catch (Exception e) { + showToast(e.getMessage()); + } + } + scriptOutput = findViewById(R.id.outputLog); + jsOptionMenu = findViewById(R.id.jsOptionMenu); + jsOptionMenu.setAdapter(new ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, + getResources().getStringArray(R.array.js_options))); + jsOptionMenu.setOnItemSelectedEvenIfUnchangedListener(new AdapterView.OnItemSelectedListener() { + + @Override + public void onItemSelected(AdapterView parentView, View selectedItemView, int myPosition, long myID) { + String minified = JSMinifier.minify(scriptInput.getText().toString()); + + switch (jsOptionMenu.getItemAtPosition(myPosition).toString()) { + case "Format code": + scriptInput.setText(JSFormatter.formatJSCode(minified)); + break; + case "Minify code": + scriptInput.setText(minified); + break; + case "Obfuscate code": + scriptInput.setText(JSConfuser.obfuscate(minified)); + break; + } + + } + + @Override + public void onNothingSelected(AdapterView parentView) { + + } + + }); + scriptInput.setHorizontallyScrolling(true); + scriptInput.addTextChangedListener(new TextWatcher() { + + @Override + public void afterTextChanged(Editable s) {} + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { } - } - - public void tabClicked(View v) { - for (Map.Entry tab : tabs.entrySet()) { - View value = tab.getValue(), - key = tab.getKey(); - if (key == v) { - value.setVisibility(View.VISIBLE); - key.setBackground(getResources().getDrawable(R.drawable.bordered_view)); - } else { - value.setVisibility(View.GONE); - key.setBackground(null); - } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + //showToast(s.toString() + " " + count); } + }); + scriptOutput.setHorizontallyScrolling(true); + scriptOutput.setRawInputType(InputType.TYPE_NULL); + scriptOutput.setTextIsSelectable(true); + + ListView scripts = findViewById(R.id.scriptsList); + scripts.setAdapter(new ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, + getResources().getStringArray(R.array.offline_scripts))); + + tabs.put(findViewById(R.id.codeTab), findViewById(R.id.editorTabPanel)); + tabs.put(findViewById(R.id.outputTab), findViewById(R.id.ouputTabPanel)); + tabs.put(findViewById(R.id.scriptsTab), findViewById(R.id.scriptsTabPanel)); + tabs.put(findViewById(R.id.settingsTab), findViewById(R.id.settingsTabPanel)); + + pkgName = findViewById(R.id.pkgName); + pkgName.setAdapter(getInstalledAppNames()); + if (RootTools.isRootAvailable() && RootTools.isAccessGiven()) { + String basePath = "/data/data/" + getPackageName().toString(); + try { + File fridaBin = new File(basePath + "/frida64"); + if (!fridaBin.exists()) + extractAsset("frida64.zip", fridaBin.getPath()); + if (!fridaBin.canExecute()) + rootShell.runRootCommand(new Command(0, new String[]{"chmod +x " + fridaBin.getPath()})); + } catch (Exception e) { + ShowDialog("Error", e.getMessage(), false); + } + } else { + ShowDialog("Error", "You need root access in order to use DroidFrida", true); } + } - public void launchClicked(View v) { - try { - scriptOutput.setText(null); - if (rootShell == null || !rootShell.isShellOpen()) - rootShell = RootShell.getShell(true); - String dataFolder = "/data/data/" + getPackageName(); - writeToFile(dataFolder + "/script.js", scriptInput.getText().toString()); - showToast("Injecting to the target application..."); - rootShell.runRootCommand(new Command(0, dataFolder + "/frida64 -s " + dataFolder + - "/script.js -f " + pkgName.getText()) { - @Override - public void commandOutput(int id, String line) { - scriptOutput.append(line + "\n"); - showToast(line); - } - }); - - } catch (Exception e) { - showToast(e.getMessage()); - } + @Override + public void onStop() { + try { + writeTextFile("/data/data/" + getPackageName() + "/script.js", scriptInput.getText().toString()); + } catch (Throwable e) { + showToast(e.getMessage()); } + super.onStop(); + } - public void ShowDialog(String title, String msg, final boolean exit) { - new AlertDialog.Builder(this) - .setTitle(title) - .setMessage(msg) - .setCancelable(false) - .setPositiveButton("Ok", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - if (exit) - finishAffinity(); - } - }) - .show(); + public void tabClicked(View v) { + for (Map.Entry tab : tabs.entrySet()) { + View value = tab.getValue(), + key = tab.getKey(); + if (key == v) { + value.setVisibility(View.VISIBLE); + key.setBackground(getResources().getDrawable(R.drawable.bordered_view)); + } else { + value.setVisibility(View.GONE); + key.setBackground(null); + } } + } + + public void launchClicked(View v) { + try { + scriptOutput.setText(""); + if (rootShell == null || !rootShell.isShellOpen()) + rootShell = RootShell.getShell(true); + String dataFolder = "/data/data/" + getPackageName(); + writeTextFile(dataFolder + "/script.js", scriptInput.getText().toString()); + showToast("Injecting to the target application..."); + rootShell.runRootCommand(new Command(0, new String[]{"killall -v " + pkgName })); + rootShell.runRootCommand(new Command(1, new String[]{dataFolder + "/frida64 -s " + dataFolder + + "/script.js -f " + pkgName.getText()}) { + @Override + public void commandOutput(int id, String line) { + scriptOutput.append(line + "\n"); + showToast(line); + } + }); + - public void showToast(String msg) { - Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show(); + } catch (Exception e) { + showToast(e.getMessage()); } + } - public ArrayAdapter getInstalledAppNames() { - Context context = getApplicationContext(); - PackageManager packageManager = context.getPackageManager(); - List applicationInfos = packageManager.getInstalledApplications(PackageManager.GET_META_DATA); - List appNames = new ArrayList<>(); - for (ApplicationInfo applicationInfo : applicationInfos) { - if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { - appNames.add(applicationInfo.packageName); - } + public void jsOptsClicked(View view) { + this.jsOptionMenu.performClick(); + } + + public void ShowDialog(String title, String msg, final boolean exit) { + new AlertDialog.Builder(this) + .setTitle(title) + .setMessage(msg) + .setCancelable(false) + .setPositiveButton("Ok", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (exit) + finishAffinity(); } - return new ArrayAdapter<>( - context, - R.layout.item, - appNames - ); + }) + .show(); + } + + public void showToast(String msg) { + Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show(); + } + + public ArrayAdapter getInstalledAppNames() { + Context context = getApplicationContext(); + PackageManager packageManager = context.getPackageManager(); + List applicationInfos = packageManager.getInstalledApplications(PackageManager.GET_META_DATA); + List appNames = new ArrayList<>(); + for (ApplicationInfo applicationInfo : applicationInfos) { + if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { + appNames.add(applicationInfo.packageName); + } } + return new ArrayAdapter<>( + context, + R.layout.item, + appNames + ); + } - public void writeToFile(String path, String text) throws IOException { - File file = new File(path); - FileWriter writer = new FileWriter(file); - writer.write(text); - writer.close(); + public void writeTextFile(String path, String text) throws IOException { + File file = new File(path); + FileWriter writer = new FileWriter(file); + writer.write(text); + writer.close(); + } + + public String readTextFile(String path) throws IOException { + File file = new File(path); + BufferedReader reader = new BufferedReader(new FileReader(file)); + StringBuilder stringBuilder = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + stringBuilder.append(line + "\n"); } + reader.close(); + return stringBuilder.toString(); + } - public void extractAsset(String assetName, String outputFilePath) throws IOException { - InputStream inputStream = null; - FileOutputStream fileOutputStream = null; - InflaterOutputStream infOutput = null; - try { - Inflater inflater = new Inflater(true); - inputStream = getAssets().open(assetName); - fileOutputStream = new FileOutputStream(outputFilePath); - infOutput = new InflaterOutputStream(fileOutputStream, inflater); - byte[] buffer = new byte[1024]; - int bytesRead; - while ((bytesRead = inputStream.read(buffer)) > 0) { - infOutput.write(buffer, 0, bytesRead); - } - } catch (IOException e) { - showToast("Error extracting asset: " + e.getMessage()); - } finally { - if (fileOutputStream != null) - fileOutputStream.close(); - if (inputStream != null) - inputStream.close(); - if (infOutput != null) { - infOutput.close(); - } - } + public void extractAsset(String assetName, String outputFilePath) throws IOException { + InputStream inputStream = null; + FileOutputStream fileOutputStream = null; + InflaterOutputStream infOutput = null; + try { + Inflater inflater = new Inflater(true); + inputStream = getAssets().open(assetName); + fileOutputStream = new FileOutputStream(outputFilePath); + infOutput = new InflaterOutputStream(fileOutputStream, inflater); + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) > 0) { + infOutput.write(buffer, 0, bytesRead); + } + } catch (IOException e) { + showToast("Error extracting asset: " + e.getMessage()); + } finally { + if (fileOutputStream != null) + fileOutputStream.close(); + if (inputStream != null) + inputStream.close(); + if (infOutput != null) { + infOutput.close(); + } } + } + + /* + + // Just for testing if everything is decompressed fine + + public static void decompressFile(String inputFilePath, String outputFilePath) throws IOException { + FileInputStream fileInputStream = new FileInputStream(inputFilePath); + FileOutputStream fileOutputStream = new FileOutputStream(outputFilePath); + Inflater inflater = new Inflater(true); + InflaterOutputStream inflaterOutputStream = new InflaterOutputStream(fileOutputStream, inflater); + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = fileInputStream.read(buffer)) > 0) { + inflaterOutputStream.write(buffer, 0, bytesRead); + } + fileInputStream.close(); + inflaterOutputStream.finish(); + inflaterOutputStream.close(); + } + + // Used this only to compress frida and pack inlt inside assets + + public static void compressFile(String inputFilePath, String outputFilePath) throws IOException { + FileInputStream fileInputStream = new FileInputStream(inputFilePath); + FileOutputStream fileOutputStream = new FileOutputStream(outputFilePath); + Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION, true); + DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(fileOutputStream, deflater); + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = fileInputStream.read(buffer)) > 0) { + deflaterOutputStream.write(buffer, 0, bytesRead); + } + fileInputStream.close(); + deflaterOutputStream.finish(); + deflaterOutputStream.close(); + } - /* - - // Just for testing if everything is decompressed fine - - public static void decompressFile(String inputFilePath, String outputFilePath) throws IOException { - FileInputStream fileInputStream = new FileInputStream(inputFilePath); - FileOutputStream fileOutputStream = new FileOutputStream(outputFilePath); - Inflater inflater = new Inflater(true); - InflaterOutputStream inflaterOutputStream = new InflaterOutputStream(fileOutputStream, inflater); - byte[] buffer = new byte[1024]; - int bytesRead; - while ((bytesRead = fileInputStream.read(buffer)) > 0) { - inflaterOutputStream.write(buffer, 0, bytesRead); - } - fileInputStream.close(); - inflaterOutputStream.finish(); - inflaterOutputStream.close(); - } - - // Used this only to compress frida and pack inlt inside assets - - public static void compressFile(String inputFilePath, String outputFilePath) throws IOException { - FileInputStream fileInputStream = new FileInputStream(inputFilePath); - FileOutputStream fileOutputStream = new FileOutputStream(outputFilePath); - Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION, true); - DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(fileOutputStream, deflater); - byte[] buffer = new byte[1024]; - int bytesRead; - while ((bytesRead = fileInputStream.read(buffer)) > 0) { - deflaterOutputStream.write(buffer, 0, bytesRead); - } - fileInputStream.close(); - deflaterOutputStream.finish(); - deflaterOutputStream.close(); - } - - */ + */ } + + + diff --git a/app/src/main/java/com/stericson/RootShell/RootShell.java b/app/src/main/java/com/stericson/RootShell/RootShell.java deleted file mode 100644 index d959e88..0000000 --- a/app/src/main/java/com/stericson/RootShell/RootShell.java +++ /dev/null @@ -1,610 +0,0 @@ -/* - * This file is part of the RootShell Project: http://code.google.com/p/RootShell/ - * - * Copyright (c) 2014 Stephen Erickson, Chris Ravenscroft - * - * This code is dual-licensed under the terms of the Apache License Version 2.0 and - * the terms of the General Public License (GPL) Version 2. - * You may use this code according to either of these licenses as is most appropriate - * for your project on a case-by-case basis. - * - * The terms of each license can be found in the root directory of this project's repository as well as at: - * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * http://www.gnu.org/licenses/gpl-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under these Licenses is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See each License for the specific language governing permissions and - * limitations under that License. - */ -package com.stericson.RootShell; - - -import com.stericson.RootShell.exceptions.RootDeniedException; -import com.stericson.RootShell.execution.Command; -import com.stericson.RootShell.execution.Shell; - -import android.util.Log; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.TimeoutException; - -public class RootShell { - - // -------------------- - // # Public Variables # - // -------------------- - - public static boolean debugMode = false; - - public static final String version = "RootShell v1.6"; - - /** - * Setting this to false will disable the handler that is used - * by default for the 3 callback methods for Command. - *

- * By disabling this all callbacks will be called from a thread other than - * the main UI thread. - */ - public static boolean handlerEnabled = true; - - - /** - * Setting this will change the default command timeout. - *

- * The default is 20000ms - */ - public static int defaultCommandTimeout = 20000; - - public static enum LogLevel { - VERBOSE, - ERROR, - DEBUG, - WARN - } - // -------------------- - // # Public Methods # - // -------------------- - - /** - * This will close all open shells. - */ - public static void closeAllShells() throws IOException { - Shell.closeAll(); - } - - /** - * This will close the custom shell that you opened. - */ - public static void closeCustomShell() throws IOException { - Shell.closeCustomShell(); - } - - /** - * This will close either the root shell or the standard shell depending on what you specify. - * - * @param root a boolean to specify whether to close the root shell or the standard shell. - */ - public static void closeShell(boolean root) throws IOException { - if (root) { - Shell.closeRootShell(); - } else { - Shell.closeShell(); - } - } - - /** - * Use this to check whether or not a file exists on the filesystem. - * - * @param file String that represent the file, including the full path to the - * file and its name. - * @return a boolean that will indicate whether or not the file exists. - */ - public static boolean exists(final String file) { - return exists(file, false); - } - - /** - * Use this to check whether or not a file OR directory exists on the filesystem. - * - * @param file String that represent the file OR the directory, including the full path to the - * file and its name. - * @param isDir boolean that represent whether or not we are looking for a directory - * @return a boolean that will indicate whether or not the file exists. - */ - public static boolean exists(final String file, boolean isDir) { - final List result = new ArrayList(); - - String cmdToExecute = "ls " + (isDir ? "-d " : " "); - - Command command = new Command(0, false, cmdToExecute + file) { - @Override - public void commandOutput(int id, String line) { - RootShell.log(line); - result.add(line); - - super.commandOutput(id, line); - } - }; - - try { - //Try without root... - RootShell.getShell(false).add(command); - commandWait(RootShell.getShell(false), command); - - } catch (Exception e) { - RootShell.log("Exception: " + e); - return false; - } - - for (String line : result) { - if (line.trim().equals(file)) { - return true; - } - } - - result.clear(); - - command = new Command(0, false, cmdToExecute + file) { - @Override - public void commandOutput(int id, String line) { - RootShell.log(line); - result.add(line); - - super.commandOutput(id, line); - } - }; - - try { - RootShell.getShell(true).add(command); - commandWait(RootShell.getShell(true), command); - - } catch (Exception e) { - RootShell.log("Exception: " + e); - return false; - } - - //Avoid concurrent modification... - List final_result = new ArrayList(); - final_result.addAll(result); - - for (String line : final_result) { - if (line.trim().equals(file)) { - return true; - } - } - - return false; - - } - - /** - * @param binaryName String that represent the binary to find. - * @param singlePath boolean that represents whether to return a single path or multiple. - * - * @return List containing the locations the binary was found at. - */ - public static List findBinary(String binaryName, boolean singlePath) { - return findBinary(binaryName, null, singlePath); - } - - /** - * @param binaryName String that represent the binary to find. - * @param searchPaths List which contains the paths to search for this binary in. - * @param singlePath boolean that represents whether to return a single path or multiple. - * - * @return List containing the locations the binary was found at. - */ - public static List findBinary(final String binaryName, List searchPaths, boolean singlePath) { - - final List foundPaths = new ArrayList(); - - boolean found = false; - - if(searchPaths == null) - { - searchPaths = RootShell.getPath(); - } - - RootShell.log("Checking for " + binaryName); - - //Try to use stat first - try { - for (String path : searchPaths) { - - if(!path.endsWith("/")) - { - path += "/"; - } - - final String currentPath = path; - - Command cc = new Command(0, false, "stat " + path + binaryName) { - @Override - public void commandOutput(int id, String line) { - if (line.contains("File: ") && line.contains(binaryName)) { - foundPaths.add(currentPath); - - RootShell.log(binaryName + " was found here: " + currentPath); - } - - RootShell.log(line); - - super.commandOutput(id, line); - } - }; - - cc = RootShell.getShell(false).add(cc); - commandWait(RootShell.getShell(false), cc); - - if(foundPaths.size() > 0 && singlePath) { - break; - } - } - - found = !foundPaths.isEmpty(); - - } catch (Exception e) { - RootShell.log(binaryName + " was not found, more information MAY be available with Debugging on."); - } - - if (!found) { - RootShell.log("Trying second method"); - - for (String path : searchPaths) { - - if(!path.endsWith("/")) - { - path += "/"; - } - - if (RootShell.exists(path + binaryName)) { - RootShell.log(binaryName + " was found here: " + path); - foundPaths.add(path); - - if(foundPaths.size() > 0 && singlePath) { - break; - } - - } else { - RootShell.log(binaryName + " was NOT found here: " + path); - } - } - } - - Collections.reverse(foundPaths); - - return foundPaths; - } - - /** - * This will open or return, if one is already open, a custom shell, you are responsible for managing the shell, reading the output - * and for closing the shell when you are done using it. - * - * @param shellPath a String to Indicate the path to the shell that you want to open. - * @param timeout an int to Indicate the length of time before giving up on opening a shell. - * @throws TimeoutException - * @throws com.stericson.RootShell.exceptions.RootDeniedException - * @throws IOException - */ - public static Shell getCustomShell(String shellPath, int timeout) throws IOException, TimeoutException, RootDeniedException - { - return Shell.startCustomShell(shellPath, timeout); - } - - /** - * This will return the environment variable PATH - * - * @return List A List of Strings representing the environment variable $PATH - */ - public static List getPath() { - return Arrays.asList(System.getenv("PATH").split(":")); - } - - /** - * This will open or return, if one is already open, a shell, you are responsible for managing the shell, reading the output - * and for closing the shell when you are done using it. - * - * @param root a boolean to Indicate whether or not you want to open a root shell or a standard shell - * @param timeout an int to Indicate the length of time to wait before giving up on opening a shell. - * @param shellContext the context to execute the shell with - * @param retry a int to indicate how many times the ROOT shell should try to open with root priviliges... - */ - public static Shell getShell(boolean root, int timeout, Shell.ShellContext shellContext, int retry) throws IOException, TimeoutException, RootDeniedException { - if (root) { - return Shell.startRootShell(timeout, shellContext, retry); - } else { - return Shell.startShell(timeout); - } - } - - /** - * This will open or return, if one is already open, a shell, you are responsible for managing the shell, reading the output - * and for closing the shell when you are done using it. - * - * @param root a boolean to Indicate whether or not you want to open a root shell or a standard shell - * @param timeout an int to Indicate the length of time to wait before giving up on opening a shell. - * @param shellContext the context to execute the shell with - */ - public static Shell getShell(boolean root, int timeout, Shell.ShellContext shellContext) throws IOException, TimeoutException, RootDeniedException { - return getShell(root, timeout, shellContext, 3); - } - - /** - * This will open or return, if one is already open, a shell, you are responsible for managing the shell, reading the output - * and for closing the shell when you are done using it. - * - * @param root a boolean to Indicate whether or not you want to open a root shell or a standard shell - * @param shellContext the context to execute the shell with - */ - public static Shell getShell(boolean root, Shell.ShellContext shellContext) throws IOException, TimeoutException, RootDeniedException { - return getShell(root, 0, shellContext, 3); - } - - /** - * This will open or return, if one is already open, a shell, you are responsible for managing the shell, reading the output - * and for closing the shell when you are done using it. - * - * @param root a boolean to Indicate whether or not you want to open a root shell or a standard shell - * @param timeout an int to Indicate the length of time to wait before giving up on opening a shell. - */ - public static Shell getShell(boolean root, int timeout) throws IOException, TimeoutException, RootDeniedException { - return getShell(root, timeout, Shell.defaultContext, 3); - } - - /** - * This will open or return, if one is already open, a shell, you are responsible for managing the shell, reading the output - * and for closing the shell when you are done using it. - * - * @param root a boolean to Indicate whether or not you want to open a root shell or a standard shell - */ - public static Shell getShell(boolean root) throws IOException, TimeoutException, RootDeniedException { - return RootShell.getShell(root, 0); - } - - /** - * @return true if your app has been given root access. - * @throws TimeoutException if this operation times out. (cannot determine if access is given) - */ - public static boolean isAccessGiven() { - return isAccessGiven(0, 3); - } - - /** - * Control how many time of retries should request - * - * @param timeout The timeout - * @param retries The number of retries - * - * @return true if your app has been given root access. - * @throws TimeoutException if this operation times out. (cannot determine if access is given) - */ - public static boolean isAccessGiven(int timeout, int retries) { - final Set ID = new HashSet(); - final int IAG = 158; - - try { - RootShell.log("Checking for Root access"); - - Command command = new Command(IAG, false, "id") { - @Override - public void commandOutput(int id, String line) { - if (id == IAG) { - ID.addAll(Arrays.asList(line.split(" "))); - } - - super.commandOutput(id, line); - } - }; - - Shell shell = Shell.startRootShell(timeout, retries); - shell.add(command); - commandWait(shell, command); - - //parse the userid - for (String userid : ID) { - RootShell.log(userid); - - if (userid.toLowerCase().contains("uid=0")) { - RootShell.log("Access Given"); - return true; - } - } - - return false; - } catch (Exception e) { - e.printStackTrace(); - return false; - } - } - - /** - * @return true if BusyBox was found. - */ - public static boolean isBusyboxAvailable() - { - return isBusyboxAvailable(false); - } - - /** - * @return true if BusyBox or Toybox was found. - */ - public static boolean isBusyboxAvailable(boolean includeToybox) - { - if(includeToybox) { - return (findBinary("busybox", true)).size() > 0 || (findBinary("toybox", true)).size() > 0; - } else { - return (findBinary("busybox", true)).size() > 0; - } - } - - /** - * @return true if su was found. - */ - public static boolean isRootAvailable() { - return (findBinary("su", true)).size() > 0; - } - - /** - * This method allows you to output debug messages only when debugging is on. This will allow - * you to add a debug option to your app, which by default can be left off for performance. - * However, when you need debugging information, a simple switch can enable it and provide you - * with detailed logging. - *

- * This method handles whether or not to log the information you pass it depending whether or - * not RootShell.debugMode is on. So you can use this and not have to worry about handling it - * yourself. - * - * @param msg The message to output. - */ - public static void log(String msg) { - log(null, msg, LogLevel.DEBUG, null); - } - - /** - * This method allows you to output debug messages only when debugging is on. This will allow - * you to add a debug option to your app, which by default can be left off for performance. - * However, when you need debugging information, a simple switch can enable it and provide you - * with detailed logging. - *

- * This method handles whether or not to log the information you pass it depending whether or - * not RootShell.debugMode is on. So you can use this and not have to worry about handling it - * yourself. - * - * @param TAG Optional parameter to define the tag that the Log will use. - * @param msg The message to output. - */ - public static void log(String TAG, String msg) { - log(TAG, msg, LogLevel.DEBUG, null); - } - - /** - * This method allows you to output debug messages only when debugging is on. This will allow - * you to add a debug option to your app, which by default can be left off for performance. - * However, when you need debugging information, a simple switch can enable it and provide you - * with detailed logging. - *

- * This method handles whether or not to log the information you pass it depending whether or - * not RootShell.debugMode is on. So you can use this and not have to worry about handling it - * yourself. - * - * @param msg The message to output. - * @param type The type of log, 1 for verbose, 2 for error, 3 for debug, 4 for warn - * @param e The exception that was thrown (Needed for errors) - */ - public static void log(String msg, LogLevel type, Exception e) { - log(null, msg, type, e); - } - - /** - * This method allows you to check whether logging is enabled. - * Yes, it has a goofy name, but that's to keep it as short as possible. - * After all writing logging calls should be painless. - * This method exists to save Android going through the various Java layers - * that are traversed any time a string is created (i.e. what you are logging) - *

- * Example usage: - * if(islog) { - * StrinbBuilder sb = new StringBuilder(); - * // ... - * // build string - * // ... - * log(sb.toString()); - * } - * - * @return true if logging is enabled - */ - public static boolean islog() { - return debugMode; - } - - /** - * This method allows you to output debug messages only when debugging is on. This will allow - * you to add a debug option to your app, which by default can be left off for performance. - * However, when you need debugging information, a simple switch can enable it and provide you - * with detailed logging. - *

- * This method handles whether or not to log the information you pass it depending whether or - * not RootShell.debugMode is on. So you can use this and not have to worry about handling it - * yourself. - * - * @param TAG Optional parameter to define the tag that the Log will use. - * @param msg The message to output. - * @param type The type of log, 1 for verbose, 2 for error, 3 for debug - * @param e The exception that was thrown (Needed for errors) - */ - public static void log(String TAG, String msg, LogLevel type, Exception e) { - if (msg != null && !msg.equals("")) { - if (debugMode) { - if (TAG == null) { - TAG = version; - } - - switch (type) { - case VERBOSE: - Log.v(TAG, msg); - break; - case ERROR: - Log.e(TAG, msg, e); - break; - case DEBUG: - Log.d(TAG, msg); - break; - case WARN: - Log.w(TAG, msg); - break; - } - } - } - } - - // -------------------- - // # Public Methods # - // -------------------- - - private static void commandWait(Shell shell, Command cmd) throws Exception { - while (!cmd.isFinished()) { - - RootShell.log(version, shell.getCommandQueuePositionString(cmd)); - RootShell.log(version, "Processed " + cmd.totalOutputProcessed + " of " + cmd.totalOutput + " output from command."); - - synchronized (cmd) { - try { - if (!cmd.isFinished()) { - cmd.wait(2000); - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - if (!cmd.isExecuting() && !cmd.isFinished()) { - if (!shell.isExecuting && !shell.isReading) { - RootShell.log(version, "Waiting for a command to be executed in a shell that is not executing and not reading! \n\n Command: " + cmd.getCommand()); - Exception e = new Exception(); - e.setStackTrace(Thread.currentThread().getStackTrace()); - e.printStackTrace(); - } else if (shell.isExecuting && !shell.isReading) { - RootShell.log(version, "Waiting for a command to be executed in a shell that is executing but not reading! \n\n Command: " + cmd.getCommand()); - Exception e = new Exception(); - e.setStackTrace(Thread.currentThread().getStackTrace()); - e.printStackTrace(); - } else { - RootShell.log(version, "Waiting for a command to be executed in a shell that is not reading! \n\n Command: " + cmd.getCommand()); - Exception e = new Exception(); - e.setStackTrace(Thread.currentThread().getStackTrace()); - e.printStackTrace(); - } - } - - } - } -} diff --git a/app/src/main/java/com/stericson/RootShell/containers/RootClass.java b/app/src/main/java/com/stericson/RootShell/containers/RootClass.java deleted file mode 100644 index 9508740..0000000 --- a/app/src/main/java/com/stericson/RootShell/containers/RootClass.java +++ /dev/null @@ -1,348 +0,0 @@ -package com.stericson.RootShell.containers; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileFilter; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FilenameFilter; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/* #ANNOTATIONS @SupportedAnnotationTypes("com.stericson.RootShell.containers.RootClass.Candidate") */ -/* #ANNOTATIONS @SupportedSourceVersion(SourceVersion.RELEASE_6) */ -public class RootClass /* #ANNOTATIONS extends AbstractProcessor */ { - - /* #ANNOTATIONS - @Override - public boolean process(Set typeElements, RoundEnvironment roundEnvironment) { - processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "I was invoked!!!"); - - return false; - } - */ - - static String PATH_TO_DX = "/Users/Chris/Projects/android-sdk-macosx/build-tools/18.0.1/dx"; - - enum READ_STATE { - STARTING, FOUND_ANNOTATION; - } - - public RootClass(String[] args) throws ClassNotFoundException, NoSuchMethodException, - IllegalAccessException, InvocationTargetException, InstantiationException { - - // Note: rather than calling System.load("/system/lib/libandroid_runtime.so"); - // which would leave a bunch of unresolved JNI references, - // we are using the 'withFramework' class as a preloader. - // So, yeah, russian dolls: withFramework > RootClass > actual method - - String className = args[0]; - RootArgs actualArgs = new RootArgs(); - actualArgs.args = new String[args.length - 1]; - System.arraycopy(args, 1, actualArgs.args, 0, args.length - 1); - Class classHandler = Class.forName(className); - Constructor classConstructor = classHandler.getConstructor(RootArgs.class); - classConstructor.newInstance(actualArgs); - } - - public @interface Candidate { - - } - - ; - - public class RootArgs { - - public String args[]; - } - - static void displayError(Exception e) { - // Not using system.err to make it easier to capture from - // calling library. - System.out.println("##ERR##" + e.getMessage() + "##"); - e.printStackTrace(); - } - - // I reckon it would be better to investigate classes using getAttribute() - // however this method allows the developer to simply select "Run" on RootClass - // and immediately re-generate the necessary jar file. - static public class AnnotationsFinder { - - private final String AVOIDDIRPATH = "stericson" + File.separator + "RootShell" + File.separator; - - private List classFiles; - - public AnnotationsFinder() throws IOException { - System.out.println("Discovering root class annotations..."); - classFiles = new ArrayList(); - lookup(new File("src"), classFiles); - System.out.println("Done discovering annotations. Building jar file."); - File builtPath = getBuiltPath(); - if (null != builtPath) { - // Android! Y U no have com.google.common.base.Joiner class? - String rc1 = "com" + File.separator - + "stericson" + File.separator - + "RootShell" + File.separator - + "containers" + File.separator - + "RootClass.class"; - String rc2 = "com" + File.separator - + "stericson" + File.separator - + "RootShell" + File.separator - + "containers" + File.separator - + "RootClass$RootArgs.class"; - String rc3 = "com" + File.separator - + "stericson" + File.separator - + "RootShell" + File.separator - + "containers" + File.separator - + "RootClass$AnnotationsFinder.class"; - String rc4 = "com" + File.separator - + "stericson" + File.separator - + "RootShell" + File.separator - + "containers" + File.separator - + "RootClass$AnnotationsFinder$1.class"; - String rc5 = "com" + File.separator - + "stericson" + File.separator - + "RootShell" + File.separator - + "containers" + File.separator - + "RootClass$AnnotationsFinder$2.class"; - String[] cmd; - boolean onWindows = (-1 != System.getProperty("os.name").toLowerCase().indexOf("win")); - if (onWindows) { - StringBuilder sb = new StringBuilder( - " " + rc1 + " " + rc2 + " " + rc3 + " " + rc4 + " " + rc5 - ); - for (File file : classFiles) { - sb.append(" " + file.getPath()); - } - cmd = new String[]{ - "cmd", "/C", - "jar cvf" + - " anbuild.jar" + - sb.toString() - }; - } else { - ArrayList al = new ArrayList(); - al.add("jar"); - al.add("cf"); - al.add("anbuild.jar"); - al.add(rc1); - al.add(rc2); - al.add(rc3); - al.add(rc4); - al.add(rc5); - for (File file : classFiles) { - al.add(file.getPath()); - } - cmd = al.toArray(new String[al.size()]); - } - ProcessBuilder jarBuilder = new ProcessBuilder(cmd); - jarBuilder.directory(builtPath); - try { - jarBuilder.start().waitFor(); - } catch (IOException e) { - } catch (InterruptedException e) { - } - - String strRawFolder = "res" + File.separator + "raw"; - if (builtPath.toString().startsWith("build")); //Check if running in AndroidStudio - strRawFolder = "src" + File.separator + "main" + File.separator + "res" + File.separator + "raw"; - - File rawFolder = new File(strRawFolder); - if (!rawFolder.exists()) { - rawFolder.mkdirs(); - } - - System.out.println("Done building jar file. Creating dex file."); - if (onWindows) { - cmd = new String[]{ - "cmd", "/C", - "dx --dex --output=" + strRawFolder + File.separator + "anbuild.dex " - + builtPath + File.separator + "anbuild.jar" - }; - } else { - cmd = new String[]{ - getPathToDx(), - "--dex", - "--output=" + strRawFolder + File.separator + "anbuild.dex", - builtPath + File.separator + "anbuild.jar" - }; - } - ProcessBuilder dexBuilder = new ProcessBuilder(cmd); - try { - dexBuilder.start().waitFor(); - } catch (IOException e) { - } catch (InterruptedException e) { - } - } - System.out.println("All done. ::: anbuild.dex should now be in your project's src" + File.separator + "main" + File.separator + "res" + File.separator + "raw" + File.separator + " folder :::"); - } - - protected void lookup(File path, List fileList) { - String desourcedPath = path.toString().replace("src" + File.separator, "").replace("main" + File.separator + "java" + File.separator, ""); - - File[] files = path.listFiles(new FileFilter() { - @Override - public boolean accept(File file) { - return true; - } - }); - for (File file : files) { - if (file.isDirectory()) { - if (-1 == file.getAbsolutePath().indexOf(AVOIDDIRPATH)) { - lookup(file, fileList); - } - } else { - if (file.getName().endsWith(".java")) { - if (hasClassAnnotation(file)) { - final String fileNamePrefix = file.getName().replace(".java", ""); - final File compiledPath = new File(getBuiltPath().toString() + File.separator + desourcedPath); - File[] classAndInnerClassFiles = compiledPath.listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String filename) { - return filename.startsWith(fileNamePrefix); - } - }); - for (final File matchingFile : classAndInnerClassFiles) { - fileList.add(new File(desourcedPath + File.separator + matchingFile.getName())); - } - - } - } - } - } - } - - protected boolean hasClassAnnotation(File file) { - READ_STATE readState = READ_STATE.STARTING; - Pattern p = Pattern.compile(" class ([A-Za-z0-9_]+)"); - try { - BufferedReader reader = new BufferedReader(new FileReader(file)); - String line; - while (null != (line = reader.readLine())) { - switch (readState) { - case STARTING: - if (-1 < line.indexOf("@RootClass.Candidate")) { - readState = READ_STATE.FOUND_ANNOTATION; - } - break; - case FOUND_ANNOTATION: - Matcher m = p.matcher(line); - if (m.find()) { - System.out.println(" Found annotated class: " + m.group(0)); - return true; - } else { - System.err.println("Error: unmatched annotation in " + - file.getAbsolutePath()); - readState = READ_STATE.STARTING; - } - break; - } - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - return false; - } - - protected String getPathToDx() throws IOException { - String androidHome = System.getenv("ANDROID_HOME"); - if (null == androidHome) { - throw new IOException("Error: you need to set $ANDROID_HOME globally"); - } - String dxPath = null; - File[] files = new File(androidHome + File.separator + "build-tools").listFiles(); - int recentSdkVersion = 0; - for (File file : files) { - - String fileName = null; - if (file.getName().contains("-")) { - String[] splitFileName = file.getName().split("-"); - if (splitFileName[1].contains("W")) { - char[] fileNameChars = splitFileName[1].toCharArray(); - fileName = String.valueOf(fileNameChars[0]); - } else if (splitFileName[1].contains("rc")) { - continue; //Do not use release candidates - } else { - fileName = splitFileName[1]; - } - } else { - fileName = file.getName(); - } - - int sdkVersion; - - String[] sdkVersionBits = fileName.split("[.]"); - sdkVersion = Integer.parseInt(sdkVersionBits[0]) * 10000; - if (sdkVersionBits.length > 1) { - sdkVersion += Integer.parseInt(sdkVersionBits[1]) * 100; - if (sdkVersionBits.length > 2) { - sdkVersion += Integer.parseInt(sdkVersionBits[2]); - } - } - if (sdkVersion > recentSdkVersion) { - String tentativePath = file.getAbsolutePath() + File.separator + "dx"; - if (new File(tentativePath).exists()) { - recentSdkVersion = sdkVersion; - dxPath = tentativePath; - } - } - } - if (dxPath == null) { - throw new IOException("Error: unable to find dx binary in $ANDROID_HOME"); - } - return dxPath; - } - - protected File getBuiltPath() { - File foundPath = null; - - File ideaPath = new File("out" + File.separator + "production"); // IntelliJ - if (ideaPath.isDirectory()) { - File[] children = ideaPath.listFiles(new FileFilter() { - @Override - public boolean accept(File pathname) { - return pathname.isDirectory(); - } - }); - if (children.length > 0) { - foundPath = new File(ideaPath.getAbsolutePath() + File.separator + children[0].getName()); - } - } - if (null == foundPath) { - File eclipsePath = new File("bin" + File.separator + "classes"); // Eclipse IDE - if (eclipsePath.isDirectory()) { - foundPath = eclipsePath; - } - } - if (null == foundPath) { - File androidStudioPath = new File("build" + File.separator + "intermediates" + File.separator + "classes" + File.separator + "debug"); // Android Studio - if (androidStudioPath.isDirectory()) { - foundPath = androidStudioPath; - } - } - - return foundPath; - } - - - } - - public static void main(String[] args) { - try { - if (args.length == 0) { - new AnnotationsFinder(); - } else { - new RootClass(args); - } - } catch (Exception e) { - displayError(e); - } - } -} diff --git a/app/src/main/java/com/stericson/RootShell/exceptions/RootDeniedException.java b/app/src/main/java/com/stericson/RootShell/exceptions/RootDeniedException.java deleted file mode 100644 index 758ba8c..0000000 --- a/app/src/main/java/com/stericson/RootShell/exceptions/RootDeniedException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the RootShell Project: https://github.com/Stericson/RootShell - * - * Copyright (c) 2014 Stephen Erickson, Chris Ravenscroft - * - * This code is dual-licensed under the terms of the Apache License Version 2.0 and - * the terms of the General Public License (GPL) Version 2. - * You may use this code according to either of these licenses as is most appropriate - * for your project on a case-by-case basis. - * - * The terms of each license can be found in the root directory of this project's repository as well as at: - * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * http://www.gnu.org/licenses/gpl-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under these Licenses is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See each License for the specific language governing permissions and - * limitations under that License. - */ - -package com.stericson.RootShell.exceptions; - -public class RootDeniedException extends Exception { - - private static final long serialVersionUID = -8713947214162841310L; - - public RootDeniedException(String error) { - super(error); - } -} diff --git a/app/src/main/java/com/stericson/RootShell/execution/Command.java b/app/src/main/java/com/stericson/RootShell/execution/Command.java deleted file mode 100644 index e3f7eb4..0000000 --- a/app/src/main/java/com/stericson/RootShell/execution/Command.java +++ /dev/null @@ -1,346 +0,0 @@ -/* - * This file is part of the RootShell Project: http://code.google.com/p/RootShell/ - * - * Copyright (c) 2014 Stephen Erickson, Chris Ravenscroft - * - * This code is dual-licensed under the terms of the Apache License Version 2.0 and - * the terms of the General Public License (GPL) Version 2. - * You may use this code according to either of these licenses as is most appropriate - * for your project on a case-by-case basis. - * - * The terms of each license can be found in the root directory of this project's repository as well as at: - * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * http://www.gnu.org/licenses/gpl-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under these Licenses is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See each License for the specific language governing permissions and - * limitations under that License. - */ - -package com.stericson.RootShell.execution; - -import com.stericson.RootShell.RootShell; - -import android.content.Context; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; - -import java.io.IOException; - -public class Command { - - //directly modified by JavaCommand - protected boolean javaCommand = false; - protected Context context = null; - - public int totalOutput = 0; - - public int totalOutputProcessed = 0; - - ExecutionMonitor executionMonitor = null; - - Handler mHandler = null; - - //Has this command already been used? - protected boolean used = false; - - boolean executing = false; - - String[] command = {}; - - boolean finished = false; - - boolean terminated = false; - - boolean handlerEnabled = true; - - int exitCode = -1; - - int id = 0; - - int timeout = RootShell.defaultCommandTimeout; - - /** - * Constructor for executing a normal shell command - * - * @param id the id of the command being executed - * @param command the command, or commands, to be executed. - */ - public Command(int id, String... command) { - this.command = command; - this.id = id; - - createHandler(RootShell.handlerEnabled); - } - - /** - * Constructor for executing a normal shell command - * - * @param id the id of the command being executed - * @param handlerEnabled when true the handler will be used to call the - * callback methods if possible. - * @param command the command, or commands, to be executed. - */ - public Command(int id, boolean handlerEnabled, String... command) { - this.command = command; - this.id = id; - - createHandler(handlerEnabled); - } - - /** - * Constructor for executing a normal shell command - * - * @param id the id of the command being executed - * @param timeout the time allowed before the shell will give up executing the command - * and throw a TimeoutException. - * @param command the command, or commands, to be executed. - */ - public Command(int id, int timeout, String... command) { - this.command = command; - this.id = id; - this.timeout = timeout; - - createHandler(RootShell.handlerEnabled); - } - - //If you override this you MUST make a final call - //to the super method. The super call should be the last line of this method. - public void commandOutput(int id, String line) { - RootShell.log("Command", "ID: " + id + ", " + line); - totalOutputProcessed++; - } - - public void commandTerminated(int id, String reason) { - //pass - } - - public void commandCompleted(int id, int exitcode) { - //pass - } - - protected final void commandFinished() { - if (!terminated) { - synchronized (this) { - if (mHandler != null && handlerEnabled) { - Message msg = mHandler.obtainMessage(); - Bundle bundle = new Bundle(); - bundle.putInt(CommandHandler.ACTION, CommandHandler.COMMAND_COMPLETED); - msg.setData(bundle); - mHandler.sendMessage(msg); - } else { - commandCompleted(id, exitCode); - } - - RootShell.log("Command " + id + " finished."); - finishCommand(); - } - } - } - - private void createHandler(boolean handlerEnabled) { - - this.handlerEnabled = handlerEnabled; - - if (Looper.myLooper() != null && handlerEnabled) { - RootShell.log("CommandHandler created"); - mHandler = new CommandHandler(); - } else { - RootShell.log("CommandHandler not created"); - } - } - - public final void finish() { - RootShell.log("Command finished at users request!"); - commandFinished(); - } - - protected final void finishCommand() { - this.executing = false; - this.finished = true; - this.notifyAll(); - } - - - public final String getCommand() { - StringBuilder sb = new StringBuilder(); - - if (javaCommand) { - String filePath = context.getFilesDir().getPath(); - - for (int i = 0; i < command.length; i++) { - /* - * TODO Make withFramework optional for applications - * that do not require access to the fw. -CFR - */ - //export CLASSPATH=/data/user/0/ch.masshardt.emailnotification/files/anbuild.dex ; app_process /system/bin - if (Build.VERSION.SDK_INT > 22) { - //dalvikvm command is not working in Android Marshmallow - sb.append( - "export CLASSPATH=" + filePath + "/anbuild.dex;" - + " app_process /system/bin " - + command[i]); - } else { - sb.append( - "dalvikvm -cp " + filePath + "/anbuild.dex" - + " com.android.internal.util.WithFramework" - + " com.stericson.RootTools.containers.RootClass " - + command[i]); - } - - sb.append('\n'); - } - } else { - for (int i = 0; i < command.length; i++) { - sb.append(command[i]); - sb.append('\n'); - } - } - - return sb.toString(); - } - - public final boolean isExecuting() { - return executing; - } - - public final boolean isHandlerEnabled() { - return handlerEnabled; - } - - public final boolean isFinished() { - return finished; - } - - public final int getExitCode() { - return this.exitCode; - } - - protected final void setExitCode(int code) { - synchronized (this) { - exitCode = code; - } - } - - protected final void startExecution() { - this.used = true; - executionMonitor = new ExecutionMonitor(this); - executionMonitor.setPriority(Thread.MIN_PRIORITY); - executionMonitor.start(); - executing = true; - } - - public final void terminate() { - RootShell.log("Terminating command at users request!"); - terminated("Terminated at users request!"); - } - - protected final void terminate(String reason) { - try { - Shell.closeAll(); - RootShell.log("Terminating all shells."); - terminated(reason); - } catch (IOException e) { - } - } - - protected final void terminated(String reason) { - synchronized (Command.this) { - - if (mHandler != null && handlerEnabled) { - Message msg = mHandler.obtainMessage(); - Bundle bundle = new Bundle(); - bundle.putInt(CommandHandler.ACTION, CommandHandler.COMMAND_TERMINATED); - bundle.putString(CommandHandler.TEXT, reason); - msg.setData(bundle); - mHandler.sendMessage(msg); - } else { - commandTerminated(id, reason); - } - - RootShell.log("Command " + id + " did not finish because it was terminated. Termination reason: " + reason); - setExitCode(-1); - terminated = true; - finishCommand(); - } - } - - protected final void output(int id, String line) { - totalOutput++; - - if (mHandler != null && handlerEnabled) { - Message msg = mHandler.obtainMessage(); - Bundle bundle = new Bundle(); - bundle.putInt(CommandHandler.ACTION, CommandHandler.COMMAND_OUTPUT); - bundle.putString(CommandHandler.TEXT, line); - msg.setData(bundle); - mHandler.sendMessage(msg); - } else { - commandOutput(id, line); - } - } - - private class ExecutionMonitor extends Thread { - - private final Command command; - - public ExecutionMonitor(Command command) { - this.command = command; - } - - public void run() { - - if (command.timeout > 0) { - synchronized (command) { - try { - RootShell.log("Command " + command.id + " is waiting for: " + command.timeout); - command.wait(command.timeout); - } catch (InterruptedException e) { - RootShell.log("Exception: " + e); - } - - if (!command.isFinished()) { - RootShell.log("Timeout Exception has occurred for command: " + command.id + "."); - terminate("Timeout Exception"); - } - } - } - } - } - - private class CommandHandler extends Handler { - - static final public String ACTION = "action"; - - static final public String TEXT = "text"; - - static final public int COMMAND_OUTPUT = 0x01; - - static final public int COMMAND_COMPLETED = 0x02; - - static final public int COMMAND_TERMINATED = 0x03; - - public final void handleMessage(Message msg) { - int action = msg.getData().getInt(ACTION); - String text = msg.getData().getString(TEXT); - - switch (action) { - case COMMAND_OUTPUT: - commandOutput(id, text); - break; - case COMMAND_COMPLETED: - commandCompleted(id, exitCode); - break; - case COMMAND_TERMINATED: - commandTerminated(id, text); - break; - } - } - } -} diff --git a/app/src/main/java/com/stericson/RootShell/execution/JavaCommand.java b/app/src/main/java/com/stericson/RootShell/execution/JavaCommand.java deleted file mode 100644 index 032569e..0000000 --- a/app/src/main/java/com/stericson/RootShell/execution/JavaCommand.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.stericson.RootShell.execution; - -import android.content.Context; - -public class JavaCommand extends Command -{ - /** - * Constructor for executing Java commands rather than binaries - * - * @param context needed to execute java command. - */ - public JavaCommand(int id, Context context, String... command) { - super(id, command); - this.context = context; - this.javaCommand = true; - } - - /** - * Constructor for executing Java commands rather than binaries - * - * @param context needed to execute java command. - */ - public JavaCommand(int id, boolean handlerEnabled, Context context, String... command) { - super(id, handlerEnabled, command); - this.context = context; - this.javaCommand = true; - } - - /** - * Constructor for executing Java commands rather than binaries - * - * @param context needed to execute java command. - */ - public JavaCommand(int id, int timeout, Context context, String... command) { - super(id, timeout, command); - this.context = context; - this.javaCommand = true; - } - - - @Override - public void commandOutput(int id, String line) - { - super.commandOutput(id, line); - } - - @Override - public void commandTerminated(int id, String reason) - { - // pass - } - - @Override - public void commandCompleted(int id, int exitCode) - { - // pass - } -} diff --git a/app/src/main/java/com/stericson/RootShell/execution/Shell.java b/app/src/main/java/com/stericson/RootShell/execution/Shell.java deleted file mode 100644 index b64923e..0000000 --- a/app/src/main/java/com/stericson/RootShell/execution/Shell.java +++ /dev/null @@ -1,1038 +0,0 @@ -/* - * This file is part of the RootShell Project: http://code.google.com/p/RootShell/ - * - * Copyright (c) 2014 Stephen Erickson, Chris Ravenscroft - * - * This code is dual-licensed under the terms of the Apache License Version 2.0 and - * the terms of the General Public License (GPL) Version 2. - * You may use this code according to either of these licenses as is most appropriate - * for your project on a case-by-case basis. - * - * The terms of each license can be found in the root directory of this project's repository as well as at: - * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * http://www.gnu.org/licenses/gpl-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under these Licenses is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See each License for the specific language governing permissions and - * limitations under that License. - */ -package com.stericson.RootShell.execution; - -import com.stericson.RootShell.RootShell; -import com.stericson.RootShell.exceptions.RootDeniedException; - -import android.content.Context; -import android.util.Log; - -import java.io.BufferedReader; -import java.io.EOFException; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.Writer; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeoutException; - -public class Shell { - - public static enum ShellType { - NORMAL, - ROOT, - CUSTOM - } - - //this is only used with root shells - public static enum ShellContext { - NORMAL("normal"), //The normal context... - SHELL("u:r:shell:s0"), //unprivileged shell (such as an adb shell) - SYSTEM_SERVER("u:r:system_server:s0"), // system_server, u:r:system:s0 on some firmwares - SYSTEM_APP("u:r:system_app:s0"), // System apps - PLATFORM_APP("u:r:platform_app:s0"), // System apps - UNTRUSTED_APP("u:r:untrusted_app:s0"), // Third-party apps - RECOVERY("u:r:recovery:s0"), //Recovery - SUPERSU("u:r:supersu:s0"); //SUPER SU default - - private String value; - - private ShellContext(String value) { - this.value = value; - } - - public String getValue() { - return this.value; - } - - } - - //Statics -- visible to all - private static final String token = "F*D^W@#FGF"; - - private static Shell rootShell = null; - - private static Shell shell = null; - - private static Shell customShell = null; - - private static String[] suVersion = new String[]{ - null, null - }; - - //the default context for root shells... - public static ShellContext defaultContext = ShellContext.NORMAL; - - //per shell - private int shellTimeout = 25000; - - private ShellType shellType = null; - - private ShellContext shellContext = Shell.ShellContext.NORMAL; - - private String error = ""; - - private final Process proc; - - private final BufferedReader inputStream; - - private final BufferedReader errorStream; - - private final OutputStreamWriter outputStream; - - private final List commands = new ArrayList(); - - //indicates whether or not to close the shell - private boolean close = false; - - private Boolean isSELinuxEnforcing = null; - - public boolean isExecuting = false; - - public boolean isReading = false; - - public boolean isClosed = false; - - private int maxCommands = 5000; - - private int read = 0; - - private int write = 0; - - private int totalExecuted = 0; - - private int totalRead = 0; - - private boolean isCleaning = false; - - private Shell(String cmd, ShellType shellType, ShellContext shellContext, int shellTimeout) throws IOException, TimeoutException, RootDeniedException { - - RootShell.log("Starting shell: " + cmd); - RootShell.log("Context: " + shellContext.getValue()); - RootShell.log("Timeout: " + shellTimeout); - - this.shellType = shellType; - this.shellTimeout = shellTimeout > 0 ? shellTimeout : this.shellTimeout; - this.shellContext = shellContext; - - if (this.shellContext == ShellContext.NORMAL) { - this.proc = Runtime.getRuntime().exec(cmd); - } else { - String display = getSuVersion(false); - String internal = getSuVersion(true); - - //only done for root shell... - //Right now only SUPERSU supports the --context switch - if (isSELinuxEnforcing() && - (display != null) && - (internal != null) && - (display.endsWith("SUPERSU")) && - (Integer.valueOf(internal) >= 190)) { - cmd += " --context " + this.shellContext.getValue(); - } else { - RootShell.log("Su binary --context switch not supported!"); - RootShell.log("Su binary display version: " + display); - RootShell.log("Su binary internal version: " + internal); - RootShell.log("SELinuxEnforcing: " + isSELinuxEnforcing()); - } - - this.proc = Runtime.getRuntime().exec(cmd); - - } - - this.inputStream = new BufferedReader(new InputStreamReader(this.proc.getInputStream(), "UTF-8")); - this.errorStream = new BufferedReader(new InputStreamReader(this.proc.getErrorStream(), "UTF-8")); - this.outputStream = new OutputStreamWriter(this.proc.getOutputStream(), "UTF-8"); - - /** - * Thread responsible for carrying out the requested operations - */ - Worker worker = new Worker(this); - worker.start(); - - try { - /** - * The flow of execution will wait for the thread to die or wait until the - * given timeout has expired. - * - * The result of the worker, which is determined by the exit code of the worker, - * will tell us if the operation was completed successfully or it the operation - * failed. - */ - worker.join(this.shellTimeout); - - /** - * The operation could not be completed before the timeout occurred. - */ - if (worker.exit == -911) { - - try { - this.proc.destroy(); - } catch (Exception e) { - } - - closeQuietly(this.inputStream); - closeQuietly(this.errorStream); - closeQuietly(this.outputStream); - - throw new TimeoutException(this.error); - } - /** - * Root access denied? - */ - else if (worker.exit == -42) { - - try { - this.proc.destroy(); - } catch (Exception e) { - } - - closeQuietly(this.inputStream); - closeQuietly(this.errorStream); - closeQuietly(this.outputStream); - - throw new RootDeniedException("Root Access Denied"); - } - /** - * Normal exit - */ - else { - /** - * The shell is open. - * - * Start two threads, one to handle the input and one to handle the output. - * - * input, and output are runnables that the threads execute. - */ - Thread si = new Thread(this.input, "Shell Input"); - si.setPriority(Thread.NORM_PRIORITY); - si.start(); - - Thread so = new Thread(this.output, "Shell Output"); - so.setPriority(Thread.NORM_PRIORITY); - so.start(); - } - } catch (InterruptedException ex) { - worker.interrupt(); - Thread.currentThread().interrupt(); - throw new TimeoutException(); - } - } - - - public Command add(Command command) throws IOException { - if (this.close) { - throw new IllegalStateException( - "Unable to add commands to a closed shell"); - } - - if(command.used) { - //The command has been used, don't re-use... - throw new IllegalStateException( - "This command has already been executed. (Don't re-use command instances.)"); - } - - while (this.isCleaning) { - //Don't add commands while cleaning - ; - } - - this.commands.add(command); - - this.notifyThreads(); - - return command; - } - - public final void useCWD(Context context) throws IOException, TimeoutException, RootDeniedException { - add( - new Command( - -1, - false, - "cd " + context.getApplicationInfo().dataDir) - ); - } - - private void cleanCommands() { - this.isCleaning = true; - int toClean = Math.abs(this.maxCommands - (this.maxCommands / 4)); - RootShell.log("Cleaning up: " + toClean); - - for (int i = 0; i < toClean; i++) { - this.commands.remove(0); - } - - this.read = this.commands.size() - 1; - this.write = this.commands.size() - 1; - this.isCleaning = false; - } - - private void closeQuietly(final Reader input) { - try { - if (input != null) { - input.close(); - } - } catch (Exception ignore) { - } - } - - private void closeQuietly(final Writer output) { - try { - if (output != null) { - output.close(); - } - } catch (Exception ignore) { - } - } - - public void close() throws IOException { - RootShell.log("Request to close shell!"); - - int count = 0; - while (isExecuting) { - RootShell.log("Waiting on shell to finish executing before closing..."); - count++; - - //fail safe - if (count > 10000) { - break; - } - - } - - synchronized (this.commands) { - /** - * instruct the two threads monitoring input and output - * of the shell to close. - */ - this.close = true; - this.notifyThreads(); - } - - RootShell.log("Shell Closed!"); - - if (this == Shell.rootShell) { - Shell.rootShell = null; - } else if (this == Shell.shell) { - Shell.shell = null; - } else if (this == Shell.customShell) { - Shell.customShell = null; - } - } - - public static void closeCustomShell() throws IOException { - RootShell.log("Request to close custom shell!"); - - if (Shell.customShell == null) { - return; - } - - Shell.customShell.close(); - } - - public static void closeRootShell() throws IOException { - RootShell.log("Request to close root shell!"); - - if (Shell.rootShell == null) { - return; - } - Shell.rootShell.close(); - } - - public static void closeShell() throws IOException { - RootShell.log("Request to close normal shell!"); - - if (Shell.shell == null) { - return; - } - Shell.shell.close(); - } - - public static void closeAll() throws IOException { - RootShell.log("Request to close all shells!"); - - Shell.closeShell(); - Shell.closeRootShell(); - Shell.closeCustomShell(); - } - - public int getCommandQueuePosition(Command cmd) { - return this.commands.indexOf(cmd); - } - - public String getCommandQueuePositionString(Command cmd) { - return "Command is in position " + getCommandQueuePosition(cmd) + " currently executing command at position " + this.write + " and the number of commands is " + commands.size(); - } - - public static Shell getOpenShell() { - if (Shell.customShell != null) { - return Shell.customShell; - } else if (Shell.rootShell != null) { - return Shell.rootShell; - } else { - return Shell.shell; - } - } - - /** - * From libsuperuser. - * - *

- * Detects the version of the su binary installed (if any), if supported - * by the binary. Most binaries support two different version numbers, - * the public version that is displayed to users, and an internal - * version number that is used for version number comparisons. Returns - * null if su not available or retrieving the version isn't supported. - *

- *

- * Note that su binary version and GUI (APK) version can be completely - * different. - *

- *

- * This function caches its result to improve performance on multiple - * calls - *

- * - * @param internal Request human-readable version or application - * internal version - * @return String containing the su version or null - */ - private synchronized String getSuVersion(boolean internal) { - int idx = internal ? 0 : 1; - if (suVersion[idx] == null) { - String version = null; - - // Replace libsuperuser:Shell.run with manual process execution - Process process; - try { - process = Runtime.getRuntime().exec(internal ? "su -V" : "su -v", null); - process.waitFor(); - } catch (IOException e) { - e.printStackTrace(); - return null; - } catch (InterruptedException e) { - e.printStackTrace(); - return null; - } - - // From libsuperuser:StreamGobbler - List stdout = new ArrayList(); - - BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); - try { - String line = null; - while ((line = reader.readLine()) != null) { - stdout.add(line); - } - } catch (IOException e) { - } - // make sure our stream is closed and resources will be freed - try { - reader.close(); - } catch (IOException e) { - } - - process.destroy(); - - List ret = stdout; - - if (ret != null) { - for (String line : ret) { - if (!internal) { - if (line.contains(".")) { - version = line; - break; - } - } else { - try { - if (Integer.parseInt(line) > 0) { - version = line; - break; - } - } catch (NumberFormatException e) { - } - } - } - } - - suVersion[idx] = version; - } - return suVersion[idx]; - } - - public static boolean isShellOpen() { - return Shell.shell == null; - } - - public static boolean isCustomShellOpen() { - return Shell.customShell == null; - } - - public static boolean isRootShellOpen() { - return Shell.rootShell == null; - } - - public static boolean isAnyShellOpen() { - return Shell.shell != null || Shell.rootShell != null || Shell.customShell != null; - } - - /** - * From libsuperuser. - * - * Detect if SELinux is set to enforcing, caches result - * - * @return true if SELinux set to enforcing, or false in the case of - * permissive or not present - */ - public synchronized boolean isSELinuxEnforcing() { - if (isSELinuxEnforcing == null) { - Boolean enforcing = null; - - // First known firmware with SELinux built-in was a 4.2 (17) - // leak - if (android.os.Build.VERSION.SDK_INT >= 17) { - - // Detect enforcing through sysfs, not always present - File f = new File("/sys/fs/selinux/enforce"); - if (f.exists()) { - try { - InputStream is = new FileInputStream("/sys/fs/selinux/enforce"); - try { - enforcing = (is.read() == '1'); - } finally { - is.close(); - } - } catch (Exception e) { - } - } - - // 4.4+ builds are enforcing by default, take the gamble - if (enforcing == null) { - enforcing = (android.os.Build.VERSION.SDK_INT >= 19); - } - } - - if (enforcing == null) { - enforcing = false; - } - - isSELinuxEnforcing = enforcing; - } - return isSELinuxEnforcing; - } - - /** - * Runnable to write commands to the open shell. - *

- * When writing commands we stay in a loop and wait for new - * commands to added to "commands" - *

- * The notification of a new command is handled by the method add in this class - */ - private Runnable input = new Runnable() { - public void run() { - - try { - while (true) { - - synchronized (commands) { - /** - * While loop is used in the case that notifyAll is called - * and there are still no commands to be written, a rare - * case but one that could happen. - */ - while (!close && write >= commands.size()) { - isExecuting = false; - commands.wait(); - } - } - - if (write >= maxCommands) { - - /** - * wait for the read to catch up. - */ - while (read != write) { - RootShell.log("Waiting for read and write to catch up before cleanup."); - } - /** - * Clean up the commands, stay neat. - */ - cleanCommands(); - } - - /** - * Write the new command - * - * We write the command followed by the token to indicate - * the end of the command execution - */ - if (write < commands.size()) { - isExecuting = true; - Command cmd = commands.get(write); - - if(null != cmd) - { - cmd.startExecution(); - RootShell.log("Executing: " + cmd.getCommand() + " with context: " + shellContext); - - //write the command - outputStream.write(cmd.getCommand()); - outputStream.flush(); - - //write the token... - String line = "\necho " + token + " " + totalExecuted + " $?\n"; - outputStream.write(line); - outputStream.flush(); - - write++; - totalExecuted++; - } - } else if (close) { - /** - * close the thread, the shell is closing. - */ - isExecuting = false; - outputStream.write("\nexit 0\n"); - outputStream.flush(); - RootShell.log("Closing shell"); - return; - } - } - } catch (IOException | InterruptedException e) { - RootShell.log(e.getMessage(), RootShell.LogLevel.ERROR, e); - } - finally { - write = 0; - closeQuietly(outputStream); - } - } - }; - - protected void notifyThreads() { - Thread t = new Thread() { - public void run() { - synchronized (commands) { - commands.notifyAll(); - } - } - }; - - t.start(); - } - - /** - * Runnable to monitor the responses from the open shell. - * - * This include the output and error stream - */ - private Runnable output = new Runnable() { - public void run() { - try { - Command command = null; - - //as long as there is something to read, we will keep reading. - while (!close || inputStream.ready() || read < commands.size()) { - isReading = false; - String outputLine = inputStream.readLine(); - isReading = true; - - /** - * If we receive EOF then the shell closed? - */ - if (outputLine == null) { - break; - } - - if (command == null) { - if (read >= commands.size()) { - if (close) { - break; - } - - continue; - } - - command = commands.get(read); - } - - /** - * trying to determine if all commands have been completed. - * - * if the token is present then the command has finished execution. - */ - int pos = -1; - - pos = outputLine.indexOf(token); - - if (pos == -1) { - /** - * send the output for the implementer to process - */ - command.output(command.id, outputLine); - } else if (pos > 0) { - /** - * token is suffix of output, send output part to implementer - */ - RootShell.log("Found token, line: " + outputLine); - command.output(command.id, outputLine.substring(0, pos)); - } - - if (pos >= 0) { - outputLine = outputLine.substring(pos); - String fields[] = outputLine.split(" "); - - if (fields.length >= 2 && fields[1] != null) { - int id = 0; - - try { - id = Integer.parseInt(fields[1]); - } catch (NumberFormatException e) { - } - - int exitCode = -1; - - try { - exitCode = Integer.parseInt(fields[2]); - } catch (NumberFormatException e) { - } - - if (id == totalRead) { - processErrors(command); - - - /** - * wait for output to be processed... - * - */ - int iterations = 0; - while (command.totalOutput > command.totalOutputProcessed) { - - if(iterations == 0) - { - iterations++; - RootShell.log("Waiting for output to be processed. " + command.totalOutputProcessed + " Of " + command.totalOutput); - } - - try { - - synchronized (this) - { - this.wait(2000); - } - } catch (Exception e) { - RootShell.log(e.getMessage()); - } - } - - RootShell.log("Read all output"); - - command.setExitCode(exitCode); - command.commandFinished(); - - command = null; - - read++; - totalRead++; - continue; - } - } - } - } - - try { - proc.waitFor(); - proc.destroy(); - } catch (Exception e) { - } - - while (read < commands.size()) { - if (command == null) { - command = commands.get(read); - } - - if(command.totalOutput < command.totalOutputProcessed) - { - command.terminated("All output not processed!"); - command.terminated("Did you forget the super.commandOutput call or are you waiting on the command object?"); - } - else - { - command.terminated("Unexpected Termination."); - } - - command = null; - read++; - } - - read = 0; - - } catch (IOException e) { - RootShell.log(e.getMessage(), RootShell.LogLevel.ERROR, e); - } finally { - closeQuietly(outputStream); - closeQuietly(errorStream); - closeQuietly(inputStream); - - RootShell.log("Shell destroyed"); - isClosed = true; - isReading = false; - } - } - }; - - public void processErrors(Command command) { - try { - while (errorStream.ready() && command != null) { - String line = errorStream.readLine(); - - /** - * If we recieve EOF then the shell closed? - */ - if (line == null) { - break; - } - - /** - * send the output for the implementer to process - */ - command.output(command.id, line); - } - } catch (Exception e) { - RootShell.log(e.getMessage(), RootShell.LogLevel.ERROR, e); - } - } - - public static Command runRootCommand(Command command) throws IOException, TimeoutException, RootDeniedException { - return Shell.startRootShell().add(command); - } - - public static Command runCommand(Command command) throws IOException, TimeoutException { - return Shell.startShell().add(command); - } - - public static Shell startRootShell() throws IOException, TimeoutException, RootDeniedException { - return Shell.startRootShell(0, 3); - } - - public static Shell startRootShell(int timeout) throws IOException, TimeoutException, RootDeniedException { - return Shell.startRootShell(timeout, 3); - } - - public static Shell startRootShell(int timeout, int retry) throws IOException, TimeoutException, RootDeniedException { - return Shell.startRootShell(timeout, Shell.defaultContext, retry); - } - - public static Shell startRootShell(int timeout, ShellContext shellContext, int retry) throws IOException, TimeoutException, RootDeniedException { - // keep prompting the user until they accept for x amount of times... - int retries = 0; - - if (Shell.rootShell == null) { - - RootShell.log("Starting Root Shell!"); - String cmd = "su"; - while (Shell.rootShell == null) { - try { - RootShell.log("Trying to open Root Shell, attempt #" + retries); - Shell.rootShell = new Shell(cmd, ShellType.ROOT, shellContext, timeout); - } catch (IOException e) { - if (retries++ >= retry) { - RootShell.log("IOException, could not start shell"); - throw e; - } - } catch (RootDeniedException e) { - if (retries++ >= retry) { - RootShell.log("RootDeniedException, could not start shell"); - throw e; - } - } catch (TimeoutException e) { - if (retries++ >= retry) { - RootShell.log("TimeoutException, could not start shell"); - throw e; - } - } - } - } else if (Shell.rootShell.shellContext != shellContext) { - try { - RootShell.log("Context is different than open shell, switching context... " + Shell.rootShell.shellContext + " VS " + shellContext); - Shell.rootShell.switchRootShellContext(shellContext); - } catch (IOException e) { - if (retries++ >= retry) { - RootShell.log("IOException, could not switch context!"); - throw e; - } - } catch (RootDeniedException e) { - if (retries++ >= retry) { - RootShell.log("RootDeniedException, could not switch context!"); - throw e; - } - } catch (TimeoutException e) { - if (retries++ >= retry) { - RootShell.log("TimeoutException, could not switch context!"); - throw e; - } - } - } else { - RootShell.log("Using Existing Root Shell!"); - } - - return Shell.rootShell; - } - - public static Shell startCustomShell(String shellPath) throws IOException, TimeoutException, RootDeniedException { - return Shell.startCustomShell(shellPath, 0); - } - - public static Shell startCustomShell(String shellPath, int timeout) throws IOException, TimeoutException, RootDeniedException { - - if (Shell.customShell == null) { - RootShell.log("Starting Custom Shell!"); - Shell.customShell = new Shell(shellPath, ShellType.CUSTOM, ShellContext.NORMAL, timeout); - } else { - RootShell.log("Using Existing Custom Shell!"); - } - - return Shell.customShell; - } - - public static Shell startShell() throws IOException, TimeoutException { - return Shell.startShell(0); - } - - public static Shell startShell(int timeout) throws IOException, TimeoutException { - - try { - if (Shell.shell == null) { - RootShell.log("Starting Shell!"); - Shell.shell = new Shell("/system/bin/sh", ShellType.NORMAL, ShellContext.NORMAL, timeout); - } else { - RootShell.log("Using Existing Shell!"); - } - return Shell.shell; - } catch (RootDeniedException e) { - //Root Denied should never be thrown. - throw new IOException(); - } - } - - public Shell switchRootShellContext(ShellContext shellContext) throws IOException, TimeoutException, RootDeniedException { - if (this.shellType == ShellType.ROOT) { - try { - Shell.closeRootShell(); - } catch (Exception e) { - RootShell.log("Problem closing shell while trying to switch context..."); - } - - //create new root shell with new context... - - return Shell.startRootShell(this.shellTimeout, shellContext, 3); - } else { - //can only switch context on a root shell... - RootShell.log("Can only switch context on a root shell!"); - return this; - } - } - - protected static class Worker extends Thread { - - public int exit = -911; - - public Shell shell; - - private Worker(Shell shell) { - this.shell = shell; - } - - public void run() { - - /** - * Trying to open the shell. - * - * We echo "Started" and we look for it in the output. - * - * If we find the output then the shell is open and we return. - * - * If we do not find it then we determine the error and report - * it by setting the value of the variable exit - */ - try { - shell.outputStream.write("echo Started\n"); - shell.outputStream.flush(); - - while (true) { - String line = shell.inputStream.readLine(); - - if (line == null) { - throw new EOFException(); - } else if ("".equals(line)) { - continue; - } else if ("Started".equals(line)) { - this.exit = 1; - setShellOom(); - break; - } - - shell.error = "unknown error occurred."; - } - } catch (IOException e) { - exit = -42; - if (e.getMessage() != null) { - shell.error = e.getMessage(); - } else { - shell.error = "RootAccess denied?."; - } - } - - } - - /* - * setOom for shell processes (sh and su if root shell) and discard outputs - * Negative values make the process LESS likely to be killed in an OOM situation - * Positive values make the process MORE likely to be killed in an OOM situation - */ - private void setShellOom() { - try { - Class processClass = shell.proc.getClass(); - Field field; - try { - field = processClass.getDeclaredField("pid"); - } catch (NoSuchFieldException e) { - field = processClass.getDeclaredField("id"); - } - field.setAccessible(true); - int pid = (Integer) field.get(shell.proc); - shell.outputStream.write("(echo -17 > /proc/" + pid + "/oom_adj) &> /dev/null\n"); - shell.outputStream.write("(echo -17 > /proc/$$/oom_adj) &> /dev/null\n"); - shell.outputStream.flush(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } -} diff --git a/app/src/main/java/com/stericson/RootTools/Constants.java b/app/src/main/java/com/stericson/RootTools/Constants.java deleted file mode 100644 index 985bfba..0000000 --- a/app/src/main/java/com/stericson/RootTools/Constants.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.stericson.RootTools; - -public class Constants -{ - public static final String TAG = "RootTools v5.1"; - public static final int FPS = 1; - public static final int BBA = 3; - public static final int BBV = 4; - public static final int GI = 5; - public static final int GS = 6; - public static final int GSYM = 7; - public static final int GET_MOUNTS = 8; - public static final int GET_SYMLINKS = 9; - -} diff --git a/app/src/main/java/com/stericson/RootTools/RootTools.java b/app/src/main/java/com/stericson/RootTools/RootTools.java deleted file mode 100644 index 4031f68..0000000 --- a/app/src/main/java/com/stericson/RootTools/RootTools.java +++ /dev/null @@ -1,841 +0,0 @@ -/* - * This file is part of the RootTools Project: http://code.google.com/p/RootTools/ - * - * Copyright (c) 2012 Stephen Erickson, Chris Ravenscroft, Dominik Schuermann, Adam Shanks - * - * This code is dual-licensed under the terms of the Apache License Version 2.0 and - * the terms of the General Public License (GPL) Version 2. - * You may use this code according to either of these licenses as is most appropriate - * for your project on a case-by-case basis. - * - * The terms of each license can be found in the root directory of this project's repository as well as at: - * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * http://www.gnu.org/licenses/gpl-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under these Licenses is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See each License for the specific language governing permissions and - * limitations under that License. - */ - -package com.stericson.RootTools; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.util.Log; - -import com.stericson.RootShell.RootShell; -import com.stericson.RootShell.exceptions.RootDeniedException; -import com.stericson.RootShell.execution.Command; -import com.stericson.RootShell.execution.Shell; -import com.stericson.RootTools.containers.Mount; -import com.stericson.RootTools.containers.Permissions; -import com.stericson.RootTools.containers.Symlink; -import com.stericson.RootTools.internal.Remounter; -import com.stericson.RootTools.internal.RootToolsInternalMethods; -import com.stericson.RootTools.internal.Runner; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.TimeoutException; - -public final class RootTools { - - /** - * This class is the gateway to every functionality within the RootTools library.The developer - * should only have access to this class and this class only.This means that this class should - * be the only one to be public.The rest of the classes within this library must not have the - * public modifier. - *

- * All methods and Variables that the developer may need to have access to should be here. - *

- * If a method, or a specific functionality, requires a fair amount of code, or work to be done, - * then that functionality should probably be moved to its own class and the call to it done - * here.For examples of this being done, look at the remount functionality. - */ - - private static RootToolsInternalMethods rim = null; - - public static void setRim(RootToolsInternalMethods rim) { - RootTools.rim = rim; - } - - private static final RootToolsInternalMethods getInternals() { - if (rim == null) { - RootToolsInternalMethods.getInstance(); - return rim; - } else { - return rim; - } - } - - // -------------------- - // # Public Variables # - // -------------------- - - public static boolean debugMode = false; - public static String utilPath; - - /** - * Setting this to false will disable the handler that is used - * by default for the 3 callback methods for Command. - *

- * By disabling this all callbacks will be called from a thread other than - * the main UI thread. - */ - public static boolean handlerEnabled = true; - - - /** - * Setting this will change the default command timeout. - *

- * The default is 20000ms - */ - public static int default_Command_Timeout = 20000; - - - // --------------------------- - // # Public Variable Getters # - // --------------------------- - - // ------------------ - // # Public Methods # - // ------------------ - - /** - * This will check a given binary, determine if it exists and determine that it has either the - * permissions 755, 775, or 777. - * - * @param util Name of the utility to check. - * @return boolean to indicate whether the binary is installed and has appropriate permissions. - */ - public static boolean checkUtil(String util) { - - return getInternals().checkUtil(util); - } - - /** - * This will close all open shells. - * - * @throws IOException - */ - public static void closeAllShells() throws IOException { - RootShell.closeAllShells(); - } - - /** - * This will close the custom shell that you opened. - * - * @throws IOException - */ - public static void closeCustomShell() throws IOException { - RootShell.closeCustomShell(); - } - - /** - * This will close either the root shell or the standard shell depending on what you specify. - * - * @param root a boolean to specify whether to close the root shell or the standard shell. - * @throws IOException - */ - public static void closeShell(boolean root) throws IOException { - RootShell.closeShell(root); - } - - /** - * Copys a file to a destination. Because cp is not available on all android devices, we have a - * fallback on the cat command - * - * @param source example: /data/data/org.adaway/files/hosts - * @param destination example: /system/etc/hosts - * @param remountAsRw remounts the destination as read/write before writing to it - * @param preserveFileAttributes tries to copy file attributes from source to destination, if only cat is available - * only permissions are preserved - * @return true if it was successfully copied - */ - public static boolean copyFile(String source, String destination, boolean remountAsRw, - boolean preserveFileAttributes) { - return getInternals().copyFile(source, destination, remountAsRw, preserveFileAttributes); - } - - /** - * Deletes a file or directory - * - * @param target example: /data/data/org.adaway/files/hosts - * @param remountAsRw remounts the destination as read/write before writing to it - * @return true if it was successfully deleted - */ - public static boolean deleteFileOrDirectory(String target, boolean remountAsRw) { - return getInternals().deleteFileOrDirectory(target, remountAsRw); - } - - /** - * Use this to check whether or not a file exists on the filesystem. - * - * @param file String that represent the file, including the full path to the - * file and its name. - * @return a boolean that will indicate whether or not the file exists. - */ - public static boolean exists(final String file) { - return exists(file, false); - } - - /** - * Use this to check whether or not a file OR directory exists on the filesystem. - * - * @param file String that represent the file OR the directory, including the full path to the - * file and its name. - * @param isDir boolean that represent whether or not we are looking for a directory - * @return a boolean that will indicate whether or not the file exists. - */ - public static boolean exists(final String file, boolean isDir) { - return RootShell.exists(file, isDir); - } - - /** - * This will try and fix a given binary. (This is for Busybox applets or Toolbox applets) By - * "fix", I mean it will try and symlink the binary from either toolbox or Busybox and fix the - * permissions if the permissions are not correct. - * - * @param util Name of the utility to fix. - * @param utilPath path to the toolbox that provides ln, rm, and chmod. This can be a blank string, a - * path to a binary that will provide these, or you can use - * RootTools.getWorkingToolbox() - */ - public static void fixUtil(String util, String utilPath) { - getInternals().fixUtil(util, utilPath); - } - - /** - * This will check an array of binaries, determine if they exist and determine that it has - * either the permissions 755, 775, or 777. If an applet is not setup correctly it will try and - * fix it. (This is for Busybox applets or Toolbox applets) - * - * @param utils Name of the utility to check. - * @return boolean to indicate whether the operation completed. Note that this is not indicative - * of whether the problem was fixed, just that the method did not encounter any - * exceptions. - * @throws Exception if the operation cannot be completed. - */ - public static boolean fixUtils(String[] utils) throws Exception { - return getInternals().fixUtils(utils); - } - - /** - * @param binaryName String that represent the binary to find. - * @param singlePath boolean that represents whether to return a single path or multiple. - * - * @return List containing the paths the binary was found at. - */ - public static List findBinary(String binaryName, boolean singlePath) { - return RootShell.findBinary(binaryName, singlePath); - } - - /** - * @param path String that represents the path to the Busybox binary you want to retrieve the version of. - * @return BusyBox version is found, "" if not found. - */ - public static String getBusyBoxVersion(String path) { - return getInternals().getBusyBoxVersion(path); - } - - /** - * @return BusyBox version is found, "" if not found. - */ - public static String getBusyBoxVersion() { - return RootTools.getBusyBoxVersion(""); - } - - /** - * This will return an List of Strings. Each string represents an applet available from BusyBox. - *

- * - * @return null If we cannot return the list of applets. - */ - public static List getBusyBoxApplets() throws Exception { - return RootTools.getBusyBoxApplets(""); - } - - /** - * This will return an List of Strings. Each string represents an applet available from BusyBox. - *

- * - * @param path Path to the busybox binary that you want the list of applets from. - * @return null If we cannot return the list of applets. - */ - public static List getBusyBoxApplets(String path) throws Exception { - return getInternals().getBusyBoxApplets(path); - } - - /** - * This will open or return, if one is already open, a custom shell, you are responsible for managing the shell, reading the output - * and for closing the shell when you are done using it. - * - * @param shellPath a String to Indicate the path to the shell that you want to open. - * @param timeout an int to Indicate the length of time before giving up on opening a shell. - * @throws TimeoutException - * @throws com.stericson.RootShell.exceptions.RootDeniedException - * @throws IOException - */ - public static Shell getCustomShell(String shellPath, int timeout) throws IOException, TimeoutException, RootDeniedException { - return RootShell.getCustomShell(shellPath, timeout); - } - - /** - * This will open or return, if one is already open, a custom shell, you are responsible for managing the shell, reading the output - * and for closing the shell when you are done using it. - * - * @param shellPath a String to Indicate the path to the shell that you want to open. - * @throws TimeoutException - * @throws com.stericson.RootShell.exceptions.RootDeniedException - * @throws IOException - */ - public static Shell getCustomShell(String shellPath) throws IOException, TimeoutException, RootDeniedException { - return RootTools.getCustomShell(shellPath, 10000); - } - - /** - * @param file String that represent the file, including the full path to the file and its name. - * @return An instance of the class permissions from which you can get the permissions of the - * file or if the file could not be found or permissions couldn't be determined then - * permissions will be null. - */ - public static Permissions getFilePermissionsSymlinks(String file) { - return getInternals().getFilePermissionsSymlinks(file); - } - - /** - * This method will return the inode number of a file. This method is dependent on having a version of - * ls that supports the -i parameter. - * - * @param file path to the file that you wish to return the inode number - * @return String The inode number for this file or "" if the inode number could not be found. - */ - public static String getInode(String file) { - return getInternals().getInode(file); - } - - /** - * This will return an ArrayList of the class Mount. The class mount contains the following - * property's: device mountPoint type flags - *

- * These will provide you with any information you need to work with the mount points. - * - * @return ArrayList an ArrayList of the class Mount. - * @throws Exception if we cannot return the mount points. - */ - public static ArrayList getMounts() throws Exception { - return getInternals().getMounts(); - } - - /** - * This will tell you how the specified mount is mounted. rw, ro, etc... - *

- * - * @param path The mount you want to check - * @return String What the mount is mounted as. - * @throws Exception if we cannot determine how the mount is mounted. - */ - public static String getMountedAs(String path) throws Exception { - return getInternals().getMountedAs(path); - } - - /** - * This will return the environment variable PATH - * - * @return List A List of Strings representing the environment variable $PATH - */ - public static List getPath() { - return Arrays.asList(System.getenv("PATH").split(":")); - } - - /** - * This will open or return, if one is already open, a shell, you are responsible for managing the shell, reading the output - * and for closing the shell when you are done using it. - * - * @param root a boolean to Indicate whether or not you want to open a root shell or a standard shell - * @param timeout an int to Indicate the length of time to wait before giving up on opening a shell. - * @param shellContext the context to execute the shell with - * @param retry a int to indicate how many times the ROOT shell should try to open with root priviliges... - * @throws TimeoutException - * @throws com.stericson.RootShell.exceptions.RootDeniedException - * @throws IOException - */ - public static Shell getShell(boolean root, int timeout, Shell.ShellContext shellContext, int retry) throws IOException, TimeoutException, RootDeniedException { - return RootShell.getShell(root, timeout, shellContext, retry); - } - - /** - * This will open or return, if one is already open, a shell, you are responsible for managing the shell, reading the output - * and for closing the shell when you are done using it. - * - * @param root a boolean to Indicate whether or not you want to open a root shell or a standard shell - * @param timeout an int to Indicate the length of time to wait before giving up on opening a shell. - * @param shellContext the context to execute the shell with - * @throws TimeoutException - * @throws com.stericson.RootShell.exceptions.RootDeniedException - * @throws IOException - */ - public static Shell getShell(boolean root, int timeout, Shell.ShellContext shellContext) throws IOException, TimeoutException, RootDeniedException { - return getShell(root, timeout, shellContext, 3); - } - - /** - * This will open or return, if one is already open, a shell, you are responsible for managing the shell, reading the output - * and for closing the shell when you are done using it. - * - * @param root a boolean to Indicate whether or not you want to open a root shell or a standard shell - * @param shellContext the context to execute the shell with - * @throws TimeoutException - * @throws com.stericson.RootShell.exceptions.RootDeniedException - * @throws IOException - */ - public static Shell getShell(boolean root, Shell.ShellContext shellContext) throws IOException, TimeoutException, RootDeniedException { - return getShell(root, 0, shellContext, 3); - } - - /** - * This will open or return, if one is already open, a shell, you are responsible for managing the shell, reading the output - * and for closing the shell when you are done using it. - * - * @param root a boolean to Indicate whether or not you want to open a root shell or a standard shell - * @param timeout an int to Indicate the length of time to wait before giving up on opening a shell. - * @throws TimeoutException - * @throws com.stericson.RootShell.exceptions.RootDeniedException - * @throws IOException - */ - public static Shell getShell(boolean root, int timeout) throws IOException, TimeoutException, RootDeniedException { - return getShell(root, timeout, Shell.defaultContext, 3); - } - - /** - * This will open or return, if one is already open, a shell, you are responsible for managing the shell, reading the output - * and for closing the shell when you are done using it. - * - * @param root a boolean to Indicate whether or not you want to open a root shell or a standard shell - * @throws TimeoutException - * @throws com.stericson.RootShell.exceptions.RootDeniedException - * @throws IOException - */ - public static Shell getShell(boolean root) throws IOException, TimeoutException, RootDeniedException { - return RootTools.getShell(root, 0); - } - - /** - * Get the space for a desired partition. - * - * @param path The partition to find the space for. - * @return the amount if space found within the desired partition. If the space was not found - * then the value is -1 - * @throws TimeoutException - */ - public static long getSpace(String path) { - return getInternals().getSpace(path); - } - - /** - * This will return a String that represent the symlink for a specified file. - *

- * - * @param file path to the file to get the Symlink for. (must have absolute path) - * @return String a String that represent the symlink for a specified file or an - * empty string if no symlink exists. - */ - public static String getSymlink(String file) { - return getInternals().getSymlink(file); - } - - /** - * This will return an ArrayList of the class Symlink. The class Symlink contains the following - * property's: path SymplinkPath - *

- * These will provide you with any Symlinks in the given path. - * - * @param path path to search for Symlinks. - * @return ArrayList an ArrayList of the class Symlink. - * @throws Exception if we cannot return the Symlinks. - */ - public static ArrayList getSymlinks(String path) throws Exception { - return getInternals().getSymlinks(path); - } - - /** - * This will return to you a string to be used in your shell commands which will represent the - * valid working toolbox with correct permissions. For instance, if Busybox is available it will - * return "busybox", if busybox is not available but toolbox is then it will return "toolbox" - * - * @return String that indicates the available toolbox to use for accessing applets. - */ - public static String getWorkingToolbox() { - return getInternals().getWorkingToolbox(); - } - - /** - * Checks if there is enough Space on SDCard - * - * @param updateSize size to Check (long) - * @return true if the Update will fit on SDCard, false if not enough - * space on SDCard. Will also return false, if the SDCard is not mounted as - * read/write - */ - public static boolean hasEnoughSpaceOnSdCard(long updateSize) { - return getInternals().hasEnoughSpaceOnSdCard(updateSize); - } - - /** - * Checks whether the toolbox or busybox binary contains a specific util - * - * @param util - * @param box Should contain "toolbox" or "busybox" - * @return true if it contains this util - */ - public static boolean hasUtil(final String util, final String box) { - //TODO Convert this to use the new shell. - return getInternals().hasUtil(util, box); - } - - /** - * This method can be used to unpack a binary from the raw resources folder and store it in - * /data/data/app.package/files/ This is typically useful if you provide your own C- or - * C++-based binary. This binary can then be executed using sendShell() and its full path. - * - * @param context the current activity's Context - * @param sourceId resource id; typically R.raw.id - * @param destName destination file name; appended to /data/data/app.package/files/ - * @param mode chmod value for this file - * @return a boolean which indicates whether or not we were able to create the new - * file. - */ - public static boolean installBinary(Context context, int sourceId, String destName, String mode) { - return getInternals().installBinary(context, sourceId, destName, mode); - } - - /** - * This method can be used to unpack a binary from the raw resources folder and store it in - * /data/data/app.package/files/ This is typically useful if you provide your own C- or - * C++-based binary. This binary can then be executed using sendShell() and its full path. - * - * @param context the current activity's Context - * @param sourceId resource id; typically R.raw.id - * @param binaryName destination file name; appended to /data/data/app.package/files/ - * @return a boolean which indicates whether or not we were able to create the new - * file. - */ - public static boolean installBinary(Context context, int sourceId, String binaryName) { - return installBinary(context, sourceId, binaryName, "700"); - } - - /** - * This method checks whether a binary is installed. - * - * @param context the current activity's Context - * @param binaryName binary file name; appended to /data/data/app.package/files/ - * @return a boolean which indicates whether or not - * the binary already exists. - */ - public static boolean hasBinary(Context context, String binaryName) { - return getInternals().isBinaryAvailable(context, binaryName); - } - - /** - * This will let you know if an applet is available from BusyBox - *

- * - * @param applet The applet to check for. - * @param path Path to the busybox binary that you want to check. (do not include binary name) - * @return true if applet is available, false otherwise. - */ - public static boolean isAppletAvailable(String applet, String path) { - return getInternals().isAppletAvailable(applet, path); - } - - /** - * This will let you know if an applet is available from BusyBox - *

- * - * @param applet The applet to check for. - * @return true if applet is available, false otherwise. - */ - public static boolean isAppletAvailable(String applet) { - return RootTools.isAppletAvailable(applet, ""); - } - /** - * @return true if your app has been given root access. - * @throws TimeoutException if this operation times out. (cannot determine if access is given) - */ - public static boolean isAccessGiven() { - return RootShell.isAccessGiven(0, 3); - } - - /** - * Control how many time of retries should request - * - * @param timeout The timeout - * @param retries The number of retries - * - * @return true if your app has been given root access. - * @throws TimeoutException if this operation times out. (cannot determine if access is given) - */ - public static boolean isAccessGiven(int timeout, int retries) { - return RootShell.isAccessGiven(timeout, retries); - } - - /** - * @return true if BusyBox was found. - */ - public static boolean isBusyboxAvailable() { - return RootShell.isBusyboxAvailable(); - } - - public static boolean isNativeToolsReady(int nativeToolsId, Context context) { - return getInternals().isNativeToolsReady(nativeToolsId, context); - } - - /** - * This method can be used to to check if a process is running - * - * @param processName name of process to check - * @return true if process was found - * @throws TimeoutException (Could not determine if the process is running) - */ - public static boolean isProcessRunning(final String processName) { - //TODO convert to new shell - return getInternals().isProcessRunning(processName); - } - - /** - * @return true if su was found. - */ - public static boolean isRootAvailable() { - return RootShell.isRootAvailable(); - } - - /** - * This method can be used to kill a running process - * - * @param processName name of process to kill - * @return true if process was found and killed successfully - */ - public static boolean killProcess(final String processName) { - //TODO convert to new shell - return getInternals().killProcess(processName); - } - - /** - * This will launch the Android market looking for BusyBox - * - * @param activity pass in your Activity - */ - public static void offerBusyBox(Activity activity) { - getInternals().offerBusyBox(activity); - } - - /** - * This will launch the Android market looking for BusyBox, but will return the intent fired and - * starts the activity with startActivityForResult - * - * @param activity pass in your Activity - * @param requestCode pass in the request code - * @return intent fired - */ - public static Intent offerBusyBox(Activity activity, int requestCode) { - return getInternals().offerBusyBox(activity, requestCode); - } - - /** - * This will launch the Android market looking for SuperUser - * - * @param activity pass in your Activity - */ - public static void offerSuperUser(Activity activity) { - getInternals().offerSuperUser(activity); - } - - /** - * This will launch the Android market looking for SuperUser, but will return the intent fired - * and starts the activity with startActivityForResult - * - * @param activity pass in your Activity - * @param requestCode pass in the request code - * @return intent fired - */ - public static Intent offerSuperUser(Activity activity, int requestCode) { - return getInternals().offerSuperUser(activity, requestCode); - } - - /** - * This will take a path, which can contain the file name as well, and attempt to remount the - * underlying partition. - *

- * For example, passing in the following string: - * "/system/bin/some/directory/that/really/would/never/exist" will result in /system ultimately - * being remounted. However, keep in mind that the longer the path you supply, the more work - * this has to do, and the slower it will run. - * - * @param file file path - * @param mountType mount type: pass in RO (Read only) or RW (Read Write) - * @return a boolean which indicates whether or not the partition has been - * remounted as specified. - */ - public static boolean remount(String file, String mountType) { - // Recieved a request, get an instance of Remounter - Remounter remounter = new Remounter(); - // send the request. - return (remounter.remount(file, mountType)); - } - - /** - * This restarts only Android OS without rebooting the whole device. This does NOT work on all - * devices. This is done by killing the main init process named zygote. Zygote is restarted - * automatically by Android after killing it. - * - * @throws TimeoutException - */ - public static void restartAndroid() { - RootTools.log("Restart Android"); - killProcess("zygote"); - } - - /** - * Executes binary in a separated process. Before using this method, the binary has to be - * installed in /data/data/app.package/files/ using the installBinary method. - * - * @param context the current activity's Context - * @param binaryName name of installed binary - * @param parameter parameter to append to binary like "-vxf" - */ - public static void runBinary(Context context, String binaryName, String parameter) { - Runner runner = new Runner(context, binaryName, parameter); - runner.start(); - } - - /** - * Executes a given command with root access or without depending on the value of the boolean passed. - * This will also start a root shell or a standard shell without you having to open it specifically. - *

- * You will still need to close the shell after you are done using the shell. - * - * @param shell The shell to execute the command on, this can be a root shell or a standard shell. - * @param command The command to execute in the shell - * - * @throws IOException - */ - public static void runShellCommand(Shell shell, Command command) throws IOException { - shell.add(command); - } - - /** - * This method allows you to output debug messages only when debugging is on. This will allow - * you to add a debug option to your app, which by default can be left off for performance. - * However, when you need debugging information, a simple switch can enable it and provide you - * with detailed logging. - *

- * This method handles whether or not to log the information you pass it depending whether or - * not RootTools.debugMode is on. So you can use this and not have to worry about handling it - * yourself. - * - * @param msg The message to output. - */ - public static void log(String msg) { - log(null, msg, 3, null); - } - - /** - * This method allows you to output debug messages only when debugging is on. This will allow - * you to add a debug option to your app, which by default can be left off for performance. - * However, when you need debugging information, a simple switch can enable it and provide you - * with detailed logging. - *

- * This method handles whether or not to log the information you pass it depending whether or - * not RootTools.debugMode is on. So you can use this and not have to worry about handling it - * yourself. - * - * @param TAG Optional parameter to define the tag that the Log will use. - * @param msg The message to output. - */ - public static void log(String TAG, String msg) { - log(TAG, msg, 3, null); - } - - /** - * This method allows you to output debug messages only when debugging is on. This will allow - * you to add a debug option to your app, which by default can be left off for performance. - * However, when you need debugging information, a simple switch can enable it and provide you - * with detailed logging. - *

- * This method handles whether or not to log the information you pass it depending whether or - * not RootTools.debugMode is on. So you can use this and not have to worry about handling it - * yourself. - * - * @param msg The message to output. - * @param type The type of log, 1 for verbose, 2 for error, 3 for debug - * @param e The exception that was thrown (Needed for errors) - */ - public static void log(String msg, int type, Exception e) { - log(null, msg, type, e); - } - - /** - * This method allows you to check whether logging is enabled. - * Yes, it has a goofy name, but that's to keep it as short as possible. - * After all writing logging calls should be painless. - * This method exists to save Android going through the various Java layers - * that are traversed any time a string is created (i.e. what you are logging) - *

- * Example usage: - * if(islog) { - * StrinbBuilder sb = new StringBuilder(); - * // ... - * // build string - * // ... - * log(sb.toString()); - * } - * - * @return true if logging is enabled - */ - public static boolean islog() { - return debugMode; - } - - /** - * This method allows you to output debug messages only when debugging is on. This will allow - * you to add a debug option to your app, which by default can be left off for performance. - * However, when you need debugging information, a simple switch can enable it and provide you - * with detailed logging. - *

- * This method handles whether or not to log the information you pass it depending whether or - * not RootTools.debugMode is on. So you can use this and not have to worry about handling it - * yourself. - * - * @param TAG Optional parameter to define the tag that the Log will use. - * @param msg The message to output. - * @param type The type of log, 1 for verbose, 2 for error, 3 for debug - * @param e The exception that was thrown (Needed for errors) - */ - public static void log(String TAG, String msg, int type, Exception e) { - if (msg != null && !msg.equals("")) { - if (debugMode) { - if (TAG == null) { - TAG = Constants.TAG; - } - - switch (type) { - case 1: - Log.v(TAG, msg); - break; - case 2: - Log.e(TAG, msg, e); - break; - case 3: - Log.d(TAG, msg); - break; - } - } - } - } -} diff --git a/app/src/main/java/com/stericson/RootTools/SanityCheckRootTools.java b/app/src/main/java/com/stericson/RootTools/SanityCheckRootTools.java deleted file mode 100644 index 32a1e21..0000000 --- a/app/src/main/java/com/stericson/RootTools/SanityCheckRootTools.java +++ /dev/null @@ -1,459 +0,0 @@ -/* - * This file is part of the RootTools Project: http://code.google.com/p/RootTools/ - * - * Copyright (c) 2012 Stephen Erickson, Chris Ravenscroft, Dominik Schuermann, Adam Shanks - * - * This code is dual-licensed under the terms of the Apache License Version 2.0 and - * the terms of the General Public License (GPL) Version 2. - * You may use this code according to either of these licenses as is most appropriate - * for your project on a case-by-case basis. - * - * The terms of each license can be found in the root directory of this project's repository as well as at: - * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * http://www.gnu.org/licenses/gpl-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under these Licenses is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See each License for the specific language governing permissions and - * limitations under that License. - */ - -package com.stericson.RootTools; - -import android.app.Activity; -import android.app.ProgressDialog; -import android.content.Context; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.os.StrictMode; -import android.widget.ScrollView; -import android.widget.TextView; - -import com.stericson.RootShell.exceptions.RootDeniedException; -import com.stericson.RootShell.execution.Command; -import com.stericson.RootShell.execution.Shell; -import com.stericson.RootTools.containers.Permissions; - -import java.io.IOException; -import java.util.List; -import java.util.concurrent.TimeoutException; - -public class SanityCheckRootTools extends Activity { - private ScrollView mScrollView; - private TextView mTextView; - private ProgressDialog mPDialog; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() - .detectDiskReads() - .detectDiskWrites() - .detectNetwork() // or .detectAll() for all detectable problems - .penaltyLog() - .build()); - StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() - .detectLeakedSqlLiteObjects() - .detectLeakedClosableObjects() - .penaltyLog() - .penaltyDeath() - .build()); - - RootTools.debugMode = true; - - mTextView = new TextView(this); - mTextView.setText(""); - mScrollView = new ScrollView(this); - mScrollView.addView(mTextView); - setContentView(mScrollView); - - print("SanityCheckRootTools \n\n"); - - if (RootTools.isRootAvailable()) { - print("Root found.\n"); - } else { - print("Root not found"); - } - - try { - Shell.startRootShell(); - } catch (IOException e2) { - // TODO Auto-generated catch block - e2.printStackTrace(); - } catch (TimeoutException e) { - print("[ TIMEOUT EXCEPTION! ]\n"); - e.printStackTrace(); - } catch (RootDeniedException e) { - print("[ ROOT DENIED EXCEPTION! ]\n"); - e.printStackTrace(); - } - - try { - if (!RootTools.isAccessGiven()) { - print("ERROR: No root access to this device.\n"); - return; - } - } catch (Exception e) { - print("ERROR: could not determine root access to this device.\n"); - return; - } - - // Display infinite progress bar - mPDialog = new ProgressDialog(this); - mPDialog.setCancelable(false); - mPDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); - - new SanityCheckThread(this, new TestHandler()).start(); - } - - protected void print(CharSequence text) { - mTextView.append(text); - mScrollView.post(new Runnable() { - public void run() { - mScrollView.fullScroll(ScrollView.FOCUS_DOWN); - } - }); - } - - // Run our long-running tests in their separate thread so as to - // not interfere with proper rendering. - private class SanityCheckThread extends Thread { - private Handler mHandler; - - public SanityCheckThread(Context context, Handler handler) { - mHandler = handler; - } - - public void run() { - visualUpdate(TestHandler.ACTION_SHOW, null); - - // First test: Install a binary file for future use - // if it wasn't already installed. - /* - visualUpdate(TestHandler.ACTION_PDISPLAY, "Installing binary if needed"); - if(false == RootTools.installBinary(mContext, R.raw.nes, "nes_binary")) { - visualUpdate(TestHandler.ACTION_HIDE, "ERROR: Failed to install binary. Please see log file."); - return; - } - */ - - boolean result; - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing getPath"); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ getPath ]\n"); - - try { - List paths = RootTools.getPath(); - - for (String path : paths) { - visualUpdate(TestHandler.ACTION_DISPLAY, path + " k\n\n"); - } - - } catch (Exception e) { - e.printStackTrace(); - } - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing A ton of commands"); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Ton of Commands ]\n"); - - for (int i = 0; i < 100; i++) { - RootTools.exists("/system/xbin/busybox"); - } - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing Find Binary"); - result = RootTools.isRootAvailable(); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Checking Root ]\n"); - visualUpdate(TestHandler.ACTION_DISPLAY, result + " k\n\n"); - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing file exists"); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Checking Exists() ]\n"); - visualUpdate(TestHandler.ACTION_DISPLAY, RootTools.exists("/system/sbin/[") + " k\n\n"); - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing Is Access Given"); - result = RootTools.isAccessGiven(); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Checking for Access to Root ]\n"); - visualUpdate(TestHandler.ACTION_DISPLAY, result + " k\n\n"); - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing Remount"); - result = RootTools.remount("/system", "rw"); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Remounting System as RW ]\n"); - visualUpdate(TestHandler.ACTION_DISPLAY, result + " k\n\n"); - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing CheckUtil"); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Checking busybox is setup ]\n"); - visualUpdate(TestHandler.ACTION_DISPLAY, RootTools.checkUtil("busybox") + " k\n\n"); - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing getBusyBoxVersion"); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Checking busybox version ]\n"); - visualUpdate(TestHandler.ACTION_DISPLAY, RootTools.getBusyBoxVersion("/system/xbin/") + " k\n\n"); - - try { - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing fixUtils"); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Checking Utils ]\n"); - visualUpdate(TestHandler.ACTION_DISPLAY, RootTools.fixUtils(new String[]{"ls", "rm", "ln", "dd", "chmod", "mount"}) + " k\n\n"); - } catch (Exception e2) { - // TODO Auto-generated catch block - e2.printStackTrace(); - } - - try { - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing getSymlink"); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Checking [[ for symlink ]\n"); - visualUpdate(TestHandler.ACTION_DISPLAY, RootTools.getSymlink("/system/bin/[[") + " k\n\n"); - } catch (Exception e2) { - // TODO Auto-generated catch block - e2.printStackTrace(); - } - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing getInode"); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Checking Inodes ]\n"); - visualUpdate(TestHandler.ACTION_DISPLAY, RootTools.getInode("/system/bin/busybox") + " k\n\n"); - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing GetBusyBoxapplets"); - try { - - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Getting all available Busybox applets ]\n"); - for (String applet : RootTools.getBusyBoxApplets("/data/data/stericson.busybox/files/bb/busybox")) { - visualUpdate(TestHandler.ACTION_DISPLAY, applet + " k\n\n"); - } - - } catch (Exception e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing GetBusyBox version in a special directory!"); - try { - - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Testing GetBusyBox version in a special directory! ]\n"); - String v = RootTools.getBusyBoxVersion("/data/data/stericson.busybox/files/bb/"); - - visualUpdate(TestHandler.ACTION_DISPLAY, v + " k\n\n"); - - } catch (Exception e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing getFilePermissionsSymlinks"); - Permissions permissions = RootTools.getFilePermissionsSymlinks("/system/xbin/busybox"); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Checking busybox permissions and symlink ]\n"); - - if (permissions != null) { - visualUpdate(TestHandler.ACTION_DISPLAY, "Symlink: " + permissions.getSymlink() + " k\n\n"); - visualUpdate(TestHandler.ACTION_DISPLAY, "Group Permissions: " + permissions.getGroupPermissions() + " k\n\n"); - visualUpdate(TestHandler.ACTION_DISPLAY, "Owner Permissions: " + permissions.getOtherPermissions() + " k\n\n"); - visualUpdate(TestHandler.ACTION_DISPLAY, "Permissions: " + permissions.getPermissions() + " k\n\n"); - visualUpdate(TestHandler.ACTION_DISPLAY, "Type: " + permissions.getType() + " k\n\n"); - visualUpdate(TestHandler.ACTION_DISPLAY, "User Permissions: " + permissions.getUserPermissions() + " k\n\n"); - } else { - visualUpdate(TestHandler.ACTION_DISPLAY, "Permissions == null k\n\n"); - } - - Shell shell; - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing output capture"); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ busybox ash --help ]\n"); - - try { - shell = RootTools.getShell(true); - Command cmd = new Command( - 0, - "busybox ash --help") { - - @Override - public void commandOutput(int id, String line) { - visualUpdate(TestHandler.ACTION_DISPLAY, line + "\n"); - super.commandOutput(id, line); - } - }; - shell.add(cmd); - - visualUpdate(TestHandler.ACTION_PDISPLAY, "getevent - /dev/input/event0"); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ getevent - /dev/input/event0 ]\n"); - - cmd = new Command(0, 0, "getevent /dev/input/event0") { - @Override - public void commandOutput(int id, String line) { - visualUpdate(TestHandler.ACTION_DISPLAY, line + "\n"); - super.commandOutput(id, line); - } - - }; - shell.add(cmd); - - } catch (Exception e) { - e.printStackTrace(); - } - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Switching RootContext - SYSTEM_APP"); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Switching Root Context - SYSTEM_APP ]\n"); - - try { - shell = RootTools.getShell(true, Shell.ShellContext.SYSTEM_APP); - Command cmd = new Command( - 0, - "id") { - - @Override - public void commandOutput(int id, String line) { - visualUpdate(TestHandler.ACTION_DISPLAY, line + "\n"); - super.commandOutput(id, line); - } - }; - shell.add(cmd); - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing PM"); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Testing pm list packages -d ]\n"); - - cmd = new Command( - 0, - "sh /system/bin/pm list packages -d") { - - @Override - public void commandOutput(int id, String line) { - visualUpdate(TestHandler.ACTION_DISPLAY, line + "\n"); - super.commandOutput(id, line); - } - }; - shell.add(cmd); - - } catch (Exception e) { - e.printStackTrace(); - } - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Switching RootContext - UNTRUSTED"); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Switching Root Context - UNTRUSTED ]\n"); - - try { - shell = RootTools.getShell(true, Shell.ShellContext.UNTRUSTED_APP); - Command cmd = new Command( - 0, - "id") { - - @Override - public void commandOutput(int id, String line) { - visualUpdate(TestHandler.ACTION_DISPLAY, line + "\n"); - super.commandOutput(id, line); - } - }; - shell.add(cmd); - - } catch (Exception e) { - e.printStackTrace(); - } - - visualUpdate(TestHandler.ACTION_PDISPLAY, "Testing df"); - long spaceValue = RootTools.getSpace("/data"); - visualUpdate(TestHandler.ACTION_DISPLAY, "[ Checking /data partition size]\n"); - visualUpdate(TestHandler.ACTION_DISPLAY, spaceValue + "k\n\n"); - - try { - shell = RootTools.getShell(true); - - Command cmd = new Command(42, false, "echo done") { - - boolean _catch = false; - - @Override - public void commandOutput(int id, String line) { - if (_catch) { - RootTools.log("CAUGHT!!!"); - } - - super.commandOutput(id, line); - - } - - @Override - public void commandTerminated(int id, String reason) { - synchronized (SanityCheckRootTools.this) { - - _catch = true; - visualUpdate(TestHandler.ACTION_PDISPLAY, "All tests complete."); - visualUpdate(TestHandler.ACTION_HIDE, null); - - try { - RootTools.closeAllShells(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - } - } - - @Override - public void commandCompleted(int id, int exitCode) { - synchronized (SanityCheckRootTools.this) { - _catch = true; - - visualUpdate(TestHandler.ACTION_PDISPLAY, "All tests complete."); - visualUpdate(TestHandler.ACTION_HIDE, null); - - try { - RootTools.closeAllShells(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - } - } - }; - - shell.add(cmd); - - } catch (Exception e) { - e.printStackTrace(); - } - - } - - private void visualUpdate(int action, String text) { - Message msg = mHandler.obtainMessage(); - Bundle bundle = new Bundle(); - bundle.putInt(TestHandler.ACTION, action); - bundle.putString(TestHandler.TEXT, text); - msg.setData(bundle); - mHandler.sendMessage(msg); - } - } - - private class TestHandler extends Handler { - static final public String ACTION = "action"; - static final public int ACTION_SHOW = 0x01; - static final public int ACTION_HIDE = 0x02; - static final public int ACTION_DISPLAY = 0x03; - static final public int ACTION_PDISPLAY = 0x04; - static final public String TEXT = "text"; - - public void handleMessage(Message msg) { - int action = msg.getData().getInt(ACTION); - String text = msg.getData().getString(TEXT); - - switch (action) { - case ACTION_SHOW: - mPDialog.show(); - mPDialog.setMessage("Running Root Library Tests..."); - break; - case ACTION_HIDE: - if (null != text) { - print(text); - } - mPDialog.hide(); - break; - case ACTION_DISPLAY: - print(text); - break; - case ACTION_PDISPLAY: - mPDialog.setMessage(text); - break; - } - } - } -} diff --git a/app/src/main/java/com/stericson/RootTools/containers/Mount.java b/app/src/main/java/com/stericson/RootTools/containers/Mount.java deleted file mode 100644 index 1d57d7a..0000000 --- a/app/src/main/java/com/stericson/RootTools/containers/Mount.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of the RootTools Project: http://code.google.com/p/RootTools/ - * - * Copyright (c) 2012 Stephen Erickson, Chris Ravenscroft, Dominik Schuermann, Adam Shanks - * - * This code is dual-licensed under the terms of the Apache License Version 2.0 and - * the terms of the General Public License (GPL) Version 2. - * You may use this code according to either of these licenses as is most appropriate - * for your project on a case-by-case basis. - * - * The terms of each license can be found in the root directory of this project's repository as well as at: - * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * http://www.gnu.org/licenses/gpl-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under these Licenses is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See each License for the specific language governing permissions and - * limitations under that License. - */ - -package com.stericson.RootTools.containers; - -import java.io.File; -import java.util.Arrays; -import java.util.LinkedHashSet; -import java.util.Set; - -public class Mount -{ - final File mDevice; - final File mMountPoint; - final String mType; - final Set mFlags; - - public Mount(File device, File path, String type, String flagsStr) - { - mDevice = device; - mMountPoint = path; - mType = type; - mFlags = new LinkedHashSet(Arrays.asList(flagsStr.split(","))); - } - - public File getDevice() - { - return mDevice; - } - - public File getMountPoint() - { - return mMountPoint; - } - - public String getType() - { - return mType; - } - - public Set getFlags() - { - return mFlags; - } - - @Override - public String toString() - { - return String.format("%s on %s type %s %s", mDevice, mMountPoint, mType, mFlags); - } -} diff --git a/app/src/main/java/com/stericson/RootTools/containers/Permissions.java b/app/src/main/java/com/stericson/RootTools/containers/Permissions.java deleted file mode 100644 index b9176e9..0000000 --- a/app/src/main/java/com/stericson/RootTools/containers/Permissions.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file is part of the RootTools Project: http://code.google.com/p/RootTools/ - * - * Copyright (c) 2012 Stephen Erickson, Chris Ravenscroft, Dominik Schuermann, Adam Shanks - * - * This code is dual-licensed under the terms of the Apache License Version 2.0 and - * the terms of the General Public License (GPL) Version 2. - * You may use this code according to either of these licenses as is most appropriate - * for your project on a case-by-case basis. - * - * The terms of each license can be found in the root directory of this project's repository as well as at: - * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * http://www.gnu.org/licenses/gpl-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under these Licenses is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See each License for the specific language governing permissions and - * limitations under that License. - */ - -package com.stericson.RootTools.containers; - -public class Permissions -{ - String type; - String user; - String group; - String other; - String symlink; - int permissions; - - public String getSymlink() - { - return this.symlink; - } - - public String getType() - { - return type; - } - - public int getPermissions() - { - return this.permissions; - } - - public String getUserPermissions() - { - return this.user; - } - - public String getGroupPermissions() - { - return this.group; - } - - public String getOtherPermissions() - { - return this.other; - } - - public void setSymlink(String symlink) - { - this.symlink = symlink; - } - - public void setType(String type) - { - this.type = type; - } - - public void setPermissions(int permissions) - { - this.permissions = permissions; - } - - public void setUserPermissions(String user) - { - this.user = user; - } - - public void setGroupPermissions(String group) - { - this.group = group; - } - - public void setOtherPermissions(String other) - { - this.other = other; - } - - public String getUser() - { - return user; - } - - public void setUser(String user) - { - this.user = user; - } - - public String getGroup() - { - return group; - } - - public void setGroup(String group) - { - this.group = group; - } - - public String getOther() - { - return other; - } - - public void setOther(String other) - { - this.other = other; - } - - -} diff --git a/app/src/main/java/com/stericson/RootTools/containers/Symlink.java b/app/src/main/java/com/stericson/RootTools/containers/Symlink.java deleted file mode 100644 index 68ad423..0000000 --- a/app/src/main/java/com/stericson/RootTools/containers/Symlink.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of the RootTools Project: http://code.google.com/p/RootTools/ - * - * Copyright (c) 2012 Stephen Erickson, Chris Ravenscroft, Dominik Schuermann, Adam Shanks - * - * This code is dual-licensed under the terms of the Apache License Version 2.0 and - * the terms of the General Public License (GPL) Version 2. - * You may use this code according to either of these licenses as is most appropriate - * for your project on a case-by-case basis. - * - * The terms of each license can be found in the root directory of this project's repository as well as at: - * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * http://www.gnu.org/licenses/gpl-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under these Licenses is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See each License for the specific language governing permissions and - * limitations under that License. - */ - -package com.stericson.RootTools.containers; - -import java.io.File; - -public class Symlink -{ - protected final File file; - protected final File symlinkPath; - - public Symlink(File file, File path) - { - this.file = file; - symlinkPath = path; - } - - public File getFile() - { - return this.file; - } - - public File getSymlinkPath() - { - return symlinkPath; - } -} diff --git a/app/src/main/java/com/stericson/RootTools/internal/Installer.java b/app/src/main/java/com/stericson/RootTools/internal/Installer.java deleted file mode 100644 index b2591cc..0000000 --- a/app/src/main/java/com/stericson/RootTools/internal/Installer.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * This file is part of the RootTools Project: http://code.google.com/p/RootTools/ - * - * Copyright (c) 2012 Stephen Erickson, Chris Ravenscroft, Dominik Schuermann, Adam Shanks - * - * This code is dual-licensed under the terms of the Apache License Version 2.0 and - * the terms of the General Public License (GPL) Version 2. - * You may use this code according to either of these licenses as is most appropriate - * for your project on a case-by-case basis. - * - * The terms of each license can be found in the root directory of this project's repository as well as at: - * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * http://www.gnu.org/licenses/gpl-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under these Licenses is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See each License for the specific language governing permissions and - * limitations under that License. - */ - -package com.stericson.RootTools.internal; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.channels.Channels; -import java.nio.channels.FileChannel; -import java.nio.channels.ReadableByteChannel; -import java.security.DigestInputStream; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -import android.util.Log; - -import com.stericson.RootShell.execution.Command; -import com.stericson.RootShell.execution.Shell; -import com.stericson.RootTools.RootTools; - -import android.content.Context; - -class Installer -{ - - //------------- - //# Installer # - //------------- - - static final String LOG_TAG = "RootTools::Installer"; - - static final String BOGUS_FILE_NAME = "bogus"; - - Context context; - String filesPath; - - public Installer(Context context) - throws IOException - { - - this.context = context; - this.filesPath = context.getFilesDir().getCanonicalPath(); - } - - /** - * This method can be used to unpack a binary from the raw resources folder and store it in - * /data/data/app.package/files/ - * This is typically useful if you provide your own C- or C++-based binary. - * This binary can then be executed using sendShell() and its full path. - * - * @param sourceId resource id; typically R.raw.id - * @param destName destination file name; appended to /data/data/app.package/files/ - * @param mode chmod value for this file - * @return a boolean which indicates whether or not we were - * able to create the new file. - */ - protected boolean installBinary(int sourceId, String destName, String mode) - { - File mf = new File(filesPath + File.separator + destName); - if (!mf.exists() || - !getFileSignature(mf).equals( - getStreamSignature( - context.getResources().openRawResource(sourceId)) - )) - { - Log.e(LOG_TAG, "Installing a new version of binary: " + destName); - // First, does our files/ directory even exist? - // We cannot wait for android to lazily create it as we will soon - // need it. - try - { - FileInputStream fis = context.openFileInput(BOGUS_FILE_NAME); - fis.close(); - } - catch (FileNotFoundException e) - { - FileOutputStream fos = null; - try - { - fos = context.openFileOutput("bogus", Context.MODE_PRIVATE); - fos.write("justcreatedfilesdirectory".getBytes()); - } - catch (Exception ex) - { - if (RootTools.debugMode) - { - Log.e(LOG_TAG, ex.toString()); - } - return false; - } - finally - { - if (null != fos) - { - try - { - fos.close(); - context.deleteFile(BOGUS_FILE_NAME); - } - catch (IOException e1) - { - } - } - } - } - catch (IOException ex) - { - if (RootTools.debugMode) - { - Log.e(LOG_TAG, ex.toString()); - } - return false; - } - - // Only now can we start creating our actual file - InputStream iss = context.getResources().openRawResource(sourceId); - ReadableByteChannel rfc = Channels.newChannel(iss); - FileOutputStream oss = null; - try - { - oss = new FileOutputStream(mf); - FileChannel ofc = oss.getChannel(); - long pos = 0; - try - { - long size = iss.available(); - while ((pos += ofc.transferFrom(rfc, pos, size - pos)) < size) - { - ; - } - } - catch (IOException ex) - { - if (RootTools.debugMode) - { - Log.e(LOG_TAG, ex.toString()); - } - return false; - } - } - catch (FileNotFoundException ex) - { - if (RootTools.debugMode) - { - Log.e(LOG_TAG, ex.toString()); - } - return false; - } - finally - { - if (oss != null) - { - try - { - oss.flush(); - oss.getFD().sync(); - oss.close(); - } - catch (Exception e) - { - } - } - } - try - { - iss.close(); - } - catch (IOException ex) - { - if (RootTools.debugMode) - { - Log.e(LOG_TAG, ex.toString()); - } - return false; - } - - try - { - Command command = new Command(0, false, "chmod " + mode + " " + filesPath + File.separator + destName); - Shell.startRootShell().add(command); - commandWait(command); - - } - catch (Exception e) - { - } - } - return true; - } - - protected boolean isBinaryInstalled(String destName) - { - boolean installed = false; - File mf = new File(filesPath + File.separator + destName); - if (mf.exists()) - { - installed = true; - // TODO: pass mode as argument and check it matches - } - return installed; - } - - protected String getFileSignature(File f) - { - String signature = ""; - try - { - signature = getStreamSignature(new FileInputStream(f)); - } - catch (FileNotFoundException ex) - { - Log.e(LOG_TAG, ex.toString()); - } - return signature; - } - - /* - * Note: this method will close any string passed to it - */ - protected String getStreamSignature(InputStream is) - { - String signature = ""; - try - { - MessageDigest md = MessageDigest.getInstance("MD5"); - DigestInputStream dis = new DigestInputStream(is, md); - byte[] buffer = new byte[4096]; - while (-1 != dis.read(buffer)) - { - ; - } - byte[] digest = md.digest(); - StringBuffer sb = new StringBuffer(); - - for (int i = 0; i < digest.length; i++) - { - sb.append(Integer.toHexString(digest[i] & 0xFF)); - } - - signature = sb.toString(); - } - catch (IOException ex) - { - Log.e(LOG_TAG, ex.toString()); - } - catch (NoSuchAlgorithmException ex) - { - Log.e(LOG_TAG, ex.toString()); - } - finally - { - try - { - is.close(); - } - catch (IOException e) - { - } - } - return signature; - } - - private void commandWait(Command cmd) - { - synchronized (cmd) - { - try - { - if (!cmd.isFinished()) - { - cmd.wait(2000); - } - } - catch (InterruptedException ex) - { - Log.e(LOG_TAG, ex.toString()); - } - } - } -} diff --git a/app/src/main/java/com/stericson/RootTools/internal/InternalVariables.java b/app/src/main/java/com/stericson/RootTools/internal/InternalVariables.java deleted file mode 100644 index 338df9e..0000000 --- a/app/src/main/java/com/stericson/RootTools/internal/InternalVariables.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of the RootTools Project: http://code.google.com/p/RootTools/ - * - * Copyright (c) 2012 Stephen Erickson, Chris Ravenscroft, Dominik Schuermann, Adam Shanks - * - * This code is dual-licensed under the terms of the Apache License Version 2.0 and - * the terms of the General Public License (GPL) Version 2. - * You may use this code according to either of these licenses as is most appropriate - * for your project on a case-by-case basis. - * - * The terms of each license can be found in the root directory of this project's repository as well as at: - * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * http://www.gnu.org/licenses/gpl-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under these Licenses is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See each License for the specific language governing permissions and - * limitations under that License. - */ - -package com.stericson.RootTools.internal; - -import java.util.ArrayList; -import java.util.regex.Pattern; - -import com.stericson.RootTools.containers.Mount; -import com.stericson.RootTools.containers.Permissions; -import com.stericson.RootTools.containers.Symlink; - -public class InternalVariables -{ - - // ---------------------- - // # Internal Variables # - // ---------------------- - - - protected static boolean nativeToolsReady = false; - protected static boolean found = false; - protected static boolean processRunning = false; - - protected static String[] space; - protected static String getSpaceFor; - protected static String busyboxVersion; - protected static String pid_list = ""; - protected static ArrayList mounts; - protected static ArrayList symlinks; - protected static String inode = ""; - protected static Permissions permissions; - - // regex to get pid out of ps line, example: - // root 2611 0.0 0.0 19408 2104 pts/2 S 13:41 0:00 bash - protected static final String PS_REGEX = "^\\S+\\s+([0-9]+).*$"; - protected static Pattern psPattern; - - static - { - psPattern = Pattern.compile(PS_REGEX); - } -} diff --git a/app/src/main/java/com/stericson/RootTools/internal/Remounter.java b/app/src/main/java/com/stericson/RootTools/internal/Remounter.java deleted file mode 100644 index 7ef7e8a..0000000 --- a/app/src/main/java/com/stericson/RootTools/internal/Remounter.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * This file is part of the RootTools Project: http://code.google.com/p/RootTools/ - * - * Copyright (c) 2012 Stephen Erickson, Chris Ravenscroft, Dominik Schuermann, Adam Shanks - * - * This code is dual-licensed under the terms of the Apache License Version 2.0 and - * the terms of the General Public License (GPL) Version 2. - * You may use this code according to either of these licenses as is most appropriate - * for your project on a case-by-case basis. - * - * The terms of each license can be found in the root directory of this project's repository as well as at: - * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * http://www.gnu.org/licenses/gpl-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under these Licenses is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See each License for the specific language governing permissions and - * limitations under that License. - */ - -package com.stericson.RootTools.internal; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; - -import com.stericson.RootShell.execution.Command; -import com.stericson.RootShell.execution.Shell; -import com.stericson.RootTools.Constants; -import com.stericson.RootTools.RootTools; -import com.stericson.RootTools.containers.Mount; - -public class Remounter -{ - - //------------- - //# Remounter # - //------------- - - /** - * This will take a path, which can contain the file name as well, - * and attempt to remount the underlying partition. - *

- * For example, passing in the following string: - * "/system/bin/some/directory/that/really/would/never/exist" - * will result in /system ultimately being remounted. - * However, keep in mind that the longer the path you supply, the more work this has to do, - * and the slower it will run. - * - * @param file file path - * @param mountType mount type: pass in RO (Read only) or RW (Read Write) - * @return a boolean which indicates whether or not the partition - * has been remounted as specified. - */ - - public boolean remount(String file, String mountType) - { - - //if the path has a trailing slash get rid of it. - if (file.endsWith("/") && !file.equals("/")) - { - file = file.substring(0, file.lastIndexOf("/")); - } - //Make sure that what we are trying to remount is in the mount list. - boolean foundMount = false; - - while (!foundMount) - { - try - { - for (Mount mount : RootTools.getMounts()) - { - RootTools.log(mount.getMountPoint().toString()); - - if (file.equals(mount.getMountPoint().toString())) - { - foundMount = true; - break; - } - } - } - catch (Exception e) - { - if (RootTools.debugMode) - { - e.printStackTrace(); - } - return false; - } - if (!foundMount) - { - try - { - file = (new File(file).getParent()); - } - catch (Exception e) - { - e.printStackTrace(); - return false; - } - } - } - - Mount mountPoint = findMountPointRecursive(file); - - if (mountPoint != null) - { - - RootTools.log(Constants.TAG, "Remounting " + mountPoint.getMountPoint().getAbsolutePath() + " as " + mountType.toLowerCase()); - final boolean isMountMode = mountPoint.getFlags().contains(mountType.toLowerCase()); - - if (!isMountMode) - { - //grab an instance of the internal class - try - { - Command command = new Command(0, - true, - "busybox mount -o remount," + mountType.toLowerCase() + " " + mountPoint.getDevice().getAbsolutePath() + " " + mountPoint.getMountPoint().getAbsolutePath(), - "busybox mount -o remount," + mountType.toLowerCase() + " " + file, - "busybox mount -o " + mountType.toLowerCase() + ",remount " + mountPoint.getDevice().getAbsolutePath(), - "busybox mount -o " + mountType.toLowerCase() + ",remount " + file, - "toolbox mount -o remount," + mountType.toLowerCase() + " " + mountPoint.getDevice().getAbsolutePath() + " " + mountPoint.getMountPoint().getAbsolutePath(), - "toolbox mount -o remount," + mountType.toLowerCase() + " " + file, "toybox mount -o remount," + mountType.toLowerCase() + " " + mountPoint.getDevice().getAbsolutePath() + " " + mountPoint.getMountPoint().getAbsolutePath(), - "toolbox mount -o " + mountType.toLowerCase() + ",remount " + mountPoint.getDevice().getAbsolutePath(), - "toolbox mount -o " + mountType.toLowerCase() + ",remount " + file, - "mount -o remount," + mountType.toLowerCase() + " " + mountPoint.getDevice().getAbsolutePath() + " " + mountPoint.getMountPoint().getAbsolutePath(), - "mount -o remount," + mountType.toLowerCase() + " " + file, - "mount -o " + mountType.toLowerCase() + ",remount " + mountPoint.getDevice().getAbsolutePath(), - "mount -o " + mountType.toLowerCase() + ",remount " + file, - "toybox mount -o remount," + mountType.toLowerCase() + " " + mountPoint.getDevice().getAbsolutePath() + " " + mountPoint.getMountPoint().getAbsolutePath(), - "toybox mount -o remount," + mountType.toLowerCase() + " " + file, - "toybox mount -o " + mountType.toLowerCase() + ",remount " + mountPoint.getDevice().getAbsolutePath(), - "toybox mount -o " + mountType.toLowerCase() + ",remount " + file); - Shell.startRootShell().add(command); - commandWait(command); - - } - catch (Exception e) - { - } - - mountPoint = findMountPointRecursive(file); - } - - if (mountPoint != null) - { - RootTools.log(Constants.TAG, mountPoint.getFlags() + " AND " + mountType.toLowerCase()); - if (mountPoint.getFlags().contains(mountType.toLowerCase())) - { - RootTools.log(mountPoint.getFlags().toString()); - return true; - } - else - { - RootTools.log(mountPoint.getFlags().toString()); - return false; - } - } - else - { - RootTools.log("mount is null, file was: " + file + " mountType was: " + mountType); - } - } - else - { - RootTools.log("mount is null, file was: " + file + " mountType was: " + mountType); - } - - return false; - } - - private Mount findMountPointRecursive(String file) - { - try - { - ArrayList mounts = RootTools.getMounts(); - - for (File path = new File(file); path != null; ) - { - for (Mount mount : mounts) - { - if (mount.getMountPoint().equals(path)) - { - return mount; - } - } - } - - return null; - - } - catch (IOException e) - { - if (RootTools.debugMode) - { - e.printStackTrace(); - } - } - catch (Exception e) - { - if (RootTools.debugMode) - { - e.printStackTrace(); - } - } - - return null; - } - - private void commandWait(Command cmd) - { - synchronized (cmd) - { - try - { - if (!cmd.isFinished()) - { - cmd.wait(2000); - } - } - catch (InterruptedException e) - { - e.printStackTrace(); - } - } - } -} diff --git a/app/src/main/java/com/stericson/RootTools/internal/RootToolsInternalMethods.java b/app/src/main/java/com/stericson/RootTools/internal/RootToolsInternalMethods.java deleted file mode 100644 index c3e7bd3..0000000 --- a/app/src/main/java/com/stericson/RootTools/internal/RootToolsInternalMethods.java +++ /dev/null @@ -1,1347 +0,0 @@ -/* - * This file is part of the RootTools Project: http://code.google.com/p/RootTools/ - * - * Copyright (c) 2012 Stephen Erickson, Chris Ravenscroft, Dominik Schuermann, Adam Shanks - * - * This code is dual-licensed under the terms of the Apache License Version 2.0 and - * the terms of the General Public License (GPL) Version 2. - * You may use this code according to either of these licenses as is most appropriate - * for your project on a case-by-case basis. - * - * The terms of each license can be found in the root directory of this project's repository as well as at: - * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * http://www.gnu.org/licenses/gpl-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under these Licenses is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See each License for the specific language governing permissions and - * limitations under that License. - */ - -package com.stericson.RootTools.internal; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Build; -import android.os.Environment; -import android.os.StatFs; -import android.util.Log; - -import com.stericson.RootTools.Constants; -import com.stericson.RootShell.RootShell; -import com.stericson.RootShell.execution.Command; -import com.stericson.RootShell.execution.Shell; -import com.stericson.RootTools.RootTools; -import com.stericson.RootTools.containers.Mount; -import com.stericson.RootTools.containers.Permissions; -import com.stericson.RootTools.containers.Symlink; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.LineNumberReader; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.concurrent.TimeoutException; -import java.util.regex.Matcher; - -public final class RootToolsInternalMethods { - - // -------------------- - // # Internal methods # - // -------------------- - - protected RootToolsInternalMethods() { - } - - public static void getInstance() { - //this will allow RootTools to be the only one to get an instance of this class. - RootTools.setRim(new RootToolsInternalMethods()); - } - - public Permissions getPermissions(String line) { - - String[] lineArray = line.split(" "); - String rawPermissions = lineArray[0]; - - if (rawPermissions.length() == 10 - && (rawPermissions.charAt(0) == '-' - || rawPermissions.charAt(0) == 'd' || rawPermissions - .charAt(0) == 'l') - && (rawPermissions.charAt(1) == '-' || rawPermissions.charAt(1) == 'r') - && (rawPermissions.charAt(2) == '-' || rawPermissions.charAt(2) == 'w')) { - RootTools.log(rawPermissions); - - Permissions permissions = new Permissions(); - - permissions.setType(rawPermissions.substring(0, 1)); - - RootTools.log(permissions.getType()); - - permissions.setUserPermissions(rawPermissions.substring(1, 4)); - - RootTools.log(permissions.getUserPermissions()); - - permissions.setGroupPermissions(rawPermissions.substring(4, 7)); - - RootTools.log(permissions.getGroupPermissions()); - - permissions.setOtherPermissions(rawPermissions.substring(7, 10)); - - RootTools.log(permissions.getOtherPermissions()); - - StringBuilder finalPermissions = new StringBuilder(); - finalPermissions.append(parseSpecialPermissions(rawPermissions)); - finalPermissions.append(parsePermissions(permissions.getUserPermissions())); - finalPermissions.append(parsePermissions(permissions.getGroupPermissions())); - finalPermissions.append(parsePermissions(permissions.getOtherPermissions())); - - permissions.setPermissions(Integer.parseInt(finalPermissions.toString())); - - return permissions; - } - - return null; - } - - public int parsePermissions(String permission) { - permission = permission.toLowerCase(Locale.US); - int tmp; - if (permission.charAt(0) == 'r') { - tmp = 4; - } else { - tmp = 0; - } - - RootTools.log("permission " + tmp); - RootTools.log("character " + permission.charAt(0)); - - if (permission.charAt(1) == 'w') { - tmp += 2; - } else { - tmp += 0; - } - - RootTools.log("permission " + tmp); - RootTools.log("character " + permission.charAt(1)); - - if (permission.charAt(2) == 'x' || permission.charAt(2) == 's' - || permission.charAt(2) == 't') { - tmp += 1; - } else { - tmp += 0; - } - - RootTools.log("permission " + tmp); - RootTools.log("character " + permission.charAt(2)); - - return tmp; - } - - public int parseSpecialPermissions(String permission) { - int tmp = 0; - if (permission.charAt(2) == 's') { - tmp += 4; - } - - if (permission.charAt(5) == 's') { - tmp += 2; - } - - if (permission.charAt(8) == 't') { - tmp += 1; - } - - RootTools.log("special permissions " + tmp); - - return tmp; - } - - /** - * Copys a file to a destination. Because cp is not available on all android devices, we have a - * fallback on the cat command - * - * @param source example: /data/data/org.adaway/files/hosts - * @param destination example: /system/etc/hosts - * @param remountAsRw remounts the destination as read/write before writing to it - * @param preserveFileAttributes tries to copy file attributes from source to destination, if only cat is available - * only permissions are preserved - * @return true if it was successfully copied - */ - public boolean copyFile(String source, String destination, boolean remountAsRw, - boolean preserveFileAttributes) { - - Command command = null; - boolean result = true; - - try { - // mount destination as rw before writing to it - if (remountAsRw) { - RootTools.remount(destination, "RW"); - } - - // if cp is available and has appropriate permissions - if (checkUtil("cp")) { - RootTools.log("cp command is available!"); - - if (preserveFileAttributes) { - command = new Command(0, false, "cp -fp " + source + " " + destination); - Shell.startRootShell().add(command); - commandWait(Shell.startRootShell(), command); - - //ensure that the file was copied, an exitcode of zero means success - result = command.getExitCode() == 0; - - } else { - command = new Command(0, false, "cp -f " + source + " " + destination); - Shell.startRootShell().add(command); - commandWait(Shell.startRootShell(), command); - - //ensure that the file was copied, an exitcode of zero means success - result = command.getExitCode() == 0; - - } - } else { - if (checkUtil("busybox") && hasUtil("cp", "busybox")) { - RootTools.log("busybox cp command is available!"); - - if (preserveFileAttributes) { - command = new Command(0, false, "busybox cp -fp " + source + " " + destination); - Shell.startRootShell().add(command); - commandWait(Shell.startRootShell(), command); - - } else { - command = new Command(0, false, "busybox cp -f " + source + " " + destination); - Shell.startRootShell().add(command); - commandWait(Shell.startRootShell(), command); - - } - } else { // if cp is not available use cat - // if cat is available and has appropriate permissions - if (checkUtil("cat")) { - RootTools.log("cp is not available, use cat!"); - - int filePermission = -1; - if (preserveFileAttributes) { - // get permissions of source before overwriting - Permissions permissions = getFilePermissionsSymlinks(source); - filePermission = permissions.getPermissions(); - } - - // copy with cat - command = new Command(0, false, "cat " + source + " > " + destination); - Shell.startRootShell().add(command); - commandWait(Shell.startRootShell(), command); - - if (preserveFileAttributes) { - // set premissions of source to destination - command = new Command(0, false, "chmod " + filePermission + " " + destination); - Shell.startRootShell().add(command); - commandWait(Shell.startRootShell(), command); - } - } else { - result = false; - } - } - } - - // mount destination back to ro - if (remountAsRw) { - RootTools.remount(destination, "RO"); - } - } catch (Exception e) { - e.printStackTrace(); - result = false; - } - - if (command != null) { - //ensure that the file was copied, an exitcode of zero means success - result = command.getExitCode() == 0; - } - - return result; - } - - /** - * This will check a given binary, determine if it exists and determine that - * it has either the permissions 755, 775, or 777. - * - * @param util Name of the utility to check. - * @return boolean to indicate whether the binary is installed and has - * appropriate permissions. - */ - public boolean checkUtil(String util) { - List foundPaths = RootShell.findBinary(util, true); - if (foundPaths.size() > 0) { - - for (String path : foundPaths) { - Permissions permissions = RootTools - .getFilePermissionsSymlinks(path + "/" + util); - - if (permissions != null) { - String permission; - - if (Integer.toString(permissions.getPermissions()).length() > 3) { - permission = Integer.toString(permissions.getPermissions()).substring(1); - } else { - permission = Integer.toString(permissions.getPermissions()); - } - - if (permission.equals("755") || permission.equals("777") - || permission.equals("775")) { - RootTools.utilPath = path + "/" + util; - return true; - } - } - } - } - - return false; - - } - - /** - * Deletes a file or directory - * - * @param target example: /data/data/org.adaway/files/hosts - * @param remountAsRw remounts the destination as read/write before writing to it - * @return true if it was successfully deleted - */ - public boolean deleteFileOrDirectory(String target, boolean remountAsRw) { - boolean result = true; - - try { - // mount destination as rw before writing to it - if (remountAsRw) { - RootTools.remount(target, "RW"); - } - - if (hasUtil("rm", "toolbox")) { - RootTools.log("rm command is available!"); - - Command command = new Command(0, false, "rm -r " + target); - Shell.startRootShell().add(command); - commandWait(Shell.startRootShell(), command); - - if (command.getExitCode() != 0) { - RootTools.log("target not exist or unable to delete file"); - result = false; - } - } else { - if (checkUtil("busybox") && hasUtil("rm", "busybox")) { - RootTools.log("busybox rm command is available!"); - - Command command = new Command(0, false, "busybox rm -rf " + target); - Shell.startRootShell().add(command); - commandWait(Shell.startRootShell(), command); - - if (command.getExitCode() != 0) { - RootTools.log("target not exist or unable to delete file"); - result = false; - } - } - } - - // mount destination back to ro - if (remountAsRw) { - RootTools.remount(target, "RO"); - } - } catch (Exception e) { - e.printStackTrace(); - result = false; - } - - return result; - } - - /** - * This will try and fix a given binary. (This is for Busybox applets or Toolbox applets) By - * "fix", I mean it will try and symlink the binary from either toolbox or Busybox and fix the - * permissions if the permissions are not correct. - * - * @param util Name of the utility to fix. - * @param utilPath path to the toolbox that provides ln, rm, and chmod. This can be a blank string, a - * path to a binary that will provide these, or you can use - * RootTools.getWorkingToolbox() - */ - public void fixUtil(String util, String utilPath) { - try { - RootTools.remount("/system", "rw"); - - List foundPaths = RootShell.findBinary(util, true); - - if (foundPaths.size() > 0) { - for (String path : foundPaths) { - Command command = new Command(0, false, utilPath + " rm " + path + "/" + util); - RootShell.getShell(true).add(command); - commandWait(RootShell.getShell(true), command); - - } - - Command command = new Command(0, false, utilPath + " ln -s " + utilPath + " /system/bin/" + util, utilPath + " chmod 0755 /system/bin/" + util); - RootShell.getShell(true).add(command); - commandWait(RootShell.getShell(true), command); - - } - - RootTools.remount("/system", "ro"); - } catch (Exception e) { - } - } - - /** - * This will check an array of binaries, determine if they exist and determine that it has - * either the permissions 755, 775, or 777. If an applet is not setup correctly it will try and - * fix it. (This is for Busybox applets or Toolbox applets) - * - * @param utils Name of the utility to check. - * @return boolean to indicate whether the operation completed. Note that this is not indicative - * of whether the problem was fixed, just that the method did not encounter any - * exceptions. - * @throws Exception if the operation cannot be completed. - */ - public boolean fixUtils(String[] utils) throws Exception { - - for (String util : utils) { - if (!checkUtil(util)) { - if (checkUtil("busybox")) { - if (hasUtil(util, "busybox")) { - fixUtil(util, RootTools.utilPath); - } - } else { - if (checkUtil("toolbox")) { - if (hasUtil(util, "toolbox")) { - fixUtil(util, RootTools.utilPath); - } - } else { - return false; - } - } - } - } - - return true; - } - - /** - * This will return an List of Strings. Each string represents an applet available from BusyBox. - *

- * - * @param path Path to the busybox binary that you want the list of applets from. - * @return null If we cannot return the list of applets. - */ - public List getBusyBoxApplets(String path) throws Exception { - - if (path != null && !path.endsWith("/") && !path.equals("")) { - path += "/"; - } else if (path == null) { - //Don't know what the user wants to do...what am I pshycic? - throw new Exception("Path is null, please specifiy a path"); - } - - final List results = new ArrayList(); - - Command command = new Command(Constants.BBA, false, path + "busybox --list") { - @Override - public void commandOutput(int id, String line) { - if (id == Constants.BBA) { - if (!line.trim().equals("") && !line.trim().contains("not found") && !line.trim().contains("file busy")) { - results.add(line); - } - } - - super.commandOutput(id, line); - } - }; - - //try without root first... - RootShell.getShell(false).add(command); - commandWait(RootShell.getShell(false), command); - - if (results.size() <= 0) { - //try with root... - - command = new Command(Constants.BBA, false, path + "busybox --list") { - @Override - public void commandOutput(int id, String line) { - if (id == Constants.BBA) { - if (!line.trim().equals("") && !line.trim().contains("not found") && !line.trim().contains("file busy")) { - results.add(line); - } - } - - super.commandOutput(id, line); - } - }; - - RootShell.getShell(true).add(command); - commandWait(RootShell.getShell(true), command); - } - - return results; - } - - /** - * @return BusyBox version if found, "" if not found. - */ - public String getBusyBoxVersion(String path) { - - final StringBuilder version = new StringBuilder(); - - if (!path.equals("") && !path.endsWith("/")) { - path += "/"; - } - - try { - Command command = new Command(Constants.BBV, false, path + "busybox") { - @Override - public void commandOutput(int id, String line) { - line = line.trim(); - - boolean foundVersion = false; - - if (id == Constants.BBV) { - RootTools.log("Version Output: " + line); - - String[] temp = line.split(" "); - - if (temp.length > 1 && temp[1].contains("v1.") && !foundVersion) { - foundVersion = true; - version.append(temp[1]); - RootTools.log("Found Version: " + version.toString()); - } - } - - super.commandOutput(id, line); - } - }; - - //try without root first - RootTools.log("Getting BusyBox Version without root"); - Shell shell = RootTools.getShell(false); - shell.add(command); - commandWait(shell, command); - - if (version.length() <= 0) { - - command = new Command(Constants.BBV, false, path + "busybox") { - @Override - public void commandOutput(int id, String line) { - line = line.trim(); - - boolean foundVersion = false; - - if (id == Constants.BBV) { - RootTools.log("Version Output: " + line); - - String[] temp = line.split(" "); - - if (temp.length > 1 && temp[1].contains("v1.") && !foundVersion) { - foundVersion = true; - version.append(temp[1]); - RootTools.log("Found Version: " + version.toString()); - } - } - - super.commandOutput(id, line); - } - }; - - RootTools.log("Getting BusyBox Version with root"); - Shell rootShell = RootTools.getShell(true); - //Now look for it... - rootShell.add(command); - commandWait(rootShell, command); - } - - } catch (Exception e) { - RootTools.log("BusyBox was not found, more information MAY be available with Debugging on."); - return ""; - } - - RootTools.log("Returning found version: " + version.toString()); - return version.toString(); - } - - /** - * @return long Size, converted to kilobytes (from xxx or xxxm or xxxk etc.) - */ - public long getConvertedSpace(String spaceStr) { - try { - double multiplier = 1.0; - char c; - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < spaceStr.length(); i++) { - c = spaceStr.charAt(i); - if (!Character.isDigit(c) && c != '.') { - if (c == 'm' || c == 'M') { - multiplier = 1024.0; - } else if (c == 'g' || c == 'G') { - multiplier = 1024.0 * 1024.0; - } - break; - } - sb.append(spaceStr.charAt(i)); - } - return (long) Math.ceil(Double.valueOf(sb.toString()) * multiplier); - } catch (Exception e) { - return -1; - } - } - - /** - * This method will return the inode number of a file. This method is dependent on having a version of - * ls that supports the -i parameter. - * - * @param file path to the file that you wish to return the inode number - * @return String The inode number for this file or "" if the inode number could not be found. - */ - public String getInode(String file) { - try { - Command command = new Command(Constants.GI, false, "/data/local/ls -i " + file) { - - @Override - public void commandOutput(int id, String line) { - if (id == Constants.GI) { - if (!line.trim().equals("") && Character.isDigit(line.trim().substring(0, 1).toCharArray()[0])) { - InternalVariables.inode = line.trim().split(" ")[0]; - } - } - - super.commandOutput(id, line); - } - }; - Shell.startRootShell().add(command); - commandWait(Shell.startRootShell(), command); - - return InternalVariables.inode; - } catch (Exception ignore) { - return ""; - } - } - - public boolean isNativeToolsReady(int nativeToolsId, Context context) { - RootTools.log("Preparing Native Tools"); - InternalVariables.nativeToolsReady = false; - - Installer installer; - try { - installer = new Installer(context); - } catch (IOException ex) { - if (RootTools.debugMode) { - ex.printStackTrace(); - } - return false; - } - - if (installer.isBinaryInstalled("nativetools")) { - InternalVariables.nativeToolsReady = true; - } else { - InternalVariables.nativeToolsReady = installer.installBinary(nativeToolsId, - "nativetools", "700"); - } - return InternalVariables.nativeToolsReady; - } - - /** - * @param file String that represent the file, including the full path to the - * file and its name. - * @return An instance of the class permissions from which you can get the - * permissions of the file or if the file could not be found or - * permissions couldn't be determined then permissions will be null. - */ - public Permissions getFilePermissionsSymlinks(String file) { - RootTools.log("Checking permissions for " + file); - if (RootTools.exists(file)) { - RootTools.log(file + " was found."); - try { - - Command command = new Command( - Constants.FPS, false, "ls -l " + file, - "busybox ls -l " + file, - "/system/bin/failsafe/toolbox ls -l " + file, - "toolbox ls -l " + file) { - @Override - public void commandOutput(int id, String line) { - if (id == Constants.FPS) { - String symlink_final = ""; - - String[] lineArray = line.split(" "); - if (lineArray[0].length() != 10) { - super.commandOutput(id, line); - return; - } - - RootTools.log("Line " + line); - - try { - String[] symlink = line.split(" "); - if (symlink[symlink.length - 2].equals("->")) { - RootTools.log("Symlink found."); - symlink_final = symlink[symlink.length - 1]; - } - } catch (Exception e) { - } - - try { - InternalVariables.permissions = getPermissions(line); - if (InternalVariables.permissions != null) { - InternalVariables.permissions.setSymlink(symlink_final); - } - } catch (Exception e) { - RootTools.log(e.getMessage()); - } - } - - super.commandOutput(id, line); - } - }; - RootShell.getShell(true).add(command); - commandWait(RootShell.getShell(true), command); - - return InternalVariables.permissions; - - } catch (Exception e) { - RootTools.log(e.getMessage()); - return null; - } - } - - return null; - } - - /** - * This will return an ArrayList of the class Mount. The class mount contains the following - * property's: device mountPoint type flags - *

- * These will provide you with any information you need to work with the mount points. - * - * @return ArrayList an ArrayList of the class Mount. - * @throws Exception if we cannot return the mount points. - */ - public ArrayList getMounts() throws Exception { - - InternalVariables.mounts = new ArrayList<>(); - - if(null == InternalVariables.mounts || InternalVariables.mounts.isEmpty()) { - Shell shell = RootTools.getShell(true); - - Command cmd = new Command(Constants.GET_MOUNTS, - false, - "cat /proc/mounts") { - - @Override - public void commandOutput(int id, String line) { - if (id == Constants.GET_MOUNTS) { - RootTools.log(line); - - String[] fields = line.split(" "); - - if(fields.length > 3) { - InternalVariables.mounts.add(new Mount(new File(fields[0]), // device - new File(fields[1]), // mountPoint - fields[2], // fstype - fields[3] // flags - )); - } - } - - super.commandOutput(id, line); - } - }; - shell.add(cmd); - this.commandWait(shell, cmd); - } - - return InternalVariables.mounts; - } - - /** - * This will tell you how the specified mount is mounted. rw, ro, etc... - *

- * - * @param path mount you want to check - * @return String What the mount is mounted as. - * @throws Exception if we cannot determine how the mount is mounted. - */ - public String getMountedAs(String path) throws Exception { - InternalVariables.mounts = getMounts(); - String mp; - if (InternalVariables.mounts != null) { - for (Mount mount : InternalVariables.mounts) { - - mp = mount.getMountPoint().getAbsolutePath(); - - if (mp.equals("/")) { - if (path.equals("/")) { - return (String) mount.getFlags().toArray()[0]; - } else { - continue; - } - } - - if (path.equals(mp) || path.startsWith(mp + "/")) { - RootTools.log((String) mount.getFlags().toArray()[0]); - return (String) mount.getFlags().toArray()[0]; - } - } - - throw new Exception(); - } else { - throw new Exception(); - } - } - - /** - * Get the space for a desired partition. - * - * @param path The partition to find the space for. - * @return the amount if space found within the desired partition. If the space was not found - * then the value is -1 - * @throws TimeoutException - */ - public long getSpace(String path) { - InternalVariables.getSpaceFor = path; - boolean found = false; - RootTools.log("Looking for Space"); - try { - final Command command = new Command(Constants.GS, false, "df " + path) { - - @Override - public void commandOutput(int id, String line) { - if (id == Constants.GS) { - if (line.contains(InternalVariables.getSpaceFor.trim())) { - InternalVariables.space = line.split(" "); - } - } - - super.commandOutput(id, line); - } - }; - Shell.startRootShell().add(command); - commandWait(Shell.startRootShell(), command); - - } catch (Exception e) { - } - - if (InternalVariables.space != null) { - RootTools.log("First Method"); - - for (String spaceSearch : InternalVariables.space) { - - RootTools.log(spaceSearch); - - if (found) { - return getConvertedSpace(spaceSearch); - } else if (spaceSearch.equals("used,")) { - found = true; - } - } - - // Try this way - int count = 0, targetCount = 3; - - RootTools.log("Second Method"); - - if (InternalVariables.space[0].length() <= 5) { - targetCount = 2; - } - - for (String spaceSearch : InternalVariables.space) { - - RootTools.log(spaceSearch); - if (spaceSearch.length() > 0) { - RootTools.log(spaceSearch + ("Valid")); - if (count == targetCount) { - return getConvertedSpace(spaceSearch); - } - count++; - } - } - } - RootTools.log("Returning -1, space could not be determined."); - return -1; - } - - /** - * This will return a String that represent the symlink for a specified file. - *

- * - * @param file file to get the Symlink for. (must have absolute path) - * @return String a String that represent the symlink for a specified file or an - * empty string if no symlink exists. - */ - public String getSymlink(String file) { - RootTools.log("Looking for Symlink for " + file); - - try { - final List results = new ArrayList(); - - Command command = new Command(Constants.GSYM, false, "ls -l " + file) { - - @Override - public void commandOutput(int id, String line) { - if (id == Constants.GSYM) { - if (!line.trim().equals("")) { - results.add(line); - } - } - - super.commandOutput(id, line); - } - }; - Shell.startRootShell().add(command); - commandWait(Shell.startRootShell(), command); - - String[] symlink = results.get(0).split(" "); - if (symlink.length > 2 && symlink[symlink.length - 2].equals("->")) { - RootTools.log("Symlink found."); - - String final_symlink; - - if (!symlink[symlink.length - 1].equals("") && !symlink[symlink.length - 1].contains("/")) { - //We assume that we need to get the path for this symlink as it is probably not absolute. - List paths = RootShell.findBinary(symlink[symlink.length - 1], true); - if (paths.size() > 0) { - //We return the first found location. - final_symlink = paths.get(0) + symlink[symlink.length - 1]; - } else { - //we couldnt find a path, return the symlink by itself. - final_symlink = symlink[symlink.length - 1]; - } - } else { - final_symlink = symlink[symlink.length - 1]; - } - - return final_symlink; - } - } catch (Exception e) { - if (RootTools.debugMode) { - e.printStackTrace(); - } - } - - RootTools.log("Symlink not found"); - return ""; - } - - /** - * This will return an ArrayList of the class Symlink. The class Symlink contains the following - * property's: path SymplinkPath - *

- * These will provide you with any Symlinks in the given path. - * - * @param path path to search for Symlinks. - * @return ArrayList an ArrayList of the class Symlink. - * @throws Exception if we cannot return the Symlinks. - */ - public ArrayList getSymlinks(String path) throws Exception { - - // this command needs find - if (!checkUtil("find")) { - throw new Exception(); - } - - InternalVariables.symlinks = new ArrayList<>(); - - Command command = new Command(0, false, "find " + path + " -type l -exec ls -l {} \\;") { - @Override - public void commandOutput(int id, String line) { - if (id == Constants.GET_SYMLINKS) { - RootTools.log(line); - - String[] fields = line.split(" "); - InternalVariables.symlinks.add(new Symlink(new File(fields[fields.length - 3]), // file - new File(fields[fields.length - 1]) // SymlinkPath - )); - - } - - super.commandOutput(id, line); - } - }; - Shell.startRootShell().add(command); - commandWait(Shell.startRootShell(), command); - - if (InternalVariables.symlinks != null) { - return InternalVariables.symlinks; - } else { - throw new Exception(); - } - } - - /** - * This will return to you a string to be used in your shell commands which will represent the - * valid working toolbox with correct permissions. For instance, if Busybox is available it will - * return "busybox", if busybox is not available but toolbox is then it will return "toolbox" - * - * @return String that indicates the available toolbox to use for accessing applets. - */ - public String getWorkingToolbox() { - if (RootTools.checkUtil("busybox")) { - return "busybox"; - } else if (RootTools.checkUtil("toolbox")) { - return "toolbox"; - } else { - return ""; - } - } - - /** - * Checks if there is enough Space on SDCard - * - * @param updateSize size to Check (long) - * @return true if the Update will fit on SDCard, false if not enough - * space on SDCard. Will also return false, if the SDCard is not mounted as - * read/write - */ - @SuppressWarnings("deprecation") - public boolean hasEnoughSpaceOnSdCard(long updateSize) { - RootTools.log("Checking SDcard size and that it is mounted as RW"); - String status = Environment.getExternalStorageState(); - if (!status.equals(Environment.MEDIA_MOUNTED)) { - return false; - } - File path = Environment.getExternalStorageDirectory(); - StatFs stat = new StatFs(path.getPath()); - long blockSize = 0; - long availableBlocks = 0; - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) { - blockSize = stat.getBlockSize(); - availableBlocks = stat.getAvailableBlocks(); - } else { - blockSize = stat.getBlockSizeLong(); - availableBlocks = stat.getAvailableBlocksLong(); - } - return (updateSize < availableBlocks * blockSize); - } - - /** - * Checks whether the toolbox or busybox binary contains a specific util - * - * @param util - * @param box Should contain "toolbox" or "busybox" - * @return true if it contains this util - */ - public boolean hasUtil(final String util, final String box) { - - InternalVariables.found = false; - - // only for busybox and toolbox - if (!(box.endsWith("toolbox") || box.endsWith("busybox"))) { - return false; - } - - try { - - Command command = new Command(0, false, box.endsWith("toolbox") ? box + " " + util : box + " --list") { - - @Override - public void commandOutput(int id, String line) { - if (box.endsWith("toolbox")) { - if (!line.contains("no such tool")) { - InternalVariables.found = true; - } - } else if (box.endsWith("busybox")) { - // go through all lines of busybox --list - if (line.contains(util)) { - RootTools.log("Found util!"); - InternalVariables.found = true; - } - } - - super.commandOutput(id, line); - } - }; - RootTools.getShell(true).add(command); - commandWait(RootTools.getShell(true), command); - - if (InternalVariables.found) { - RootTools.log("Box contains " + util + " util!"); - return true; - } else { - RootTools.log("Box does not contain " + util + " util!"); - return false; - } - } catch (Exception e) { - RootTools.log(e.getMessage()); - return false; - } - } - - /** - * This method can be used to unpack a binary from the raw resources folder and store it in - * /data/data/app.package/files/ This is typically useful if you provide your own C- or - * C++-based binary. This binary can then be executed using sendShell() and its full path. - * - * @param context the current activity's Context - * @param sourceId resource id; typically R.raw.id - * @param destName destination file name; appended to /data/data/app.package/files/ - * @param mode chmod value for this file - * @return a boolean which indicates whether or not we were able to create the new - * file. - */ - public boolean installBinary(Context context, int sourceId, String destName, String mode) { - Installer installer; - - try { - installer = new Installer(context); - } catch (IOException ex) { - if (RootTools.debugMode) { - ex.printStackTrace(); - } - return false; - } - - return (installer.installBinary(sourceId, destName, mode)); - } - - /** - * This method checks whether a binary is installed. - * - * @param context the current activity's Context - * @param binaryName binary file name; appended to /data/data/app.package/files/ - * @return a boolean which indicates whether or not - * the binary already exists. - */ - public boolean isBinaryAvailable(Context context, String binaryName) { - Installer installer; - - try { - installer = new Installer(context); - } catch (IOException ex) { - if (RootTools.debugMode) { - ex.printStackTrace(); - } - return false; - } - - return (installer.isBinaryInstalled(binaryName)); - } - - /** - * This will let you know if an applet is available from BusyBox - *

- * - * @param applet The applet to check for. - * @return true if applet is available, false otherwise. - */ - public boolean isAppletAvailable(String applet, String binaryPath) { - try { - for (String aplet : getBusyBoxApplets(binaryPath)) { - if (aplet.equals(applet)) { - return true; - } - } - return false; - } catch (Exception e) { - RootTools.log(e.toString()); - return false; - } - } - - /** - * This method can be used to to check if a process is running - * - * @param processName name of process to check - * @return true if process was found - * @throws TimeoutException (Could not determine if the process is running) - */ - public boolean isProcessRunning(final String processName) { - - RootTools.log("Checks if process is running: " + processName); - - InternalVariables.processRunning = false; - - try { - Command command = new Command(0, false, "ps | grep " + processName) { - @Override - public void commandOutput(int id, String line) { - if (line.contains(processName)) { - InternalVariables.processRunning = true; - } - - super.commandOutput(id, line); - } - }; - RootTools.getShell(true).add(command); - commandWait(RootTools.getShell(true), command); - - } catch (Exception e) { - RootTools.log(e.getMessage()); - } - - return InternalVariables.processRunning; - } - - /** - * This method can be used to kill a running process - * - * @param processName name of process to kill - * @return true if process was found and killed successfully - */ - public boolean killProcess(final String processName) { - RootTools.log("Killing process " + processName); - - InternalVariables.pid_list = ""; - - //Assume that the process is running - InternalVariables.processRunning = true; - - try { - - Command command = new Command(0, false, "ps") { - @Override - public void commandOutput(int id, String line) { - if (line.contains(processName)) { - Matcher psMatcher = InternalVariables.psPattern.matcher(line); - - try { - if (psMatcher.find()) { - String pid = psMatcher.group(1); - - InternalVariables.pid_list += " " + pid; - InternalVariables.pid_list = InternalVariables.pid_list.trim(); - - RootTools.log("Found pid: " + pid); - } else { - RootTools.log("Matching in ps command failed!"); - } - } catch (Exception e) { - RootTools.log("Error with regex!"); - e.printStackTrace(); - } - } - - super.commandOutput(id, line); - } - }; - RootTools.getShell(true).add(command); - commandWait(RootTools.getShell(true), command); - - // get all pids in one string, created in process method - String pids = InternalVariables.pid_list; - - // kill processes - if (!pids.equals("")) { - try { - // example: kill -9 1234 1222 5343 - command = new Command(0, false, "kill -9 " + pids); - RootTools.getShell(true).add(command); - commandWait(RootTools.getShell(true), command); - - return true; - } catch (Exception e) { - RootTools.log(e.getMessage()); - } - } else { - //no pids match, must be dead - return true; - } - } catch (Exception e) { - RootTools.log(e.getMessage()); - } - - return false; - } - - /** - * This will launch the Android market looking for BusyBox - * - * @param activity pass in your Activity - */ - public void offerBusyBox(Activity activity) { - RootTools.log("Launching Market for BusyBox"); - Intent i = new Intent(Intent.ACTION_VIEW, - Uri.parse("market://details?id=stericson.busybox")); - activity.startActivity(i); - } - - /** - * This will launch the Android market looking for BusyBox, but will return the intent fired and - * starts the activity with startActivityForResult - * - * @param activity pass in your Activity - * @param requestCode pass in the request code - * @return intent fired - */ - public Intent offerBusyBox(Activity activity, int requestCode) { - RootTools.log("Launching Market for BusyBox"); - Intent i = new Intent(Intent.ACTION_VIEW, - Uri.parse("market://details?id=stericson.busybox")); - activity.startActivityForResult(i, requestCode); - return i; - } - - /** - * This will launch the Play Store looking for SuperUser - * - * @param activity pass in your Activity - */ - public void offerSuperUser(Activity activity) { - RootTools.log("Launching Play Store for SuperSU"); - Intent i = new Intent(Intent.ACTION_VIEW, - Uri.parse("market://details?id=eu.chainfire.supersu")); - activity.startActivity(i); - } - - /** - * This will launch the Play Store looking for SuperSU, but will return the intent fired - * and starts the activity with startActivityForResult - * - * @param activity pass in your Activity - * @param requestCode pass in the request code - * @return intent fired - */ - public Intent offerSuperUser(Activity activity, int requestCode) { - RootTools.log("Launching Play Store for SuperSU"); - Intent i = new Intent(Intent.ACTION_VIEW, - Uri.parse("market://details?id=eu.chainfire.supersu")); - activity.startActivityForResult(i, requestCode); - return i; - } - - private void commandWait(Shell shell, Command cmd) throws Exception { - - while (!cmd.isFinished()) { - - RootTools.log(Constants.TAG, shell.getCommandQueuePositionString(cmd)); - RootTools.log(Constants.TAG, "Processed " + cmd.totalOutputProcessed + " of " + cmd.totalOutput + " output from command."); - - synchronized (cmd) { - try { - if (!cmd.isFinished()) { - cmd.wait(2000); - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - if (!cmd.isExecuting() && !cmd.isFinished()) { - if (!shell.isExecuting && !shell.isReading) { - Log.e(Constants.TAG, "Waiting for a command to be executed in a shell that is not executing and not reading! \n\n Command: " + cmd.getCommand()); - Exception e = new Exception(); - e.setStackTrace(Thread.currentThread().getStackTrace()); - e.printStackTrace(); - } else if (shell.isExecuting && !shell.isReading) { - Log.e(Constants.TAG, "Waiting for a command to be executed in a shell that is executing but not reading! \n\n Command: " + cmd.getCommand()); - Exception e = new Exception(); - e.setStackTrace(Thread.currentThread().getStackTrace()); - e.printStackTrace(); - } else { - Log.e(Constants.TAG, "Waiting for a command to be executed in a shell that is not reading! \n\n Command: " + cmd.getCommand()); - Exception e = new Exception(); - e.setStackTrace(Thread.currentThread().getStackTrace()); - e.printStackTrace(); - } - } - - } - } -} diff --git a/app/src/main/java/com/stericson/RootTools/internal/Runner.java b/app/src/main/java/com/stericson/RootTools/internal/Runner.java deleted file mode 100644 index d48cd12..0000000 --- a/app/src/main/java/com/stericson/RootTools/internal/Runner.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This file is part of the RootTools Project: http://code.google.com/p/RootTools/ - * - * Copyright (c) 2012 Stephen Erickson, Chris Ravenscroft, Dominik Schuermann, Adam Shanks - * - * This code is dual-licensed under the terms of the Apache License Version 2.0 and - * the terms of the General Public License (GPL) Version 2. - * You may use this code according to either of these licenses as is most appropriate - * for your project on a case-by-case basis. - * - * The terms of each license can be found in the root directory of this project's repository as well as at: - * - * * http://www.apache.org/licenses/LICENSE-2.0 - * * http://www.gnu.org/licenses/gpl-2.0.txt - * - * Unless required by applicable law or agreed to in writing, software - * distributed under these Licenses is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See each License for the specific language governing permissions and - * limitations under that License. - */ - -package com.stericson.RootTools.internal; - -import java.io.IOException; - -import com.stericson.RootShell.execution.Command; -import com.stericson.RootShell.execution.Shell; -import com.stericson.RootTools.RootTools; - -import android.content.Context; -import android.util.Log; - -public class Runner extends Thread -{ - - private static final String LOG_TAG = "RootTools::Runner"; - - Context context; - String binaryName; - String parameter; - - public Runner(Context context, String binaryName, String parameter) - { - this.context = context; - this.binaryName = binaryName; - this.parameter = parameter; - } - - public void run() - { - String privateFilesPath = null; - try - { - privateFilesPath = context.getFilesDir().getCanonicalPath(); - } - catch (IOException e) - { - if (RootTools.debugMode) - { - Log.e(LOG_TAG, "Problem occured while trying to locate private files directory!"); - } - e.printStackTrace(); - } - if (privateFilesPath != null) - { - try - { - Command command = new Command(0, false, privateFilesPath + "/" + binaryName + " " + parameter); - Shell.startRootShell().add(command); - commandWait(command); - - } - catch (Exception e) - { - } - } - } - - private void commandWait(Command cmd) - { - synchronized (cmd) - { - try - { - if (!cmd.isFinished()) - { - cmd.wait(2000); - } - } - catch (InterruptedException e) - { - e.printStackTrace(); - } - } - } - -} diff --git a/app/src/main/res/drawable/horizontal_borders.xml b/app/src/main/res/drawable/horizontal_borders.xml new file mode 100644 index 0000000..fe67dc1 --- /dev/null +++ b/app/src/main/res/drawable/horizontal_borders.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/main.xml b/app/src/main/res/layout/main.xml index bcb033e..4889535 100644 --- a/app/src/main/res/layout/main.xml +++ b/app/src/main/res/layout/main.xml @@ -2,7 +2,9 @@ + android:layout_height="match_parent" + android:background="@drawable/bordered_view" + android:fillViewport="true"> + android:layout_margin="10dp"> + + + + + android:layout_height="match_parent"> - + + + + + + + + + + + + + + + + + android:visibility="gone" + android:id="@+id/scriptsTabPanel"> + + - + + + android:visibility="gone" + android:id="@+id/settingsTabPanel" + android:gravity="center_horizontal" + android:paddingTop="10dp"> + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3746ed7..538904d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,6 +2,18 @@ DroidFrida - Hello, World! + + + Format code + Minify code + Obfuscate code + + + + AntiRootDetection.js + MethodTraceJava.js + NativeMethodTrace.js + NativeHexPatching.js +