Support .img.tar format for ODIN

This commit is contained in:
topjohnwu 2017-09-03 17:24:05 +08:00
parent d4a10e2873
commit 04a589722c
7 changed files with 97 additions and 13 deletions

View File

@ -62,6 +62,7 @@ dependencies {
implementation 'com.atlassian.commonmark:commonmark:0.9.0'
implementation 'org.bouncycastle:bcprov-jdk15on:1.57'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.57'
implementation 'org.kamranzafar:jtar:2.3'
implementation 'com.google.android.gms:play-services-safetynet:9.0.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}

View File

@ -100,6 +100,7 @@ public class MagiskManager extends Application {
public int suNamespaceMode;
public String localeConfig;
public int updateChannel;
public String bootFormat;
// Global resources
public SharedPreferences prefs;
@ -176,6 +177,7 @@ public class MagiskManager extends Application {
updateNotification = prefs.getBoolean("notification", true);
updateChannel = Utils.getPrefsInt(prefs, "update_channel", CheckUpdates.STABLE_CHANNEL);
bootFormat = prefs.getString("boot_format", ".img");
}
public void toast(String msg, int duration) {
@ -225,6 +227,7 @@ public class MagiskManager extends Application {
.putString("mnt_ns", String.valueOf(suNamespaceMode))
.putString("update_channel", String.valueOf(updateChannel))
.putString("locale", localeConfig)
.putString("boot_format", bootFormat)
.apply();
// Create notification channel on Android O

View File

@ -8,10 +8,16 @@ import android.text.TextUtils;
import com.topjohnwu.magisk.MagiskManager;
import com.topjohnwu.magisk.utils.AdaptiveList;
import com.topjohnwu.magisk.utils.Shell;
import com.topjohnwu.magisk.utils.TarEntry;
import com.topjohnwu.magisk.utils.ZipUtils;
import org.kamranzafar.jtar.TarOutputStream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
@ -135,7 +141,7 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
getShell().sh(mList,
"cd " + install,
"KEEPFORCEENCRYPT=" + mKeepEnc + " KEEPVERITY=" + mKeepVerity + " sh " +
"update-binary indep boot_patch.sh " + boot + " 2>&1" +
"update-binary indep boot_patch.sh " + boot +
" && echo 'Success!' || echo 'Failed!'"
);
@ -146,10 +152,36 @@ public class InstallMagisk extends ParallelTask<Void, Void, Boolean> {
mList.add("");
switch (mode) {
case PATCH_MODE:
// Move boot image
File dest = new File(Environment.getExternalStorageDirectory() + "/MagiskManager/" + "patched_boot.img");
File dest = new File(Environment.getExternalStorageDirectory() + "/MagiskManager/patched_boot" + mm.bootFormat);
dest.getParentFile().mkdirs();
getShell().sh_raw("cp " + patched_boot + " " + dest);
switch (mm.bootFormat) {
case ".img":
getShell().sh_raw("cp -f " + patched_boot + " " + dest);
break;
case ".img.tar":
// Workaround root shell issues so we can access the file through Java
if (Shell.rootAccess()) {
// Get non-root UID
int uid = mm.getApplicationInfo().uid;
// Get app selabel
String selabel = getShell().su("/system/bin/ls -dZ " + install + " | cut -d' ' -f1").get(0);
getShell().su(
"chcon " + selabel + " " + patched_boot,
"chown " + uid + "." + uid + " " + patched_boot);
}
TarOutputStream tar = new TarOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
tar.putNextEntry(new TarEntry(patched_boot, "boot.img"));
byte buffer[] = new byte[4096];
BufferedInputStream in = new BufferedInputStream(new FileInputStream(patched_boot));
int len;
while ((len = in.read(buffer)) != -1) {
tar.write(buffer, 0, len);
}
tar.flush();
tar.close();
in.close();
break;
}
mList.add("*********************************");
mList.add(" Patched Boot Image is placed in ");
mList.add(" " + dest + " ");

View File

@ -0,0 +1,27 @@
package com.topjohnwu.magisk.utils;
import org.kamranzafar.jtar.TarHeader;
import java.io.File;
public class TarEntry extends org.kamranzafar.jtar.TarEntry {
public TarEntry(File file, String entryName) {
super(file, entryName);
}
public TarEntry(byte[] headerBuf) {
super(headerBuf);
}
/*
* Workaround missing java.nio.file.attribute.PosixFilePermission
* Simply just assign a default permission to the file
* */
@Override
public void extractTarHeader(String entryName) {
int permissions = file.isDirectory() ? 040755 : 0100644;
header = TarHeader.createHeader(entryName, file.length(), file.lastModified() / 1000, file.isDirectory(), permissions);
}
}

View File

@ -77,4 +77,9 @@
<item>@string/settings_update_beta</item>
</string-array>
<string-array name="boot_formats">
<item>.img</item>
<item>.img.tar</item>
</string-array>
</resources>

View File

@ -156,9 +156,12 @@
<string name="settings_hide_manager_summary">Temporarily hide Magisk Manager.\nThis will install a new app called \"Unhide Magisk Manager\"</string>
<string name="language">Language</string>
<string name="system_default">(System Default)</string>
<string name="settings_update">Update Settings</string>
<string name="settings_update_channel_title">Update Channel</string>
<string name="settings_update_stable">Stable</string>
<string name="settings_update_beta">Beta</string>
<string name="settings_boot_format_title">Patched Boot Output File Format</string>
<string name="settings_boot_format_summary">Select the output file format of the patched boot image\nChoose .img to flash through fastboot/download mode\nChoose .img.tar to flash with ODIN</string>
<string name="settings_core_only_title">Magisk Core Only Mode</string>
<string name="settings_core_only_summary">Enable only core features, all modules will not be loaded. MagiskSU, MagiskHide, and systemless hosts will still be enabled</string>

View File

@ -10,6 +10,22 @@
android:title="@string/settings_dark_theme_title"
android:summary="@string/settings_dark_theme_summary" />
<Preference
android:key="clear"
android:title="@string/settings_clear_cache_title"
android:summary="@string/settings_clear_cache_summary" />
<Preference
android:key="hide"
android:title="@string/settings_hide_manager_title"
android:summary="@string/settings_hide_manager_summary" />
</PreferenceCategory>
<PreferenceCategory
android:key="update"
android:title="@string/settings_update">
<SwitchPreference
android:key="notification"
android:title="@string/settings_notification_title"
@ -21,15 +37,12 @@
android:entries="@array/update_channel"
android:entryValues="@array/value_array" />
<Preference
android:key="clear"
android:title="@string/settings_clear_cache_title"
android:summary="@string/settings_clear_cache_summary" />
<Preference
android:key="hide"
android:title="@string/settings_hide_manager_title"
android:summary="@string/settings_hide_manager_summary" />
<ListPreference
android:key="boot_format"
android:title="@string/settings_boot_format_title"
android:entries="@array/boot_formats"
android:entryValues="@array/boot_formats"
android:summary="@string/settings_boot_format_summary"/>
</PreferenceCategory>