mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-28 04:25:27 +00:00
Fix non-root boot patching
This commit is contained in:
parent
4ff39f8817
commit
23f697d62b
@ -17,7 +17,6 @@ import com.topjohnwu.magisk.utils.Utils;
|
|||||||
import com.topjohnwu.magisk.utils.ZipUtils;
|
import com.topjohnwu.magisk.utils.ZipUtils;
|
||||||
import com.topjohnwu.superuser.Shell;
|
import com.topjohnwu.superuser.Shell;
|
||||||
import com.topjohnwu.superuser.ShellUtils;
|
import com.topjohnwu.superuser.ShellUtils;
|
||||||
import com.topjohnwu.superuser.io.SuFile;
|
|
||||||
import com.topjohnwu.superuser.io.SuFileInputStream;
|
import com.topjohnwu.superuser.io.SuFileInputStream;
|
||||||
import com.topjohnwu.utils.SignBoot;
|
import com.topjohnwu.utils.SignBoot;
|
||||||
|
|
||||||
@ -43,17 +42,18 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
private static final int DIRECT_MODE = 1;
|
private static final int DIRECT_MODE = 1;
|
||||||
private static final int FIX_ENV_MODE = 2;
|
private static final int FIX_ENV_MODE = 2;
|
||||||
|
|
||||||
private Uri mBootImg, mZip;
|
private Uri bootUri, mZip;
|
||||||
private List<String> console, logs;
|
private List<String> console, logs;
|
||||||
private String mBootLocation;
|
private String mBoot;
|
||||||
private int mode;
|
private int mode;
|
||||||
private File install;
|
private File installDir;
|
||||||
private ProgressDialog dialog;
|
private ProgressDialog dialog;
|
||||||
private boolean highCompression;
|
private MagiskManager mm;
|
||||||
|
|
||||||
public InstallMagisk(Activity context, Uri zip) {
|
public InstallMagisk(Activity context, Uri zip) {
|
||||||
super(context);
|
super(context);
|
||||||
mZip = zip;
|
mZip = zip;
|
||||||
|
mm = MagiskManager.get();
|
||||||
mode = FIX_ENV_MODE;
|
mode = FIX_ENV_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,14 +65,13 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
|
|
||||||
public InstallMagisk(FlashActivity context, List<String> console, List<String> logs, Uri zip, Uri boot) {
|
public InstallMagisk(FlashActivity context, List<String> console, List<String> logs, Uri zip, Uri boot) {
|
||||||
this(context, console, logs, zip);
|
this(context, console, logs, zip);
|
||||||
mBootImg = boot;
|
bootUri = boot;
|
||||||
highCompression = false;
|
|
||||||
mode = PATCH_MODE;
|
mode = PATCH_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstallMagisk(FlashActivity context, List<String> console, List<String> logs, Uri zip, String boot) {
|
public InstallMagisk(FlashActivity context, List<String> console, List<String> logs, Uri zip, String boot) {
|
||||||
this(context, console, logs, zip);
|
this(context, console, logs, zip);
|
||||||
mBootLocation = boot;
|
mBoot = boot;
|
||||||
mode = DIRECT_MODE;
|
mode = DIRECT_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,19 +85,18 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void extractFiles(String arch) throws IOException {
|
private void extractFiles(String arch) throws IOException {
|
||||||
MagiskManager mm = MagiskManager.get();
|
|
||||||
console.add("- Extracting files");
|
console.add("- Extracting files");
|
||||||
try (InputStream in = mm.getContentResolver().openInputStream(mZip)) {
|
try (InputStream in = mm.getContentResolver().openInputStream(mZip)) {
|
||||||
if (in == null) throw new FileNotFoundException();
|
if (in == null) throw new FileNotFoundException();
|
||||||
BufferedInputStream buf = new BufferedInputStream(in);
|
BufferedInputStream buf = new BufferedInputStream(in);
|
||||||
buf.mark(Integer.MAX_VALUE);
|
buf.mark(Integer.MAX_VALUE);
|
||||||
ZipUtils.unzip(buf, install, arch + "/", true);
|
ZipUtils.unzip(buf, installDir, arch + "/", true);
|
||||||
buf.reset();
|
buf.reset();
|
||||||
ZipUtils.unzip(buf, install, "common/", true);
|
ZipUtils.unzip(buf, installDir, "common/", true);
|
||||||
buf.reset();
|
buf.reset();
|
||||||
ZipUtils.unzip(buf, install, "chromeos/", false);
|
ZipUtils.unzip(buf, installDir, "chromeos/", false);
|
||||||
buf.reset();
|
buf.reset();
|
||||||
ZipUtils.unzip(buf, install, "META-INF/com/google/android/update-binary", true);
|
ZipUtils.unzip(buf, installDir, "META-INF/com/google/android/update-binary", true);
|
||||||
buf.close();
|
buf.close();
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
console.add("! Invalid Uri");
|
console.add("! Invalid Uri");
|
||||||
@ -108,68 +106,46 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
Shell.Sync.sh(Utils.fmt("chmod -R 755 %s/*; %s/magiskinit -x magisk %s/magisk",
|
Shell.Sync.sh(Utils.fmt("chmod -R 755 %s/*; %s/magiskinit -x magisk %s/magisk",
|
||||||
install, install, install));
|
installDir, installDir, installDir));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean dumpBoot(File boot) throws IOException {
|
private boolean dumpBoot() {
|
||||||
MagiskManager mm = MagiskManager.get();
|
console.add("- Copying boot image to " + mBoot);
|
||||||
switch (mode) {
|
// Copy boot image to local
|
||||||
case PATCH_MODE:
|
try (InputStream in = mm.getContentResolver().openInputStream(bootUri);
|
||||||
// Copy boot image to local
|
OutputStream out = new FileOutputStream(mBoot)
|
||||||
try (InputStream in = mm.getContentResolver().openInputStream(mBootImg);
|
) {
|
||||||
OutputStream out = new FileOutputStream(boot)
|
if (in == null)
|
||||||
) {
|
throw new FileNotFoundException();
|
||||||
InputStream source;
|
|
||||||
if (in == null) throw new FileNotFoundException();
|
|
||||||
|
|
||||||
if (Utils.getNameFromUri(mm, mBootImg).endsWith(".tar")) {
|
InputStream src;
|
||||||
// Extract boot.img from tar
|
if (Utils.getNameFromUri(mm, bootUri).endsWith(".tar")) {
|
||||||
TarInputStream tar = new TarInputStream(new BufferedInputStream(in));
|
// Extract boot.img from tar
|
||||||
org.kamranzafar.jtar.TarEntry entry;
|
TarInputStream tar = new TarInputStream(new BufferedInputStream(in));
|
||||||
while ((entry = tar.getNextEntry()) != null) {
|
org.kamranzafar.jtar.TarEntry entry;
|
||||||
if (entry.getName().equals("boot.img"))
|
while ((entry = tar.getNextEntry()) != null) {
|
||||||
break;
|
if (entry.getName().equals("boot.img"))
|
||||||
}
|
break;
|
||||||
source = tar;
|
|
||||||
} else {
|
|
||||||
// Direct copy raw image
|
|
||||||
source = new BufferedInputStream(in);
|
|
||||||
}
|
|
||||||
ShellUtils.pump(source, out);
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
console.add("! Invalid Uri");
|
|
||||||
throw e;
|
|
||||||
} catch (IOException e) {
|
|
||||||
console.add("! Copy failed");
|
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
break;
|
src = tar;
|
||||||
case DIRECT_MODE:
|
} else {
|
||||||
console.add("- Patch boot/ramdisk image: " + mBootLocation);
|
// Direct copy raw image
|
||||||
if (mm.remoteMagiskVersionCode >= 1463) {
|
src = new BufferedInputStream(in);
|
||||||
highCompression = Integer.parseInt(ShellUtils.fastCmd(Utils.fmt(
|
}
|
||||||
"%s/magiskboot --parse %s; echo $?", install, mBootLocation))) == 2;
|
ShellUtils.pump(src, out);
|
||||||
if (highCompression)
|
} catch (FileNotFoundException e) {
|
||||||
console.add("! Insufficient boot partition size detected");
|
console.add("! Invalid Uri");
|
||||||
}
|
return false;
|
||||||
if (boot.createNewFile()) {
|
} catch (IOException e) {
|
||||||
Shell.Sync.su("cat " + mBootLocation + " > " + boot);
|
console.add("! Copy failed");
|
||||||
} else {
|
return false;
|
||||||
console.add("! Dump boot image failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean patchBoot(File boot, SuFile patched_boot) throws IOException {
|
private File patchBoot() throws IOException {
|
||||||
MagiskManager mm = MagiskManager.get();
|
|
||||||
|
|
||||||
boolean isSigned;
|
boolean isSigned;
|
||||||
try (InputStream in = new FileInputStream(boot)) {
|
try (InputStream in = new SuFileInputStream(mBoot)) {
|
||||||
isSigned = SignBoot.verifySignature(in, null);
|
isSigned = SignBoot.verifySignature(in, null);
|
||||||
if (isSigned) {
|
if (isSigned) {
|
||||||
console.add("- Boot image is signed with AVB 1.0");
|
console.add("- Boot image is signed with AVB 1.0");
|
||||||
@ -181,35 +157,33 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
|
|
||||||
// Patch boot image
|
// Patch boot image
|
||||||
Shell.Sync.sh(console, logs,
|
Shell.Sync.sh(console, logs,
|
||||||
"cd " + install,
|
"cd " + installDir,
|
||||||
Utils.fmt("KEEPFORCEENCRYPT=%b KEEPVERITY=%b HIGHCOMP=%b " +
|
Utils.fmt("KEEPFORCEENCRYPT=%b KEEPVERITY=%b sh update-binary indep " +
|
||||||
"sh update-binary indep boot_patch.sh %s || echo 'Failed!'",
|
"boot_patch.sh %s || echo 'Failed!'",
|
||||||
mm.keepEnc, mm.keepVerity, highCompression, boot));
|
mm.keepEnc, mm.keepVerity, mBoot));
|
||||||
|
|
||||||
if (TextUtils.equals(console.get(console.size() - 1), "Failed!"))
|
if (TextUtils.equals(console.get(console.size() - 1), "Failed!"))
|
||||||
return false;
|
return null;
|
||||||
|
|
||||||
Shell.Sync.sh("mv -f new-boot.img ../",
|
Shell.Sync.sh("mv bin/busybox busybox",
|
||||||
"mv bin/busybox busybox",
|
"rm -rf magisk.apk bin boot.img update-binary",
|
||||||
"rm -rf magisk.apk bin *.img update-binary",
|
|
||||||
"cd /");
|
"cd /");
|
||||||
|
|
||||||
|
File patched = new File(installDir, "new-boot.img");
|
||||||
if (isSigned) {
|
if (isSigned) {
|
||||||
console.add("- Signing boot image with test keys");
|
console.add("- Signing boot image with test keys");
|
||||||
File signed = new File(install.getParent(), "signed.img");
|
File signed = new File(installDir, "signed.img");
|
||||||
try (InputStream in = new SuFileInputStream(patched_boot);
|
try (InputStream in = new BufferedInputStream(new FileInputStream(patched));
|
||||||
OutputStream out = new BufferedOutputStream(new FileOutputStream(signed))
|
OutputStream out = new BufferedOutputStream(new FileOutputStream(signed))
|
||||||
) {
|
) {
|
||||||
SignBoot.doSignature("/boot", in, out, null, null);
|
SignBoot.doSignature("/boot", in, out, null, null);
|
||||||
}
|
}
|
||||||
Shell.Sync.sh("mv -f " + signed + " " + patched_boot);
|
signed.renameTo(patched);
|
||||||
}
|
}
|
||||||
return true;
|
return patched;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void outputBoot(SuFile patched_boot) throws IOException {
|
private void outputBoot(File patched) throws IOException {
|
||||||
MagiskManager mm = MagiskManager.get();
|
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case PATCH_MODE:
|
case PATCH_MODE:
|
||||||
File dest = new File(Const.EXTERNAL_PATH, "patched_boot" + mm.bootFormat);
|
File dest = new File(Const.EXTERNAL_PATH, "patched_boot" + mm.bootFormat);
|
||||||
@ -218,14 +192,14 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
switch (mm.bootFormat) {
|
switch (mm.bootFormat) {
|
||||||
case ".img.tar":
|
case ".img.tar":
|
||||||
out = new TarOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
|
out = new TarOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
|
||||||
((TarOutputStream) out).putNextEntry(new TarEntry(patched_boot, "boot.img"));
|
((TarOutputStream) out).putNextEntry(new TarEntry(patched, "boot.img"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case ".img":
|
case ".img":
|
||||||
out = new BufferedOutputStream(new FileOutputStream(dest));
|
out = new BufferedOutputStream(new FileOutputStream(dest));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try (InputStream in = new SuFileInputStream(patched_boot)) {
|
try (InputStream in = new FileInputStream(patched)) {
|
||||||
ShellUtils.pump(in, out);
|
ShellUtils.pump(in, out);
|
||||||
out.close();
|
out.close();
|
||||||
}
|
}
|
||||||
@ -236,32 +210,37 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
console.add("*********************************");
|
console.add("*********************************");
|
||||||
break;
|
break;
|
||||||
case DIRECT_MODE:
|
case DIRECT_MODE:
|
||||||
String binPath = mm.remoteMagiskVersionCode >= Const.MAGISK_VER.HIDDEN_PATH ? "/data/adb/magisk" : "/data/magisk";
|
String binPath = mm.remoteMagiskVersionCode >= Const.MAGISK_VER.HIDDEN_PATH ?
|
||||||
|
"/data/adb/magisk" : "/data/magisk";
|
||||||
Shell.Sync.su(console, logs,
|
Shell.Sync.su(console, logs,
|
||||||
|
Utils.fmt("flash_boot_image %s %s; rm -f %s", patched, mBoot, patched),
|
||||||
Utils.fmt("rm -rf %s/*; mkdir -p %s; chmod 700 /data/adb", binPath, binPath),
|
Utils.fmt("rm -rf %s/*; mkdir -p %s; chmod 700 /data/adb", binPath, binPath),
|
||||||
Utils.fmt("cp -af %s/* %s; rm -rf %s", install, binPath, install),
|
Utils.fmt("cp -af %s/* %s; rm -rf %s", installDir, binPath, installDir),
|
||||||
Utils.fmt("flash_boot_image %s %s", patched_boot, mBootLocation),
|
|
||||||
mm.keepVerity ? "" : "patch_dtbo_image");
|
mm.keepVerity ? "" : "patch_dtbo_image");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
patched_boot.delete();
|
patched.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Boolean doInBackground(Void... voids) {
|
protected Boolean doInBackground(Void... voids) {
|
||||||
MagiskManager mm = MagiskManager.get();
|
|
||||||
|
|
||||||
if (mode == FIX_ENV_MODE) {
|
if (mode == FIX_ENV_MODE) {
|
||||||
install = new File("/data/adb/magisk");
|
installDir = new File("/data/adb/magisk");
|
||||||
Shell.Sync.sh("rm -rf " + install + "/*");
|
Shell.Sync.sh("rm -rf " + installDir + "/*");
|
||||||
} else {
|
} else {
|
||||||
install = new File(
|
installDir = new File(
|
||||||
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ?
|
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ?
|
||||||
mm.createDeviceProtectedStorageContext() : mm)
|
mm.createDeviceProtectedStorageContext() : mm)
|
||||||
.getFilesDir().getParent()
|
.getFilesDir().getParent()
|
||||||
, "install");
|
, "install");
|
||||||
Shell.Sync.sh("rm -rf " + install);
|
Shell.Sync.sh("rm -rf " + installDir);
|
||||||
install.mkdirs();
|
installDir.mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == PATCH_MODE) {
|
||||||
|
mBoot = new File(installDir, "boot.img").getAbsolutePath();
|
||||||
|
if (!dumpBoot())
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> abis = Arrays.asList(Build.SUPPORTED_ABIS);
|
List<String> abis = Arrays.asList(Build.SUPPORTED_ABIS);
|
||||||
@ -284,7 +263,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
extractFiles(arch);
|
extractFiles(arch);
|
||||||
if (mode == FIX_ENV_MODE) {
|
if (mode == FIX_ENV_MODE) {
|
||||||
Shell.Sync.sh(
|
Shell.Sync.sh(
|
||||||
"cd " + install,
|
"cd " + installDir,
|
||||||
"sh update-binary extract",
|
"sh update-binary extract",
|
||||||
"rm -f update-binary magisk.apk",
|
"rm -f update-binary magisk.apk",
|
||||||
"cd /",
|
"cd /",
|
||||||
@ -292,13 +271,10 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
"/sbin/.core/mirror/bin/busybox --install -s /sbin/.core/busybox"
|
"/sbin/.core/mirror/bin/busybox --install -s /sbin/.core/busybox"
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
File boot = new File(install, "boot.img");
|
File patched = patchBoot();
|
||||||
SuFile patched_boot = new SuFile(install.getParent(), "new-boot.img");
|
if (patched == null)
|
||||||
|
|
||||||
if (!dumpBoot(boot) || !patchBoot(boot, patched_boot))
|
|
||||||
return false;
|
return false;
|
||||||
outputBoot(patched_boot);
|
outputBoot(patched);
|
||||||
|
|
||||||
console.add("- All done!");
|
console.add("- All done!");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -317,7 +293,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
// Running in FlashActivity
|
// Running in FlashActivity
|
||||||
FlashActivity activity = (FlashActivity) getActivity();
|
FlashActivity activity = (FlashActivity) getActivity();
|
||||||
if (!result) {
|
if (!result) {
|
||||||
Shell.Async.sh("rm -rf " + install);
|
Shell.Async.sh("rm -rf " + installDir);
|
||||||
console.add("! Installation failed");
|
console.add("! Installation failed");
|
||||||
activity.reboot.setVisibility(View.GONE);
|
activity.reboot.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
@ -40,8 +40,11 @@ public class ZipUtils {
|
|||||||
} else {
|
} else {
|
||||||
name = entry.getName();
|
name = entry.getName();
|
||||||
}
|
}
|
||||||
SuFile dest = new SuFile(folder, name);
|
File dest = new File(folder, name);
|
||||||
dest.getParentFile().mkdirs();
|
if (!dest.getParentFile().mkdirs()) {
|
||||||
|
dest = new SuFile(folder, name);
|
||||||
|
dest.getParentFile().mkdirs();
|
||||||
|
}
|
||||||
try (OutputStream out = new SuFileOutputStream(dest)) {
|
try (OutputStream out = new SuFileOutputStream(dest)) {
|
||||||
ShellUtils.pump(zipfile, out);
|
ShellUtils.pump(zipfile, out);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user