7

I'm looking for a fast way to check if a ELF binary is a shared object or a position independent executable. I think a can do that by checking the contained symbols / functions. I'm looking for a more efficient way of not having to read the complete file. I have to perform the check on different platforms, at least Android, Linux (32 and 64 bit).

Alex Lauerman
  • 2,152
  • 1
  • 13
  • 10
Uhli
  • 323
  • 4
  • 19
  • On Solaris and old versions of Android there exists a `DF_1_PIE` flag (a bit of the `DT_FLAGS_1`) that is supposed to tell you exactly this. The story of this field on Linux is really amusing. Quoting from a paper by Denis Silakov: "dynamic entry DT_FLAGS_1 was first added in the LSB 1.0, withdrawn in the LSB 1.2, added once again in the LSB 1.3 and finally dropped in the LSB 2.0." – Fizz Jan 24 '15 at 18:05

2 Answers2

6

I'm looking for a fast way to check if a ELF binary is a shared object or a position independend executable.

There is no way to check: a PIE executable is a shared object.

I think a can do that by checking the contained symbols / functions.

Symbols can be stripped, and once they are, you can't tell.

shared objects and executables they normally differ by the linked startup code

That's true: the PIE is normally linked with Scrt1.o, but a shared library is normally not. But there is nothing to prevent a shared library to be linked with Scrt1.o as well, and in a stripped binary even finding that startup code may be somewhat problematic.

If what you really want is to distinguish between a shared library and a PIE executable which you built yourself (rather than solving a general case of any shared library and any PIE), then checking for presence of PT_INTERP (readelf -l a.out | grep INTERP) is likely the easiest way to go: a PIE executable is guaranteed to have PT_INTERP, and shared libraries normally don't have it (libc.so.6 is a notable exception).

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • When Creating shared objects and executables they normally differ by the linked startup code. Is there really no difference between PIEs and shared objects? – Uhli May 03 '13 at 10:09
  • 1
    For more about what `PT_INTERP` does see http://www.cs.virginia.edu/~dww4s/articles/ld_linux.html – Fizz Jan 24 '15 at 04:06
  • 1
    By the way, you can run `libc.so.6` as a program (and it prints some info); its `.interp` section is not some kind of fake/artifact. – Fizz Jan 24 '15 at 17:41
  • 1
    N.B.: this is how [IDA 6.7 does it too](https://www.hex-rays.com/products/ida/6.7/): "ELF: if a dynamic shared object file has ".interp" section, do not mark it as DLL (it's a position-independent executable)". – Fizz Jan 24 '15 at 18:12
0

Try the elfutils and the included program eh-readelf:

eh-readelf --file-header $ELFFILE

showw you the file header and what kind of file it is:

...
Typ:                               EXEC (Executable file)
...

or

Typ:                               DYN (Shared object file)

In combination with a little sed line you should get the results you want.

akluth
  • 8,393
  • 5
  • 38
  • 42
  • 3
    seems that does not work for PIEs (executables build with g++ and flags -fPIC -pie). The type for the executable is also DYN. – Uhli Apr 30 '13 at 15:03