Accessing system files through an application - Android Software Development

Im trying to find out how i would go about creating or removing system files on an already rooted device from within an app. I have been told this code is relevant, im guessing it wont work in the emulator?
Code:
Process process = Runtime.getRuntime().exec("su");
DataOutputStream outputStream = new DataOutputStream(process.getOutputStream());
DataInputStream inputStream = new DataInputStream(process.getInputStream());
outputStream.writeBytes(command + "\n");
outputStream.flush();
process.waitFor();
}
where command is the variable of the command i want to run.
ive run this with "mkdir /system/test" as the string and nothing was created in the emu

I guess the emulator ain't rooted

Related

Android SDK Emulator - Root Access

When I run the android emulator, using the Android 2.2 - API Level 8, by issuing from cmd emulator -avd test (test being the emulator name) I am not given root access. If I open terminal emulator and issue the SU command i recieve permission denied.
I thought the emulator was meant to run in root access?
I wish someone else would shed some light on this as well. I feel like I have been able to gain access to root, using the su command, but I cant remember as it has been a few months since using the emulator.
I also help someone else will look into this...
Sent from my DROIDX using XDA App
ANy update on this topic?
Hey guys, could anyone fill me in on how to get root in the emulator?
Does anyone knows the answer for this?
I tried chaining the commands, but still not working
Code:
try {
Runtime rt = Runtime.getRuntime();
String[] cmd = { "su", "-c", "ls -l /data/data/"};
Process pcs = rt.exec(cmd); //("ls -l /data/data/");
BufferedReader br = new BufferedReader(new InputStreamReader(pcs
.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
Log.e("line","line="+line);
}
br.close();
pcs.waitFor();
int ret = pcs.exitValue();
Log.e("ret","ret="+ret);
} catch (Exception e) {
Log.e("Exception", "Exception", e);
}

Need help with Root access app.

I have a simple app that I'm trying to develop. I have written Android apps for work but this would be the first app with root access, and it is not for work. Here is my onCreate code.
Code:
setContentView(R.layout.main);
/**
* Set up the spinner for the buffer size
*/
spinner = (Spinner) findViewById(R.id.spKBSelect);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.KBs, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
txtCurVal = (TextView) findViewById(R.id.txtCurrentV);
try {
txtCurVal.setText(getString(R.string.cursetvalue) + " " + getCurrentValue() + " KB");
p = Runtime.getRuntime().exec("su");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
This code works fine. I get root access from Superuser. Now when I click the button in the following code it works. The only thing is that when I try to refresh my txtCurVal.setText() after the update I get the same value. I have checked and the update to the file did go through. So what I think is that the su process and/or commands dealing with the su have not finished when I read the value again. After searching online most people were saying that I needed to add a p.waitfor(); so that the terminal could finish. This is where the problems occurs it gets to the point and the app just stops. After a few second Android says that the app is non responsive and wants to force close. Here is the button click code.
Code:
public void onClick(View v) throws Exception {
switch (v.getId()) {
case R.id.btnAbout:
Toast.makeText(this, "Created by: Ben Murphy (Smurph82)\nCreated on: 2011_0618", Toast.LENGTH_LONG).show();
break;
case R.id.btnSave:
DataOutputStream os = new DataOutputStream(p.getOutputStream());
DataInputStream osRes = new DataInputStream(p.getInputStream());
//backupFile(getString(R.string.rakpath));
os.writeBytes("busybox cp " + getString(R.string.rakpath) + " " + sdcard + "/.sdspeedshifter\n");
os.flush();
os.writeBytes("busybox mv -f " + sdcard + "/.sdspeedshifter/read_ahead_kb " + " " + sdcard + "/.sdspeedshifter/read_ahead_kb_bak\n");
os.flush();
//writeNewValue(spinner.getSelectedItem().toString(), getString(R.string.rakpath));
os.writeBytes("echo \"" + spinner.getSelectedItem().toString() + "\" > " + getString(R.string.rakpath) + "\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
[B]p.waitFor();[/B]
txtCurVal.setText(getString(R.string.cursetvalue) + " " + getCurrentValue() + " KB");
break;
default:
break;
}
}
If I take the p.waitfor(); out everything runs but the value is not displayed correctly. This is just an app for me to learn how to use su access. As you can tell all this does is increase the value in the read_ahead_kb file that helps with sd card speed. Any help of advice would be great. Thanks.
I don't see "p" every declared, so there's no way to know, given what you've posted, whether it is in-scope for both "setContentView" and "onClick" so that may be why you're app is hanging, but I don't think this is the way to go about it. Running a bare "su" command in exec is going to spawn off a new command shell with root privileges, but without passing any arguments, the shell is just going to sit there assuming it is a login shell, waiting for the user to type commands.
Generally, if you need root level control over some resource, you just do it once for the time it is needed and then drop the privilege once the work is done. I typically write a small C code executable that does the privileged stuff, then call is as a command line argument for the su command with the "-c" argument:
Code:
Runtime.getRuntime().exec("su -c mycmd");
Now, mycmd runs, does what it needs to do, then exits returning full control to the app (no hang).
You need to use JNI or another toolchain to write command-line exe's for the device.
Here is the whole class.
Code:
public class SDSpeedShifterActivity extends Activity {
private final static File sdcard = Environment.getExternalStorageDirectory();
private static Process p = null;
private static TextView txtCurVal = null;
private static Spinner spinner = null;
private static StringBuilder sb = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/**
* Set up the spinner for the buffer size
*/
spinner = (Spinner) findViewById(R.id.spKBSelect);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
this, R.array.KBs, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
txtCurVal = (TextView) findViewById(R.id.txtCurrentV);
try {
txtCurVal.setText(getString(R.string.cursetvalue) + " " + getCurrentValue() + " KB");
p = Runtime.getRuntime().exec("su");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* This handles all of the button clicks.
* @param v The view (Button) that was clicked.
* @throws Exception If something goes wrong.
*/
public void onClick(View v) throws Exception {
switch (v.getId()) {
case R.id.btnAbout:
Toast.makeText(this, "Created by: Ben Murphy (Smurph82)\nCreated on: 2011_0618", Toast.LENGTH_LONG).show();
break;
case R.id.btnSave:
DataOutputStream os = new DataOutputStream(p.getOutputStream());
DataInputStream osRes = new DataInputStream(p.getInputStream());
os.writeBytes("busybox cp " + getString(R.string.rakpath) + " " + sdcard + "/.sdspeedshifter\n");
os.flush();
os.writeBytes("busybox mv -f " + sdcard + "/.sdspeedshifter/read_ahead_kb " + " " + sdcard + "/.sdspeedshifter/read_ahead_kb_bak\n");
os.flush();
//writeNewValue(spinner.getSelectedItem().toString(), getString(R.string.rakpath));
os.writeBytes("echo \"" + spinner.getSelectedItem().toString() + "\" > " + getString(R.string.rakpath) + "\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
//p.waitFor();
txtCurVal.setText(getString(R.string.cursetvalue) + " " + getCurrentValue() + " KB");
break;
default:
break;
}
}
/**
* Show the current read_ahead_kb value from the file.
* @param v The view (Textview) that needs to be changed.
* @throws IOException
*/
private final String getCurrentValue() throws IOException{
File rak = new File(getString(R.string.rakpath));
BufferedReader br = new BufferedReader(new FileReader(rak));
String line, vm = "";
while ((line = br.readLine()) != null) {
vm = line;
break;
}
return vm;
}
Thanks for the help.
So I assume it is the "busybox mv..." and/or "busybox cp ..." commands that need root permissions? Just change them to:
Code:
"su -c 'busybox mv ...'"
Search z4root source code in Google and have a good look at VirtualTerminal(in source code) and how to use it.
maybe you want to check out this one:
http://code.google.com/p/roottools/

[Help] Android GUI for privoxy+polipo

Hi
How are you?
I have make simple android GUI to start privoxy and polipo binary
but my problem.How i can stop privoxy and polipo when press on stop button
i can get process id (PID) for privoxy and polipo using this code
Code:
public int findProcessIdWithPS(String str) throws IOException {
String readLine;
Runtime runtime = Runtime.getRuntime();
CharSequence name = new File(str).getName();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(runtime.exec("ps " + name).getInputStream()));
bufferedReader.readLine();
do {
readLine = bufferedReader.readLine();
if (readLine == null) {
return -1;
}
} while (!readLine.contains(name));
return Integer.parseInt(readLine.split("\\s+")[1]);
}
this code return the PID of process
then i have try kill process but not working with this code
Code:
Process process = Runtime.getRuntime().exec("kill -9 " + findProcessIdWithPS("privoxy"));
process.waitFor();
but this code not working with me
Please any help
Sorry of my English

[Q] External process with ProcessBuilder

I wrote a simple application that needs to run external programs as superuser. I run this piece of code in a periodic task: the code is contained in a Runnable that runs periodically by using a ScheduledThreadPoolExecutor. The code works well for a while, but after some times it stops to work randomly. To do that I used the following code. By debugging the application I found the problem is in the line Process process = builder.start();
I mean that when the problem happens the execution wait the return of this method forever.
Code:
//Code in run() Method of a class that implemnst Runnable:
ArrayList<String> results = new ArrayList<String>();
try {
ProcessBuilder builder = new ProcessBuilder("su");
builder.redirectErrorStream(true);
Process process = builder.start();
DataOutputStream os = new DataOutputStream(
process.getOutputStream());
BufferedReader bRes = new BufferedReader(new InputStreamReader(
process.getInputStream()));
os.writeBytes("busybox ifconfig | busybox grep 'eth'; echo done_done\n"); //<-- this is my command for now
os.flush();
String r;
long curr = System.currentTimeMillis();
while ((r = bRes.readLine()).equals("done_done") == false){
results.add(r);
}
os.writeBytes("exit\n");
os.flush();
process.waitFor();
} catch (Exception e) {
//...
}
Any suggestions? I can't figure out what kind of problems produce this situation. I used this code in past without problems. Can the command line "busybox ifconfig | busybox grep 'eth'; echo done_done\n" not return and works forever? I don't think so..
Thank you, Nico

Two processes start when I programatically start a shell, but only on one phone

I have the same app on two different phones that have root access but I get different behavior from them while creating a shell. One phone runs CM12, the other runs CM13. My program runs a compiled executable and basically uses the code below. The executables I run won't stop until I close the shell. For this thread, we'll call it "specialProgram". I use 'ps' while using a terminal emulator to check what processes are running.
Code:
........
..................
Process process = Runtime.getRuntime().exec("su");
int processID = -1;
try {
Field f = process.getClass().getDeclaredField("pid");
f.setAccessible(true);
processID = f.getLong(process);
f.setAccessible(false);
} catch (Exception e) {}
System.out.println("Process: " + processID);
OutputStream stdout = process.getOutputStream();
stdout.write("specialProgram\n").getBytes());
..................
........
The phone that runs CM12 will create two processes, one call "su" and another called "specialProgram". The process ID for the process that is called "su", matches the processID for my variable 'processID'.
The phone that runs CM13 will only create a process called "specialProgram". This processes ID matches what my variable 'processID' becomes.
What I assume is that I'm creating a new process from within that shell, when I write to the OutputStream. But this only happens on one of my phones. Why?
So I think I figured it out. When I run
Code:
Process process = Runtime.getRuntime().exec("su");
it creates a process. And then when I run
Code:
stdout.write("specialProgram\n").getBytes());
it create another process. Closing the first process won't close the second process. I made my own class to properly close them though.

Resources