mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-26 00:27:39 +00:00
Update boot signing in InstallMagisk
This commit is contained in:
parent
adf930f126
commit
fdd700f3e5
@ -19,15 +19,13 @@ public class DownloadBusybox extends ParallelTask<Void, Void, Void> {
|
|||||||
private static final String BUSYBOX_ARM = "https://github.com/topjohnwu/ndk-busybox/releases/download/1.27.2/busybox-arm";
|
private static final String BUSYBOX_ARM = "https://github.com/topjohnwu/ndk-busybox/releases/download/1.27.2/busybox-arm";
|
||||||
private static final String BUSYBOX_X86 = "https://github.com/topjohnwu/ndk-busybox/releases/download/1.27.2/busybox-x86";
|
private static final String BUSYBOX_X86 = "https://github.com/topjohnwu/ndk-busybox/releases/download/1.27.2/busybox-x86";
|
||||||
|
|
||||||
private File busybox;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(Void... voids) {
|
protected Void doInBackground(Void... voids) {
|
||||||
Context context = MagiskManager.get();
|
Context context = MagiskManager.get();
|
||||||
busybox = new File(context.getCacheDir(), "busybox");
|
File busybox = new File(context.getCacheDir(), "busybox");
|
||||||
Utils.removeItem(context.getApplicationInfo().dataDir + "/busybox");
|
Utils.removeItem(context.getApplicationInfo().dataDir + "/busybox");
|
||||||
try {
|
try (FileOutputStream out = new FileOutputStream(busybox)) {
|
||||||
FileOutputStream out = new FileOutputStream(busybox);
|
|
||||||
HttpURLConnection conn = WebService.request(
|
HttpURLConnection conn = WebService.request(
|
||||||
Build.SUPPORTED_32_BIT_ABIS[0].contains("x86") ?
|
Build.SUPPORTED_32_BIT_ABIS[0].contains("x86") ?
|
||||||
BUSYBOX_X86 :
|
BUSYBOX_X86 :
|
||||||
@ -36,12 +34,7 @@ public class DownloadBusybox extends ParallelTask<Void, Void, Void> {
|
|||||||
);
|
);
|
||||||
if (conn == null) throw new IOException();
|
if (conn == null) throw new IOException();
|
||||||
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
|
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
|
||||||
byte[] buffer = new byte[4096];
|
Utils.inToOut(bis, out);
|
||||||
int len;
|
|
||||||
while ((len = bis.read(buffer)) != -1) {
|
|
||||||
out.write(buffer, 0, len);
|
|
||||||
}
|
|
||||||
out.close();
|
|
||||||
conn.disconnect();
|
conn.disconnect();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -64,10 +64,7 @@ public class FlashZip extends ParallelTask<Void, Void, Integer> {
|
|||||||
) {
|
) {
|
||||||
if (in == null) throw new FileNotFoundException();
|
if (in == null) throw new FileNotFoundException();
|
||||||
InputStream buf= new BufferedInputStream(in);
|
InputStream buf= new BufferedInputStream(in);
|
||||||
byte buffer[] = new byte[4096];
|
Utils.inToOut(buf, out);
|
||||||
int length;
|
|
||||||
while ((length = buf.read(buffer)) > 0)
|
|
||||||
out.write(buffer, 0, length);
|
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
mList.add("! Invalid Uri");
|
mList.add("! Invalid Uri");
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package com.topjohnwu.magisk.asyncs;
|
package com.topjohnwu.magisk.asyncs;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.res.AssetManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.topjohnwu.crypto.SignBoot;
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
import com.topjohnwu.magisk.container.AdaptiveList;
|
import com.topjohnwu.magisk.container.AdaptiveList;
|
||||||
import com.topjohnwu.magisk.container.TarEntry;
|
import com.topjohnwu.magisk.container.TarEntry;
|
||||||
@ -103,6 +105,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
ZipUtils.unzip(buf, install, "chromeos/", false);
|
ZipUtils.unzip(buf, install, "chromeos/", false);
|
||||||
buf.reset();
|
buf.reset();
|
||||||
ZipUtils.unzip(buf, install, "META-INF/com/google/android/update-binary", true);
|
ZipUtils.unzip(buf, install, "META-INF/com/google/android/update-binary", true);
|
||||||
|
buf.close();
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
mList.add("! Invalid Uri");
|
mList.add("! Invalid Uri");
|
||||||
throw e;
|
throw e;
|
||||||
@ -111,10 +114,9 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
File boot;
|
File boot = new File(install, "boot.img");
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case PATCH_MODE:
|
case PATCH_MODE:
|
||||||
boot = new File(install, "boot.img");
|
|
||||||
// Copy boot image to local
|
// Copy boot image to local
|
||||||
try (
|
try (
|
||||||
InputStream in = mm.getContentResolver().openInputStream(mBootImg);
|
InputStream in = mm.getContentResolver().openInputStream(mBootImg);
|
||||||
@ -136,10 +138,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
// Direct copy raw image
|
// Direct copy raw image
|
||||||
source = new BufferedInputStream(in);
|
source = new BufferedInputStream(in);
|
||||||
}
|
}
|
||||||
byte buffer[] = new byte[1024];
|
Utils.inToOut(source, out);
|
||||||
int length;
|
|
||||||
while ((length = source.read(buffer)) > 0)
|
|
||||||
out.write(buffer, 0, length);
|
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
mList.add("! Invalid Uri");
|
mList.add("! Invalid Uri");
|
||||||
throw e;
|
throw e;
|
||||||
@ -147,26 +146,41 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
mList.add("! Copy failed");
|
mList.add("! Copy failed");
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
mList.add("- Use boot image: " + boot);
|
||||||
break;
|
break;
|
||||||
case DIRECT_MODE:
|
case DIRECT_MODE:
|
||||||
boot = new File(mBootLocation);
|
try (OutputStream out = new FileOutputStream(boot)) {
|
||||||
|
Process process = Runtime.getRuntime().exec(new String[] { "su", "-c", "cat " + mBootLocation });
|
||||||
|
Utils.inToOut(process.getInputStream(), out);
|
||||||
|
process.waitFor();
|
||||||
|
process.destroy();
|
||||||
|
} catch (Exception e) {
|
||||||
|
mList.add("! Dump boot image failed");
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
mList.add("- Use boot image: " + mBootLocation);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mList.add("- Use boot image: " + boot);
|
boolean isSigned;
|
||||||
|
try (InputStream in = new FileInputStream(boot)) {
|
||||||
Shell shell;
|
isSigned = SignBoot.verifySignature(in, null);
|
||||||
if (mode == PATCH_MODE && Shell.rootAccess()) {
|
if (isSigned) {
|
||||||
// Force non-root shell
|
mList.add("- Signed boot image detected");
|
||||||
shell = new Shell("sh");
|
}
|
||||||
} else {
|
} catch (Exception e) {
|
||||||
shell = Shell.getShell();
|
mList.add("! Unable to check signature");
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shell == null)
|
// Force non-root shell
|
||||||
return false;
|
Shell shell;
|
||||||
|
if (Shell.rootAccess())
|
||||||
|
shell = new Shell("sh");
|
||||||
|
else
|
||||||
|
shell = Shell.getShell();
|
||||||
|
|
||||||
// Patch boot image
|
// Patch boot image
|
||||||
shell.run(mList,
|
shell.run(mList,
|
||||||
@ -180,6 +194,22 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
File patched_boot = new File(install, "new-boot.img");
|
File patched_boot = new File(install, "new-boot.img");
|
||||||
|
|
||||||
|
if (isSigned) {
|
||||||
|
mList.add("- Signing boot image");
|
||||||
|
File signed = new File(install, "signed.img");
|
||||||
|
AssetManager assets = mm.getAssets();
|
||||||
|
try (
|
||||||
|
InputStream in = new FileInputStream(patched_boot);
|
||||||
|
OutputStream out = new BufferedOutputStream(new FileOutputStream(signed));
|
||||||
|
InputStream keyIn = assets.open(ZipUtils.PRIVATE_KEY_NAME);
|
||||||
|
InputStream certIn = assets.open(ZipUtils.PUBLIC_KEY_NAME)
|
||||||
|
) {
|
||||||
|
SignBoot.doSignature("/boot", in, out, keyIn, certIn);
|
||||||
|
}
|
||||||
|
shell.run_raw(false, "mv -f " + signed + " " + patched_boot);
|
||||||
|
}
|
||||||
|
|
||||||
mList.add("");
|
mList.add("");
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case PATCH_MODE:
|
case PATCH_MODE:
|
||||||
@ -190,17 +220,13 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
|
|||||||
shell.run_raw(false, "cp -f " + patched_boot + " " + dest);
|
shell.run_raw(false, "cp -f " + patched_boot + " " + dest);
|
||||||
break;
|
break;
|
||||||
case ".img.tar":
|
case ".img.tar":
|
||||||
TarOutputStream tar = new TarOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
|
try (
|
||||||
tar.putNextEntry(new TarEntry(patched_boot, "boot.img"));
|
TarOutputStream tar = new TarOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
|
||||||
byte buffer[] = new byte[4096];
|
InputStream in = new FileInputStream(patched_boot)
|
||||||
BufferedInputStream in = new BufferedInputStream(new FileInputStream(patched_boot));
|
) {
|
||||||
int len;
|
tar.putNextEntry(new TarEntry(patched_boot, "boot.img"));
|
||||||
while ((len = in.read(buffer)) != -1) {
|
Utils.inToOut(in, tar);
|
||||||
tar.write(buffer, 0, len);
|
|
||||||
}
|
}
|
||||||
tar.flush();
|
|
||||||
tar.close();
|
|
||||||
in.close();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mList.add("*********************************");
|
mList.add("*********************************");
|
||||||
|
@ -54,8 +54,6 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
|
|||||||
JarOutputStream dest = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(output)));
|
JarOutputStream dest = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(output)));
|
||||||
JarEntry entry;
|
JarEntry entry;
|
||||||
String path;
|
String path;
|
||||||
int size;
|
|
||||||
byte buffer[] = new byte[4096];
|
|
||||||
while ((entry = source.getNextJarEntry()) != null) {
|
while ((entry = source.getNextJarEntry()) != null) {
|
||||||
// Remove the top directory from the path
|
// Remove the top directory from the path
|
||||||
path = entry.getName().substring(entry.getName().indexOf("/") + 1);
|
path = entry.getName().substring(entry.getName().indexOf("/") + 1);
|
||||||
@ -68,9 +66,7 @@ public class ProcessRepoZip extends ParallelTask<Void, Object, Boolean> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dest.putNextEntry(new JarEntry(path));
|
dest.putNextEntry(new JarEntry(path));
|
||||||
while((size = source.read(buffer)) != -1) {
|
Utils.inToOut(source, dest);
|
||||||
dest.write(buffer, 0, size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
source.close();
|
source.close();
|
||||||
dest.close();
|
dest.close();
|
||||||
|
@ -28,6 +28,9 @@ import com.topjohnwu.magisk.components.SnackbarMaker;
|
|||||||
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
import com.topjohnwu.magisk.receivers.DownloadReceiver;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -215,4 +218,13 @@ public class Utils {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void inToOut(InputStream in, OutputStream out) throws IOException {
|
||||||
|
int read;
|
||||||
|
byte buffer[] = new byte[4096];
|
||||||
|
while ((read = in.read(buffer)) > 0) {
|
||||||
|
out.write(buffer, 0, read);
|
||||||
|
}
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
}
|
}
|
@ -16,8 +16,8 @@ import java.util.jar.JarInputStream;
|
|||||||
|
|
||||||
public class ZipUtils {
|
public class ZipUtils {
|
||||||
// File name in assets
|
// File name in assets
|
||||||
static final String PUBLIC_KEY_NAME = "public.certificate.x509.pem";
|
public static final String PUBLIC_KEY_NAME = "public.certificate.x509.pem";
|
||||||
static final String PRIVATE_KEY_NAME = "private.key.pk8";
|
public static final String PRIVATE_KEY_NAME = "private.key.pk8";
|
||||||
|
|
||||||
static {
|
static {
|
||||||
System.loadLibrary("zipadjust");
|
System.loadLibrary("zipadjust");
|
||||||
@ -32,7 +32,6 @@ public class ZipUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void unzip(InputStream zip, File folder, String path, boolean junkPath) throws Exception {
|
public static void unzip(InputStream zip, File folder, String path, boolean junkPath) throws Exception {
|
||||||
byte data[] = new byte[4096];
|
|
||||||
try {
|
try {
|
||||||
JarInputStream zipfile = new JarInputStream(zip);
|
JarInputStream zipfile = new JarInputStream(zip);
|
||||||
JarEntry entry;
|
JarEntry entry;
|
||||||
@ -49,13 +48,9 @@ public class ZipUtils {
|
|||||||
}
|
}
|
||||||
File dest = new File(folder, name);
|
File dest = new File(folder, name);
|
||||||
dest.getParentFile().mkdirs();
|
dest.getParentFile().mkdirs();
|
||||||
FileOutputStream out = new FileOutputStream(dest);
|
try (FileOutputStream out = new FileOutputStream(dest)) {
|
||||||
int count;
|
Utils.inToOut(zipfile, out);
|
||||||
while ((count = zipfile.read(data)) != -1) {
|
|
||||||
out.write(data, 0, count);
|
|
||||||
}
|
}
|
||||||
out.flush();
|
|
||||||
out.close();
|
|
||||||
}
|
}
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -15,8 +15,6 @@ import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
|
|||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user