0

I am building a forensic tool, that shall read and write from file slacks. At the moment I use JNI to call the C functions read() and write() to write a buffer to the FAT SD card (also EXT4 internal memory would be nice). I use those because you can pass the length to read/write thus ignoring EOF. I already tried writing by using a standard write and then truncate it in order to write in the file slack, which works on ubuntu 14.04 but not on Android (API 21). Reading more from a file than the actuall file size does not reflect the flie slack on the SD-card. There are tools e.g. "bmap" or "slacker.exe" (for NTFS) that manage to access file slacks. I am in need of a way to ignore EOF or handle it myself. I would prefere not to change existing file system drivers. I appreciate any suggestions.

here is some sample code (that does not work yet):

jstring
Java_com_example_hellojni_HelloJni_write(JNIEnv *env, jobject thiz, jstring path)
{
char *cpath = (*env)->GetStringUTFChars(env, path, NULL);
int raw_file_descriptor = open(cpath,O_WRONLY,0);
lseek(raw_file_descriptor,0,SEEK_END);
char block_buffer [4096] = "hidden";
int buffer_length = 6;
int wret = write(raw_file_descriptor,block_buffer,buffer_length); // increases file size and moves EOF - I don't want that
LOGD(" char written: %d", wret);
free(cpath);
return (*env)->NewStringUTF(env, "write ok ");
}

jbyteArray
Java_com_example_hellojni_HelloJni_read2(JNIEnv *env, jobject thiz, jstring path) {

char *cpath = (*env)->GetStringUTFChars(env, path, NULL);
LOGD("open %s with ", cpath);
int raw_file_descriptor = open(cpath,O_RDONLY,0);
char buffer [4096];
int readretval = read(raw_file_descriptor, buffer, 50); // stops at EOF - I want it to continue reading all 50 bytes from the SD-card - This gives me the file content until EOF and then I get some random characters from the uninitialized buffer. 
LOGD("read (%d) buffer with length  %d: %s", readretval, sizeof(buffer), buffer);
int i; // Debug code
for (i=0; i < 49; ++i) {
    LOGD("%c",buffer[i]);
}

close(raw_file_descriptor);
free(cpath);
return NULL;
}
hengsti
  • 310
  • 3
  • 11
  • `lseek()` to the end of a file followed by `write()` does not guarantee that you write to the end of the file - the calls are not atomic. Call `open()` with the `O_APPEND` flag set. And your code *won't* work if you call `free()` on the `char *` returned from `GetStringUTFChars()`. See http://stackoverflow.com/questions/5859673/should-you-call-releasestringutfchars-if-getstringutfchars-returned-a-copy?rq=1. Also, `read()` and `write()` both return `ssize_t`, not `int`. They are not the same. JNI is **extremely** unforgiving. – Andrew Henle Jan 13 '16 at 15:08
  • Clearification: the code above complies and runs. Just not the way I intent it to. @AndrewHenle 1. **lseek()** and **write()** works fine for my purposes. 2. Thank you for pointing out the **GetStringUTFChars()** this may make my program more stable. 3. As defined in **types.h** for C ssize_t is in fact a int. I accept the improvement though. And I agree in to the unforgivingness of JNI. Thank you for the comment – hengsti Jan 14 '16 at 10:36
  • *As defined in types.h for C ssize_t is in fact a int* [Oh really?](https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models) Types in standards - such as `read()`/`write()` returning the type `ssize_t` - are done for a **reason**. But if you think you're more knowledgeable about such things than the authors of those standards and you know better because you looked in `types.h` on **one** platform for **one** implementation and saw *ssize_t is in fact an int*, go right ahead. – Andrew Henle Jan 14 '16 at 11:07
  • I already agreed to use ssize_t because **read() / write ()** do return ssize_t and not int. This is a topic secondary to my problem. Let's focus at a solution - How to read and write to the file slack. Shall we? – hengsti Jan 14 '16 at 19:49
  • for your reference that wikipedia is not always right check the [android source code](https://android.googlesource.com/platform/bionic/+/b6e2248%5E!/) – hengsti Jan 14 '16 at 20:22

1 Answers1

0

Apparently this way is impossible. But with root it is possible to write file slack via mounting a loop back device. Still, ignoring EOF is not possible without changing the driver or implementing your own kernel module.

hengsti
  • 310
  • 3
  • 11