Sending AT Commands in Android Using atinout library - android

As the question title suggest, I'm going to use atinout library in my android application to be able to send AT Commands to my device's gsm modem and get the response back.
I've searched the SO and other blogs and the best code I got is something like this, which does not cauese anything to be written to output :
Runtime r = Runtime.getRuntime();
Process process = r.exec(new String[] {"su", "-c", "echo -n -e 'AT\r' > /dev/smd0"});
BufferedReader in = new BufferedReader( new InputStreamReader(process.getInputStream()));
String line = "";
while ((line = in.readLine()) != null)
{
output+= line ;
}
tv.setText(output);
So my main concerns are :
1- How to send a simple AT commmad (like AT Ok) to the device's gsm modem and "print" the response back ?
2- I have no idea how to use the atinout library in an android application project, since it is written in C language.
By the way :
I have successfully rooted my Sony Xperia M Dual (C2005) phone and have SuperUser installed on it, so this prerequisite is met.
Also, I think I need some fundamental training on Unix commands and Serial communication and I really love to learn any needed material.
Finally, I'm on a tight deadline ! So the more straightforward , the better!
P.S. I don't want someone to write the code for me, I just need the guidelines.
Thanks for your help.

Step 0. Compile atinout for android and install it. For this I have no experience and cannot give any help other than some general guidelines that you need to replace CC = gcc in the Makefile with an appropriate cross compiler.
Step 1. Write all the AT commands you want to run into a file input.txt (using normal '\n' line endings, there is no need to mess with '\r' here).
Step 2. Change the exec line to
Process process = r.exec(new String[] {"su", "-c",
"atinout input.txt /dev/smd0 output.txt"});
Wait for the process to finish execution (process.waitFor() I think).
Step 3. Open the file output.txt and read the output from this instead of process.getInputStream().

Related

Complete terminal control on android

I have been trying to run a few Linux commands on my android phone with
Process process = Runtime.getRuntime().exec(COMMAND);
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
And noticed that I can only run specific commands and get the proper output even if the device is rooted with SuperSU (I have also tested it with a device without SuperSU on it).
For example, if I run ls and try to put it on a screen (through a TextView) as follows:
public void onBtnClick(View view) {
try {
EditText commandLine = findViewById(R.id.commandText);
Process process = Runtime.getRuntime().exec(commandLine.getText().toString());
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
((TextView) findViewById(R.id.mainTextView)).setText(((TextView) findViewById(R.id.mainTextView)).getText() + "\n" + in.readLine());
commandLine.setText("");
} catch (IOException e) {
e.printStackTrace();
}
}
the output is acct which makes sense.
But on the other hand, if lets say I run pwd it gives me the following error:
W/System.err: java.io.IOException: Error running exec(). Command:
[pwd] Working Directory: null Environment: null
I did some research online and stumbled upon Termux that can have complete control over the phone through a terminal which is exactly what I'm looking to make (for my own learning and testing purposes).
And although it's just an emulator it can do exactly what I want but the only problem is that it requires I input the commands through the terminal.
What I'm here for is to sort of replicate what Termux does for myself so that I could run Linux commands properly from the Java code of the application, not requiring the user to actually input commands.
Can anyone help me with where to start and the basics of running those commands properly on my device?
Termux states that it doesn't work as a traditional Linux bash does since it sets its own virtual-ish environment when first setting up in its data directory in /data/data/com.termux/files/usr see here and here
Also, according to the official android docs, the exec(command) method,
Executes the specified string command in a separate process.
This is a convenience method. An invocation of the form exec(command)
behaves in exactly the same way as the invocation exec(command, null,
null).
So if it's a separate process, when executing a command, it will run it inside that process' directory (Each process in Linux gets its directory and is assigned an PID which os uses). So what the ls command gives you is simply whatever's inside that process' directory. You should be somewhere like /proc/31415/ and there's only a acct file (cgroup in regular Linux).
What you should be doing is running the command inside a directory by declaring it when invoking getRuntime().exec() see the link above to find the right one you'll need. I'd suggest using the override which handles all the parameters.
You'll need something like this:
String[] cmd = {"mkdir", "testDir"};
File env = new File(getFilesDir().getAbsolutePath());
Runtime.getRuntime().exec(cmd, null, env);
Also, it doesn't hurt to take a look at Termux's installer code (exec(). It'll give you a good overlook to setting up your environment as well as working with basic commands.
Also, I think you've done it already but double check to make sure that you're requesting WRITE_EXTERNAL_STORAGE permission for your application.

Why can't my Android APP use tcpdump eventhough I change the permission of tcpdump to 777?

I change the permission of /system/xbin/tcpdump to 777 and write the code in my Android APP like below.
But I still get the error message "stderr=tcpdump: any: You don't have permission to capture on that device" and "stderr=(socket: Operation not permitted)".
Is there anyone know what's the problem here?
Thanks.
Process process
String[] cmd = {"/system/xbin/tcpdump", "-i any", "-w /sdcard/tcpdump.pkt"};
TextUtils.join(" ", cmd);
process = Runtime.getRuntime().exec(cmd);
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line;
while ((line = errorReader.readLine()) != null) {
Log.d(TAG, "stderr="+line);
}
Android does not support raw sockets, which would include the ability to collect raw frames using a sniffer, by any user space process on non-rooted devices.
If you check the main support site for TCPDump on Android, you'll find that one of the very first requirements is a rooted Android device.

How to run root commands from Android application?

I want to write an application which roots the device on which it is installed, I mean by installing this app you will be able to root your device without a computer, just like the app in the following link,
http://www.kingoapp.com/root-tutorials/how-to-root-android-without-computer.htm
I've searched a lot on how to do that using Java code for Android devices, but there was no clear solution to me. Based on my research, I think we need the following steps:
1- Being able to use shell commands in Android using Runtime.getRuntime().exec();
2- Executing a command that gains root privileges (I think su, but this needs a rooted device to be executed).
3- Initiate a root command that will root the device.
I couldn't find a code explanation on how to do the steps above. I want to understand this process first, the commands that can be used in it, then I want to try to implement it by myself. Since there are many apps on the store that offer this feature, then implementing it must be feasible.
Could anyone please explain to me how to implement this process?
Also, is there a possibility to write a code for the opposite process, which is unrooting the device?
Any help is appreciated.
Thanks.
To run root commands, you have to use the following format:
public void RunAsRoot(String[] cmds){
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
for (String tmpCmd : cmds) {
os.writeBytes(tmpCmd+"\n");
}
os.writeBytes("exit\n");
os.flush();
}
where you pass in an array of strings, each string being a command that needs to be executed. For example:
String[] cmds = {"sysrw", "rm /data/local/bootanimation.zip", "sysro"};

command injection in Android by executing the mount command

I am trying to execute this code
Process process = new ProcessBuilder().command("mount").start();
process.waitFor();
to find out the sd card location and then afterwards checking if it is managed by vold and if the file system is vfat.
My question is if anyway this code can be comproprised and become a candidate for command injection in Android.
Couple points from my side.
Its not user input so there will be no command injection in that case. Can the whole Android OS environment be changed such that mount command can be ill used ?
cheers,
Saurav
ok...Currently i am reading /proc/mounts replacing the mount command.
Is this is the good way to do.
References for this solution
http://renzhi.ca/2012/02/03/how-to-list-all-sd-cards-on-android/
How can I get the list of mounted external storage of android device
code below
reader = new BufferedReader(new FileReader("/proc/mounts"));
String line;
while ((line = reader.readLine()) != null) {
// Output the line of output from the mount command
logger.debug(" {}", line);
if (line.startsWith("/dev/block/vold/")) {
Can anyone please if this is the correct way to do and is free of any security issues.
cheers,
Saurav
As you said, as long as you don't have any user input you're safe from this kind of injection.
The only case where you could be in trouble is if the mount binary have been replaced by a some malicious binary. To encounter this situation, the user must have had rooted the device and replaced the OS with a custom ROM.
I think you can assume that the mount command should run properly.

android : how to run a shell command from within code

I am trying to execute a command from within my code,
the command is "echo 125 > /sys/devices/platform/flashlight.0/leds/flashlight/brightness"
and I can run it without problems from adb shell
I am using Runtime class to execute it :
Runtime.getRuntime().exec("echo 125 > /sys/devices/platform/flashlight.0/leds/flashlight/brightness");
However I get a permissions error since I am not supposed to access the sys directory.
I have also tried to place the command in a String[] just in case spaces caused a problem but it didn't make much differense.
Does anyone know any workaround for this ?
The phone needs to be rooted, afterwards you can do something like:
public static void doCmds(List<String> cmds) throws Exception {
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
for (String tmpCmd : cmds) {
os.writeBytes(tmpCmd+"\n");
}
os.writeBytes("exit\n");
os.flush();
os.close();
process.waitFor();
}
If you're just trying to set brightness, why don't you do so through the provided API (AKA, is there a reason you are trying to do it the way you are).
int brightness = 125;
Settings.System.putInt(
ftaContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS,
brightness);
Agreed you probably need to root the phone to write to system files. I'm surprised the brightness isn't exposed through the SDK.
For details on running shell commands from code, check out this project:
You also may remout /system with permissions to write..
I think the device will need to be "rooted" for this to work. Have a search on google and see how other developers have dont this, there is no shortage of flashlight apps.
The adb shell can behave as a superuser without rooted devices.
it's a debug bridge. you can do whatever you want through it.
BUT, when your calling Runtime.getRuntime().exec, you don't have the same premissions. some shell commands aren't even available from exec.
so not only you need a rooted device, you also need su premmisions.

Categories

Resources