开发者

How to REALLY strip a binary in MacOs

开发者 https://www.devze.com 2022-12-14 21:53 出处:网络
MacOs 10.6, if I have a file \"unwanted.c\" which contains: class secret_thing { public: secret_thing() {}

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 : p开发者_运维百科ublic 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();
}


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


This seems to work as desired...:

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


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..


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

0

精彩评论

暂无评论...
验证码 换一张
取 消