├── 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 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | Default 529 | 530 | 531 | 532 | 533 | 534 | 535 | Left to Right 536 | 537 | 538 | 539 | 540 | 541 | 542 | Right to Left 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | Default 554 | 555 | 556 | 557 | 558 | 559 | 560 | Left to Right 561 | 562 | 563 | 564 | 565 | 566 | 567 | Right to Left 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 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 | --------------------------------------------------------------------------------