https://github.com/preemptive/PPiOS-Rename.git
git clone https://github.com/preemptive/PPiOS-Rename
$ svn co --depth empty https://github.com/preemptive/PPiOS-Rename
Checked out revision 1.
$ cd repo
$ svn up trunk
基于windows的抢先保护- 重命名,或者 ppios重命名为模糊的objective-c 类,协议,属性和方法名称,在iOS应用程序中的obfuscating。 它是来自 Polidea的 iOS-Class-Guard插件,有大量的改进和修改。
ppios重命名通过生成一组特殊的#define
语句来工作( 比如。 #define createArray y09FzL7T
) 在编译期间自动重命名符号。 它包含了许多特性:
ppios重命名不仅仅是你的项目代码。 它还通过查看所有外部/依赖框架和核心数据( xcdatamodel ) 文件自动查找要排除的符号。 重命名的符号也将应用到 xib/Storyboard 文件,以及项目中任何开放源码CocoaPods库。
抢先解决方案还提供了另一个产品,抢先保护,用于控制流管理,包括额外的模糊。 这是为了与 ppios ControlFlow 一起工作;它们提供了比单独提供更好的保护,比单独提供更多的保护。
在 GNU ppios v2下,是许可的,但商业支持也可以通过商业支持协议提供,通过商业支持协议。 有关详细信息,请参见 LICENSE.txt。
开发人员注:这个 fork 包含了对git历史的大量重写,从而修复了最初的repo 语句中的corrupted commit。 更详细的信息在变更日志。
ppios重命名被设计为在构建和发布过程的两个阶段中使用。 在第一个阶段,ppios重命名分析应用程序的编译版本,确定应该重命名哪些符号,并将哪些符号排除在重命名之后。 在第二阶段,重命名将那些重命名规则应用到应用程序的source,这样,从该源代码生成的下一个版本就会被混淆。 这两个阶段可以通过多种方式集成到你的构建和发布过程中,包括 back-to-back。
ppios-rename --analyze [--symbols-map symbols.map] <Mach-O binary>
在这个阶段,ppios重命名分析unobfuscated编译的构建,以确定哪些符号应该被重命名。 它解析所有类。属性。方法和我在该文件中定义的变量,将所有符号添加到一个"重命名列表"。 然后使用标准保留词。依赖框架符号。核心数据( xcdatamodel ) 文件中的符号和通过 命令行 参数显式排除的任何符号构建一个"排除列表"。 它组合这些列表来生成将被重命名的符号的最终列表。
对于每个这样的符号,它生成一个随机标识符,并将"映射文件"( symbols.map
,默认情况下) 写入新的名称。 映射文件是分析阶段的最后输出,是下一阶段的必要输入,模糊源是。
注意:通常在这一点上,你应该归档 symbols.map
文件。 你将需要它能够混淆由模糊基于它生成的构建所生成的任何堆栈跟踪。
ppios-rename --obfuscate-sources [--symbols-map symbols.map]
在这个阶段,ppios重命名读取映射文件并生成一个头文件(。symbols.h
,默认情况下),该文件包含要重命名的每个符号的#define
。 然后在源代码中找到适当的预编译头( .pch
) 文件,并添加一个带有头文件路径的#include
。 在源树中找到所有 xibs/Storyboard,并直接更新这些文件中的名称。
现在,源代码修改就绪,你就可以像往常一样构建应用程序。 它将用模糊的符号编译。 ( 而且任何开源CocoaPods也将使它的符号模糊。)
注意:模糊处理源阶段修改了应用程序的源代码,但你不应该签入它所做的更改。 如果这样做,下次需要执行分析阶段会导致错误,并会导致 Storyboard 中的出现问题。 我们建议在版本( 自动或者自动) 生成过程中使用,阶段,在进行进一步开发之前,应该先清理/重置源代码树。
ppios重命名支持应用程序开发:
使用:
我们建议从发布的页面下载一个二进制版本。 存档包含一个独立的二进制文件,你可以复制到系统上的适当位置,比如 /usr/local/bin
。 我们建议确保你的位置在你的路径上。 发布存档还包括其他文件,如本自述文件。变更日志和我们的许可证。
基本过程是:
使用 ppios重命名,第一次使用将执行Analyze分析:
ppios-rename --analyze/path/to/program.app/program
分析过程生成 symbols.map
,该文件包含一个符号映射,该映射可以用于在崩溃时解码堆栈跟踪。 在发布过程中创建的符号文件应始终存档,以便以后使用。
然后,可以使用以下方法完成应用重命名步骤:
ppios-rename --obfuscate-sources
注意:模糊处理源阶段( 在应用重命名步骤中调用) 修改了你的应用程序的源代码,但是你不应该签入它所做的更改。 如果这样做,下次需要执行分析阶段会导致错误,并会导致 Storyboard 中的出现问题。 我们建议在版本( 自动或者自动) 生成过程中使用,阶段,在进行进一步开发之前,应该先清理/重置源代码树。
一旦你使用 ppios重命名插件,将它作为构建过程的一部分集成到Xcode项目中,就更容易使用。 可以通过以下过程设置这里过程:
在Xcode中打开项目。
转到项目导航器,然后选择项目。
选择打开"显示项目和目标列表"( 靠近主窗格左上角)的icon。
选择要模糊的目标,右键单击,然后选择重复的( 命令d )。
注:可能需要设置目标的签名详细信息,以便生成成功完成。 可以在常规选项卡上配置这些选项。
注意:如果对框架项目应用这些更改,那么你可能需要在新的目标名称中使用 underscores underscores underscores spaces spaces。
使用缺省的NAME 复制目标复制相关的.plist
文件。 重命名 .plist
file:
Info.plist File
的值,使它的与原始目标的值一致( 类似于 <project-name>/Build and Analyze <original-target-name>-Info.plist
)。.plist
文件移动/重命名为新的NAME 和路径( 比如。 使用查找器)。.plist
文件中。选择生成阶段。
通过选择 +
( 在目标依赖关系之上),然后选择new运行脚本阶段( 它应该作为最后一个阶段运行,默认情况下),添加脚本阶段。
将阶段从 Run Script
重命名为 Analyze Binary
。
展开阶段,并在其中显示 Type a script or.. .
粘贴以下脚本,以调整正确的路径:
PATH="$PATH:$HOME/Downloads/PPiOS-Rename-v1.2.0"
[["$SDKROOT" == *iPhoneSimulator*.sdk* ]] && sdk="$SDKROOT"
test -z"$sdk" && sdk="$CORRESPONDING_SIMULATOR_SDK_DIR"
test -z"$sdk" && sdk="$CORRESPONDING_SIMULATOR_PLATFORM_DIR/Developer/SDKs/iPhoneSimulator${SDK_VERSION}.sdk"
ppios-rename --analyze --sdk-root"$sdk""$BUILT_PRODUCTS_DIR/$EXECUTABLE_PATH"
从菜单中,选择产品| 方案| 管理方案。
如果启用了Autocreate方案,则将创建一个新的复制目标方案。 将它的重命名为 Build and Analyze <original-scheme-name>
,并关闭对话框。 否则,为构建和分析目标创建一个新的方案。
再次复制原始目标,将它的重命名为 Apply Renaming to <original-target-name>
同样,可以根据需要重命名 Info.plist
文件,如在步骤 6中所述。
注:可能需要设置目标的签名详细信息,以便生成成功完成。 可以在常规选项卡上配置这些选项。
如果对框架项目应用这些更改,那么你可能需要在新的目标名称中使用 underscores underscores underscores spaces spaces。
删除这里目标中的所有生成阶段。
如果存在任何目标依赖项,也可以删除它们。
添加脚本阶段,并将它的重命名为 Apply Renaming to Sources
( 这应该是该目标的唯一实际操作)。
粘贴下面的脚本,再次调整正确的路径:
PATH="$PATH:$HOME/Downloads/PPiOS-Rename-v1.2.0"
ppios-rename --obfuscate-sources
编辑这里新目标的方案( 或者添加一个),将方案重命名为 Apply Renaming to <original-scheme-name>
这些更改应该提交到源代码管理,因为构建目标将改变源代码的方式。
当准备开始测试模糊生成时:
确保已经提交所有本地源代码更改。
使用生成和分析方案生成,生成符号文件 symbols.map
。
提交或者保存 symbols.map
文件。
使用应用重命名方案进行生成,该方案将重命名应用于源。
使用原始方案生成。
在继续开发之前恢复对源的更改。
一旦将重命名应用到源,就可以使用原始方案( 只要你没有恢复源代码) 重复构建和测试不同目的地的过程( 步骤1.
如果修改原始构建目标或者方案,请确保删除并重新创建生成和分析目标,如下所示。 在某些条件下,需要重新创建应用重命名目标和方案。
面向web的抢先保护- 重命名 ( ppios重命名) 提供"重命名"混淆,这是通常应用于应用程序的混淆类型,主要用于应用程序,知识产权盗窃,软件盗版,篡改和数据损失。 然而,还有其他的模糊技术,对于严重保护应用程序非常重要。 抢先解决方案提供另一产品,为iOS控制流控制流,其中包括额外的混淆转换。 这是为了与 ppios ControlFlow 一起工作;它们提供了比单独提供更好的保护,比单独提供更多的保护。
有关使用它们的简单说明可以在 ppios ControlFlow 文档中找到。
下面是应用模糊处理的效果的演示。 优化的二进制使用料斗反向工程,没有调试符号。 这是一个现实的例子,攻击者将使用反向工程工具来看到它。
原始代码:
反向工程代码:( 攻击者会看到什么)
带有ppios重命名的反向工程代码:
反向工程代码,带有 ppios重命名和 ppios ControlFlow:
如上所述,代码的理解相对简单,无需混淆。 在应用基于java的ppios重命名方法后不明显,但是仍然可以通过使用的系统框架方法推断逻辑。 最后,在最后一个版本中理解逻辑是极其困难的:ppios ControlFlow 模糊 obfuscation。 反编译的代码实际上比这里显示的长。
一个示例项目演示了混淆iOS应用程序的过程,在GitHub上可以看到: 这个项目既可以使用 ,也可以使用/ppios重命名插件,但可以单独检查它们的效果。 已经应用到现有Xcode项目中的所有集成插件的步骤已经应用。 配置也经过调整,以确保使用模糊应用的积极用户体验。 项目的文档详细讨论如何构建和使用示例。如何配置项目以及如何解释生成输出。
.pch
文件在模糊处理源阶段,你可能会遇到错误:
Error: could not find any *-Prefix.pch files under.
这是因为 ppios重命名试图向预编译头文件添加 #include
,而且它找不到合适的文件来添加它。 通常,在 Xcode 6和上创建的项目在默认情况下不包含 .pch
文件。
若要修复这里问题,请按如下所示添加 .pch
文件:
在Xcode转到文件-> 新-> 文件-> iOS -> 其他-> PCH文件。
将文件命名为 比如 MyProject-Prefix.pch
。 ppios重命名查找匹配 *-Prefix.pch
的文件。
在目标构建设置的 Apple苹果 LLVM - 语言部分,将前缀头设置为PCH文件名。
在目标构建设置 Apple Apple Apple Language Language section section section Precompile Precompile Prefix Prefix Prefix Prefix Prefix yes yes yes。
你试图在 static 库或者框架上运行分析。
如果要分析一个 static 库,请按照下面的模糊 static 库中的说明操作。
如果你试图分析一个框架,有时它会工作,如果你在存档时 --analyze
创建的AppName.framework
目录。 尝试从Xcode归档框架并使用在项目数据文件夹的导出中创建的AppName.framework
文件夹( ~Library/Developer/Xcode/DerivedData/ProjectName-.../...
)。
在生成期间,在模糊处理源阶段之后,你可能会看到如下错误:
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_n9z", referenced from:
objc-class-ref in GRAppDelegate.o
如果使用了 unresolved external
函数并使用相同名称命名了方法,则可能还会看到链接器错误。
这些错误通常意味着 ppios重命名混淆一个需要排除的符号。 可以通过搜索 symbols.map
或者 symbols.h
查找引用的符号( n9z
,在本示例中) 来查找符号,以查看原始 NAME 是什么。 然后,可以通过 命令行 参数将符号排除在分析阶段,通过 -F
或者 -x
进行分析,如下所述。
如果 n9z
已经映射到 PSSomeClass
,那么在运行 --analyze
时,你将向参数添加 -F'PSSomeClass'
。!
-F
选项定义对类。协议和类别名称进行匹配的筛选器。 -F
的参数是支持 *
( 任何字符的任意数量) 和 ?
( 任何单个字符)的Pattern。 如果 Pattern的第一个字符是一个 ,那么过滤器将任何匹配的类。协议和类别。! 如果第一个字符是 ,而不是,那么过滤器将包含任何匹配类。协议和类别。
默认筛选器相当于 -F'*'
,系统的行为如同始终指定第一个筛选器一样。 可以在 命令行 上指定其他筛选器,并且每个筛选器都会覆盖之前出现的规则。 例如:
-F '!A?H*' -F 'ATH*'
这将过滤所有以"a"开头的类。协议和类别,有任何下一个字符,然后对类。协议和专门以"ath"开头的类别进行收费。 默认规则中所有其他类都将是"已经过滤"。
筛选模式区分大小写,因此 -F ABC
将与不同。 对字符类有基本支持,因此你可以使用 比如 -F'[Aa][Bb][Cc]'
进行 MATCH。
如果通过 -F
排除项,如果排除的项 MATCHES 一个类,协议或者类别 NAME,则可以根据该名称应用它的他排除。
例如如果排除类 NAME,则下面的内容也将被排除在( 假设"classname"类名称) 中:
也请参见下面关于属性 NAME 排除的部分。
符号过滤器你可以使用分析阶段中的-x
参数来排除特定符号。 例如:
-x 'deflate' -x 'curl_*'
这将排除名为 deflate deflate deflate和符号的符号,这些符号以 curl_。
?
MATCHES 任何单个字符,而 *
MATCHES 包含任意数量的字符。
注:带 -x
的符号排除将被排除,无论正 -F
过滤器( -x
"是否成功。 但是,-x
排除不像 -F
包含/排除那样传播。 例如指定 -F '!*' -F MyClass -x MyClass
将不重命名 MyClass
类本身,但将重命名其中包含的属性和方法。
当排除属性( 通过 -x
或者通过 -F
传播) 时,下列名称也将被排除在( 假定 NAME的属性为 propertyName
) 中:
确保已经排除了分布式头文件中指定的所有类,属性等,如果有人重命名了链接和/或者运行时问题。
架构的未定义符号。: " OBJC_CLASS $_SomeClass", 引用: ObjectFile.o 中的objc-class-ref这里链接问题发生,原因是在分析框架时没有排除 SomeClass
。 分析时将 -F'ClassName'
添加到 命令行。! 然后,你需要对框架进行混淆。构建和重新发布。
由于分析框架时没有排除 propertyName
,因此发生了这里最终用户应用程序运行时故障。 分析时将 -x PropertyName
添加到 命令行。 然后,你需要对框架进行混淆。构建和重新发布。
如果使用外部库提供接口生成器文件,请确保在启动应用程序时忽略这些符号。 你可以在分析阶段使用 -F
选项。
在混淆过程中,KVO会停止工作。 大多数开发人员使用硬编码的字符串来指定 KeyPath。
- (void)registerObserver { [self.otherObject addObserver:selfforKeyPath:@"isFinished"options:NSKeyValueObservingOptionNewcontext:nil]; } - (void)unregisterObserver { [otherObject removeObserver:selfforKeyPath:@"isFinished"context:nil]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:@"isFinished"]) { //.. . } }
这将不起作用属性 isFinished 将获取新的NAME,并且硬编码字符串将不会反映更改。
删除任何 并将它的更改为 NSStringFromSelector(@selector(keyPath))
固定代码的应如下所示:
- (void)registerObserver { [self.otherObject addObserver:selfforKeyPath:NSStringFromSelector(@selector(isFinished)) options:NSKeyValueObservingOptionNewcontext:nil]; } - (void)unregisterObserver { [otherObject removeObserver:selfforKeyPath:NSStringFromSelector(@selector(isFinished)) context:nil]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:NSStringFromSelector(@selector(isFinished))]) { //.. . } }
如果使用序列化( 比如。 NSCoding
或者 NSUserDefaults
),必须从混淆中排除受影响的类。 否则,你将无法生成新符号( 例如。 分析阶段) 不破坏现有数据的反序列化。
当 --obfuscate-sources
在同一源树上使用两次时发生这里错误。 这可能导致你的应用程序不被混淆。 确保源树总是在使用 --obfuscate-sources
之前重置为未修改状态。
当 --analyze
在已经模糊的二进制文件上使用时会发生这个错误。 这可能导致你的应用程序不被混淆。 在尝试运行分析过程之前,确保程序始终从干净和非模糊源代码重新生成。
当要验证混淆或者向AnalysisServices发送模糊的dSYMs时,必须首先找到二进制文件和dSYM文件。
Xcode存档如果你创建档案,Xcode会把它放在档案目录里 ~/Library/Developer/Xcode/Archives/{Date}/{AppName} {Date}, {Time}.xcarchive
在那里,你应该可以找到:
Products/Applications/{AppName}.app/{AppName}
注意:如果你已经将存档上载到 apple,可能是从 bitcode recompiled recompiled或者你需要从 https://itunesconnect.apple.com 下载新的dSYM文件,或者使用下载 dSYMs。 xcode Organizer窗口中的按钮 of。 这个插件下载 dSYMs - 按钮将在存档目录中下载每个架构的一个 dSYM,但是它将被命名为 {SOME GUID}.dSYM
。
如果有 {AppName}.ipa
文件,则需要通过运行 unzip {AppName}.ipa
来提取它。 在 Payload
目录中,你应该可以找到:
{AppName}.app/{AppName}
如果从 命令行 生成( 比如。 xcodebuild
),这通常会创建一个 build
目录。 在 build
目录中,你应该可以找到:
Release-[iphoneos|iphonesimulator]/{AppName}.app/{AppName}
Release-[iphoneos|iphonesimulator]/{AppName}.app.dSYM
要验证你的应用程序是否已经模糊,使用 nm
工具,这是在Xcode开发工具工具中。 运行:
nm path/to/your/binary | less
这将显示你的应用程序中的符号。 如果使用unobfuscated构建执行这里操作,则会看到原始符号。 如果你用模糊的构建来做这个,你会看到模糊的符号。
注意:nm
从二进制文件中删除符号后不能正常工作。 你可以使用 otool
工具,如果你需要检查后的objective-c 符号。
如果 otool
显示不需要的信息,则可以使用 grep
和 awk
过滤这些信息,只显示符号:
otool -o/path/to/your/binary | grep 'name 0x' | awk '{print $3}' | sort | uniq
注意: X__PPIOS_DOUBLE_OBFUSCATION_GUARD__
符号用于帮助确保正确地应用重命名。
ppios重命名允许你反转故障转储文件的模糊处理过程。 这很重要,因此你可以找到崩溃所涉及的原始类和方法。 它使用来自映射文件( 比如 )的信息来实现。 symbols.map
) 修改故障转储文本,用原始名称替换模糊的符号。 例如:
ppios-rename --translate-crashdump --symbols-map path/to/symbols_x.y.z.map path/to/crashdump path/to/output
可以使用 ppios ControlFlow 附带的实用工具来反转dSYMs中混淆的过程。 obfuscated dSYMs让你可以看到自动崩溃报告工具中的原始名称,例如 HockeyApp。Crashlytics。fabric。bugsense/splunk Mint或者 Crittercism。 它使用来自映射文件( 比如 )的信息来实现。 symbols.map
) 生成一个"反向 dSYM"文件,其中含有不模糊的符号名称。 例如:
/usr/local/share/preemptive/PPiOS/bin/llvm-dsymutil -ppios-map=path/to/symbols_x.y.z.map path/to/input.dSYM -o=path/to/output.dSYM
注:如果不通过传递参数指定输出 dSYM,那么输入dSYM本身的将通过运行 llvm-dsymutil
命令来改变。
生成的dSYM文件可以上传到 比如 HockeyApp。
dSYMs使用的二进制格式必须由 llvm-dsymutil
正确解释。 因此,来自 ppios ControlFlow的llvm-dsymutil
版本必须 MATCH 用于生成dSYMs的Xcode的主要版本。 例如来自 ppios ControlFlow 版本 2.5的llvm-dsymutil
只能用于 Xcode 8,这是该版本的ppios ControlFlow支持的最新版本。
,ppios ControlFlow 支持 Xcode,dSYM翻译不可用于使用 Xcode 9构建的应用程序或者库。
开发人员注意:原始 --translate-dsym
逻辑与小符号名不正常,而且模糊名称不同于原始的大小。 它已经被 ppios ControlFlow 中的一个特性取代。
分析动态框架类似于分析应用程序,但是可能需要更多的过滤器。 要启动,请使用:
ppios-rename --analyze/path/to/ProjectName.framework/ProjectName
而不是看到 Processing external symbols from ProjectName...
你将看到,对于其他框架,你应该看到 Processing internal symbols from ProjectName...
如果 --analyze
没有正确找到框架,那么添加 --framework
参数:
ppios-rename --analyze --framework ProjectName/path/to/framework/executable
然后你需要确定并使用适当的过滤器。 根据框架中包含的public api数量,你需要选择两种方法之一:
.h
文件中提到的所有内容。-F'*'
( 排除所有内容) 开始,然后包含那些标题中没有提到的内容。!一旦使用适当的筛选器运行 ppios-rename --analyze
,继续执行标准 ppios-rename --obfuscate-sources
步骤,并遵循它的他指令。
web服务不能直接处理 static 库,但是它可以解决技术问题,防止直接处理。 虽然初始设置有些复杂,但是一旦完成了构建过程,构建过程就不会比使用 ppios重命名插件更复杂了,其他项目。 基本的想法是:
将 static 库导入包装应用程序中,将提取所有这些类以及它们引用到应用程序中的所有类。 将这里用作分析的基础将重命名库中的所有符号。 由于API中的所有标识符都将被重命名,因此生成的库将不可用。 为了使 static 库外部可以用,需要在重命名时排除所有 public 符号。 必须手动完成这些类别。 ppios-rename
会自动排除这些类的所有成员,一旦类被排除。
过程如下所示:
如果 static 库项目( 在这里被称为 StaticLib
) 还没有包含工作区,请创建一个:
File
> New
> Workspace.. .
。LibWorkspace
) 选择适当的NAME,并将它的保存到包含 StaticLib
项目目录的目录中。 见下面显示的源树布局。File
> Add Files to"LibWorkspace"...
StaticLib/StaticLib.xcodeproj
。从工作空间中,创建一个新项目:
在Xcode中,转到 File
> New
> Project.. .
。
选择 iOS
,并在 Application
部分选择 Single View Application
。
选择选项时,将 Product Name
指定为 WrappingApp
,并确保选择 objective-c 作为语言。
指定存储 WrappingApp
项目的目录,作为库目录 static 项目的兄弟项。 这些指令需要源树布局,如下所示,所有内容均位于源代码管理下的someParentDir
之下:
someParentDir/StaticLib/StaticLib.xcodeproj
someParentDir/LibWorkspace.xcworkspace
someParentDir/WrappingApp/WrappingApp.xcodeproj
在这里对话框的底部,指定 Add to:
的LibWorkspace
工作区,然后选择 Create
。
选择WrappingApp目标,然后清理并生成项目以验证项目是否生成。
转到项目导航器,选择 WrappingApp
项目,然后选择 WrappingApp
目标。
选择 General
,滚动到底部,然后选择要添加到列表中的+
Linked Frameworks and Libraries
添加 libStaticLib.a
。这应该出现在对话框的Workspace
部分下面。 添加 StaticLib
之后,你可以能需要关闭和重新打开 LibWorkspace
,以便能够正确地显示它。
选择 Build Settings
,搜索 other linker
,并设置 Other Linker Flags
以包含 -ObjC
。
清理并重新生成以验证工作区是否正确生成。 它应该首先构建 static 库,然后构建应用程序。
设置 ppios重命名以分析应用程序:
Project Setup
中的指令 5 -12,但将它们应用到 WrappingApp
,而不是 static 库,并修改原始的WrappingApp
目标。 不需要复制目标。Build and Analyze WrappingApp
目标。Generated unique symbols
的数目。 这个数字应该包括所有的public 和 StaticLib
中所有非公共符号。 这也将包括应用程序本身中的少量符号。 这些应该是良性的,但如果需要,可以手动排除。public-types.list
。 使用以下过程创建列表,或者手动创建列表。 过程要求 public 头文件的名称对类型的名称进行 MATCH,或者遵循 AffectedType+CategoryName.h
约定。转到报表导航器,查看日志的生成,为其中一个头文件选择一个复制文件任务,右键单击并单击。
将结果粘贴到文本编辑器中。
选择并复制生成输出路径。 这应该具有以下形式: <products-directory>/include/StaticLib
,并包含字符串 /DerivedData/
。
在 命令行 中,从 someParentDir
运行以下命令:
# Replace".../include/StaticLib" with the path
# Replace"StaticLib" with the name of the umbrella header
ls".../include/StaticLib" | sed 's/.*+//' | sed 's/[.]h$//' | grep -v StaticLib> public-types.list
# Or omit the grep -v part if you have no umbrella header
ls".../include/StaticLib" | sed 's/.*+//' | sed 's/[.]h$//'> public-types.list
# verify the contents
head public-types.list
# SLAPublicClass
# SLProtocolForSomething
# SLSomeCategory
#.. .
注意:这是一个额外的维护点: 由于库的public API中添加或者删除了类型,因这里需要相应地更新 public-types.list
。
用以下方法替换分析脚本(。Analyze Binary
运行脚本阶段),以排除重命名的public 类型:
PATH="$PATH:$HOME/Downloads/PPiOS-Rename-v1.2.0"
[["$SDKROOT" == *iPhoneSimulator*.sdk* ]] && sdk="$SDKROOT"
test -z"$sdk" && sdk="$CORRESPONDING_SIMULATOR_SDK_DIR"
test -z"$sdk" && sdk="$CORRESPONDING_SIMULATOR_PLATFORM_DIR/Developer/SDKs/iPhoneSimulator${SDK_VERSION}.sdk"
ppios-rename --analyze --sdk-root"$sdk"
$(for each in $(cat.. /public-types.list) ; do printf -- '-F!%s '"$each" ; done)
"$BUILT_PRODUCTS_DIR/$EXECUTABLE_PATH"
重复步骤 3. iii - 3. iv。 唯一符号的数量应该减少,但仍然是重要的。 这应该是所有非公共符号( 非公共符号,其中没有具有相同名称的public 符号)的计数。
查看将在 命令行 ( 假设所有类型名都以两个字母 SL
开头) 上执行以下命令重命名的类型列表:
cat WrappingApp/symbols.map | awk '{print $3}' | sed 's/[",]//g' | grep '^SL'> renamed-types.txt
修改 static 库项目以应用重命名:
按照上面的中的指令 13 -16,将它们应用到 static 库目标中。
调用 ppios-rename
需要使用 --symbols-map
选项引用WrappingApp项目中的symbols.map
文件。 在新运行脚本阶段( 根据需要调整路径) 中使用这里脚本:
PATH="$PATH:$HOME/Downloads/PPiOS-Rename-v1.2.0"
ppios-rename --obfuscate-sources --symbols-map.. /WrappingApp/symbols.map
按照上面的指令在中执行指令 18.
在这一点上,所有这些更改都应该提交给源代码管理,因为构建应用程序的目标将以不应该提交的方式改变源代码。
生成具有重命名的static 库的过程变成:
Build and Analyze WrappingApp
目标,它还应该清理并构建 static 库。Apply Renaming to StaticLib
目标。StaticLib
目标。
ppios-rename --analyze [options] <mach-o-file>
Analyze a Mach-O binary and generate a symbol map
Options:
--symbols-map <symbols.map> Path to symbol map file
-F '[!]<pattern>' Filter classes/protocols/categories
-x '<pattern>' Exclude arbitrary symbols
--arch <arch> Specify architecture from universal binary
--sdk-root <path> Specify full SDK root path
--sdk-ios <version> Specify iOS SDK by version
--framework <name> Override the detected framework name
ppios-rename --obfuscate-sources [options]
Alter source code (relative to current working directory), renaming based on the symbol map
Options:
--symbols-map <symbols.map> Path to symbol map file
--storyboards <path> Alternate path for XIBs and storyboards
--symbols-header <symbols.h> Path to obfuscated symbol header file
ppios-rename --translate-crashdump [options] <input crash dump file> <output crash dump file>
Translate symbolicated crash dump
Options:
--symbols-map <symbols.map> Path to symbol map file
ppios-rename --list-arches <mach-o-file>
List architectures available in a fat binary
ppios-rename --version
Print out version information
ppios-rename --help
Print out usage information
版权所有 2016 -2017抢先解决方案,有限责任公司