Saturday, May 14, 2011

Loading and executing a binary on Android

While attempting to get the hidd running on Android, I noticed that this is not easy to to. There are some barriers in place to prevent something like this:
  • The SD Card is mounted noexec
  • The System memory is read-only (NAND in my case)
  • Apps cannot write outside their folder (except for SD card)
The first thing you need to do is to get the executable onto the device. This can be done by placing the executable in the "raw" folder, which packages the file as a binary resource. Once your app starts, you can then open the binary resource for reading, and write it into the filesystem:
private void CopyRawToFile(int resourceId, String filename) throws IOException {
InputStream input = m_context.getResources().openRawResource(resourceId);
OutputStream output = m_context.openFileOutput(filename, Context.MODE_PRIVATE);

byte[] buffer = new byte[1024 * 4];
int a;
while((a = input.read(buffer)) > 0)
output.write(buffer, 0, a);

input.close();
output.close();
}
Once the file is loaded you can then make it executable by invoking chmod:
private String MakeExecutable(String filename) {
//First get the absolute path to the file
File folder = m_context.getFilesDir();

String filefolder = folder.getCanonicalPath();
if (!filefolder.endsWith("/"))
filefolder += "/";

String fullpath = filefolder + filename;

Runtime.getRuntime().exec("chmod 770 " + fullpath).waitForExit();

return fullpath;
}


After this, you should be able to execute the binary the same way you would with any system binary. Hopefully this will save you some time avoiding the painful JNI wrapper approach.

This does not compromise the security of the Android OS. Because the binary is executed as the app user, and thus has the same restrictions as the app itself. In other words, this does not allow you to execute operations with root privileges on a non-rooted device.

No comments: