Search code examples
c++cstringcmakestrip

How can I make a C++ program hide the source file path from the "strings" command?


The strings command allows you to search for strings in binary files.

So if I use the strings command and search for .cc with grep, I get the following results.

strings myProgram | grep '.cc'

> 
...
{hidden}/vcpkg/buildtrees/gflags/src/v2.2.2-d51934acae.clean/src/gflags.cc
{hidden}/vcpkg/buildtrees/gflags/src/v2.2.2-d51934acae.clean/src/gflags_reporting.cc
{hidden}/vcpkg/buildtrees/gflags/src/v2.2.2-d51934acae.clean/src/gflags_completions.cc
...

It adds the paths to all the source files locally, not just the ones installed by vcpkg. What should I do?

I tried building with cmake and adding -s, -g to cxxflags, but to no avail.


Solution

  • There are 2 main reasons for source filenames to appear in the executable:

    • if you compile with debugging information, using -g for example. Don't ship a debug build and strip debugging information from the executable by running strip with the appropriate flags, read the man page for your system.

    • if you use the __FILE__ macro, either directly in your program or macros or indirectly through assert macros or similar features. You can disable runtime checks performed by the assert calls by defining NDEBUG at compile time, for example for a -DNDEBUG compiler option. This should be the default for non debug builds, but check the compiler configuration.

    Fixing the above problems should remove these strings from the executable file, but this is only the tip of the iceberg:

    • other string literals will still be trivial to extract with the strings command or other tools,
    • data files may contain sensitive information,
    • system calls are trivial to track with strace,
    • most C library call can be tracked and replaced using llpreload. Using static linking can make this more difficult, but may cause portability problems and is not supported for selected libraries on some targets, such as macOS.
    • the code can always be reverse engineered with modern tools that are amazingly efficient, some of which even produce compilable C or C++ source code.

    Needless to say, motivated hackers can investigate and not only find out what tools and/or technologies were used, but also what algorithms, what configuration parameters, data protection schemes, encryption methods and keys, licensing checks, etc. Hackers are available for hire if your client does not have them in house.

    You can hide some stuff from amateurs and make it a bit harder, but be aware that such protection is very limited, like anti-theft devices used in department stores.

    You can also look for executable compressors and/or obfuscators that may be available for the target system: they could reduce the executable size and hide most strings at the same time, but uncompressing is not difficult for savvy developers, and running the program from a debugger lets the embedded loader do the decompression at startup time. Again some of these tools are more advanced than others and raise the bar a little, but not sufficiently to protect yourself from dishonest clients.