Is it possible to run a native arm binary on a non-rooted android phone?
Asked Answered
K

1

22

Well, I've been diving in the murky waters of low-level Android programming (native C/C++ using the CodeSourcery toolchain). I tried out the executable on an emulator and it worked. I'd like to try it out on a real device. So I plugged in my nexus and pushed the files on to the filesystem. Then I tried to execute the binary, and I got a permission error. It really doesn't matter how I mount it, or where I send it, I'm not root and it's not letting me execute it. Is there any way to run a program like this on a non-rooted phone?

Kanpur answered 16/1, 2011 at 0:55 Comment(4)
You will almost certainly need root. How did you even get it on the phone if your phone isn't rooted?Areopagite
Where did you put the binary? You can't put it on the sdcard because it is mounted with the "noexec" option (unless rooted).Alaster
Exactly, that's why it didn't work on the sdcard. I was able to put it in /data (but it wouldn't execute or even let me chmod it). As for how put the executable to the filesystem: "adb push".Kanpur
On some phones, you can copy it to /data/local/tmp/ then add +x permission and it'll run. Not posting as an answer since this only works in a narrow range of devices.Chose
S
41

Update: notice that apps targeting API level 29 (Android 10) and above will not be able to use the trick below, as the OS will restrict the execute permission. See Behavior changes: apps targeting API 29+.

After using the toolchain included in the Android NDK to compile your binaries, it is possible to package them with a typical Android app and have them spawn as subprocesses.

You'll have to include all the necessary files within the assets folder of your application. In order to run them, you have to have the program copy them from the assets folder to a runnable location like: /data/data/com.yourdomain.yourapp/nativeFolder

You can do this like so:

private static void copyFile(String assetPath, String localPath, Context context) {
    try {
        InputStream in = context.getAssets().open(assetPath);
        FileOutputStream out = new FileOutputStream(localPath);
        int read;
        byte[] buffer = new byte[4096];
        while ((read = in.read(buffer)) > 0) {
            out.write(buffer, 0, read);
        }
        out.close();
        in.close();
    
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

Keep in mind that the assetPath is not absolute but in respect to assets/.

IE: "assets/nativeFolder" is just "nativeFolder"

To then run your application and read its output you could do something like this:

  Process nativeApp = Runtime.getRuntime().exec("/data/data/com.yourdomain.yourapp/nativeFolder/application");
                            
                        
            BufferedReader reader = new BufferedReader(new InputStreamReader(nativeApp.getInputStream()));
            int read;
            char[] buffer = new char[4096];
            StringBuffer output = new StringBuffer();
            while ((read = reader.read(buffer)) > 0) {
                output.append(buffer, 0, read);
            }
            reader.close();
            
            // Waits for the command to finish.
            nativeApp.waitFor();
            
            String nativeOutput =  output.toString();
Sparid answered 23/7, 2011 at 21:1 Comment(5)
Happy to help. Would love to see google make the non-JNI side of the NDK a little easier to use.Sparid
Hey, you mention "expanding on the above answer" and there is not "above answer" can you edit your post to add the "above answer" (maybe a deleted one) ?Sarabia
I guess the author deleted it, I'll remove the reference. I believe it just suggested "you should check out the NDK".Sparid
Make sure you mark the new (copied) binary as executable: mBin.setExecutable(true); if you're using Java's File objects.Traipse
Yes, Android has a chmod, but it at least used to be a simple one which only accepted octal modes, and not the textual flags available on most desktop unixes. And Android's shell error messages are notoriously unspecific - permission denied can actually be any sort of problem.Haemin

© 2022 - 2024 — McMap. All rights reserved.