Awesome
Symbol Extractor, Name Mapper and Renamer
This repository is part of Sirius - Swift Obfuscator project.
Repository contains the Swift compiler fork with three additional tools and one additional library added.
The tools are:
-
SymbolExtractor with sources in
swift/tools/obfuscator-symbol-extractor/
directory and the build file inswift/tools/obfuscator-symbol-extractor/CMakeLists.txt
-
NameMapper with sources in
swift/tools/obfuscator-name-mapper/
directory and the build file inswift/tools/obfuscator-name-mapper/CMakeLists.txt
-
Renamer with sources in
swift/tools/obfuscator-renamer/
directory and the build file inswift/tools/obfuscator-renamer/CMakeLists.txt
All these tools use a shared library called swiftObfuscation
. Its headers are in swift/include/swift/Obfuscation/
directory and its implementations are in swift/lib/Obfuscation/
directory. The build file is in swift/lib/Obfuscation/CMakeLists.txt
.
The descriptions of the tools are presented below.
SymbolExtractor
Overview
This tool is part of Swift Obfuscator project.
It performs the analysis of Swift source code files and identifies the symbols that should be obfuscated. Once identified, the symbol is written down so that it could be recognized later.
Usage
$ obfuscator-symbol-extractor -filesjson <path-to-input-files-json> -symbolsjson <path-to-output-symbols-json> [-hidediagnostics] [-verbose]
where
<path-to-input-files-json>
is a path to files.json
that contains the data required for performing the analysis of Swift source code. This parameter is required.
<path-to-output-symbols-json>
is a path to symbols.json
file that the extracted symbols data will be written to. This parameter is required.
-hidediagnostics
is the optional flag. It prevents the compiler diagnostics from being printed to standard output. The logs contain compilation warnings and errors that occured during compilation of the input project. This flag should be used with caution, considering that compilation warnings could prevent the symbol-extractor
from correctly identifying the symbol.
-verbose
is the optional flag. When present, the symbols.json
contents are also printed to standard output.
<a name="symbol-extractor-data-formats"></a> Data Formats
The input data format is called files.json
. It's defined and explained in the FilesExtractor project documentation.
The output data format is called symbols.json
and it is presented below:
{
"symbols": [
{
"identifier": <string>,
"name": <string>,
"module": <string>,
"type": <enum string>("type",
"namedFunction",
"externalParameter",
"internalParameter",
"singleParameter",
"variable",
"operator")
}
]
}
symbols
is a list of extracted symbols.
name
is directly corresponding to the actual string defined in the Swift source code. This string will be replaced in the source code by the Renamer
.
identifier
contains all the information required to uniquely identify the given symbol in the source code. It allows Renamer
to identify if the symbol should be renamed.
module
is the name of the module in which the extracted symbol was originally declared. For some symbols it is different from the module in which the symbol occures. E.g. for function declaration that satisfies the protocol requirement (or overrides the function from base class), the module
represents the module in which the protocol (or base class) is declared. It allows Renamer
to identify if the symbol should be renamed.
type
contains the type of the symbol. It's a string of value from a strictly limited enumeration:
type
for symbol that represents type (class, struct, enum, protocol).namedFunction
for symbol that represents function or method with name.externalParameter
for symbol that represents the function's external parameter name.internalParameter
for symbol that represents the function's internal parameter name.singleParameter
for symbol that represents the function's single parameter name (parameter has only one name).variable
for symbol that representslet
orvar
field.operator
for symbol that represents the operator.
NameMapper
Overview
This tool is part of Swift Obfuscator project.
It generates the new names for the symbols provided in the symbols.json
file. It does not perform the actual renaming, just generates the the new names for the symbols that potentially needs to be renamed.
Usage
$ obfuscator-name-mapper -symbolsjson <path-to-input-symbols-file> -renamesjson <path-to-output-renames-file> [-namemappingstrategy <name-mapping-strategy>] [-verbose]
where
<path-to-input-symbols-file>
is a path to symbols.json
file that contains the information about the extracted symbols. It's a required parameter.
<path-to-output-renames-file>
is a path to the file that the symbols with proposed obfuscated names will be written to. It's a required parameter.
<name-mapping-strategy>
is the optional parameter of type enum string determining which of the following strategies it used when generating the new names:
random
strategy generates random alphanumeric strings of length 32, e.g.gnxWyHU0uN3bXejy8bVAoNbyfg4gRuN8
.deterministic
strategy generates deterministic renames based on symbol's original name, e.g.T1_RootViewController
.minifying
strategy generates strings as short as possible, e.g.a
.
When the -namemappingstrategy
parameter is not provided, the default random
strategy is used.
-verbose
is the optional flag. When present, the Renames.json
contents are also printed to standard output.
##<a name="name-mapper-data-formats"></a> Data Formats
The input format is called symbols.json
and is described and explained in the SymbolExtractor data formats section.
The output format is called Renames.json
and it is presented below:
{
"symbols": [
{
"identifier": <string>,
"originalName": <string>,
"obfuscatedName": <string>,
"module": <string>,
"type": <enum string>("type",
"namedFunction",
"externalParameter",
"internalParameter",
"singleParameter",
"variable",
"operator")
}
]
}
Most of the fields in each element of the symbols
array are copied from the input symbols.json
file and described in SymbolExtractor data formats section. The differences are described below:
originalName
is the same as name
in symbols.json
.
obfuscatedName
is the proposed new name that the symbols should be renamed to.
Renamer
Overview
This tool is part of Swift Obfuscator project.
It performs the actual renaming. It parses the Swift source code to identify the symbols, checks whether these symbols should be renamed and what to rename them to, and then does the actual job of changing the symbol name. It generates the new Swift source code in the process.
Usage
$ obfuscator-renamer -filesjson <path-to-input-files-json-file> -renamesjson <path-to-input-renames-json-file> -obfuscatedproject <path-to-directory-for-obfuscated-project> [-hidediagnostics] [-verbose]
where
<path-to-input-files-json-file>
is the path to the symbols.json
file. It's a required parameter.
<path-to-input-renames-json-file>
is the path to the Renames.json
file. It's a required parameter.
<path-to-directory-for-obfuscated-project>
is the path to the directory that the newly generated obfuscated Swift source code files will be written to, as well as the new project.
In case when project should be obfuscated in place (without making a copy), -inplace
argument can be used instead of -obfuscatedproject
.
-hidediagnostics
is the optional flag. It prevents the compiler diagnostics from being printed to standard output. The logs contain compilation warnings and errors that occured during compilation of the input project. This flag should be used with caution, considering that compilation warnings could prevent the renamer
from correctly identifying the symbol.
-verbose
is the optional flag. When present, the list of the obfuscated files is printed to the standard output.
Data formats
The input data formats are files.json
and Renames.json
and are described in the SymbolExtractor data formats and NameMapper data formats sections.
Common for all three projects
Build notes for developers
-
Ensure you have the Xcode 9.2 installed and available under /Applications/Xcode.app. The version and path are important as the Xcode project for the compiler that is generated during build has the path baked in.
-
Clone the source code
git clone git@github.com:Polidea/SiriusObfuscator-SymbolExtractorAndRenamer.git
-
Install build tools
brew install cmake ninja
-
(optional, only if there is a need for change in the dependencies) Update dependencies
/bin/bash Scripts/git_remotes.sh
Script takes the parameter defining which version of Swift will be used as the basis of the changes to the compiler. -
Build the Swift compiler in the Xcode-friendly way. A build can take multiple hours. Build artifacts require ~20GB of free disk space.
swift/utils/build-script --clean --xcode --release-debuginfo --debug-swift
-
Build the Swift compiler using ninja with support for iOS, tvOS and watchOS. A build can take multiple hours. Build artifacts require ~20GB of free disk space.
swift/utils/build-script --ios --tvos --watchos --release-debuginfo --debug-swift
-
Copy the generated libraries from ninja build to Xcode build
rm -r -f build/Xcode-RelWithDebInfoAssert+swift-DebugAssert/swift-macosx-x86_64/Debug/lib/swift
cp -r build/Ninja-RelWithDebInfoAssert+swift-DebugAssert/swift-macosx-x86_64/lib/swift build/Xcode-RelWithDebInfoAssert+swift-DebugAssert/swift-macosx-x86_64/Debug/lib/swift
-
Remove the ninja build as it's no longer needed (unless you plan to use it)
rm -r -f build/Ninja-RelWithDebInfoAssert+swift-DebugAssert
-
Open
build/Xcode-RelWithDebInfoAssert+swift-DebugAssert/swift-macosx-x86_64/Swift.xcodeproj
and create the schemes for the tools that you're interested in (autocreating schemes is not recommended, as there's a lot of them).
Build documentation (optional)
-
Install doxygen
brew install doxygen
-
Install graphviz
brew install graphviz
-
Build documentation
doxygen Doxyfile
-
Open documentation
open Documentation/doxygen/index.html
Further read
Please consult the Documentation folder for the further explanations.
Contributing
Contributors
In the alphabetical order:
CLA
We require contributors to have signed Contributor Licence Agreement.
Licence
Copyright 2018 Polidea Sp. z o.o
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.