0
votes

I've got problem with this code which is working on windows machine with sdcard connected, but wont work on android. Does anyone know how to read sdcard as a single file byte by byte? I'd like to read all bytes from partition.

    public void buttonOnClick(View v) throws IOException {
    //File diskRoot = new File("\\\\.\\G:"); // for Windows disk ex. G

    int off=0;
    int len=1024;

    FileInputStream stream = null;

    //TODO find direct access to sd card
    //File sdDir = new File("storage/extSdCard");
    File sdDir = new File("storage/extSdCard");
    //File sdDir = new File("dev/block/platform/s3c-sdhci.2/mmcblk1");
    //File sdDir = Environment.getExternalStorageDirectory();
    //FileInputStream asd = openFileInput(Environment.getExternalStorageState());

    //File sdDir = new File(Environment.getExternalStorageDirectory()); gives internal storage of device
    //sdDir.getParentFile().mkdirs();
    //File file = new File(sdDir,"");
    byte[] buffer = new byte[1024];
    try {
        stream = new FileInputStream(sdDir);

        while (stream.read(buffer, off, len) != -1) {
            //
        }
        stream.close();
    } catch (FileNotFoundException e){
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

Any of commented above versions of "File sdDir" gives in logcat same output:

01-01 21:13:06.751  10887-10887/raf.test W/System.err﹕ java.io.FileNotFoundException: /storage/extSdCard: open failed: EISDIR (Is a directory)
01-01 21:13:06.751  10887-10887/raf.test W/System.err﹕ at libcore.io.IoBridge.open(IoBridge.java:416)
01-01 21:13:06.751  10887-10887/raf.test W/System.err﹕ at java.io.FileInputStream.(FileInputStream.java:78)
01-01 21:13:06.751  10887-10887/raf.test W/System.err﹕ at raf.test.MBR.buttonOnClick(MBR.java:77)
01-01 21:13:06.751  10887-10887/raf.test W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)
01-01 21:13:06.751  10887-10887/raf.test W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:511)
01-01 21:13:06.751  10887-10887/raf.test W/System.err﹕ at android.view.View$1.onClick(View.java:3719)
01-01 21:13:06.751  10887-10887/raf.test W/System.err﹕ at android.view.View.performClick(View.java:4261)
01-01 21:13:06.751  10887-10887/raf.test W/System.err﹕ at android.view.View$PerformClick.run(View.java:17356)
01-01 21:13:06.751  10887-10887/raf.test W/System.err﹕ at android.os.Handler.handleCallback(Handler.java:615)
01-01 21:13:06.751  10887-10887/raf.test W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:92)
01-01 21:13:06.751  10887-10887/raf.test W/System.err﹕ at android.os.Looper.loop(Looper.java:137)
01-01 21:13:06.751  10887-10887/raf.test W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:4921)
01-01 21:13:06.751  10887-10887/raf.test W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)
01-01 21:13:06.756  10887-10887/raf.test W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:511)
01-01 21:13:06.756  10887-10887/raf.test W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
01-01 21:13:06.756  10887-10887/raf.test W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
01-01 21:13:06.756  10887-10887/raf.test W/System.err﹕ at dalvik.system.NativeStart.main(Native Method)
01-01 21:13:06.756  10887-10887/raf.test W/System.err﹕ Caused by: libcore.io.ErrnoException: open failed: EISDIR (Is a directory)
01-01 21:13:06.756  10887-10887/raf.test W/System.err﹕ at libcore.io.IoBridge.open(IoBridge.java:405)
01-01 21:13:06.756  10887-10887/raf.test W/System.err﹕ ... 16 more

Permisions are:

 <uses-permission android:name="android.permission.read_external_storage"/>
<uses-permission android:name="android.permission.write_external_storage"/>
1

1 Answers

0
votes

I'm not sure you will have that kind of access from a standard Android app without root - there are a few things to consider:

  1. Android gives you file system access from your application - not raw access to partitions.
  2. You typically need to unmount a partition/file system in order to access byte-by-byte since you don't want any permissions to get in your way and you can only unmount as a root user.
  3. If you are root then you can unmount the drive and then issue a dd command to create a new file with a raw image with something like:

    Runtime.getRuntime().exec("su -c dd if=/dev/deviceToRead1> of=rawOutputFile");

  4. I can tell you that if this is possible from a non-root device then it will treated as a security vulnerability that will be patched ASAP since it would put the entire phone and all of the data on it at risk. If this were possible from a non-root device then it would be possible for any application to steal/read the data from other applications which Android specifically restricts in various ways.

  5. This behavior would likely be blocked by the Google Play verification process if you plan on putting this app in the Google Play store because it is considered malicious.

  6. I can also tell you if you can find a way to make this happen then it will require an exploit that will give you root permissions. Once you have root (via an exploit) then the rest is easy to do with basic command line utilities (mount and dd, specifically).

  7. From a commercial standpoint if this were possible your app would put forensic software out of business :) Keep in mind that forensic software that does exactly this procedure also needs raw access to the partitions that require physical access to the device and/or root access on the device.

  8. The reason why you get the java.io.FileNotFoundException is because you using APIs that give you access on a File System level and what you need bypasses file system functionality. You will never have raw access to a partition using file system calls.

I think that this list answers your question. You won't be able to do it without first getting root otherwise the entire security model of Android would be proven to be useless.