regularfry regularfry - 1 year ago 78
Linux Question

Accessing data appended to an ELF binary

I have a static ELF binary which reads data from a zipfile. In order to simplify distribution, I want to append the zipfile to the binary, like so:

$ cat >> mybinary

I know that doing so won't damage mybinary, but I don't know how to access the contents of having done so. Is it possible? If so, how?

In the past, I've used the trick of appending the data then appending the length of the data, so that all I have to do is open the binary, read the last int of the stream, rewind that length then start unzipping, but that won't work here for various reasons (for instance, I can't guarantee that the file will still be on disc when the zipfile comes to be needed).

Super-extra-doubleplus-points all round if the solution works across OS X and MinGW.

Answer Source

On the assumption at the start of the execution of the application you have access to the file, then opening a handle to it should prevent the operating system from obliterating the file on-disk until the last reference to the file has been closed. This would allow you to seek through the file to you heart's content, using that file handle without worry.

Create a global variable:

int app_fd;

The process for most of these is the same, in the main routine, simply issue:

app_fd = open(argv[0], O_RDONLY);

at the start of execution. When it comes to the point in the execution that you need to access the zip file, then simply use the file descriptor, rather than the filename.

At run-time, if you don't have some form of handle to the original contents of the application, then you will probably not be able to access the content of the zip file. This is due to the loader only mapping in the sections of the file that are expected. The content at the end of the binary would be considered garbage and not mapped in.

To accomplish the mapping of the zip file into memory, you would need to follow a different tack. You would need to embed the .zip into an ELF(linux)/COFF(Windows)/Mach-O(Mac OS X) section of the binary that has properties set such that it is guaranteed to be mapped into the application (this requires a lot of pre-work in the app, and a lot more post-work in the processing). It's not trivial, and probably involves quite a bit of coding to get it right for each of the platforms.

As an aside, it is not trivial to delete an application from a windows system while that application is running (I think you can move it if it resides on NTFS though).