Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into blacklisting-with-s…
Browse files Browse the repository at this point in the history
…ources
  • Loading branch information
kam800 committed Jul 14, 2019
2 parents af123c2 + 53e4046 commit cbe31e9
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 36 deletions.
6 changes: 6 additions & 0 deletions MachObfuscator.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
objects = {

/* Begin PBXBuildFile section */
8444A5C522A91A7400941940 /* ObfuscableFilesFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8444A5C422A91A7400941940 /* ObfuscableFilesFilter.swift */; };
8444A5C622A9204400941940 /* ObfuscableFilesFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8444A5C422A91A7400941940 /* ObfuscableFilesFilter.swift */; };
8831AF4C22081D63006BEB91 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = D48B8F471F7FEBC200E73BBD /* main.swift */; };
8831AF4D22081D93006BEB91 /* CaesarExportTrieMangler.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F47C81529825A2DAB1FCAC /* CaesarExportTrieMangler.swift */; };
8831AF4E22081DA5006BEB91 /* CaesarCypher.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F47D828D5B299A6471F1BA /* CaesarCypher.swift */; };
Expand Down Expand Up @@ -282,6 +284,7 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
8444A5C422A91A7400941940 /* ObfuscableFilesFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObfuscableFilesFilter.swift; sourceTree = "<group>"; };
88A1F2AD21F5F1FD00C8389E /* RealWordsExportTrieMangler_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealWordsExportTrieMangler_Tests.swift; sourceTree = "<group>"; };
D403A4F1217FACB300285492 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
D4065D3722612357004DCA7D /* Pipe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pipe.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -872,6 +875,7 @@
D481609B2120A9D9008671D8 /* DependencyNode.swift */,
D44D73F7211C3CE800DE002B /* DependencyNodeLoader.swift */,
D44D73FE211C63C300DE002B /* DependencyNodeLoader+isMachOExecutable.swift */,
8444A5C422A91A7400941940 /* ObfuscableFilesFilter.swift */,
);
path = DependencyAnalysis;
sourceTree = "<group>";
Expand Down Expand Up @@ -1082,6 +1086,7 @@
D4C98AD22143249F008340B2 /* RealWordsMangler.swift in Sources */,
D410A6CF20CF2C30006A31E5 /* URL+NibLoading.swift in Sources */,
D455EB28223E637100E4B1E7 /* Mach+classNames.swift in Sources */,
8444A5C522A91A7400941940 /* ObfuscableFilesFilter.swift in Sources */,
D4AAA5FE201C8AEC009BB8FA /* NibArchive.swift in Sources */,
D467A1082274375800BA953A /* String+objCPropertyNames.swift in Sources */,
D455EB2A223E637100E4B1E7 /* Mach+exportTrie.swift in Sources */,
Expand Down Expand Up @@ -1276,6 +1281,7 @@
D44D73892119EBD100DE002B /* NibPlist+Nib.swift in Sources */,
D4816070211C69AD008671D8 /* ImportStack+Parsing.swift in Sources */,
D432EAEC213DE0F200C2ADA0 /* ImageLoaderProtocol.swift in Sources */,
8444A5C622A9204400941940 /* ObfuscableFilesFilter.swift in Sources */,
D4D82CF12202547800090614 /* ArraySentenceGenerator.swift in Sources */,
D481617721256771008671D8 /* Mach+Loading_FatIos_Tests.swift in Sources */,
D432EADE213DDFBE00C2ADA0 /* SimpleImageLoader+DependencyNodeLoader.swift in Sources */,
Expand Down
9 changes: 8 additions & 1 deletion MachObfuscator/Controller/Obfuscator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,21 @@ class Obfuscator {

private let swiftReflectionObfuscation: Bool

private let obfuscableFilesFilter: ObfuscableFilesFilter

private let skippedSymbolsSources: [URL]

init(directoryURL: URL,
mangler: SymbolMangling,
methTypeObfuscation: Bool = false,
swiftReflectionObfuscation: Bool = false,
obfuscableFilesFilter: ObfuscableFilesFilter = ObfuscableFilesFilter.defaultObfuscableFilesFilter(),
skippedSymbolsSources: [URL] = []) {
self.directoryURL = directoryURL
self.mangler = mangler
self.methTypeObfuscation = methTypeObfuscation
self.swiftReflectionObfuscation = swiftReflectionObfuscation
self.obfuscableFilesFilter = obfuscableFilesFilter
self.skippedSymbolsSources = skippedSymbolsSources
}

Expand All @@ -28,8 +32,11 @@ class Obfuscator {
LOGGER.info("Will obfuscate \(directoryURL)")

LOGGER.info("Looking for dependencies...")
let paths = ObfuscationPaths.forAllExecutablesWithDependencies(inDirectory: directoryURL, dependencyNodeLoader: loader)
let paths = ObfuscationPaths.forAllExecutablesWithDependencies(inDirectory: directoryURL, dependencyNodeLoader: loader,
obfuscableFilesFilter: obfuscableFilesFilter)
LOGGER.info("\(paths.obfuscableImages.count) obfuscable images")
LOGGER.debug("Obfuscable images:")
paths.obfuscableImages.forEach { u in LOGGER.debug(u.absoluteString) }
LOGGER.info("\(paths.nibs.count) obfuscable NIBs")

LOGGER.info("Collecting symbols...")
Expand Down
47 changes: 47 additions & 0 deletions MachObfuscator/DependencyAnalysis/ObfuscableFilesFilter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Foundation

struct ObfuscableFilesFilter {
let isObfuscable: (URL) -> Bool
}

extension ObfuscableFilesFilter {
func and(_ other: ObfuscableFilesFilter) -> ObfuscableFilesFilter {
return ObfuscableFilesFilter { url in
self.isObfuscable(url) && other.isObfuscable(url)
}
}

static func defaultObfuscableFilesFilter() -> ObfuscableFilesFilter {
// > Swift apps no longer include dynamically linked libraries
// > for the Swift standard library and Swift SDK overlays in
// > build variants for devices running iOS 12.2, watchOS 5.2,
// > and tvOS 12.2.
// -- https://developer.apple.com/documentation/xcode_release_notes/xcode_10_2_beta_release_notes/swift_5_release_notes_for_xcode_10_2_beta
return skipSwiftLibrary()
}

static func skipSwiftLibrary() -> ObfuscableFilesFilter {
return ObfuscableFilesFilter { url in
!url.lastPathComponent.starts(with: "libswift")
}
}

static func onlyFiles(in obfuscableDirectory: URL) -> ObfuscableFilesFilter {
return ObfuscableFilesFilter { url in
obfuscableDirectory.contains(url)
}
}

static func skipFramework(framework: String) -> ObfuscableFilesFilter {
let frameworkComponent = framework + ".framework"
return ObfuscableFilesFilter { url in
!url.pathComponents.contains(frameworkComponent)
}
}

static func skipAllFrameworks() -> ObfuscableFilesFilter {
return ObfuscableFilesFilter { url in
!url.pathComponents.contains("Frameworks")
}
}
}
36 changes: 2 additions & 34 deletions MachObfuscator/DependencyAnalysis/ObfuscationPaths+Building.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import Foundation

extension ObfuscationPaths {
static func forAllExecutablesWithDependencies(inDirectory dir: URL, fileRepository: FileRepository = FileManager.default, dependencyNodeLoader: DependencyNodeLoader) -> ObfuscationPaths {
static func forAllExecutablesWithDependencies(inDirectory dir: URL, fileRepository: FileRepository = FileManager.default, dependencyNodeLoader: DependencyNodeLoader, obfuscableFilesFilter: ObfuscableFilesFilter) -> ObfuscationPaths {
var paths = ObfuscationPaths()
// TODO: create better exclusion mechanism (with custom excludes and includes)
paths.addAllExecutablesWithDependencies(inDirectory: dir,
fileRepository: fileRepository,
imageLoader: dependencyNodeLoader,
obfuscableFilesFilter: defaultObfuscableFilesFilter(obfuscableDirectory: dir))
obfuscableFilesFilter: obfuscableFilesFilter.and(ObfuscableFilesFilter.onlyFiles(in: dir)))
return paths
}

Expand Down Expand Up @@ -65,34 +64,3 @@ extension ObfuscationPaths {
.uniq
}
}

private struct ObfuscableFilesFilter {
let isObfuscable: (URL) -> Bool
}

private extension ObfuscableFilesFilter {
func and(_ other: ObfuscableFilesFilter) -> ObfuscableFilesFilter {
return ObfuscableFilesFilter { url in
self.isObfuscable(url) && other.isObfuscable(url)
}
}
}

private func defaultObfuscableFilesFilter(obfuscableDirectory: URL) -> ObfuscableFilesFilter {
// > Swift apps no longer include dynamically linked libraries
// > for the Swift standard library and Swift SDK overlays in
// > build variants for devices running iOS 12.2, watchOS 5.2,
// > and tvOS 12.2.
// -- https://developer.apple.com/documentation/xcode_release_notes/xcode_10_2_beta_release_notes/swift_5_release_notes_for_xcode_10_2_beta
return onlyFiles(in: obfuscableDirectory).and(notSwiftLibrary)
}

private let notSwiftLibrary = ObfuscableFilesFilter { url in
!url.lastPathComponent.starts(with: "libswift")
}

private func onlyFiles(in obfuscableDirectory: URL) -> ObfuscableFilesFilter {
return ObfuscableFilesFilter { url in
obfuscableDirectory.contains(url)
}
}
15 changes: 15 additions & 0 deletions MachObfuscator/Options/Options.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ struct Options {
var methTypeObfuscation: Bool
var machOViewDoom: Bool
var swiftReflectionObfuscation: Bool
var obfuscableFilesFilter: ObfuscableFilesFilter
var manglerType: SymbolManglers?
var skipSymbolsFromSources: [URL]
var appDirectory: URL?
Expand Down Expand Up @@ -37,6 +38,7 @@ extension Options {
var machOViewDoom = false
var methTypeObfuscation = false
var swiftReflectionObfuscation = false
var obfuscableFilesFilter = ObfuscableFilesFilter.defaultObfuscableFilesFilter()
var manglerKey = SymbolManglers.defaultManglerKey
var skipSymbolsFromSources: [URL] = []

Expand All @@ -53,6 +55,8 @@ extension Options {
enum OptLongCases: Int32 {
case OPT_FIRST = 256
case swiftReflection
case skipFramework
case skipAllFrameworks
case skipSymbolsFromSources
}

Expand All @@ -62,6 +66,8 @@ extension Options {
option(name: Options.newCCharPtrFromStaticString("methtype"), has_arg: no_argument, flag: nil, val: OptLongChars.methTypeObfuscation),
option(name: Options.newCCharPtrFromStaticString("machoview-doom"), has_arg: no_argument, flag: nil, val: OptLongChars.machOViewDoom),
option(name: Options.newCCharPtrFromStaticString("swift-reflection"), has_arg: no_argument, flag: nil, val: OptLongCases.swiftReflection.rawValue),
option(name: Options.newCCharPtrFromStaticString("skip-framework"), has_arg: required_argument, flag: nil, val: OptLongCases.skipFramework.rawValue),
option(name: Options.newCCharPtrFromStaticString("skip-all-frameworks"), has_arg: no_argument, flag: nil, val: OptLongCases.skipAllFrameworks.rawValue),
option(name: Options.newCCharPtrFromStaticString("mangler"), has_arg: required_argument, flag: nil, val: OptLongChars.manglerKey),
option(name: Options.newCCharPtrFromStaticString("skip-symbols-from-sources"), has_arg: required_argument, flag: nil, val: OptLongCases.skipSymbolsFromSources.rawValue),
option(), // { NULL, NULL, NULL, NULL }
Expand All @@ -85,6 +91,10 @@ extension Options {
manglerKey = String(cString: optarg)
case OptLongCases.swiftReflection.rawValue:
swiftReflectionObfuscation = true
case OptLongCases.skipFramework.rawValue:
obfuscableFilesFilter = obfuscableFilesFilter.and(ObfuscableFilesFilter.skipFramework(framework: String(cString: optarg)))
case OptLongCases.skipAllFrameworks.rawValue:
obfuscableFilesFilter = obfuscableFilesFilter.and(ObfuscableFilesFilter.skipAllFrameworks())
case OptLongCases.skipSymbolsFromSources.rawValue:
let sourcesPath = URL(fileURLWithPath: String(cString: optarg))
skipSymbolsFromSources.append(sourcesPath)
Expand Down Expand Up @@ -113,6 +123,7 @@ extension Options {
methTypeObfuscation: methTypeObfuscation,
machOViewDoom: machOViewDoom,
swiftReflectionObfuscation: swiftReflectionObfuscation,
obfuscableFilesFilter: obfuscableFilesFilter,
manglerType: manglerType,
skipSymbolsFromSources: skipSymbolsFromSources,
appDirectory: appDirectoryURL)
Expand All @@ -133,6 +144,10 @@ extension Options {
-t, --methtype obfuscate methType section (objc/runtime.h methods may work incorrectly)
-D, --machoview-doom MachOViewDoom, MachOView crashes after trying to open your binary (doesn't work with caesarMangler)
--swift-reflection obfuscate Swift reflection sections (typeref and reflstr). May cause problems for Swift >= 4.2
--skip-all-frameworks do not obfuscate frameworks
--skip-framework framework do not obfuscate given framework
-m mangler_key,
--mangler mangler_key select mangler to generate obfuscated symbols
Expand Down
1 change: 1 addition & 0 deletions MachObfuscator/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ private func main() {
mangler: mangler,
methTypeObfuscation: options.methTypeObfuscation,
swiftReflectionObfuscation: options.swiftReflectionObfuscation,
obfuscableFilesFilter: options.obfuscableFilesFilter,
skippedSymbolsSources: options.skipSymbolsFromSources)
obfuscator.run()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class ObfuscationPaths_Building_forAllExecutablesWithDependencies_Tests: XCTestC
func buildSUT() -> ObfuscationPaths {
return ObfuscationPaths.forAllExecutablesWithDependencies(inDirectory: sampleAppURL,
fileRepository: testRepository,
dependencyNodeLoader: testRepository)
dependencyNodeLoader: testRepository, obfuscableFilesFilter: ObfuscableFilesFilter.defaultObfuscableFilesFilter())
}

func test_shouldCollectAllExecutables() {
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ Options:
-t, --methtype obfuscate methType section (objc/runtime.h methods may work incorrectly)
-D, --machoview-doom MachOViewDoom, MachOView crashes after trying to open your binary (doesn't work with caesarMangler)
--swift-reflection obfuscate Swift reflection sections (typeref and reflstr). May cause problems for Swift >= 4.2
--skip-all-frameworks do not obfuscate frameworks
--skip-framework framework do not obfuscate given framework
-m mangler_key,
--mangler mangler_key select mangler to generate obfuscated symbols
Expand Down

0 comments on commit cbe31e9

Please sign in to comment.