Question

MacOs 10.6, if I have a file "unwanted.c" which contains:

class secret_thing {
public:
secret_thing() {}
void revealing_method_name() {}
};

main()
{
    secret_thing obj;
    obj.revealing_method_name();
}

Now I do:

$ g++ unwanted.c -o unwanted
$ strip unwanted
$ nm unwanted | grep secret
0000000100000eb8 T __ZN12secret_thing21revealing_method_nameEv 
0000000100000eae T __ZN12secret_thingC1Ev

If I split out the interface and implementation of the secret class, as most people do when writing C++ code, then there are no unwanted symbols in the stripped executable. Sadly, I am handed an existing code base of many thousand lines of code and this isn't one of my choices.

I have tried -fno-rtti, as a wild guess, and that didn't fix anything. I have prayed to the Google gods and found many references to strip clubs, but no helpful links. I have skimmed the man pages for strip, g++, and ld on the mac, and there were no obvious things to try, though the phrase "private externs" was intriguing, I couldn't figure out what to do about that.

[ update ] Sadly, there turns out to be a problem with my attempt to make a small example. Here is a more complicated example, which is closer to what the real problem is, which still has unwanted symbols if it is built optimized.

I apologize for the bad examples. It turns out to be hard to find the smallest actual problem. Many thanks for the answers, though, each answer pushes me close to a solution.

class base {
public:
    virtual int revealing_method_name() = 0;
    virtual ~base() {};
};

class secret_thing : public base {
public:
    int revealing_method_name() { return 0; };
};

class other_thing : public base {
public:
    int revealing_method_name() { return 1; };
};

int main(int argc, char**)
{
    base *object = 0;
    if( argc > 1 ) object = new secret_thing;
    else object = new other_thing;

    return object->revealing_method_name();
}
Was it helpful?

Solution

Using the following compile line I successfully strip the symbols from the executable:

$ g++ -Xlinker -unexported_symbol -Xlinker "*" -o executable file.cpp
$ strip executable

Given the latest sample file, this results in:

$ nm executable
                 U __ZTVN10__cxxabiv117__class_type_infoE
                 U __ZTVN10__cxxabiv120__si_class_type_infoE
                 U __ZdlPv
                 U __Znwm
                 U ___cxa_pure_virtual
                 U ___gxx_personality_v0
0000000100000000 A __mh_execute_header
                 U _exit
                 U dyld_stub_binder

OTHER TIPS

It sounds like what you really want isn't to strip the executable, but to obfuscate its symbol table. I'm not sure, but perhaps something like this would be helpful. At least, "C++ symbol table obfuscator" is probably a better Google search string..

This seems to work as desired...:

$ strip unwanted
$ nm unwanted | grep secret | cut -f 3 -d ' ' > /tmp/remove
$ strip -R /tmp/remove unwanted

Given the example code you’ve posted, adding the ‘-O’ optimisation flag results in those symbols not being shown by nm after compilation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top