【问题标题】:How to REALLY strip a binary in MacOs如何在 MacOs 中真正剥离二进制文件
【发布时间】:2010-12-28 05:55:00
【问题描述】:

MacOs 10.6,如​​果我有一个文件“unwanted.c”,其中包含:

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

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

现在我做:

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

如果我像大多数人在编写 C++ 代码时那样拆分秘密类的接口和实现,那么剥离的可执行文件中就没有不需要的符号。遗憾的是,我收到了一个包含数千行代码的现有代码库,这不是我的选择之一。

我已经尝试过 -fno-rtti,作为一个疯狂的猜测,但这并没有解决任何问题。我向谷歌众神祈祷,发现很多脱衣舞俱乐部的参考资料,但没有有用的链接。我浏览了 mac 上的 strip、g++ 和 ld 的手册页,没有明显的尝试,尽管“私人外部人员”这个短语很有趣,但我不知道该怎么做。

[更新] 可悲的是,我尝试做一个小例子时出现了问题。这是一个更复杂的例子,它更接近真正的问题,如果它被优化构建,它仍然有不需要的符号。

我为不好的例子道歉。事实证明,很难找到最小的实际问题。非常感谢您的回答,但是,每个答案都让我接近解决方案。

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();
}

【问题讨论】:

    标签: binary executable strip darwin macos


    【解决方案1】:

    使用以下编译行,我成功地从可执行文件中剥离了符号:

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

    鉴于最新的示例文件,结果如下:

    $ 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
    

    【讨论】:

      【解决方案2】:

      这似乎可以按预期工作...:

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

      【讨论】:

      • 我发布了错误的代码。使用正确的示例代码,正如问题现在所读的那样,使用类定义内的方法的实现,strip 说:strip:由无法删除的间接符号表条目引用的符号:/Users/michael.toy/不需要的 __ZN12secret_thing21revealing_method_nameEv __ZN12secret_thingC1Ev
      • 但是答案非常有用,因为它给了我更多的谷歌素材,该错误字符串确实揭示了一些更有趣的调查领域。
      【解决方案3】:

      听起来您真正想要的不是剥离可执行文件,而是混淆其符号表。我不确定,但也许像this 这样的东西会有所帮助。至少,“C++ 符号表混淆器”可能是一个更好的谷歌搜索字符串..

      【讨论】:

      • 我真的想剥离可执行文件。但是,这可能会出现在“我希望我永远不需要实施的备份解决方案”标题下的笔记本中。它就在“编写我自己的后处理器,它链接需要这些符号的未链接内容,然后剥离符号”的正上方
      【解决方案4】:

      鉴于您发布的示例代码,添加“-O”优化标志会导致编译后nm 不显示这些符号。

      【讨论】:

      • 已经发布了一个更接近实际问题的示例,该示例仍然存在问题。将我带到这一点的原始应用程序是经过优化的。感谢您的回复。
      猜你喜欢
      • 2020-01-23
      • 2014-05-06
      • 1970-01-01
      • 2014-03-06
      • 2013-04-05
      • 2012-10-22
      • 2014-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多