mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-04-16 11:21:24 +00:00
Root shell with no outputs
This commit is contained in:
parent
87ea2a2bef
commit
f4097a372b
@ -197,7 +197,7 @@ public class MagiskFragment extends Fragment
|
|||||||
@Override
|
@Override
|
||||||
public void onFinish() {
|
public void onFinish() {
|
||||||
progress.setMessage(getString(R.string.reboot_countdown, 0));
|
progress.setMessage(getString(R.string.reboot_countdown, 0));
|
||||||
magiskManager.rootShell.su(
|
magiskManager.rootShell.su_raw(
|
||||||
"mv -f " + uninstaller + " /cache/" + MagiskManager.UNINSTALLER,
|
"mv -f " + uninstaller + " /cache/" + MagiskManager.UNINSTALLER,
|
||||||
"mv -f " + utils + " /data/magisk/" + MagiskManager.UTIL_FUNCTIONS,
|
"mv -f " + utils + " /data/magisk/" + MagiskManager.UTIL_FUNCTIONS,
|
||||||
"reboot"
|
"reboot"
|
||||||
|
@ -154,7 +154,7 @@ public class MagiskLogFragment extends Fragment {
|
|||||||
return "";
|
return "";
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
magiskManager.rootShell.su("echo > " + MAGISK_LOG);
|
magiskManager.rootShell.su_raw("echo > " + MAGISK_LOG);
|
||||||
SnackbarMaker.make(txtLog, R.string.logs_cleared, Snackbar.LENGTH_SHORT).show();
|
SnackbarMaker.make(txtLog, R.string.logs_cleared, Snackbar.LENGTH_SHORT).show();
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ public class MagiskManager extends Application {
|
|||||||
File busybox = new File(getApplicationInfo().dataDir + "/busybox/busybox");
|
File busybox = new File(getApplicationInfo().dataDir + "/busybox/busybox");
|
||||||
if (!busybox.exists() || !TextUtils.equals(prefs.getString("busybox_version", ""), BUSYBOX_VERSION)) {
|
if (!busybox.exists() || !TextUtils.equals(prefs.getString("busybox_version", ""), BUSYBOX_VERSION)) {
|
||||||
busybox.getParentFile().mkdirs();
|
busybox.getParentFile().mkdirs();
|
||||||
rootShell.su(
|
rootShell.su_raw(
|
||||||
"cp -f " + new File(getApplicationInfo().nativeLibraryDir, "libbusybox.so") + " " + busybox,
|
"cp -f " + new File(getApplicationInfo().nativeLibraryDir, "libbusybox.so") + " " + busybox,
|
||||||
"chmod -R 755 " + busybox.getParent(),
|
"chmod -R 755 " + busybox.getParent(),
|
||||||
busybox + " --install -s " + busybox.getParent()
|
busybox + " --install -s " + busybox.getParent()
|
||||||
@ -148,7 +148,7 @@ public class MagiskManager extends Application {
|
|||||||
.putString("busybox_version", BUSYBOX_VERSION)
|
.putString("busybox_version", BUSYBOX_VERSION)
|
||||||
.apply();
|
.apply();
|
||||||
// Add busybox to PATH
|
// Add busybox to PATH
|
||||||
rootShell.su("PATH=$PATH:" + busybox.getParent());
|
rootShell.su_raw("PATH=$PATH:" + busybox.getParent());
|
||||||
|
|
||||||
// Create notification channel on Android O
|
// Create notification channel on Android O
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
@ -175,11 +175,11 @@ public class SettingsActivity extends Activity {
|
|||||||
case "hosts":
|
case "hosts":
|
||||||
enabled = prefs.getBoolean("hosts", false);
|
enabled = prefs.getBoolean("hosts", false);
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
magiskManager.rootShell.su(
|
magiskManager.rootShell.su_raw(
|
||||||
"cp -af /system/etc/hosts /magisk/.core/hosts",
|
"cp -af /system/etc/hosts /magisk/.core/hosts",
|
||||||
"mount -o bind /magisk/.core/hosts /system/etc/hosts");
|
"mount -o bind /magisk/.core/hosts /system/etc/hosts");
|
||||||
} else {
|
} else {
|
||||||
magiskManager.rootShell.su(
|
magiskManager.rootShell.su_raw(
|
||||||
"umount -l /system/etc/hosts",
|
"umount -l /system/etc/hosts",
|
||||||
"rm -f /magisk/.core/hosts");
|
"rm -f /magisk/.core/hosts");
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ public class FlashZip extends ParallelTask<Void, String, Integer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int cleanup(int ret) {
|
private int cleanup(int ret) {
|
||||||
magiskManager.rootShell.su(
|
magiskManager.rootShell.su_raw(
|
||||||
"rm -rf " + mCachedFile.getParent() + "/*",
|
"rm -rf " + mCachedFile.getParent() + "/*",
|
||||||
"rm -rf " + MagiskManager.TMP_FOLDER_PATH
|
"rm -rf " + MagiskManager.TMP_FOLDER_PATH
|
||||||
);
|
);
|
||||||
@ -146,7 +146,7 @@ public class FlashZip extends ParallelTask<Void, String, Integer> {
|
|||||||
new AlertDialogBuilder(activity)
|
new AlertDialogBuilder(activity)
|
||||||
.setTitle(R.string.reboot_title)
|
.setTitle(R.string.reboot_title)
|
||||||
.setMessage(R.string.reboot_msg)
|
.setMessage(R.string.reboot_msg)
|
||||||
.setPositiveButton(R.string.reboot, (dialogInterface, i) -> magiskManager.rootShell.su("reboot"))
|
.setPositiveButton(R.string.reboot, (dialogInterface, i) -> magiskManager.rootShell.su_raw("reboot"))
|
||||||
.setNegativeButton(R.string.no_thanks, null)
|
.setNegativeButton(R.string.no_thanks, null)
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ public class ProcessMagiskZip extends ParallelTask<Void, Void, Boolean> {
|
|||||||
@Override
|
@Override
|
||||||
protected Boolean doInBackground(Void... params) {
|
protected Boolean doInBackground(Void... params) {
|
||||||
if (Shell.rootAccess()) {
|
if (Shell.rootAccess()) {
|
||||||
magiskManager.rootShell.su("rm -f /dev/.magisk",
|
magiskManager.rootShell.su_raw("rm -f /dev/.magisk",
|
||||||
(mBoot != null) ? "echo \"BOOTIMAGE=" + mBoot + "\" >> /dev/.magisk" : "",
|
(mBoot != null) ? "echo \"BOOTIMAGE=" + mBoot + "\" >> /dev/.magisk" : "",
|
||||||
"echo \"KEEPFORCEENCRYPT=" + String.valueOf(mEnc) + "\" >> /dev/.magisk",
|
"echo \"KEEPFORCEENCRYPT=" + String.valueOf(mEnc) + "\" >> /dev/.magisk",
|
||||||
"echo \"KEEPVERITY=" + String.valueOf(mVerity) + "\" >> /dev/.magisk"
|
"echo \"KEEPVERITY=" + String.valueOf(mVerity) + "\" >> /dev/.magisk"
|
||||||
|
@ -18,12 +18,12 @@ public class Shell {
|
|||||||
// -1 = problematic/unknown issue; 0 = not rooted; 1 = properly rooted
|
// -1 = problematic/unknown issue; 0 = not rooted; 1 = properly rooted
|
||||||
public static int rootStatus;
|
public static int rootStatus;
|
||||||
|
|
||||||
private static boolean isInit = false;
|
|
||||||
|
|
||||||
private final Process rootShell;
|
private final Process rootShell;
|
||||||
private final DataOutputStream rootSTDIN;
|
private final DataOutputStream rootSTDIN;
|
||||||
private final DataInputStream rootSTDOUT;
|
private final DataInputStream rootSTDOUT;
|
||||||
|
|
||||||
|
private boolean isValid;
|
||||||
|
|
||||||
private Shell() {
|
private Shell() {
|
||||||
Process process;
|
Process process;
|
||||||
try {
|
try {
|
||||||
@ -34,15 +34,17 @@ public class Shell {
|
|||||||
rootShell = null;
|
rootShell = null;
|
||||||
rootSTDIN = null;
|
rootSTDIN = null;
|
||||||
rootSTDOUT = null;
|
rootSTDOUT = null;
|
||||||
|
isValid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rootStatus = 1;
|
rootStatus = 1;
|
||||||
|
isValid = true;
|
||||||
rootShell = process;
|
rootShell = process;
|
||||||
rootSTDIN = new DataOutputStream(rootShell.getOutputStream());
|
rootSTDIN = new DataOutputStream(rootShell.getOutputStream());
|
||||||
rootSTDOUT = new DataInputStream(rootShell.getInputStream());
|
rootSTDOUT = new DataInputStream(rootShell.getInputStream());
|
||||||
|
|
||||||
su("umask 022");
|
su_raw("umask 022");
|
||||||
List<String> ret = su("echo -BOC-", "id");
|
List<String> ret = su("echo -BOC-", "id");
|
||||||
|
|
||||||
if (ret.isEmpty()) {
|
if (ret.isEmpty()) {
|
||||||
@ -118,33 +120,43 @@ public class Shell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<String> su(String... commands) {
|
public List<String> su(String... commands) {
|
||||||
|
if (!isValid) return null;
|
||||||
List<String> res = new ArrayList<>();
|
List<String> res = new ArrayList<>();
|
||||||
su(res, commands);
|
su(res, commands);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void su(List<String> res, String... commands) {
|
public void su_raw(String... commands) {
|
||||||
try {
|
if (!isValid) return;
|
||||||
rootShell.exitValue();
|
|
||||||
return; // The process is dead, return
|
|
||||||
} catch (IllegalThreadStateException ignored) {
|
|
||||||
// This should be the expected result
|
|
||||||
}
|
|
||||||
synchronized (rootShell) {
|
synchronized (rootShell) {
|
||||||
StreamGobbler STDOUT = new StreamGobbler(rootSTDOUT, Collections.synchronizedList(res), true);
|
|
||||||
STDOUT.start();
|
|
||||||
try {
|
try {
|
||||||
for (String command : commands) {
|
for (String command : commands) {
|
||||||
rootSTDIN.write((command + "\n").getBytes("UTF-8"));
|
rootSTDIN.write((command + "\n").getBytes("UTF-8"));
|
||||||
rootSTDIN.flush();
|
rootSTDIN.flush();
|
||||||
}
|
}
|
||||||
rootSTDIN.write(("echo \'-root-done-\'\n").getBytes("UTF-8"));
|
} catch (IOException e) {
|
||||||
rootSTDIN.flush();
|
|
||||||
STDOUT.join();
|
|
||||||
} catch (InterruptedException | IOException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
rootShell.destroy();
|
rootShell.destroy();
|
||||||
|
isValid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void su(List<String> output, String... commands) {
|
||||||
|
if (!isValid) return;
|
||||||
|
try {
|
||||||
|
rootShell.exitValue();
|
||||||
|
isValid = false;
|
||||||
|
return; // The process is dead, return
|
||||||
|
} catch (IllegalThreadStateException ignored) {
|
||||||
|
// This should be the expected result
|
||||||
|
}
|
||||||
|
synchronized (rootShell) {
|
||||||
|
StreamGobbler STDOUT = new StreamGobbler(rootSTDOUT, output, true);
|
||||||
|
STDOUT.start();
|
||||||
|
su_raw(commands);
|
||||||
|
su_raw("echo \'-root-done-\'");
|
||||||
|
try { STDOUT.join(); } catch (InterruptedException ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,13 +29,17 @@ public class StreamGobbler extends Thread {
|
|||||||
* @param outputList {@literal List<String>} to write to, or null
|
* @param outputList {@literal List<String>} to write to, or null
|
||||||
*/
|
*/
|
||||||
public StreamGobbler(InputStream inputStream, List<String> outputList) {
|
public StreamGobbler(InputStream inputStream, List<String> outputList) {
|
||||||
|
try {
|
||||||
|
while (inputStream.available() != 0) {
|
||||||
|
inputStream.skip(inputStream.available());
|
||||||
|
}
|
||||||
|
} catch (IOException ignored) {}
|
||||||
reader = new BufferedReader(new InputStreamReader(inputStream));
|
reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||||
writer = outputList;
|
writer = outputList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StreamGobbler(InputStream inputStream, List<String> outputList, boolean root) {
|
public StreamGobbler(InputStream inputStream, List<String> outputList, boolean root) {
|
||||||
reader = new BufferedReader(new InputStreamReader(inputStream));
|
this(inputStream, outputList);
|
||||||
writer = outputList;
|
|
||||||
isRoot = root;
|
isRoot = root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +52,7 @@ public class StreamGobbler extends Thread {
|
|||||||
if (TextUtils.equals(line, "-root-done-"))
|
if (TextUtils.equals(line, "-root-done-"))
|
||||||
return;
|
return;
|
||||||
writer.add(line);
|
writer.add(line);
|
||||||
Logger.shell(isRoot, "OUT: " + line);
|
Logger.shell(isRoot, line);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// reader probably closed, expected exit condition
|
// reader probably closed, expected exit condition
|
||||||
|
@ -52,12 +52,12 @@ public class Utils {
|
|||||||
public static void createFile(Shell shell, String path) {
|
public static void createFile(Shell shell, String path) {
|
||||||
String folder = path.substring(0, path.lastIndexOf('/'));
|
String folder = path.substring(0, path.lastIndexOf('/'));
|
||||||
String command = "mkdir -p " + folder + " 2>/dev/null; touch " + path + " 2>/dev/null; if [ -f \"" + path + "\" ]; then echo true; else echo false; fi";
|
String command = "mkdir -p " + folder + " 2>/dev/null; touch " + path + " 2>/dev/null; if [ -f \"" + path + "\" ]; then echo true; else echo false; fi";
|
||||||
shell.su(command);
|
shell.su_raw(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeItem(Shell shell, String path) {
|
public static void removeItem(Shell shell, String path) {
|
||||||
String command = "rm -rf " + path + " 2>/dev/null; if [ -e " + path + " ]; then echo false; else echo true; fi";
|
String command = "rm -rf " + path + " 2>/dev/null; if [ -e " + path + " ]; then echo false; else echo true; fi";
|
||||||
shell.su(command);
|
shell.su_raw(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> getModList(Shell shell, String path) {
|
public static List<String> getModList(Shell shell, String path) {
|
||||||
@ -66,14 +66,8 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> readFile(Shell shell, String path) {
|
public static List<String> readFile(Shell shell, String path) {
|
||||||
List<String> ret;
|
|
||||||
String command = "cat " + path;
|
String command = "cat " + path;
|
||||||
if (Shell.rootAccess()) {
|
return shell.su(command);
|
||||||
ret = shell.su(command);
|
|
||||||
} else {
|
|
||||||
ret = Shell.sh(command);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void dlAndReceive(Context context, DownloadReceiver receiver, String link, String filename) {
|
public static void dlAndReceive(Context context, DownloadReceiver receiver, String link, String filename) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user