Hiding Symbols in ELF Binaries
Under Linux when you compile C++ code using GCC or Clang there ends up being tons of debugging information that simply should not be there when you are not releasing open source software. The
strip command does not do enough to remove that information.
In order to do this you need to pass
-fvisibility-inlines-hidden to the compiler. This will hide symbol names and reduce the size of the binary. However, if you are linking to something like
boost, you won’t be able to hide symbols for the entire binary. In that case, you need to create two header files to programmatically change the visibility of your
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) #pragma GCC visibility push(hidden) #endif
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) #pragma GCC visibility pop #endif
In every code file / header file you’ll need to do this:
... other includes #include "visibility_hidden.h" ... your code #include "visibility_pop.h"
After you compile your program, you should then run
strip --strip-all --discard-all ... and also
sstrip ... from ELF Kickers.
Here’s a quick Python script I wrote to add the headers to .cpp files on Windows. It will look for the
stdafx include and insert the visibility include underneath it then add the pop header to the end of the file.
import os stdafx = '#include "stdafx.h"' for name in os.listdir(): if not name.endswith('.cpp'): continue with open(name, 'r', newline="\r\n") as f: text = f.read() if text.find('visibility') != -1: continue idx = text.find(stdafx) if idx == -1: continue text = text[:idx + len(stdafx)].strip() + "\r\n" + '#include "visibility_hidden.h"' + text[idx + len(stdafx):] text += "\r\n\r\n" + '#include "visibility_pop.h"' with open(name, 'w', newline='') as f: f.write(text)