Example #1
0
        public static bool canRunRootCommands()
        {
            bool    retval = false;
            Process suProcess;

            try
            {
                suProcess = Runtime.GetRuntime().Exec("su");
                var os    = new Java.IO.DataOutputStream(suProcess.OutputStream);
                var osRes = new Java.IO.DataInputStream(suProcess.InputStream);
                if (null != os && null != osRes)
                {
                    os.WriteBytes("id\n");
                    os.Flush();
                    string currUid = osRes.ReadLine();
                    bool   exitSu  = false;
                    if (null == currUid)
                    {
                        retval = false;
                        exitSu = false;
                        Console.WriteLine("Can't get root access or denied by user");
                    }
                    else if (true == currUid.Contains("uid=0"))
                    {
                        retval = true;
                        exitSu = true;
                        Console.WriteLine("Root access granted");
                    }
                    else
                    {
                        retval = false;
                        exitSu = true;
                        Console.WriteLine("Root access rejected: " + currUid);
                    }

                    if (exitSu)
                    {
                        os.WriteBytes("exit\n");
                        os.Flush();
                    }
                }
            }
            catch (Java.Lang.Exception e)
            {
                retval = false;
                Console.WriteLine("Root access rejected [" + e.Class.Name + "] : " + e.Message);
            }

            return(retval);
        }
Example #2
0
		public static bool canRunRootCommands()
		{
			bool retval = false;
			Process suProcess;
			try
			{
				suProcess = Runtime.GetRuntime().Exec("su");
				var os = new Java.IO.DataOutputStream(suProcess.OutputStream);
				var osRes = new Java.IO.DataInputStream(suProcess.InputStream);
				if (null != os && null != osRes)
				{
					os.WriteBytes("id\n");
					os.Flush();
					string currUid = osRes.ReadLine();
					bool exitSu = false;
					if (null == currUid)
					{
						retval = false;
						exitSu = false;
						Console.WriteLine("Can't get root access or denied by user");
					}
					else if (true == currUid.Contains("uid=0"))
					{
						retval = true;
						exitSu = true;
						Console.WriteLine("Root access granted");
					}
					else
					{
						retval = false;
						exitSu = true;
						Console.WriteLine("Root access rejected: " + currUid);
					}

					if (exitSu)
					{
						os.WriteBytes("exit\n");
						os.Flush();
					}
				}
			}
			catch (Java.Lang.Exception e)
			{
				retval = false;
				Console.WriteLine("Root access rejected [" + e.Class.Name + "] : " + e.Message);
			}

			return retval;
		}
Example #3
0
        /**
         * <p>
         * Runs commands using the supplied shell, and returns the output, or null
         * in case of errors.
         * </p>
         * <p>
         * Note that due to compatibility with older Android versions, wantSTDERR is
         * not implemented using redirectErrorStream, but rather appended to the
         * output. STDOUT and STDERR are thus not guaranteed to be in the correct
         * order in the output.
         * </p>
         * <p>
         * Note as well that this code will intentionally crash when run in debug
         * mode from the main thread of the application. You should always execute
         * shell commands from a background thread.
         * </p>
         * <p>
         * When in debug mode, the code will also excessively log the commands
         * passed to and the output returned from the shell.
         * </p>
         * <p>
         * Though this function uses background threads to gobble STDOUT and STDERR
         * so a deadlock does not occur if the shell produces massive output, the
         * output is still stored in a List&lt;String&gt;, and as such doing
         * something like <em>'ls -lR /'</em> will probably have you run out of
         * memory.
         * </p>
         *
         * @param shell The shell to use for executing the commands
         * @param commands The commands to execute
         * @param environment List of all environment variables (in 'key=value'
         *            format) or null for defaults
         * @param wantSTDERR Return STDERR in the output ?
         * @return Output of the commands, or null in case of an error
         */
        public static List<string> run(string shell, string[] commands, string[] environment, bool wantSTDERR)
        {
            string shellUpper = shell.ToUpperInvariant (); //.ToUpperCase(Locale.ENGLISH);

            if (Debug.getSanityChecksEnabledEffective () && Debug.onMainThread ()) {
                // check if we're running in the main thread, and if so, crash if
                // we're in debug mode, to let the developer know attention is
                // needed here.

                Debug.log (ShellOnMainThreadException.EXCEPTION_COMMAND);
            // vhe				throw new ShellOnMainThreadException (ShellOnMainThreadException.EXCEPTION_COMMAND);
            }
            Debug.logCommand (string.Format ("[{0}] START", shellUpper));

            var res = Java.Util.Collections.SynchronizedList (new System.Collections.ArrayList ());

            try {
                // Combine passed environment with system environment
                if (environment != null) {
                    var newEnvironment = new Dictionary<string, string> (global::Java.Lang.JavaSystem.Getenv ());
                    //int split;
                    var split = new char[]{ '=' };
                    foreach (string entry in environment) {
                        var splat = entry.Split (split, 1, StringSplitOptions.RemoveEmptyEntries);
                        if (splat != null && splat.Length == 2) {
                            newEnvironment [splat [0]] = splat [1];
                        }
                    }
            //				int i = 0;
            //					environment = new String[newEnvironment.size()];
            //					foreach (Map.Entry<String, String> entry in newEnvironment.entrySet()) {
            //						environment[i] = entry.getKey() + "=" + entry.getValue();
            //						i++;
            //					}
                    environment = newEnvironment.Select (x => string.Format ("{0}={1}", x.Key, x.Value)).ToArray ();

                }

                // setup our process, retrieve STDIN stream, and STDOUT/STDERR
                // gobblers
                Process process = Runtime.GetRuntime ().Exec (shell, environment);
                var STDIN = new Java.IO.DataOutputStream (process.OutputStream);
                StreamGobbler STDOUT = new StreamGobbler (shellUpper + "-", process.InputStream, res);
                StreamGobbler STDERR = new StreamGobbler (shellUpper + "*", process.ErrorStream, wantSTDERR ? res : null);

                // start gobbling and write our commands to the shell
                STDOUT.Start ();
                STDERR.Start ();
                try {
                    foreach (string write in commands) {
                        Debug.logCommand (string.Format ("[{0}+] {1}", shellUpper, write));
                        STDIN.Write ((write + "\n").getBytes ("UTF-8"));
                        STDIN.Flush ();
                    }
                    STDIN.Write ("exit\n".getBytes ("UTF-8"));
                    STDIN.Flush ();
                } catch (System.Exception e) {
                    if (e.ToString ().Contains ("EPIPE")) {
                        // method most horrid to catch broken pipe, in which case we
                        // do nothing. the command is not a shell, the shell closed
                        // STDIN, the script already contained the exit command, etc.
                        // these cases we want the output instead of returning null
                    } else {
                        // other issues we don't know how to handle, leads to
                        // returning null
                        throw;
                    }
                }

                // wait for our process to finish, while we gobble away in the
                // background
                process.WaitFor ();

                // make sure our threads are done gobbling, our streams are closed,
                // and the process is destroyed - while the latter two shouldn't be
                // needed in theory, and may even produce warnings, in "normal" Java
                // they are required for guaranteed cleanup of resources, so lets be
                // safe and do this on Android as well
                try {
                    STDIN.Close ();
                } catch (System.Exception e) {
                    // might be closed already
                }
                STDOUT.Join ();
                STDERR.Join ();
                process.Destroy ();

                // in case of su, 255 usually indicates access denied
                if (SU.isSU (shell) && (process.ExitValue() != 255)) {  // vhe
                    res = null;
                }
            } catch (Java.IO.IOException e) {
                // shell probably not found
                res = null;
            } catch (InterruptedException e) {
                // this should really be re-thrown
                res = null;
            }

            Debug.logCommand (string.Format ("[{0}%] END", shell.ToUpperInvariant ()));
            var result = new List<string> ();
            foreach (var r in res)
                result.Add (r.ToString ());
            return result;
        }
Example #4
0
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            // set views
            btnPush = FindViewById<Button>(Resource.Id.btn_pushDB);
            btnSettings = FindViewById<Button>(Resource.Id.btn_settings);
            layout_settingsOK = FindViewById<LinearLayout>(Resource.Id.layout_settingsOK);

            btnPush.Click += async delegate
            {
                //btnPush.Text = "";
                string smsdb = "/data/data/com.android.providers.telephony/databases/mmssms.db";
                //btnPush.Text = "copying db to sdcard";
                var p = Java.Lang.Runtime.GetRuntime().Exec("su");
                var os = new Java.IO.DataOutputStream(p.OutputStream);
                var osRes = new Java.IO.DataInputStream(p.InputStream);
                var cmd = "cp " + smsdb + " /sdcard/dev/tmp/";
                os.WriteBytes(cmd + '\n');
                os.Flush();
                //string msg = osRes.ReadLine();
                //btnPush.Text = "maybe copied to sdcard";

                HttpResponseMessage res;
                bool isGood;
                string msg;
                string localsmsdb = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, "dev/tmp/mmssms.db");
                using (var stream = File.OpenRead(localsmsdb))
                {
                    using (HttpClient httpClient = new HttpClient(
                        new HttpClientHandler()
                        {
                            Credentials = new NetworkCredential(user,pass),
                            PreAuthenticate = true
                        })
                    )
                    {
                        try
                        {
                            isGood = true;
                            res = await httpClient.PutAsync(remotePath,new StreamContent(stream));
                            res.EnsureSuccessStatusCode();
                            msg="OK";
                        }
                        catch (Exception ex)
                        {
                            isGood = false;
                            msg = ex.Message;
                        }

                    }
                }
                btnPush.Text = string.Format("{0} => {1}", isGood, msg);
            };

            btnSettings.Click += (sender, e)=>
            {
                var intent = new Intent(this, typeof(Settings));
                StartActivity(intent);

            };
        }
Example #5
0
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            // set views
            btnPush           = FindViewById <Button>(Resource.Id.btn_pushDB);
            btnSettings       = FindViewById <Button>(Resource.Id.btn_settings);
            layout_settingsOK = FindViewById <LinearLayout>(Resource.Id.layout_settingsOK);


            btnPush.Click += async delegate
            {
                //btnPush.Text = "";
                string smsdb = "/data/data/com.android.providers.telephony/databases/mmssms.db";
                //btnPush.Text = "copying db to sdcard";
                var p     = Java.Lang.Runtime.GetRuntime().Exec("su");
                var os    = new Java.IO.DataOutputStream(p.OutputStream);
                var osRes = new Java.IO.DataInputStream(p.InputStream);
                var cmd   = "cp " + smsdb + " /sdcard/dev/tmp/";
                os.WriteBytes(cmd + '\n');
                os.Flush();
                //string msg = osRes.ReadLine();
                //btnPush.Text = "maybe copied to sdcard";

                HttpResponseMessage res;
                bool   isGood;
                string msg;
                string localsmsdb = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, "dev/tmp/mmssms.db");
                using (var stream = File.OpenRead(localsmsdb))
                {
                    using (HttpClient httpClient = new HttpClient(
                               new HttpClientHandler()
                    {
                        Credentials = new NetworkCredential(user, pass),
                        PreAuthenticate = true
                    })
                           )
                    {
                        try
                        {
                            isGood = true;
                            res    = await httpClient.PutAsync(remotePath, new StreamContent(stream));

                            res.EnsureSuccessStatusCode();
                            msg = "OK";
                        }
                        catch (Exception ex)
                        {
                            isGood = false;
                            msg    = ex.Message;
                        }
                    }
                }
                btnPush.Text = string.Format("{0} => {1}", isGood, msg);
            };


            btnSettings.Click += (sender, e) =>
            {
                var intent = new Intent(this, typeof(Settings));
                StartActivity(intent);
            };
        }
Example #6
0
        /**
         * <p>
         * Runs commands using the supplied shell, and returns the output, or null
         * in case of errors.
         * </p>
         * <p>
         * Note that due to compatibility with older Android versions, wantSTDERR is
         * not implemented using redirectErrorStream, but rather appended to the
         * output. STDOUT and STDERR are thus not guaranteed to be in the correct
         * order in the output.
         * </p>
         * <p>
         * Note as well that this code will intentionally crash when run in debug
         * mode from the main thread of the application. You should always execute
         * shell commands from a background thread.
         * </p>
         * <p>
         * When in debug mode, the code will also excessively log the commands
         * passed to and the output returned from the shell.
         * </p>
         * <p>
         * Though this function uses background threads to gobble STDOUT and STDERR
         * so a deadlock does not occur if the shell produces massive output, the
         * output is still stored in a List&lt;String&gt;, and as such doing
         * something like <em>'ls -lR /'</em> will probably have you run out of
         * memory.
         * </p>
         *
         * @param shell The shell to use for executing the commands
         * @param commands The commands to execute
         * @param environment List of all environment variables (in 'key=value'
         *            format) or null for defaults
         * @param wantSTDERR Return STDERR in the output ?
         * @return Output of the commands, or null in case of an error
         */
        public static List <string> run(string shell, string[] commands, string[] environment, bool wantSTDERR)
        {
            string shellUpper = shell.ToUpperInvariant();              //.ToUpperCase(Locale.ENGLISH);

            if (Debug.getSanityChecksEnabledEffective() && Debug.onMainThread())
            {
                // check if we're running in the main thread, and if so, crash if
                // we're in debug mode, to let the developer know attention is
                // needed here.

                Debug.log(ShellOnMainThreadException.EXCEPTION_COMMAND);
                throw new ShellOnMainThreadException(ShellOnMainThreadException.EXCEPTION_COMMAND);
            }
            Debug.logCommand(string.Format("[{0}] START", shellUpper));

            var res = Java.Util.Collections.SynchronizedList(new System.Collections.ArrayList());

            try {
                // Combine passed environment with system environment
                if (environment != null)
                {
                    var newEnvironment = new Dictionary <string, string> (global::Java.Lang.JavaSystem.Getenv());
                    //int split;
                    var split = new char[] { '=' };
                    foreach (string entry in environment)
                    {
                        var splat = entry.Split(split, 1, StringSplitOptions.RemoveEmptyEntries);
                        if (splat != null && splat.Length == 2)
                        {
                            newEnvironment [splat [0]] = splat [1];
                        }
                    }
                    int i = 0;
//					environment = new String[newEnvironment.size()];
//					foreach (Map.Entry<String, String> entry in newEnvironment.entrySet()) {
//						environment[i] = entry.getKey() + "=" + entry.getValue();
//						i++;
//					}
                    environment = newEnvironment.Select(x => string.Format("{0}={1}", x.Key, x.Value)).ToArray();
                }

                // setup our process, retrieve STDIN stream, and STDOUT/STDERR
                // gobblers
                Process       process = Runtime.GetRuntime().Exec(shell, environment);
                var           STDIN   = new Java.IO.DataOutputStream(process.OutputStream);
                StreamGobbler STDOUT  = new StreamGobbler(shellUpper + "-", process.InputStream, res);
                StreamGobbler STDERR  = new StreamGobbler(shellUpper + "*", process.ErrorStream, wantSTDERR ? res : null);

                // start gobbling and write our commands to the shell
                STDOUT.Start();
                STDERR.Start();
                try {
                    foreach (string write in commands)
                    {
                        Debug.logCommand(string.Format("[{0}+] {1}", shellUpper, write));
                        STDIN.Write((write + "\n").getBytes("UTF-8"));
                        STDIN.Flush();
                    }
                    STDIN.Write("exit\n".getBytes("UTF-8"));
                    STDIN.Flush();
                } catch (System.Exception e) {
                    if (e.ToString().Contains("EPIPE"))
                    {
                        // method most horrid to catch broken pipe, in which case we
                        // do nothing. the command is not a shell, the shell closed
                        // STDIN, the script already contained the exit command, etc.
                        // these cases we want the output instead of returning null
                    }
                    else
                    {
                        // other issues we don't know how to handle, leads to
                        // returning null
                        throw;
                    }
                }

                // wait for our process to finish, while we gobble away in the
                // background
                process.WaitFor();

                // make sure our threads are done gobbling, our streams are closed,
                // and the process is destroyed - while the latter two shouldn't be
                // needed in theory, and may even produce warnings, in "normal" Java
                // they are required for guaranteed cleanup of resources, so lets be
                // safe and do this on Android as well
                try {
                    STDIN.Close();
                } catch (System.Exception e) {
                    // might be closed already
                }
                STDOUT.Join();
                STDERR.Join();
                process.Destroy();

                // in case of su, 255 usually indicates access denied
                if (SU.isSU(shell) && (process.ExitValue() == 255))
                {
                    res = null;
                }
            } catch (Java.IO.IOException e) {
                // shell probably not found
                res = null;
            } catch (InterruptedException e) {
                // this should really be re-thrown
                res = null;
            }

            Debug.logCommand(string.Format("[{0}%] END", shell.ToUpperInvariant()));
            var result = new List <string> ();

            foreach (var r in res)
            {
                result.Add(r.ToString());
            }
            return(result);
        }