├── CCPObfuscation
├── Assets.xcassets
│ ├── Contents.json
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── CCPObfuscation.entitlements
├── ViewC ontroller.swift
├── Obfuscator
│ ├── RenameFunc.swift
│ ├── ObfuscatorModify.swift
│ ├── DeleteNotes.swift
│ ├── ObfuscatorUtils.swift
│ ├── RenameClass.swift
│ ├── RenameProperty.swift
│ ├── ExtractHardCode.swift
│ └── Obfuscator.swift
├── AppDelegate.swift
├── Info.plist
└── Base.lproj
│ └── Main.storyboard
├── CCPObfuscation.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── chuchengpeng.xcuserdatad
│ │ │ └── IDEFindNavigatorScopes.plist
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── xcuserdata
│ └── chuchengpeng.xcuserdatad
│ │ ├── xcschemes
│ │ └── xcschememanagement.plist
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
└── project.pbxproj
└── CCPObfuscationTests
├── Info.plist
└── CCPObfuscationTests.swift
/CCPObfuscation/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/CCPObfuscation/CCPObfuscation.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/CCPObfuscation.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CCPObfuscation.xcodeproj/project.xcworkspace/xcuserdata/chuchengpeng.xcuserdatad/IDEFindNavigatorScopes.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/CCPObfuscation.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/CCPObfuscation.xcodeproj/xcuserdata/chuchengpeng.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | CCPObfuscation.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/CCPObfuscation/ViewC ontroller.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // CCPObfuscation
4 | //
5 | // Created by 储诚鹏 on 2019/12/17.
6 | // Copyright © 2019 储诚鹏. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | class ViewController: NSViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | // Do any additional setup after loading the view.
17 | }
18 |
19 | override var representedObject: Any? {
20 | didSet {
21 | // Update the view, if already loaded.
22 | }
23 | }
24 |
25 |
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/CCPObfuscation/Obfuscator/RenameFunc.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RenameFunc.swift
3 | // CCPObfuscation
4 | //
5 | // Created by 储诚鹏 on 2019/12/19.
6 | // Copyright © 2019 储诚鹏. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | extension Obfuscator {
12 | /* oc
13 | * 提取.h里的方法
14 | ps: 如果系统类放在.h中,也会被修改
15 | * swift
16 | * 提取private和fileprivate修饰的函数
17 |
18 | * 修改方法名称, 添加参数(后缀参数,依据方法返回生成参数类型,如果返回viod,生成BOOL)
19 | */
20 | func renameFunc() {
21 | validExtensions = ["h", "swift"]
22 | let renameFuncURLs = urls.filter { return valid($0) }
23 | let ocName = "-\\s*\\([a-zA-Z]+\\s*\\**\\)([a-zA-Z_]{1}\\w*\\s*:).*;+"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/CCPObfuscationTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(PRODUCT_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | NSDockTilePlugIn
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/CCPObfuscation/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // CCPObfuscation
4 | //
5 | // Created by 储诚鹏 on 2019/12/17.
6 | // Copyright © 2019 储诚鹏. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | @NSApplicationMain
12 | class AppDelegate: NSObject, NSApplicationDelegate {
13 |
14 |
15 |
16 | func applicationDidFinishLaunching(_ aNotification: Notification) {
17 | do {
18 | try Obfuscator(source: "/Users/chuchengpeng/Desktop/ForObTest").go()
19 | } catch {
20 | try? FileManager.default.removeItem(at: URL(fileURLWithPath: "/Users/chuchengpeng/Desktop/ForObTest_CCP"))
21 | assertionFailure(error.localizedDescription)
22 | }
23 | // Insert code here to initialize your application
24 | }
25 |
26 | func applicationWillTerminate(_ aNotification: Notification) {
27 | // Insert code here to tear down your application
28 | }
29 |
30 |
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/CCPObfuscation/Obfuscator/ObfuscatorModify.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ObfuscatorModify.swift
3 | // CCPObfuscation
4 | //
5 | // Created by 储诚鹏 on 2019/12/19.
6 | // Copyright © 2019 储诚鹏. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | enum ModifyCondition {
12 | case prefix(_ prefix: String)
13 | case suffix(_ suffix: String)
14 | case none
15 |
16 | func validFile(url: URL) -> Bool {
17 | let last = url.deletingPathExtension().lastPathComponent
18 | switch self {
19 | case .prefix(let p):
20 | return last.hasPrefix(p)
21 | case .suffix(let s):
22 | return last.hasSuffix(s)
23 | default:
24 | return true
25 | }
26 | }
27 | }
28 |
29 | enum ObfuscatorModify {
30 |
31 | typealias FileUnit = (oldURL: URL, newURL: URL, oldName: String, newName: String)
32 |
33 | case prefix(_ prefix: String)
34 | case suffix(_ suffix: String)
35 | case random
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/CCPObfuscation/Obfuscator/DeleteNotes.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DeleteNotes.swift
3 | // CCPObfuscation
4 | //
5 | // Created by 储诚鹏 on 2019/12/19.
6 | // Copyright © 2019 储诚鹏. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | extension Obfuscator {
12 |
13 | func deleteNotes() {
14 | let notesRegx: String = {
15 | let _1 = "([^:/])?//.*" //
16 | let _2 = "/\\*+?[\\s\\S]*?(\\*/){1}?"/**/
17 | return "(\(_1))|(\(_2))"
18 | }()
19 | let spaceRegx = "(?<=\n)\\s+" //空行
20 | for url in urls {
21 | guard valid(url) else { continue }
22 | var content = ""
23 | do {
24 | content = try String(contentsOf: url).replace(pattern: notesRegx, with: "").replace(pattern: spaceRegx, with: "")
25 | try content.write(to: url, atomically: true, encoding: .utf8)
26 | }
27 | catch {
28 | print(error.localizedDescription)
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/CCPObfuscation.xcodeproj/xcuserdata/chuchengpeng.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
9 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/CCPObfuscation/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/CCPObfuscation/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(PRODUCT_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSHumanReadableCopyright
26 | Copyright © 2019 储诚鹏. All rights reserved.
27 | NSMainStoryboardFile
28 | Main
29 | NSPrincipalClass
30 | NSApplication
31 | NSSupportsAutomaticTermination
32 |
33 | NSSupportsSuddenTermination
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/CCPObfuscationTests/CCPObfuscationTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CCPObfuscationTests.swift
3 | // CCPObfuscationTests
4 | //
5 | // Created by 储诚鹏 on 2019/12/17.
6 | // Copyright © 2019 储诚鹏. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import CCPObfuscation
11 |
12 | class CCPObfuscationTests: XCTestCase {
13 |
14 | override func setUp() {
15 | // Put setup code here. This method is called before the invocation of each test method in the class.
16 | }
17 |
18 | override func tearDown() {
19 | // Put teardown code here. This method is called after the invocation of each test method in the class.
20 | }
21 |
22 | func testExample() {
23 | // This is an example of a functional test case.
24 | // Use XCTAssert and related functions to verify your tests produce the correct results.
25 | }
26 |
27 | func testPerformanceExample() {
28 | // This is an example of a performance test case.
29 | self.measure {
30 | // Put the code you want to measure the time of here.
31 | }
32 | }
33 |
34 |
35 |
36 | func testMoveFiles() {
37 | do {
38 | try Obfuscation().moveToNewDocument(source: "/Users/chuchengpeng/Desktop/ForObTest")
39 | } catch {
40 | assertionFailure(error.localizedDescription)
41 | }
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/CCPObfuscation/Obfuscator/ObfuscatorUtils.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CCPObfuscation.swift
3 | // CCPObfuscation
4 | //
5 | // Created by 储诚鹏 on 2019/12/17.
6 | // Copyright © 2019 储诚鹏. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 |
12 | enum ObfuscationError: Error {
13 | case emptySource
14 | case invalidURL(_ url: URL)
15 | case unkonwn
16 | case createFilesGroupFailed
17 | case failedToCreate(_ url: URL)
18 | case noDesktop
19 | }
20 |
21 | extension ObfuscationError: LocalizedError {
22 | var errorDescription: String? {
23 | let base = "[ObfuscationError🐯🐯🐯]--"
24 | switch self {
25 | case .invalidURL(let url):
26 | return base + "无效的地址: \(url.path)"
27 | case .emptySource:
28 | return base + "空地址"
29 | case .createFilesGroupFailed:
30 | return base + "创建新代码文件夹失败"
31 | case .failedToCreate(let url):
32 | return base + "创建\(url.path)失败"
33 | case .noDesktop:
34 | return base + "找不到桌面文件夹"
35 | default:
36 | return base + "unkonwn error"
37 | }
38 | }
39 | }
40 |
41 | protocol ObfuscationSource {
42 | func url() throws -> URL
43 | }
44 |
45 | extension String: ObfuscationSource {
46 | func url() throws -> URL {
47 | return URL(fileURLWithPath: self)
48 | }
49 | }
50 |
51 | extension URL: ObfuscationSource {
52 | func url() throws -> URL {
53 | return self
54 | }
55 | }
56 |
57 | extension Optional where Wrapped: ObfuscationSource {
58 | func url() throws -> URL {
59 | switch self {
60 | case .some(let v):
61 | return try v.url()
62 | default:
63 | throw ObfuscationError.emptySource
64 | }
65 | }
66 | }
67 |
68 | extension String {
69 | func match(pattern: String) -> Bool {
70 | do {
71 | let regexp = try NSRegularExpression(pattern: pattern)
72 | if let rlt = regexp.firstMatch(in: self, options: [], range: NSRange(location: 0, length: self.count)) {
73 | return rlt.range.location != NSNotFound
74 | }
75 | } catch {
76 | print(error.localizedDescription)
77 | }
78 | return false
79 | }
80 |
81 | func replace(pattern: String, with str: String) throws -> String {
82 | let regexp = try NSRegularExpression(pattern: pattern)
83 | var ranges = [NSRange]()
84 | regexp.enumerateMatches(in: self, options: [], range: NSRange(location: 0, length: self.count)) { (result, _, _) in
85 | if let rlt = result {
86 | ranges.append(rlt.range)
87 | }
88 | }
89 |
90 | let mstr = NSMutableString(string: self)
91 | for range in ranges.reversed() {
92 | mstr.replaceCharacters(in: range, with: str)
93 | }
94 | return mstr as String
95 | }
96 |
97 |
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/CCPObfuscation/Obfuscator/RenameClass.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RenameClass.swift
3 | // CCPObfuscation
4 | //
5 | // Created by 储诚鹏 on 2019/12/19.
6 | // Copyright © 2019 储诚鹏. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | extension ObfuscatorModify {
12 | fileprivate func file(of oldURL: URL) -> FileUnit? {
13 | //分类时,只考虑xxx+xxx的场景
14 | let oldFileName = oldURL.deletingPathExtension().lastPathComponent
15 | if oldFileName == "main" || oldURL.pathExtension == "pch" { return nil }
16 | let components = oldFileName.components(separatedBy: "+")
17 | guard (1 ... 2).contains(components.count) else { return nil }
18 | let oldName = components.last!
19 | let oldClass = components.count == 2 ? components.first! : nil
20 |
21 | var newName = ""
22 | switch self {
23 | case .prefix(let p):
24 | newName = oldClass != nil ? "\(oldClass!)+\(p + oldName)" : "\(p + oldName)"
25 | case .suffix(let s):
26 | newName = oldClass != nil ? "\(oldClass!)+\(oldName + s)" : "\(oldName + s)"
27 | case .random:
28 | let randomIdx = Int.random(in: (0 ... oldName.count))
29 | let idx = String.Index(utf16Offset: randomIdx, in: oldName)
30 | var varOldName = oldName
31 | varOldName.insert(contentsOf: "\(oldName.hashValue)", at: idx)
32 | newName = oldClass != nil ? "\(oldClass!)+\(varOldName)" : varOldName
33 | }
34 | let newFileURL = oldURL.deletingLastPathComponent().appendingPathComponent("\(newName).\(oldURL.pathExtension)")
35 | do {
36 | try FileManager.default.copyItem(at: oldURL, to: newFileURL)
37 | try FileManager.default.removeItem(at: oldURL)
38 | return (oldURL, newFileURL, oldFileName, newName)
39 | } catch {
40 | print(error.localizedDescription)
41 | }
42 | return nil
43 | }
44 | }
45 |
46 |
47 | extension Obfuscator {
48 | func renameClass() {
49 | var newUnits = [ObfuscatorModify.FileUnit]()
50 | let renamedURLs = urls.compactMap { (url) -> URL? in
51 | guard valid(url) else { return nil }
52 | guard modifyCondition.validFile(url: url) else { return nil }
53 | if let new = modify.file(of: url) {
54 | newUnits.append(new)
55 | return new.newURL
56 | }
57 | return url
58 | }
59 | for unit in newUnits {
60 | urls.removeAll { $0 == unit.oldURL }
61 | urls.append(unit.newURL)
62 | let oldName = unit.oldName.replacingOccurrences(of: "+", with: "\\+")
63 | for url in renamedURLs + pbxprojsURL {
64 | do {
65 | let content = try String(contentsOf: url).replace(pattern: "(?<=[^\\w])\(oldName)(?=[^\\w])", with: unit.newName)
66 | try content.write(to: url, atomically: true, encoding: .utf8)
67 | } catch {
68 | print(error.localizedDescription)
69 | }
70 | }
71 | }
72 |
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/CCPObfuscation/Obfuscator/RenameProperty.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RenameProperty.swift
3 | // CCPObfuscation
4 | //
5 | // Created by 储诚鹏 on 2019/12/19.
6 | // Copyright © 2019 储诚鹏. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | class A {
12 | var a: String = ""
13 | let b: String = ""
14 | }
15 |
16 | extension ObfuscatorModify {
17 |
18 | typealias PropertyUnit = (old: String, new: String)
19 |
20 | fileprivate func property(_ url: URL) -> [PropertyUnit] {
21 | let isSwift = url.pathExtension == "swift"
22 | let regx = isSwift ? "(?:var|let)\\s+(\\w+)\\s*:{1}" : "@property\\s*\\(.+\\)\\s*\\w+[\\s*]+\\s*(\\w+)\\s*;"
23 | do {
24 | let content = try String(contentsOf: url)
25 | return properties(pattern: regx, str: content)
26 | } catch {
27 | print(error.localizedDescription)
28 | }
29 | return []
30 | }
31 |
32 | private func properties(pattern: String, str: String) -> [PropertyUnit] {
33 | var properties = [PropertyUnit]()
34 | do {
35 | let regexp = try NSRegularExpression(pattern: pattern)
36 |
37 | regexp.enumerateMatches(in: str, options: [], range: NSRange(location: 0, length: str.count)) { (result, _, _) in
38 | if let rlt = result, rlt.numberOfRanges == 2 {
39 | let old = (str as NSString).substring(with: rlt.range(at: 1))
40 | var new = ""
41 | switch self {
42 | case .prefix(let p):
43 | new = p + old
44 | case .suffix(let s):
45 | new = old + s
46 | case .random:
47 | new = old + "\(old.hashValue)"
48 | }
49 | properties.append((old, new))
50 | }
51 | }
52 | } catch {
53 | print(error.localizedDescription)
54 | }
55 |
56 | return properties
57 | }
58 | }
59 |
60 | extension Obfuscator {
61 | //修改掉同名的局部变量
62 | func renameProperty() {
63 | let validURLs: [URL] = urls.compactMap {
64 | if valid($0) { return $0 }
65 | return nil
66 | }
67 | let properties = validURLs.compactMap { (url) -> [ObfuscatorModify.PropertyUnit]? in
68 | guard valid(url) else { return nil }
69 | return modify.property(url)
70 | }.flatMap { return $0 }
71 | for property in properties {
72 | for url in validURLs {
73 | replace(in: url, old: property.old, new: property.new)
74 | }
75 | }
76 | }
77 |
78 | private func replace(in url: URL, old: String, new: String) {
79 | let regx = "\\b(?()
15 |
16 | fileprivate func extractHardCode(_ url: URL) {
17 | let reg = "[\\w\\*]*\\w+\\s*={1,2}\\s*((@\"\\w+\")|([\\d.]+))"
18 | do {
19 | let content = try String(contentsOf: url)
20 | let exp = try NSRegularExpression(pattern: reg)
21 | exp.enumerateMatches(in: content, options: [], range: NSRange(location: 0, length: content.count)) { (result, _, _) in
22 | if let rlt = result {
23 | ObfuscatorModify.hardCodeSet.insert((content as NSString).substring(with: rlt.range(at: 1)))
24 | }
25 | }
26 |
27 | } catch {
28 | print(error.localizedDescription)
29 | }
30 | }
31 |
32 |
33 | fileprivate func writeConst(in document: URL) -> [HardCodeUnit] {
34 | var units = [HardCodeUnit]()
35 | if ObfuscatorModify.hardCodeSet.count == 0 {
36 | print("项目中没有硬代码")
37 | return units
38 | }
39 | guard let url = createConstFile(in: document) else {
40 | print("创建常量文件失败")
41 | return units
42 | }
43 | let name = url.deletingPathExtension().lastPathComponent + "_h"
44 | var codeStr = "#ifndef \(name)\n#define \(name)\n\n"
45 | for code in ObfuscatorModify.hardCodeSet {
46 | var key = ""
47 | switch self {
48 | case .prefix(let p):
49 | key = "\(p)_\(abs(code.hashValue))"
50 | case .suffix(let s):
51 | key = "k\(abs(code.hashValue))_\(s)"
52 | default:
53 | key = "CCPConst_\(abs(code.hashValue))"
54 | }
55 | let str = "#define \(key) \(code)\n"
56 | codeStr.append(contentsOf: str)
57 | units.append((code, key))
58 | }
59 | codeStr.append(contentsOf: "\n#endif")
60 | do {
61 | try codeStr.write(to: url, atomically: true, encoding: .utf8)
62 | } catch {
63 | print(error.localizedDescription)
64 | }
65 | return units
66 | }
67 |
68 | private func createConstFile(in document: URL) -> URL? {
69 | var fileURL = document.appendingPathComponent("CCPHardCodeConst.h")
70 | var idx = 0
71 | while FileManager.default.fileExists(atPath: fileURL.path) {
72 | idx += 1
73 | fileURL = document.appendingPathComponent("CCPHardCodeConst_\(idx).h")
74 | }
75 | if FileManager.default.createFile(atPath: fileURL.path, contents: nil, attributes: nil) {
76 | return fileURL
77 | }
78 | return nil
79 | }
80 |
81 | }
82 |
83 |
84 | /* 暂时只支持oc
85 | * 将生成的CCPHardCodeConst.h移动到BUILT_PRODUCTS_DIR(就是工程创建时和proj同级的目录)
86 | * pch #import
87 |
88 | */
89 | extension Obfuscator {
90 | func extractHardCode() {
91 | validExtensions = ["m"]
92 | let extractFilesURL = urls.filter { return valid($0) }
93 | for url in extractFilesURL {
94 | modify.extractHardCode(url)
95 | }
96 | for unit in modify.writeConst(in: rootURL) {
97 | let old = unit.old.replacingOccurrences(of: ".", with: "\\.")
98 | let reg = "(?<=\\={1,3})\\s*(\(old))(?!\\.)\\s*"
99 | for url in extractFilesURL {
100 | do {
101 | var content = try String(contentsOf: url)
102 | let exp = try NSRegularExpression(pattern: reg)
103 | var ranges = [NSRange]()
104 | exp.enumerateMatches(in: content, options: [], range: NSRange(location: 0, length: content.count)) { (reslut, _, _) in
105 | if let rlt = reslut, rlt.numberOfRanges == 2 {
106 | ranges.append(rlt.range(at: 1))
107 | }
108 | }
109 | for range in ranges.reversed() {
110 | content = (content as NSString).replacingCharacters(in: range, with: unit.new)
111 | }
112 | try content.write(to: url, atomically: true, encoding: .utf8)
113 | } catch {
114 | print(error.localizedDescription)
115 | }
116 | }
117 | }
118 | }
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/CCPObfuscation/Obfuscator/Obfuscator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Obfuscator.swift
3 | // CCPObfuscation
4 | //
5 | // Created by 储诚鹏 on 2019/12/19.
6 | // Copyright © 2019 储诚鹏. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | enum ObfuscationFunction: CaseIterable {
12 | case deleteNotes
13 | case renameClass
14 | case renameProperty
15 | case extractHardCode
16 | case renameFunc
17 |
18 | case garbageInFunc
19 | case garbageInClass
20 | case garbageClasses
21 | case md5ClassName
22 | case md5FuncName
23 | case layout
24 | }
25 |
26 | extension ObfuscationFunction {
27 | func _func(_ obj: Obfuscator) -> (() ->()) {
28 | switch self {
29 | case .renameClass:
30 | return obj.renameClass
31 | case .deleteNotes:
32 | return obj.deleteNotes
33 | case .renameProperty:
34 | return obj.renameProperty
35 | case .extractHardCode:
36 | return obj.extractHardCode
37 | case .renameFunc:
38 | return obj.renameFunc
39 | default:
40 | return empty
41 | }
42 | }
43 |
44 | func empty() {
45 | print("empty func")
46 | }
47 |
48 | }
49 |
50 | enum ObfuscationIgnores {
51 | case prefix(_ condition: String)
52 | case suffix(_ condition: String)
53 | case contains(_ condition: String)
54 | case equal(_ condition: String)
55 | case document(_ condition: String)
56 |
57 | //区分大小写
58 | //不过滤分类
59 | func evaluate(with value: URL) -> Bool {
60 | if value.lastPathComponent.contains("+") {
61 | return false
62 | }
63 | switch self {
64 | case .prefix(let condition):
65 | return value.lastPathComponent.hasPrefix(condition)
66 | case .suffix(let condition):
67 | return value.lastPathComponent.hasSuffix(condition)
68 | case .contains(let condition):
69 | return value.lastPathComponent.contains(condition)
70 | case .equal(let condition):
71 | return value.lastPathComponent == condition
72 | case .document(let condition):
73 | return value.path.match(pattern: "(?<=/)\(condition)(?=/)")
74 | }
75 | }
76 |
77 | static var `default`: [ObfuscationIgnores] {
78 | return [document("Pods")]
79 | }
80 |
81 | static func evalutes(ignores: [ObfuscationIgnores], value: URL) -> Bool {
82 | for ignore in ignores {
83 | if ignore.evaluate(with: value) {
84 | return true
85 | }
86 | }
87 | return false
88 | }
89 | }
90 |
91 | class Obfuscator {
92 |
93 | var validExtensions: [String] = []
94 |
95 | var modifyCondition: ModifyCondition = .none
96 |
97 | var pbxprojsURL: [URL] = [] //存放工程中类文件路径名称的地方,若此文件缺失,则无法修改工程中文件名称,只能在修改后从文件夹中手动引入
98 | var urls: [URL] = []
99 |
100 | let ignores: [ObfuscationIgnores]
101 | var modify: ObfuscatorModify!
102 | var rootURL: URL!
103 |
104 | fileprivate let source: ObfuscationSource!
105 |
106 | func go(funcs: [ObfuscationFunction] = ObfuscationFunction.allCases) {
107 | for f in funcs {
108 | validExtensions = ["h", "m", "c", "mm", "swift", "pch"]
109 | f._func(self)()
110 | }
111 | }
112 |
113 | init(source: ObfuscationSource,
114 | modifyCondition: ModifyCondition = .none,
115 | modify: ObfuscatorModify = .prefix("CCPObfuscator"),
116 | ignores: [ObfuscationIgnores] = ObfuscationIgnores.default) throws {
117 | self.source = source
118 | self.modifyCondition = modifyCondition
119 | self.modify = modify
120 | self.ignores = ignores
121 | try copyToDesktop()
122 | }
123 |
124 | func allFilesURL(in document: URL) -> [URL] {
125 | var urls = [URL]()
126 | guard let enumerators = FileManager.default.enumerator(atPath: document.path) else {
127 | return urls
128 | }
129 | while let next = enumerators.nextObject() as? String {
130 | let url = document.appendingPathComponent(next)
131 | var isDirectory: ObjCBool = false
132 | let isExists = FileManager.default.fileExists(atPath: url.path, isDirectory: &isDirectory)
133 | if !isExists { continue }
134 | if !isDirectory.boolValue {
135 | if url.pathExtension == "pbxproj" {
136 | self.pbxprojsURL.append(url)
137 | }
138 | urls.append(url)
139 | }
140 | }
141 | return urls
142 | }
143 |
144 | func valid(_ url: URL) -> Bool {
145 | return !ObfuscationIgnores.evalutes(ignores: ignores, value: url) && validExtensions.contains(url.pathExtension)
146 | }
147 |
148 | func copyToDesktop() throws {
149 | guard let desktop = FileManager.default.urls(for: .desktopDirectory, in: .userDomainMask).first else {
150 | throw ObfuscationError.noDesktop
151 | }
152 | let oldURL = try source.url()
153 | var newURL = desktop.appendingPathComponent("\(oldURL.lastPathComponent)_ccp")
154 | var idx = 0
155 | while FileManager.default.fileExists(atPath: newURL.path) {
156 | idx += 1
157 | newURL = desktop.appendingPathComponent("\(oldURL.lastPathComponent)_ccp_\(idx)")
158 | }
159 | do {
160 | try FileManager.default.copyItem(at: oldURL, to: newURL)
161 | self.urls = allFilesURL(in: newURL)
162 | self.rootURL = newURL
163 |
164 | } catch {
165 | print(error.localizedDescription)
166 | }
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/CCPObfuscation.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 0079489023AB4AF3006DB77A /* Obfuscator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0079488F23AB4AF3006DB77A /* Obfuscator.swift */; };
11 | 0079489223AB4B95006DB77A /* DeleteNotes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0079489123AB4B95006DB77A /* DeleteNotes.swift */; };
12 | 0079489423AB4BE6006DB77A /* RenameClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0079489323AB4BE6006DB77A /* RenameClass.swift */; };
13 | 0079489623AB4F2D006DB77A /* ObfuscatorModify.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0079489523AB4F2D006DB77A /* ObfuscatorModify.swift */; };
14 | 0079489823AB50BB006DB77A /* RenameFunc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0079489723AB50BB006DB77A /* RenameFunc.swift */; };
15 | 0079489A23AB547C006DB77A /* RenameProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0079489923AB547C006DB77A /* RenameProperty.swift */; };
16 | 0079489C23AB90F9006DB77A /* ExtractHardCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0079489B23AB90F9006DB77A /* ExtractHardCode.swift */; };
17 | 00FC6B5123A8A80700D67B71 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00FC6B5023A8A80700D67B71 /* AppDelegate.swift */; };
18 | 00FC6B5323A8A80700D67B71 /* ViewC ontroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00FC6B5223A8A80700D67B71 /* ViewC ontroller.swift */; };
19 | 00FC6B5523A8A80800D67B71 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 00FC6B5423A8A80800D67B71 /* Assets.xcassets */; };
20 | 00FC6B5823A8A80800D67B71 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 00FC6B5623A8A80800D67B71 /* Main.storyboard */; };
21 | 00FC6B6423A8A80800D67B71 /* CCPObfuscationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00FC6B6323A8A80800D67B71 /* CCPObfuscationTests.swift */; };
22 | 00FC6B7023A8A84600D67B71 /* ObfuscatorUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00FC6B6F23A8A84600D67B71 /* ObfuscatorUtils.swift */; };
23 | /* End PBXBuildFile section */
24 |
25 | /* Begin PBXContainerItemProxy section */
26 | 00FC6B6023A8A80800D67B71 /* PBXContainerItemProxy */ = {
27 | isa = PBXContainerItemProxy;
28 | containerPortal = 00FC6B4523A8A80600D67B71 /* Project object */;
29 | proxyType = 1;
30 | remoteGlobalIDString = 00FC6B4C23A8A80600D67B71;
31 | remoteInfo = CCPObfuscation;
32 | };
33 | /* End PBXContainerItemProxy section */
34 |
35 | /* Begin PBXFileReference section */
36 | 0079488F23AB4AF3006DB77A /* Obfuscator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Obfuscator.swift; sourceTree = ""; };
37 | 0079489123AB4B95006DB77A /* DeleteNotes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteNotes.swift; sourceTree = ""; };
38 | 0079489323AB4BE6006DB77A /* RenameClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RenameClass.swift; sourceTree = ""; };
39 | 0079489523AB4F2D006DB77A /* ObfuscatorModify.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObfuscatorModify.swift; sourceTree = ""; };
40 | 0079489723AB50BB006DB77A /* RenameFunc.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RenameFunc.swift; sourceTree = ""; };
41 | 0079489923AB547C006DB77A /* RenameProperty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RenameProperty.swift; sourceTree = ""; };
42 | 0079489B23AB90F9006DB77A /* ExtractHardCode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtractHardCode.swift; sourceTree = ""; };
43 | 00FC6B4D23A8A80600D67B71 /* CCPObfuscation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CCPObfuscation.app; sourceTree = BUILT_PRODUCTS_DIR; };
44 | 00FC6B5023A8A80700D67B71 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
45 | 00FC6B5223A8A80700D67B71 /* ViewC ontroller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ViewC ontroller.swift"; sourceTree = ""; };
46 | 00FC6B5423A8A80800D67B71 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
47 | 00FC6B5723A8A80800D67B71 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
48 | 00FC6B5923A8A80800D67B71 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
49 | 00FC6B5A23A8A80800D67B71 /* CCPObfuscation.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = CCPObfuscation.entitlements; sourceTree = ""; };
50 | 00FC6B5F23A8A80800D67B71 /* CCPObfuscationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CCPObfuscationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
51 | 00FC6B6323A8A80800D67B71 /* CCPObfuscationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CCPObfuscationTests.swift; sourceTree = ""; };
52 | 00FC6B6523A8A80800D67B71 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
53 | 00FC6B6F23A8A84600D67B71 /* ObfuscatorUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObfuscatorUtils.swift; sourceTree = ""; };
54 | /* End PBXFileReference section */
55 |
56 | /* Begin PBXFrameworksBuildPhase section */
57 | 00FC6B4A23A8A80600D67B71 /* Frameworks */ = {
58 | isa = PBXFrameworksBuildPhase;
59 | buildActionMask = 2147483647;
60 | files = (
61 | );
62 | runOnlyForDeploymentPostprocessing = 0;
63 | };
64 | 00FC6B5C23A8A80800D67B71 /* Frameworks */ = {
65 | isa = PBXFrameworksBuildPhase;
66 | buildActionMask = 2147483647;
67 | files = (
68 | );
69 | runOnlyForDeploymentPostprocessing = 0;
70 | };
71 | /* End PBXFrameworksBuildPhase section */
72 |
73 | /* Begin PBXGroup section */
74 | 00FC6B4423A8A80600D67B71 = {
75 | isa = PBXGroup;
76 | children = (
77 | 00FC6B4F23A8A80600D67B71 /* CCPObfuscation */,
78 | 00FC6B6223A8A80800D67B71 /* CCPObfuscationTests */,
79 | 00FC6B4E23A8A80600D67B71 /* Products */,
80 | );
81 | sourceTree = "";
82 | };
83 | 00FC6B4E23A8A80600D67B71 /* Products */ = {
84 | isa = PBXGroup;
85 | children = (
86 | 00FC6B4D23A8A80600D67B71 /* CCPObfuscation.app */,
87 | 00FC6B5F23A8A80800D67B71 /* CCPObfuscationTests.xctest */,
88 | );
89 | name = Products;
90 | sourceTree = "";
91 | };
92 | 00FC6B4F23A8A80600D67B71 /* CCPObfuscation */ = {
93 | isa = PBXGroup;
94 | children = (
95 | 00FC6B6E23A8A82600D67B71 /* Obfuscator */,
96 | 00FC6B5023A8A80700D67B71 /* AppDelegate.swift */,
97 | 00FC6B5223A8A80700D67B71 /* ViewC ontroller.swift */,
98 | 00FC6B5423A8A80800D67B71 /* Assets.xcassets */,
99 | 00FC6B5623A8A80800D67B71 /* Main.storyboard */,
100 | 00FC6B5923A8A80800D67B71 /* Info.plist */,
101 | 00FC6B5A23A8A80800D67B71 /* CCPObfuscation.entitlements */,
102 | );
103 | path = CCPObfuscation;
104 | sourceTree = "";
105 | };
106 | 00FC6B6223A8A80800D67B71 /* CCPObfuscationTests */ = {
107 | isa = PBXGroup;
108 | children = (
109 | 00FC6B6323A8A80800D67B71 /* CCPObfuscationTests.swift */,
110 | 00FC6B6523A8A80800D67B71 /* Info.plist */,
111 | );
112 | path = CCPObfuscationTests;
113 | sourceTree = "";
114 | };
115 | 00FC6B6E23A8A82600D67B71 /* Obfuscator */ = {
116 | isa = PBXGroup;
117 | children = (
118 | 00FC6B6F23A8A84600D67B71 /* ObfuscatorUtils.swift */,
119 | 0079489523AB4F2D006DB77A /* ObfuscatorModify.swift */,
120 | 0079488F23AB4AF3006DB77A /* Obfuscator.swift */,
121 | 0079489123AB4B95006DB77A /* DeleteNotes.swift */,
122 | 0079489323AB4BE6006DB77A /* RenameClass.swift */,
123 | 0079489723AB50BB006DB77A /* RenameFunc.swift */,
124 | 0079489923AB547C006DB77A /* RenameProperty.swift */,
125 | 0079489B23AB90F9006DB77A /* ExtractHardCode.swift */,
126 | );
127 | path = Obfuscator;
128 | sourceTree = "";
129 | };
130 | /* End PBXGroup section */
131 |
132 | /* Begin PBXNativeTarget section */
133 | 00FC6B4C23A8A80600D67B71 /* CCPObfuscation */ = {
134 | isa = PBXNativeTarget;
135 | buildConfigurationList = 00FC6B6823A8A80800D67B71 /* Build configuration list for PBXNativeTarget "CCPObfuscation" */;
136 | buildPhases = (
137 | 00FC6B4923A8A80600D67B71 /* Sources */,
138 | 00FC6B4A23A8A80600D67B71 /* Frameworks */,
139 | 00FC6B4B23A8A80600D67B71 /* Resources */,
140 | );
141 | buildRules = (
142 | );
143 | dependencies = (
144 | );
145 | name = CCPObfuscation;
146 | productName = CCPObfuscation;
147 | productReference = 00FC6B4D23A8A80600D67B71 /* CCPObfuscation.app */;
148 | productType = "com.apple.product-type.application";
149 | };
150 | 00FC6B5E23A8A80800D67B71 /* CCPObfuscationTests */ = {
151 | isa = PBXNativeTarget;
152 | buildConfigurationList = 00FC6B6B23A8A80800D67B71 /* Build configuration list for PBXNativeTarget "CCPObfuscationTests" */;
153 | buildPhases = (
154 | 00FC6B5B23A8A80800D67B71 /* Sources */,
155 | 00FC6B5C23A8A80800D67B71 /* Frameworks */,
156 | 00FC6B5D23A8A80800D67B71 /* Resources */,
157 | );
158 | buildRules = (
159 | );
160 | dependencies = (
161 | 00FC6B6123A8A80800D67B71 /* PBXTargetDependency */,
162 | );
163 | name = CCPObfuscationTests;
164 | productName = CCPObfuscationTests;
165 | productReference = 00FC6B5F23A8A80800D67B71 /* CCPObfuscationTests.xctest */;
166 | productType = "com.apple.product-type.bundle.unit-test";
167 | };
168 | /* End PBXNativeTarget section */
169 |
170 | /* Begin PBXProject section */
171 | 00FC6B4523A8A80600D67B71 /* Project object */ = {
172 | isa = PBXProject;
173 | attributes = {
174 | LastSwiftUpdateCheck = 1120;
175 | LastUpgradeCheck = 1120;
176 | ORGANIZATIONNAME = "储诚鹏";
177 | TargetAttributes = {
178 | 00FC6B4C23A8A80600D67B71 = {
179 | CreatedOnToolsVersion = 11.2.1;
180 | };
181 | 00FC6B5E23A8A80800D67B71 = {
182 | CreatedOnToolsVersion = 11.2.1;
183 | TestTargetID = 00FC6B4C23A8A80600D67B71;
184 | };
185 | };
186 | };
187 | buildConfigurationList = 00FC6B4823A8A80600D67B71 /* Build configuration list for PBXProject "CCPObfuscation" */;
188 | compatibilityVersion = "Xcode 9.3";
189 | developmentRegion = en;
190 | hasScannedForEncodings = 0;
191 | knownRegions = (
192 | en,
193 | Base,
194 | );
195 | mainGroup = 00FC6B4423A8A80600D67B71;
196 | productRefGroup = 00FC6B4E23A8A80600D67B71 /* Products */;
197 | projectDirPath = "";
198 | projectRoot = "";
199 | targets = (
200 | 00FC6B4C23A8A80600D67B71 /* CCPObfuscation */,
201 | 00FC6B5E23A8A80800D67B71 /* CCPObfuscationTests */,
202 | );
203 | };
204 | /* End PBXProject section */
205 |
206 | /* Begin PBXResourcesBuildPhase section */
207 | 00FC6B4B23A8A80600D67B71 /* Resources */ = {
208 | isa = PBXResourcesBuildPhase;
209 | buildActionMask = 2147483647;
210 | files = (
211 | 00FC6B5523A8A80800D67B71 /* Assets.xcassets in Resources */,
212 | 00FC6B5823A8A80800D67B71 /* Main.storyboard in Resources */,
213 | );
214 | runOnlyForDeploymentPostprocessing = 0;
215 | };
216 | 00FC6B5D23A8A80800D67B71 /* Resources */ = {
217 | isa = PBXResourcesBuildPhase;
218 | buildActionMask = 2147483647;
219 | files = (
220 | );
221 | runOnlyForDeploymentPostprocessing = 0;
222 | };
223 | /* End PBXResourcesBuildPhase section */
224 |
225 | /* Begin PBXSourcesBuildPhase section */
226 | 00FC6B4923A8A80600D67B71 /* Sources */ = {
227 | isa = PBXSourcesBuildPhase;
228 | buildActionMask = 2147483647;
229 | files = (
230 | 00FC6B5323A8A80700D67B71 /* ViewC ontroller.swift in Sources */,
231 | 00FC6B7023A8A84600D67B71 /* ObfuscatorUtils.swift in Sources */,
232 | 0079489223AB4B95006DB77A /* DeleteNotes.swift in Sources */,
233 | 0079489623AB4F2D006DB77A /* ObfuscatorModify.swift in Sources */,
234 | 00FC6B5123A8A80700D67B71 /* AppDelegate.swift in Sources */,
235 | 0079489423AB4BE6006DB77A /* RenameClass.swift in Sources */,
236 | 0079489023AB4AF3006DB77A /* Obfuscator.swift in Sources */,
237 | 0079489C23AB90F9006DB77A /* ExtractHardCode.swift in Sources */,
238 | 0079489A23AB547C006DB77A /* RenameProperty.swift in Sources */,
239 | 0079489823AB50BB006DB77A /* RenameFunc.swift in Sources */,
240 | );
241 | runOnlyForDeploymentPostprocessing = 0;
242 | };
243 | 00FC6B5B23A8A80800D67B71 /* Sources */ = {
244 | isa = PBXSourcesBuildPhase;
245 | buildActionMask = 2147483647;
246 | files = (
247 | 00FC6B6423A8A80800D67B71 /* CCPObfuscationTests.swift in Sources */,
248 | );
249 | runOnlyForDeploymentPostprocessing = 0;
250 | };
251 | /* End PBXSourcesBuildPhase section */
252 |
253 | /* Begin PBXTargetDependency section */
254 | 00FC6B6123A8A80800D67B71 /* PBXTargetDependency */ = {
255 | isa = PBXTargetDependency;
256 | target = 00FC6B4C23A8A80600D67B71 /* CCPObfuscation */;
257 | targetProxy = 00FC6B6023A8A80800D67B71 /* PBXContainerItemProxy */;
258 | };
259 | /* End PBXTargetDependency section */
260 |
261 | /* Begin PBXVariantGroup section */
262 | 00FC6B5623A8A80800D67B71 /* Main.storyboard */ = {
263 | isa = PBXVariantGroup;
264 | children = (
265 | 00FC6B5723A8A80800D67B71 /* Base */,
266 | );
267 | name = Main.storyboard;
268 | sourceTree = "";
269 | };
270 | /* End PBXVariantGroup section */
271 |
272 | /* Begin XCBuildConfiguration section */
273 | 00FC6B6623A8A80800D67B71 /* Debug */ = {
274 | isa = XCBuildConfiguration;
275 | buildSettings = {
276 | ALWAYS_SEARCH_USER_PATHS = NO;
277 | CLANG_ANALYZER_NONNULL = YES;
278 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
279 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
280 | CLANG_CXX_LIBRARY = "libc++";
281 | CLANG_ENABLE_MODULES = YES;
282 | CLANG_ENABLE_OBJC_ARC = YES;
283 | CLANG_ENABLE_OBJC_WEAK = YES;
284 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
285 | CLANG_WARN_BOOL_CONVERSION = YES;
286 | CLANG_WARN_COMMA = YES;
287 | CLANG_WARN_CONSTANT_CONVERSION = YES;
288 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
289 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
290 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
291 | CLANG_WARN_EMPTY_BODY = YES;
292 | CLANG_WARN_ENUM_CONVERSION = YES;
293 | CLANG_WARN_INFINITE_RECURSION = YES;
294 | CLANG_WARN_INT_CONVERSION = YES;
295 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
296 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
297 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
298 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
299 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
300 | CLANG_WARN_STRICT_PROTOTYPES = YES;
301 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
302 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
303 | CLANG_WARN_UNREACHABLE_CODE = YES;
304 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
305 | COPY_PHASE_STRIP = NO;
306 | DEBUG_INFORMATION_FORMAT = dwarf;
307 | ENABLE_STRICT_OBJC_MSGSEND = YES;
308 | ENABLE_TESTABILITY = YES;
309 | GCC_C_LANGUAGE_STANDARD = gnu11;
310 | GCC_DYNAMIC_NO_PIC = NO;
311 | GCC_NO_COMMON_BLOCKS = YES;
312 | GCC_OPTIMIZATION_LEVEL = 0;
313 | GCC_PREPROCESSOR_DEFINITIONS = (
314 | "DEBUG=1",
315 | "$(inherited)",
316 | );
317 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
318 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
319 | GCC_WARN_UNDECLARED_SELECTOR = YES;
320 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
321 | GCC_WARN_UNUSED_FUNCTION = YES;
322 | GCC_WARN_UNUSED_VARIABLE = YES;
323 | MACOSX_DEPLOYMENT_TARGET = 10.8;
324 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
325 | MTL_FAST_MATH = YES;
326 | ONLY_ACTIVE_ARCH = YES;
327 | SDKROOT = macosx;
328 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
329 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
330 | };
331 | name = Debug;
332 | };
333 | 00FC6B6723A8A80800D67B71 /* Release */ = {
334 | isa = XCBuildConfiguration;
335 | buildSettings = {
336 | ALWAYS_SEARCH_USER_PATHS = NO;
337 | CLANG_ANALYZER_NONNULL = YES;
338 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
339 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
340 | CLANG_CXX_LIBRARY = "libc++";
341 | CLANG_ENABLE_MODULES = YES;
342 | CLANG_ENABLE_OBJC_ARC = YES;
343 | CLANG_ENABLE_OBJC_WEAK = YES;
344 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
345 | CLANG_WARN_BOOL_CONVERSION = YES;
346 | CLANG_WARN_COMMA = YES;
347 | CLANG_WARN_CONSTANT_CONVERSION = YES;
348 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
349 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
350 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
351 | CLANG_WARN_EMPTY_BODY = YES;
352 | CLANG_WARN_ENUM_CONVERSION = YES;
353 | CLANG_WARN_INFINITE_RECURSION = YES;
354 | CLANG_WARN_INT_CONVERSION = YES;
355 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
356 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
357 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
358 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
359 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
360 | CLANG_WARN_STRICT_PROTOTYPES = YES;
361 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
362 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
363 | CLANG_WARN_UNREACHABLE_CODE = YES;
364 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
365 | COPY_PHASE_STRIP = NO;
366 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
367 | ENABLE_NS_ASSERTIONS = NO;
368 | ENABLE_STRICT_OBJC_MSGSEND = YES;
369 | GCC_C_LANGUAGE_STANDARD = gnu11;
370 | GCC_NO_COMMON_BLOCKS = YES;
371 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
372 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
373 | GCC_WARN_UNDECLARED_SELECTOR = YES;
374 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
375 | GCC_WARN_UNUSED_FUNCTION = YES;
376 | GCC_WARN_UNUSED_VARIABLE = YES;
377 | MACOSX_DEPLOYMENT_TARGET = 10.8;
378 | MTL_ENABLE_DEBUG_INFO = NO;
379 | MTL_FAST_MATH = YES;
380 | SDKROOT = macosx;
381 | SWIFT_COMPILATION_MODE = wholemodule;
382 | SWIFT_OPTIMIZATION_LEVEL = "-O";
383 | };
384 | name = Release;
385 | };
386 | 00FC6B6923A8A80800D67B71 /* Debug */ = {
387 | isa = XCBuildConfiguration;
388 | buildSettings = {
389 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
390 | CODE_SIGN_ENTITLEMENTS = CCPObfuscation/CCPObfuscation.entitlements;
391 | CODE_SIGN_IDENTITY = "-";
392 | CODE_SIGN_STYLE = Automatic;
393 | COMBINE_HIDPI_IMAGES = YES;
394 | DEVELOPMENT_TEAM = "";
395 | INFOPLIST_FILE = CCPObfuscation/Info.plist;
396 | LD_RUNPATH_SEARCH_PATHS = (
397 | "$(inherited)",
398 | "@executable_path/../Frameworks",
399 | );
400 | MACOSX_DEPLOYMENT_TARGET = 10.12;
401 | PRODUCT_BUNDLE_IDENTIFIER = ccp.CCPObfuscation;
402 | PRODUCT_NAME = "$(TARGET_NAME)";
403 | PROVISIONING_PROFILE_SPECIFIER = "";
404 | SWIFT_VERSION = 5.0;
405 | };
406 | name = Debug;
407 | };
408 | 00FC6B6A23A8A80800D67B71 /* Release */ = {
409 | isa = XCBuildConfiguration;
410 | buildSettings = {
411 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
412 | CODE_SIGN_ENTITLEMENTS = CCPObfuscation/CCPObfuscation.entitlements;
413 | CODE_SIGN_STYLE = Manual;
414 | COMBINE_HIDPI_IMAGES = YES;
415 | DEVELOPMENT_TEAM = "";
416 | INFOPLIST_FILE = CCPObfuscation/Info.plist;
417 | LD_RUNPATH_SEARCH_PATHS = (
418 | "$(inherited)",
419 | "@executable_path/../Frameworks",
420 | );
421 | MACOSX_DEPLOYMENT_TARGET = 10.12;
422 | PRODUCT_BUNDLE_IDENTIFIER = ccp.CCPObfuscation;
423 | PRODUCT_NAME = "$(TARGET_NAME)";
424 | PROVISIONING_PROFILE_SPECIFIER = "";
425 | SWIFT_VERSION = 5.0;
426 | };
427 | name = Release;
428 | };
429 | 00FC6B6C23A8A80800D67B71 /* Debug */ = {
430 | isa = XCBuildConfiguration;
431 | buildSettings = {
432 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
433 | BUNDLE_LOADER = "$(TEST_HOST)";
434 | CODE_SIGN_STYLE = Automatic;
435 | COMBINE_HIDPI_IMAGES = YES;
436 | INFOPLIST_FILE = CCPObfuscationTests/Info.plist;
437 | LD_RUNPATH_SEARCH_PATHS = (
438 | "$(inherited)",
439 | "@executable_path/../Frameworks",
440 | "@loader_path/../Frameworks",
441 | );
442 | MACOSX_DEPLOYMENT_TARGET = 10.14;
443 | PRODUCT_BUNDLE_IDENTIFIER = ccp.CCPObfuscationTests;
444 | PRODUCT_NAME = "$(TARGET_NAME)";
445 | SWIFT_VERSION = 5.0;
446 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CCPObfuscation.app/Contents/MacOS/CCPObfuscation";
447 | };
448 | name = Debug;
449 | };
450 | 00FC6B6D23A8A80800D67B71 /* Release */ = {
451 | isa = XCBuildConfiguration;
452 | buildSettings = {
453 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
454 | BUNDLE_LOADER = "$(TEST_HOST)";
455 | CODE_SIGN_STYLE = Automatic;
456 | COMBINE_HIDPI_IMAGES = YES;
457 | INFOPLIST_FILE = CCPObfuscationTests/Info.plist;
458 | LD_RUNPATH_SEARCH_PATHS = (
459 | "$(inherited)",
460 | "@executable_path/../Frameworks",
461 | "@loader_path/../Frameworks",
462 | );
463 | MACOSX_DEPLOYMENT_TARGET = 10.14;
464 | PRODUCT_BUNDLE_IDENTIFIER = ccp.CCPObfuscationTests;
465 | PRODUCT_NAME = "$(TARGET_NAME)";
466 | SWIFT_VERSION = 5.0;
467 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CCPObfuscation.app/Contents/MacOS/CCPObfuscation";
468 | };
469 | name = Release;
470 | };
471 | /* End XCBuildConfiguration section */
472 |
473 | /* Begin XCConfigurationList section */
474 | 00FC6B4823A8A80600D67B71 /* Build configuration list for PBXProject "CCPObfuscation" */ = {
475 | isa = XCConfigurationList;
476 | buildConfigurations = (
477 | 00FC6B6623A8A80800D67B71 /* Debug */,
478 | 00FC6B6723A8A80800D67B71 /* Release */,
479 | );
480 | defaultConfigurationIsVisible = 0;
481 | defaultConfigurationName = Release;
482 | };
483 | 00FC6B6823A8A80800D67B71 /* Build configuration list for PBXNativeTarget "CCPObfuscation" */ = {
484 | isa = XCConfigurationList;
485 | buildConfigurations = (
486 | 00FC6B6923A8A80800D67B71 /* Debug */,
487 | 00FC6B6A23A8A80800D67B71 /* Release */,
488 | );
489 | defaultConfigurationIsVisible = 0;
490 | defaultConfigurationName = Release;
491 | };
492 | 00FC6B6B23A8A80800D67B71 /* Build configuration list for PBXNativeTarget "CCPObfuscationTests" */ = {
493 | isa = XCConfigurationList;
494 | buildConfigurations = (
495 | 00FC6B6C23A8A80800D67B71 /* Debug */,
496 | 00FC6B6D23A8A80800D67B71 /* Release */,
497 | );
498 | defaultConfigurationIsVisible = 0;
499 | defaultConfigurationName = Release;
500 | };
501 | /* End XCConfigurationList section */
502 | };
503 | rootObject = 00FC6B4523A8A80600D67B71 /* Project object */;
504 | }
505 |
--------------------------------------------------------------------------------
/CCPObfuscation/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
--------------------------------------------------------------------------------