I've built a native Android app with NDK toolcahain.
I've first tested the app using the adb tool and got the following output:
Code:
generic:/ $ run-as cardservice.hr.cardservice
generic:/data/data/cardservice.hr.cardservice $ cd card/
generic:/data/data/cardservice.hr.cardservice/card/ $ ./cardService
2016-11-30 20:36:06,245 INFO [default] Starting CardService
App continues to run
But problem starts when I try to do the same thing from a Android application.
The following code:
Code:
private void exec_command() throws IOException, InterruptedException {
String command = "./data/data/cardservice.hr.cardservice/card/cardService"
Process check_card_service = Runtime.getRuntime().exec(command);
BufferedReader in = new BufferedReader(new InputStreamReader(check_card_service.getInputStream()));
String line;
String content = "";
while ((line = in.readLine()) != null) {
System.out.println(line);
content = content + line;
}
check_card_service.waitFor();
};
It starts the application but the application fails, and stops working.
Code:
2016-11-30 19:25:11,417 INFO [default] Starting CardService
2016-11-30 19:25:11,447 INFO [default] Underlying Transport Error, Code: websocketpp.transport.asio:3
So my question is what is different in my approaches, what changes if i run it from my app or from the adb shell?
The application does not need root access.
Do you need any extra information?
Muha12 said:
I've built a native Android app with NDK toolcahain.
I've first tested the app using the adb tool and got the following output:
Code:
generic:/ $ run-as cardservice.hr.cardservice
generic:/data/data/cardservice.hr.cardservice $ cd card/
generic:/data/data/cardservice.hr.cardservice/card/ $ ./cardService
2016-11-30 20:36:06,245 INFO [default] Starting CardService
App continues to run
But problem starts when I try to do the same thing from a Android application.
The following code:
Code:
private void exec_command() throws IOException, InterruptedException {
String command = "./data/data/cardservice.hr.cardservice/card/cardService"
Process check_card_service = Runtime.getRuntime().exec(command);
BufferedReader in = new BufferedReader(new InputStreamReader(check_card_service.getInputStream()));
String line;
String content = "";
while ((line = in.readLine()) != null) {
System.out.println(line);
content = content + line;
}
check_card_service.waitFor();
};
It starts the application but the application fails, and stops working.
Code:
2016-11-30 19:25:11,417 INFO [default] Starting CardService
2016-11-30 19:25:11,447 INFO [default] Underlying Transport Error, Code: websocketpp.transport.asio:3
So my question is what is different in my approaches, what changes if i run it from my app or from the adb shell?
The application does not need root access.
Do you need any extra information?
Click to expand...
Click to collapse
Hello,
Please post your query here App Development Forum with all relevant details, the experts there maybe able to assist you.
Regards
Vatsal,
Forum Moderator.
Thank you very much.
Related
If someone has a stock RC30 installed, can you tell me what user id runs adbd and debuggerd?
To be able to debug processes and take screenshots, those processes must running be with some sort of privileged permissions and may be exploitable...
debuggerd runs as root, adbd runs as shell (that's on my official RC30 phone)
Hmm, in that case, it may actually be possible to take a screenshot without root by writing an ADB client in Java to connect to the adb daemon. And, shell also has access to the surface flinger, so it may be possible to do autorotation as well.
Anyways, I'll take a look at debuggerd and see if there anything interesting.
I did find some funny code in debuggerd.c a minute ago. Watch your phone's LED and type this into a root shell:
echo 255 > /sys/class/leds/red/brightness
Yup.
http://forum.xda-developers.com/showthread.php?p=2905504&highlight=backlight#post2905504
Holy ****!!! There may be a root hole in installd:
installd runs as root; it is the daemon that allows you to do the following commands related to installing and uninstalling APKs and managing their DEX files.
Code:
{ "ping", 0, do_ping },
{ "install", 3, do_install },
{ "dexopt", 3, do_dexopt },
{ "movedex", 2, do_move_dex },
{ "rmdex", 1, do_rm_dex },
{ "remove", 1, do_remove },
{ "freecache", 1, do_free_cache },
{ "rmcache", 1, do_rm_cache },
{ "protect", 2, do_protect },
{ "getsize", 3, do_get_size },
{ "rmuserdata", 1, do_rm_user_data },
The install daemon reads these commands from a socket and then executes them.
The interesting command is the "install" command, which maps to the following function:
Code:
static int do_install(char **arg, char reply[REPLY_MAX])
{
return install(arg[0], atoi(arg[1]), atoi(arg[2])); /* pkgname, uid, gid */
}
int install(const char *pkgname, uid_t uid, gid_t gid)
{
char pkgdir[PKG_PATH_MAX];
char libdir[PKG_PATH_MAX];
if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
LOGE("invalid uid/gid: %d %d\n", uid, gid);
return -1;
}
if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX))
return -1;
if (create_pkg_path(libdir, PKG_LIB_PREFIX, pkgname, PKG_LIB_POSTFIX))
return -1;
if (mkdir(pkgdir, 0755) < 0) {
LOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
return -errno;
}
if (chown(pkgdir, uid, gid) < 0) {
LOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
unlink(pkgdir);
return -errno;
}
if (mkdir(libdir, 0755) < 0) {
LOGE("cannot create dir '%s': %s\n", libdir, strerror(errno));
unlink(pkgdir);
return -errno;
}
if (chown(libdir, AID_SYSTEM, AID_SYSTEM) < 0) {
LOGE("cannot chown dir '%s': %s\n", libdir, strerror(errno));
unlink(libdir);
unlink(pkgdir);
return -errno;
}
return 0;
}
The 2nd and 3rd arguments let you specify an ARBITRARY uid that owns that package. I think we can either rebuild adb to always pass in uid 0 and gid 0 (this may not be possible; adb may not have anything to do with the uid/gid selected). Or maybe connect to the socket from an application on the phone, and then marshall the command manually. That would get an APK onto the phone running as root.
Gonna give this a shot right now.
Look at the beginning of the function.
Code:
if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
LOGE("invalid uid/gid: %d %d\n", uid, gid);
return -1;
That will disallow installing something with root access. AID_SYSTEM is 1000, the root uid is 0 of course.
But if we could get an app installed as the system user.. that may open up some more possibilities.
Also, I believe the socket that installd listens on is protected. If I remember correctly, it is restricted to the system user.
JesusFreke said:
Look at the beginning of the function.
Code:
if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
LOGE("invalid uid/gid: %d %d\n", uid, gid);
return -1;
That will disallow installing something with root access. AID_SYSTEM is 1000, the root uid is 0 of course.
But if we could get an app installed as the system user.. that may open up some more possibilities.
Also, I believe the socket that installd listens on is protected. If I remember correctly, it is restricted to the system user.
Click to expand...
Click to collapse
Ahh goddamnit.
I'm developing my first application, and I'm curious if there are any "standard" ways for executing privileged shell commands. I've only been able to find one way to do it, by executing su, and then appending my commands to stdin of the su process.
Code:
Process p = Runtime.getRuntime().exec("su");
DataOutputStream pOut = new DataOutputStream(p.getOutputStream());
DataInputStream pIn = new DataInputStream(p.getInputStream());
String rv = "";
// su must exit before its output can be read
pOut.writeBytes(cmd + "\nexit\n");
pOut.flush();
p.waitFor();
while (pIn.available() > 0)
rv += pIn.readLine() + "\n";
I've read about wrapping privileged (superuser) calls up in JNI: is this possible? If so, how would one go about accomplishing it? Other than that, are there any other ways of calling privileged instructions from Java?
EDIT: Also, why exactly must su exit before I can capture it's output? When I read from the processes stdout before it has closed I get nothing.
Hey guys,
I've seen quite a few threads here, regarding ADB binaries, but I've not seen one which incorporates the binaries for every OS.
So here's mine. And as a little special, I'm going to add a guide on how to download these binaries from my server (All links refer to there) and install them to any computer using Java.
FIRST:
Download links:
Linux (64-bit only!):
ADB
Fastboot
Mac OS X (Intel):
ADB
Fastboot
Windows (Any, except ARM!):
ADB
ADB Windows API
ADB Windows USB API
Fastboot
SECOND (Optional)
Installation on Debian systems.
If you just want to use ADB for your own personal use, you don't have to download the binary and always CD (change directory: Terminal) to the location on your hard drive where you downloaded it to.
If you're running Debian Linux, you can enter following commands into the terminal.
(
KDE: Konsole
Gnome: Terminal
)
Code:
For ADB: sudo apt-get install android-tools-adb
For Fastboot: sudo apt-get install android-tools-fastboot
Or for both (Easiest)
sudo apt-get update && sudo apt-get install android-tools-adb && sudo apt-get install android-tools-fastboot
Just copy & paste the command(s) into the terminal program of your choice and enter your password, the rest is done via the package manager.
Post #2 has the Java code examples for downloading the binaries in your program from my server to your client's computer.
Before you go there;
Please do not mirror these links.
I compiled them myself on my system (and my Dad's Mac Mini) and it was a real pain getting these to work correctly.
Java Download Tutorial
FIRST;
Open your editor or IDE of choice.
I'm using NetBeans 7.4.
You will be greeted by this screen (if you're using NetBeans):
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Next, create a new project and create a main class.
(I'll be using Universal Android Toolkit for this example, so I already have the code I want).
For the basic stuff, you should add at least two buttons, one to install ADB, and one to remove it again.
Now, go into the code section of your IDE and add the following variables (or copy this code):
import java.io.*;
import javax.swing.*;
public class Main extends JFrame {
// Files
static File adb = null;
static File fastboot = null;
// Depending on the operating system you're programming for, you'll have to add more variables.
// Weblinks
static String webAdb = "http://team-m4gkbeatz.eu/Beatsleigher/adb_linux/adb";
static String webFastboot = "http://team-m4gkbeatz.eu/Beatsleigher/fastboot_linux/fastboot";
// Constructor
public Main() {
adb = new File(System.getProperty("user.home") + "/.programName/.bin/adb");
fastboot = new File(System.getProperty("user.home") + "/.programName/.bin/fastboot");
}
/**
* Calls method <saveUrl> and downloads file.
static void installAdb() {
try {
if (adb.exists()) adb.delete(); // Delete file if it exists, to ensure a clean install
if (fastboot.exists()) fastboot.delete(); // Delete file if it exists, to ensure a clean install
adb.getParentFile().mkdirs(); // Create all directories in front of ADB (user.home/.programName/.bin/).
adb.createNewFile(); // Create new file, so we can write data into it.
;
fastboot.getParentFile().mkdirs(); // Create all directories in front of fastboot (In case they're in different locations)
fastboot.createNewFile(); // Create new file, so we can write data into it.
;
saveUrl(adb.toString(), webAdb); // Download data into ADB.
saveUrl(fastboot.toString(), webFastboot); // Download data into fastboot.
; // Now we chmod the files, so that we can execute them at a later time.
; // I spent a few hours working this out, so please don't forget to give credit in your code/program!
new Thread() { // Create background thread, so UI doesn't freeze.
public void run() {
try {
Runtime r = Runtime.getRuntime();
r.exec("chmod 775 " + adb.toString()); // Chmod the adb executable, so it is marked as executable.
Thread.sleep(2000); // Give the program some time to finish.
interrupt(); // Exit thread.
} catch (IOException | InterruptedException ex) {
// Enter your handling code here.
}
}
}
;
new Thread() { // Create another background thread, so the UI doesn't freeze and so the program can chmod fastboot, while it is sorting out adb.
public void run() {
try {
Runtime r = Runtime.getRuntime();
r.exec("chmod 775 " + fastboot.toString()); // Chmod the fastboot executable, so it is marked as executable.
Thread.sleep(2000); // Give the program some time to finish.
interrupt(); // Exit thread.
} catch (IOException | InterruptedException ex) {
// Enter your handling code here.
}
}
JOptionPane.showMessageDialog(null, "INFO: ADB has been installed to your system!", "SUCCESS", JOptionPane.INFORMATION_MESSAGE); // Display message dialog notifying user of success.
} catch (IOException | InterruptedException ex) {
// Enter your handling code here.
}
}
static void removeAdb() {
try {
if (adb.exists()) adb.delete(); // Delete adb binary if it exists.
if (fastboot.exists()) fastboot.delete(); // Delete fastboot binary if it exists.
JOptionPane.showMessageDialog(null, "INFO: ADB has been removed from your system!", "SUCCESS", JOptionPane.INFORMATION_MESSAGE); // Display message dialog notifiying user of success.
} catch (IOException ex) {
// Enter your handling code here.
}
}
/**
* This is where all the magic happens.
*/
public static short saveUrl(String filename, String urlString) throws MalformedURLException, IOException {
BufferedInputStream fileIn = null; // Defines a BufferedInputStream (Used to download the information/data)
FileOutputStream fileout = null; // Defines a FileOutputStream (Used to write the data to the file)
try {
fileIn = new BufferedInputStream(new URL(urlString).openStream()); // Creates a new instance of said BufferedInputStream, using parameters in the method head.
fileOut = new FileOutputStream(filename); // Creates a new instance of said FileOutputStream, using parameters in the method head.
byte data[] = new byte[1024]; // Creates a new variable of type byte.
int count; // Defines a new variable of type int.
while ((count = fileIn.read(data, 0, 1024)) != -1) { // Reads bytes from this byte-input stream into the specified byte array, starting at the given offset.
fileOut.write(data, 0, count); // Writes downloaded data to specified file.
}
} finally {
if (fileIn != null) {
fileIn.close(); // Closes (Disposes of) fileIn
}
if (fileOut != null) {
fileOut.close(); // Closes (Disposes of) fileOut
}
}
return 1; // Exits method with value code 1
}
}
Click to expand...
Click to collapse
Depending on your IDE, it should look very similar to this:
Note:
Depending on the operating system you're using, you might have to change the variables/add variables, add conditional statements and download more files.
After you've added all the code,
if should look similar to this when executing your program:
Controls:
Installation Success:
Installed Binaries:
Removal Success:
Removed Binaries:
The operating system used in this tutorial was Kubuntu Linux 13.10 64-bit.
The IDE used is NetBeans IDE 7.4 with Java JDK 7.
/** Disclaimer
* I am not responsible for any damage or similar that may have happened by following this tutorial.
* I have tested and used all the codes and binaries provided without any issues.
* Should the binaries not work, please make sure you downloaded the correct binaries.
* I typed all this code by hand instead of copy-pasting it from NetBeans, as my methods contain some custom code
* which would only confuse you.
* To view the full source code, check out my GitHub (Although it may take a few days to get on there, as I'm still doing major stuff to the program!)
*/
I hope you liked this post of mine and that it was helpful.
If you have any suggestions for this post, please let me know.
If you have anything to say about this post, please stay constructive. And bashing will be reported to the mods and handled accordingly.
#Reserved 2
404
links are not working . kindly fix it and resend.
I can retrieve the path of ./busybox cat or such process which is not terminated quickly.
However I cannot gather the path of processes which ended up quickly ./busybox ps
What is the easiest way to get all of the processes executable path in kernel level?
Code:
rcu_read_lock();
struct task_struct *task;
struct list_head *list;``
struct mm_struct *mm;
struct file *exe_file;
char *pathname,*path;
pathname = kmalloc(PATH_MAX, GFP_ATOMIC);
task = list_entry(list, struct task_struct, sibling);
for_each_process(task) {
printk("/----------------------------------/\n");
mm = get_task_mm(task);
if(mm != NULL) {
exe_file = get_mm_exe_file(mm);
path_get(&exe_file->f_path);
path = d_path(&mm->exe_file->f_path,pathname,PATH_MAX);
printk("CHILD %s[%d]->%s\n\n ", task->comm, task->pid ,path);
}
}
rcu_read_unlock();
I can retrieve the path of ./busybox cat or such process which is not terminated quickly.
However I cannot gather the path of processes which ended up quickly ./busybox ps
What is the easiest way to get all of the processes executable path in kernel level?
Code:
rcu_read_lock();
struct task_struct *task;
struct list_head *list;``
struct mm_struct *mm;
struct file *exe_file;
char *pathname,*path;
pathname = kmalloc(PATH_MAX, GFP_ATOMIC);
task = list_entry(list, struct task_struct, sibling);
for_each_process(task) {
printk("/----------------------------------/\n");
mm = get_task_mm(task);
if(mm != NULL) {
exe_file = get_mm_exe_file(mm);
path_get(&exe_file->f_path);
path = d_path(&mm->exe_file->f_path,pathname,PATH_MAX);
printk("CHILD %s[%d]->%s\n\n ", task->comm, task->pid ,path);
}
}
rcu_read_unlock();