Copy and execute custom binary and audit service logs

I am creating an application that uses a Native service binary.

Now my requirements are:

Place your own service binary in your application's assets folder.

  • When the app starts, copy this native file to the device (path as getExternalFilesDir(null)

    )
  • Execute this binary inside the device.
  • Check if the file was executed successfully in the logs.

Now, to copy the file, I used:

private void copyAssets() {
    AssetManager assetManager = getAssets();
    String[] files = null;
    try {
        files = assetManager.list("");
    } catch (IOException e) {
        Log.e("tag", "Failed to get asset file list.", e);
    }
    for (String filename : files) {
        if (filename.equals("native-file")) { // native-file is the file name present is assets folder
            InputStream in = null;
            OutputStream out = null;
            try {
                in = assetManager.open(filename);
                File outFile = new File(getExternalFilesDir(null), filename);
                out = new FileOutputStream(outFile);
                copyFile(in, out);
                in.close();
                in = null;
                out.flush();
                out.close();
                out = null;

            } catch (IOException e) {
                Log.e("tag", "Failed to copy asset file: " + filename, e);
            }
            break;
        }
    }
}

      

And after copying to execute the file I am using:

File sdCard = getExternalFilesDir(null); // directory where native file is placed
Process proc = Runtime.getRuntime().exec("sh -c shell " + sdCard.getAbsolutePath() + "/native-file "+ sdCard.getAbsolutePath() +"/native-file.log\" "); // command 1
proc = Runtime.getRuntime().exec("sh -c less " + sdCard.getAbsolutePath() +"/native-file.log\""); // command 2

      

Questions:

  • How can I make sure the file is placed.
  • How to make sure it's done. As I cannot find and write the files (native-file.log) when starting the application.

PS - I am unable to provide the JNI file due to permissions issues. So I guess we can use the opensource asl library (there is a native file called asl-native)

+3


source to share


1 answer


Your current code isn't too far off, but there are a few details you need to take care of:

  • As noted, you cannot execute files that you entered into /sdcard

    . However, you can execute files in the internal memory. So instead getExternalFilesDir(null)

    usegetFilesDir()

  • After copying the executable to the target directory, it needs to be executed. You can run Runtime.getRuntime().exec("chmod 755 " + getFilesDir() + "/native-file").waitFor();

    or try using a private android.os.FileUtils

    class (as in fooobar.com/questions/1422362 / ... ).
  • When starting the application, you do not need an additional "sh -c shell", this is enough: Process proc = Runtime.getRuntime().exec(getFilesDir() + "/native-file");

  • If you want to read the stdout / stderr output from your executable (to make sure it works correctly), you can do so for example. this is:

    InputStream stdout = proc.getInputStream();
    InputStream stderr = proc.getErrorStream();
    BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
    String line;
    while ((line = br.readLine()) != null)
        System.out.println("stdout: " + line);
    br = new BufferedReader(new InputStreamReader(stderr));
    while ((line = br.readLine()) != null)
        System.out.println("stderr: " + line);
    
          



To simplify steps 1 and 2, and to avoid having to worry about different architectures for your own binaries yourself, you can rename your command line executable according to the pattern lib<something>.so

and place it in a directory libs/<abi>

in your project. It will then be picked up by the APK packer and packaged like any native library. To accomplish it, you can simply doProcess proc = Runtime.getRuntime().exec(getApplicationInfo().nativeLibraryDir + "/libnative-file.so");

+1


source







All Articles