如何避免 iOS 二进制文件中的符号和源路径?

Posted

技术标签:

【中文标题】如何避免 iOS 二进制文件中的符号和源路径?【英文标题】:How to avoid symbols and source paths in iOS binary? 【发布时间】:2011-12-31 08:37:42 【问题描述】:

当我编译我的 ios 应用程序的 release 版本时(基于 Apple 提供的标准 iOS 应用程序模板),查看生成的可执行二进制文件,我看到各种符号,甚至本地 cpp 源和那里的标题路径。我真的很困惑为什么会这样(我没有启用 RTTI *)。尤其是源文件路径让我在全球发送这个应用程序时感觉不舒服(为什么每个人都能看到我的开发机器的目录布局?)。

以下是两段(随机挑选、审核的)摘录:

TS/../ACTORS/CActorCanvasCharPart.cpplastMeshcapVerticesOFF BOUNDSupload VERTICES: %d 20CActorCanvasCharPartgrassscrub/Volumes/Data/iOS_projects/code/MyAppName_proj/MyAppName/source/STATES/GAMES/2/CStateGame2_grass.cppbaseShadowmowerstartmowerloopmowermowerCharcutGrassChargrassStuffgrassParticles/Volumes/Data/iOS_projects/code/MyAppName_proj/MyAppName/source/STATES/GAMES/2/CStateGame2_grass.h17CStateGame2_grasssinwriteStroke/Volumes/Data/iOS_projects/code/MyAppName_proj/MyAppName/source/STATES/GAMES/2/CStateGame2_flowers.hflowerBedsandTrailclickstart3inplace2sandDrag/Volumes/Data/iOS_projects/code/MyAppName_proj/MyAppName/source/STATES/GAMES/2/CStateGame

这里有很多用于自定义类型和结构的符号:

CAssetMgr="_vptr$CMgrBase"^^?"pMain"^CMain"inited"B"curveCount"S"curveSpecs"^CCurveSpec"gameSpecs"[23CGameStateSpec="header"SpecDiskHeader="type"i"version"S"gameID"C"backgroundColor"CRGBAcolorf="r"f"g"f"b"f"a"f"clickPointColor"CRGBAcolorf="r"f"g"f"b"f"a"f"clickPointIconColor"CRGBAcolorf="r"f"g"f"b"f"a"f"hintColor"CRGBAcolorf="r"f"g"f"b"f"a"f]"currentFont"^CCharset"userCharParts"^^CCharPart"words"CDataSet<CName4,CCharArray>="_vptr$CObjectBase"^^?"pMain"^CMain"count"i"data"*"dataSize"l"sets"CDataSet<CName16,CCharArray>="_vptr$CObjectBase"^^?"pMain"^CMain"count"i"data"*"dataSize"l

这可以避免吗,如何避免?

*更新:我刚刚发现 RTTI 默认是开启的。所以我清理了目标,禁用了 RTTI (GCC_ENABLE_CPP_RTTI = NO) 并重新编译。我仍然在二进制文件中看到很多符号和源路径。

更新 2:我检查了应用商店中的其他一些应用,其中许多还显示了它们的源文件路径。很吓人,如果你问我:

Joined Up Lite /Users/lloydy/Documents/Development/iPhone/ABC Joined Up/main.m /Users/lloydy/Documents/Development/iPhone/ABC Joined Up/Classes/SettingsView.m

Crayon Physics /Users/smproot/Desktop/unzip/CrayonPhysics/v104/Classes/crayon/src/ceng/gameutils/killspriteslowly/killspriteslowly.cpp /Users/smproot/Desktop/unzip/CrayonPhysics/v104/Classes/crayon/src/ceng/tasks/task/sdl/mixer/ctaskaudiosdlmixer.cpp

Wall Times /Users/fred/_WORK/ZDNDRP/WallTimes/main.m /Users/fred/_WORK/ZDNDRP/WallTimes/Classes/SystemCategories.m

Jumbo Calculator /Users/Christopher/Documents/Development/JumboCalculator 1.0.3/main.m /Users/Christopher/Documents/Development/JumboCalculator 1.0.3/Classes/CalculatorFaceViewController.m

【问题讨论】:

***.com/questions/730478/… 我已经尝试了那里列出的所有配置选项,但无济于事:很多 CPP 符号和 很多 文件路径。太糟糕了,它看起来很有希望...... 试试***.com/questions/730478/… 【参考方案1】:

是否在构建设置中勾选了带调试符号?您可以根据配置(构建/发布)执行此操作(或不执行此操作)。您也可以查看Objective-C Code Obfuscation(冗长)。根据我收集的信息,您不能完全删除 Objective-C 信息,因为所有方法调用都是动态完成的,因此库必须具有有关您的类/方法名称的信息才能运行。一个有用的提示here。

如果你有 c++ 代码,那么你可以使用gcc strip utility,虽然我不确定它和 Objetive-C++ 的相似之处,如果不是,你可以将所有 cpp 编译到一个库中,剥离它并链接到它在你的 iOS 项目中。

【讨论】:

是的,为发布配置开启。 我认为你适合 objC,但这个应用程序中只有一小部分 Objective-C。它主要是直接的 cpp,但有些文件是 .mm 的。【参考方案2】:

文件路径很可能来自断言宏,这些宏将__FILE__ 字符串化为它们的失败消息的一部分。 iOS 的 assert(3) 实现就是这样做的,NSAssert 宏也是这样做的。

您可以通过定义 NDEBUG(对于 C 断言)和 NS_BLOCK_ASSERTIONS(对于 NSAsserts)来删除发布版本中的断言。

【讨论】:

【参考方案3】:

在 Xcode 中,将 Deployment Prostprocessing 设置为 Yes 以触发 Xcode 在构建过程中调用 strip 命令。然后通过 nm -a 看不到任何源路径。

但是,我仍然可以通过 strings 命令看到一些 m 文件的源路径:/

【讨论】:

这帮助我剥离了大部分路径。【参考方案4】:

对我有用的是将 Generate Debug Symbols 设置为 No 以进行发布构建。这是在 Xcode 7.2 中的 Apple LLVM 7.0 - Code Generation 下。

【讨论】:

以上是关于如何避免 iOS 二进制文件中的符号和源路径?的主要内容,如果未能解决你的问题,请参考以下文章

如何修复分布式二进制文件中的“符号查找错误”?

恢复二进制文件中的block符号表

Visual Studio - 如何修复二进制项目文件中的路径?

如何使用短完整路径创建符号链接?

如何撤消strip - 即将符号添加回剥离的二进制文件

用外部符号替换 MacOS Mach-O 二进制文件中的静态符号