Fixed rewritten java code being java-styled in kotlin

Fixed accessing kotlin code illegally via companion helper
This commit is contained in:
Viktor De Pasquale 2019-05-05 12:09:22 +02:00 committed by topjohnwu
parent 0a703585b0
commit 79d704008b
6 changed files with 135 additions and 112 deletions

View File

@ -1,73 +1,96 @@
package com.topjohnwu.magisk.tasks package com.topjohnwu.magisk.tasks
import android.net.Uri import android.net.Uri
import com.skoumal.teanity.extensions.subscribeK
import com.topjohnwu.magisk.App import com.topjohnwu.magisk.App
import com.topjohnwu.magisk.Const import com.topjohnwu.magisk.Const
import com.topjohnwu.magisk.utils.* import com.topjohnwu.magisk.utils.fileName
import com.topjohnwu.magisk.utils.inject
import com.topjohnwu.magisk.utils.readUri
import com.topjohnwu.magisk.utils.unzip
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.internal.UiThreadHandler import io.reactivex.Single
import java.io.File import java.io.File
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.io.IOException import java.io.IOException
abstract class FlashZip(private val mUri: Uri, abstract class FlashZip(
private val console: MutableList<String>, private val mUri: Uri,
private val logs: MutableList<String>) { private val console: MutableList<String>,
private val logs: MutableList<String>
) {
private val tmpFile: File = File(App.self.cacheDir, "install.zip") private val app: App by inject()
private val tmpFile: File = File(app.cacheDir, "install.zip")
@Throws(IOException::class) @Throws(IOException::class)
private fun unzipAndCheck(): Boolean { private fun unzipAndCheck(): Boolean {
unzip(tmpFile, tmpFile.parentFile!!, "META-INF/com/google/android", true) val parentFile = tmpFile.parentFile ?: return false
return Shell.su("grep -q '#MAGISK' ${File(tmpFile.parentFile, "updater-script")}") tmpFile.unzip(parentFile, "META-INF/com/google/android", true)
.exec().isSuccess
val updaterScript = File(parentFile, "updater-script")
return Shell
.su("grep -q '#MAGISK' $updaterScript")
.exec()
.isSuccess
} }
@Throws(IOException::class) @Throws(IOException::class)
private fun flash(): Boolean { private fun flash(): Boolean {
console.add("- Copying zip to temp directory") console.add("- Copying zip to temp directory")
try {
App.self.readUri(mUri).use { input -> runCatching {
app.readUri(mUri).use { input ->
tmpFile.outputStream().use { out -> input.copyTo(out) } tmpFile.outputStream().use { out -> input.copyTo(out) }
} }
} catch (e: FileNotFoundException) { }.getOrElse {
console.add("! Invalid Uri") when (it) {
throw e is FileNotFoundException -> console.add("! Invalid Uri")
} catch (e: IOException) { is IOException -> console.add("! Cannot copy to cache")
console.add("! Cannot copy to cache") }
throw e throw it
} }
try { val isMagiskModule = runCatching {
if (!unzipAndCheck()) { unzipAndCheck()
console.add("! This zip is not a Magisk Module!") }.getOrElse {
return false
}
} catch (e: IOException) {
console.add("! Unzip error") console.add("! Unzip error")
throw e throw it
}
if (!isMagiskModule) {
console.add("! This zip is not a Magisk Module!")
return false
} }
console.add("- Installing ${mUri.fileName}") console.add("- Installing ${mUri.fileName}")
return Shell.su("cd " + tmpFile.parent!!,
"BOOTMODE=true sh update-binary dummy 1 $tmpFile") val parentFile = tmpFile.parent ?: return false
.to(console, logs)
.exec().isSuccess return Shell
.su(
"cd $parentFile",
"BOOTMODE=true sh update-binary dummy 1 $tmpFile"
)
.to(console, logs)
.exec().isSuccess
} }
fun exec() { fun exec() = Single
App.THREAD_POOL.execute { .fromCallable {
val success = try { runCatching {
flash() flash()
} catch (e: IOException) { }.getOrElse {
it.printStackTrace()
false false
}.apply {
Shell.su("cd /", "rm -rf ${tmpFile.parent} ${Const.TMP_FOLDER_PATH}")
.submit()
} }
Shell.su("cd /", "rm -rf ${tmpFile.parent} ${Const.TMP_FOLDER_PATH}").submit()
UiThreadHandler.run { onResult(success) }
} }
} .subscribeK(onError = { onResult(false) }) { onResult(it) }
.let { Unit } // ignores result disposable
protected abstract fun onResult(success: Boolean) protected abstract fun onResult(success: Boolean)
} }

View File

@ -89,7 +89,7 @@ public class DownloadApp {
// Make it world readable // Make it world readable
apk.setReadable(true, false); apk.setReadable(true, false);
if (Shell.su("pm install " + apk).exec().isSuccess()) if (Shell.su("pm install " + apk).exec().isSuccess())
RootUtils.Companion.rmAndLaunch(app.getPackageName(), RootUtils.rmAndLaunch(app.getPackageName(),
new ComponentName(BuildConfig.APPLICATION_ID, new ComponentName(BuildConfig.APPLICATION_ID,
ClassMap.get(SplashActivity.class).getName())); ClassMap.get(SplashActivity.class).getName()));
progress.dismiss(); progress.dismiss();

View File

@ -3,8 +3,6 @@ package com.topjohnwu.magisk.utils;
import android.content.ComponentName; import android.content.ComponentName;
import android.widget.Toast; import android.widget.Toast;
import androidx.core.app.NotificationCompat;
import com.topjohnwu.magisk.App; import com.topjohnwu.magisk.App;
import com.topjohnwu.magisk.BuildConfig; import com.topjohnwu.magisk.BuildConfig;
import com.topjohnwu.magisk.ClassMap; import com.topjohnwu.magisk.ClassMap;
@ -29,6 +27,8 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import androidx.core.app.NotificationCompat;
public class PatchAPK { public class PatchAPK {
public static final String LOWERALPHA = "abcdefghijklmnopqrstuvwxyz"; public static final String LOWERALPHA = "abcdefghijklmnopqrstuvwxyz";
@ -56,7 +56,7 @@ public class PatchAPK {
return builder.toString(); return builder.toString();
} }
private static boolean findAndPatch(byte xml[], String from, String to) { private static boolean findAndPatch(byte[] xml, String from, String to) {
if (from.length() != to.length()) if (from.length() != to.length())
return false; return false;
CharBuffer buf = ByteBuffer.wrap(xml).order(ByteOrder.LITTLE_ENDIAN).asCharBuffer(); CharBuffer buf = ByteBuffer.wrap(xml).order(ByteOrder.LITTLE_ENDIAN).asCharBuffer();
@ -83,7 +83,7 @@ public class PatchAPK {
return true; return true;
} }
private static boolean findAndPatch(byte xml[], int a, int b) { private static boolean findAndPatch(byte[] xml, int a, int b) {
IntBuffer buf = ByteBuffer.wrap(xml).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer(); IntBuffer buf = ByteBuffer.wrap(xml).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
int len = xml.length / 4; int len = xml.length / 4;
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {
@ -112,7 +112,7 @@ public class PatchAPK {
Config.set(Config.Key.SU_MANAGER, pkg); Config.set(Config.Key.SU_MANAGER, pkg);
Config.export(); Config.export();
RootUtils.Companion.rmAndLaunch(BuildConfig.APPLICATION_ID, RootUtils.rmAndLaunch(BuildConfig.APPLICATION_ID,
new ComponentName(pkg, ClassMap.get(SplashActivity.class).getName())); new ComponentName(pkg, ClassMap.get(SplashActivity.class).getName()));
return true; return true;
@ -122,7 +122,7 @@ public class PatchAPK {
try { try {
JarMap jar = new JarMap(in); JarMap jar = new JarMap(in);
JarEntry je = jar.getJarEntry(Const.ANDROID_MANIFEST); JarEntry je = jar.getJarEntry(Const.ANDROID_MANIFEST);
byte xml[] = jar.getRawData(je); byte[] xml = jar.getRawData(je);
if (!findAndPatch(xml, BuildConfig.APPLICATION_ID, pkg) || if (!findAndPatch(xml, BuildConfig.APPLICATION_ID, pkg) ||
!findAndPatch(xml, R.string.app_name, R.string.re_app_name)) !findAndPatch(xml, R.string.app_name, R.string.re_app_name))

View File

@ -38,72 +38,70 @@ fun Intent.toCommand(args: MutableList<String>) {
} }
val extras = extras val extras = extras
if (extras != null) { if (extras != null) {
for (key in extras.keySet()) { loop@ for (key in extras.keySet()) {
val v = extras.get(key) ?: continue val v = extras.get(key) ?: continue
var value: Any = v var value: Any = v
val arg: String val arg: String
if (v is String) when {
arg = "--es" v is String -> arg = "--es"
else if (v is Boolean) v is Boolean -> arg = "--ez"
arg = "--ez" v is Int -> arg = "--ei"
else if (v is Int) v is Long -> arg = "--el"
arg = "--ei" v is Float -> arg = "--ef"
else if (v is Long) v is Uri -> arg = "--eu"
arg = "--el" v is ComponentName -> {
else if (v is Float) arg = "--ecn"
arg = "--ef" value = v.flattenToString()
else if (v is Uri)
arg = "--eu"
else if (v is ComponentName) {
arg = "--ecn"
value = v.flattenToString()
} else if (v is ArrayList<*>) {
if (v.size <= 0)
/* Impossible to know the type due to type erasure */
continue
arg = if (v[0] is Int)
"--eial"
else if (v[0] is Long)
"--elal"
else if (v[0] is Float)
"--efal"
else if (v[0] is String)
"--esal"
else
continue /* Unsupported */
val sb = StringBuilder()
for (o in v) {
sb.append(o.toString().replace(",", "\\,"))
sb.append(',')
} }
// Remove trailing comma v is ArrayList<*> -> {
sb.deleteCharAt(sb.length - 1) if (v.size <= 0)
value = sb /* Impossible to know the type due to type erasure */
} else if (v.javaClass.isArray) { continue@loop
arg = if (v is IntArray)
"--eia"
else if (v is LongArray)
"--ela"
else if (v is FloatArray)
"--efa"
else if (v is Array<*> && v.isArrayOf<String>())
"--esa"
else
continue /* Unsupported */
val sb = StringBuilder() arg = if (v[0] is Int)
val len = RArray.getLength(v) "--eial"
for (i in 0 until len) { else if (v[0] is Long)
sb.append(RArray.get(v, i)!!.toString().replace(",", "\\,")) "--elal"
sb.append(',') else if (v[0] is Float)
"--efal"
else if (v[0] is String)
"--esal"
else
continue@loop /* Unsupported */
val sb = StringBuilder()
for (o in v) {
sb.append(o.toString().replace(",", "\\,"))
sb.append(',')
}
// Remove trailing comma
sb.deleteCharAt(sb.length - 1)
value = sb
} }
// Remove trailing comma v.javaClass.isArray -> {
sb.deleteCharAt(sb.length - 1) arg = if (v is IntArray)
value = sb "--eia"
} else else if (v is LongArray)
continue /* Unsupported */ "--ela"
else if (v is FloatArray)
"--efa"
else if (v is Array<*> && v.isArrayOf<String>())
"--esa"
else
continue@loop /* Unsupported */
val sb = StringBuilder()
val len = RArray.getLength(v)
for (i in 0 until len) {
sb.append(RArray.get(v, i)!!.toString().replace(",", "\\,"))
sb.append(',')
}
// Remove trailing comma
sb.deleteCharAt(sb.length - 1)
value = sb
}
else -> continue@loop
} /* Unsupported */
args.add(arg) args.add(arg)
args.add(key) args.add(key)
@ -153,10 +151,12 @@ class RootUtils : Shell.Initializer() {
companion object { companion object {
@JvmStatic
fun rmAndLaunch(rm: String, component: ComponentName) { fun rmAndLaunch(rm: String, component: ComponentName) {
Shell.su("(rm_launch $rm ${component.flattenToString()})").exec() Shell.su("(rm_launch $rm ${component.flattenToString()})").exec()
} }
@JvmStatic
fun reboot() { fun reboot() {
Shell.su("/system/bin/reboot ${if (Config.recovery) "recovery" else ""}").submit() Shell.su("/system/bin/reboot ${if (Config.recovery) "recovery" else ""}").submit()
} }

View File

@ -9,16 +9,16 @@ import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream import java.util.zip.ZipInputStream
@Throws(IOException::class) @Throws(IOException::class)
fun unzip(zip: File, folder: File, path: String = "", junkPath: Boolean = false) { fun File.unzip(folder: File, path: String = "", junkPath: Boolean = false) {
zip.inputStream().buffered().use { inputStream().buffered().use {
unzip(it, folder, path, junkPath) it.unzip(folder, path, junkPath)
} }
} }
@Throws(IOException::class) @Throws(IOException::class)
fun unzip(zip: InputStream, folder: File, path: String, junkPath: Boolean) { fun InputStream.unzip(folder: File, path: String, junkPath: Boolean) {
try { try {
val zin = ZipInputStream(zip) val zin = ZipInputStream(this)
var entry: ZipEntry var entry: ZipEntry
while (true) { while (true) {
entry = zin.nextEntry ?: break entry = zin.nextEntry ?: break

View File

@ -4,8 +4,6 @@ import android.app.Activity;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import com.topjohnwu.magisk.R; import com.topjohnwu.magisk.R;
import com.topjohnwu.magisk.tasks.MagiskInstaller; import com.topjohnwu.magisk.tasks.MagiskInstaller;
import com.topjohnwu.magisk.utils.RootUtils; import com.topjohnwu.magisk.utils.RootUtils;
@ -14,6 +12,8 @@ import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.internal.UiThreadHandler; import com.topjohnwu.superuser.internal.UiThreadHandler;
import com.topjohnwu.superuser.io.SuFile; import com.topjohnwu.superuser.io.SuFile;
import androidx.annotation.NonNull;
public class EnvFixDialog extends CustomAlertDialog { public class EnvFixDialog extends CustomAlertDialog {
public EnvFixDialog(@NonNull Activity activity) { public EnvFixDialog(@NonNull Activity activity) {
@ -38,7 +38,7 @@ public class EnvFixDialog extends CustomAlertDialog {
pd.dismiss(); pd.dismiss();
Utils.toast(success ? R.string.reboot_delay_toast : R.string.setup_fail, Toast.LENGTH_LONG); Utils.toast(success ? R.string.reboot_delay_toast : R.string.setup_fail, Toast.LENGTH_LONG);
if (success) if (success)
UiThreadHandler.handler.postDelayed(RootUtils.Companion::reboot, 5000); UiThreadHandler.handler.postDelayed(RootUtils::reboot, 5000);
} }
}.exec(); }.exec();
}); });