├── .gitignore ├── CDUnitTests-Info.plist ├── CHANGELOG.md ├── External └── GData │ └── lib │ ├── GDataXMLNode.h │ └── GDataXMLNode.m ├── Info.plist ├── LICENSE.txt ├── Makefile ├── Podfile ├── Podfile.lock ├── README.md ├── Source ├── CDBalanceFormatter.h ├── CDBalanceFormatter.m ├── CDClassDump.h ├── CDClassDump.m ├── CDClassDumpVisitor.h ├── CDClassDumpVisitor.m ├── CDClassFrameworkVisitor.h ├── CDClassFrameworkVisitor.m ├── CDCoreDataModelParser.h ├── CDCoreDataModelParser.m ├── CDCoreDataModelProcessor.h ├── CDCoreDataModelProcessor.m ├── CDDataCursor.h ├── CDDataCursor.m ├── CDExtensions.h ├── CDFatArch.h ├── CDFatArch.m ├── CDFatFile.h ├── CDFatFile.m ├── CDFile.h ├── CDFile.m ├── CDFindMethodVisitor.h ├── CDFindMethodVisitor.m ├── CDLCDataInCode.h ├── CDLCDataInCode.m ├── CDLCDyldInfo.h ├── CDLCDyldInfo.m ├── CDLCDylib.h ├── CDLCDylib.m ├── CDLCDylinker.h ├── CDLCDylinker.m ├── CDLCDynamicSymbolTable.h ├── CDLCDynamicSymbolTable.m ├── CDLCEncryptionInfo.h ├── CDLCEncryptionInfo.m ├── CDLCFunctionStarts.h ├── CDLCFunctionStarts.m ├── CDLCLinkeditData.h ├── CDLCLinkeditData.m ├── CDLCMain.h ├── CDLCMain.m ├── CDLCPrebindChecksum.h ├── CDLCPrebindChecksum.m ├── CDLCPreboundDylib.h ├── CDLCPreboundDylib.m ├── CDLCRoutines32.h ├── CDLCRoutines32.m ├── CDLCRoutines64.h ├── CDLCRoutines64.m ├── CDLCRunPath.h ├── CDLCRunPath.m ├── CDLCSegment.h ├── CDLCSegment.m ├── CDLCSourceVersion.h ├── CDLCSourceVersion.m ├── CDLCSubClient.h ├── CDLCSubClient.m ├── CDLCSubFramework.h ├── CDLCSubFramework.m ├── CDLCSubLibrary.h ├── CDLCSubLibrary.m ├── CDLCSubUmbrella.h ├── CDLCSubUmbrella.m ├── CDLCSymbolTable.h ├── CDLCSymbolTable.m ├── CDLCTwoLevelHints.h ├── CDLCTwoLevelHints.m ├── CDLCUUID.h ├── CDLCUUID.m ├── CDLCUnixThread.h ├── CDLCUnixThread.m ├── CDLCUnknown.h ├── CDLCUnknown.m ├── CDLCVersionMinimum.h ├── CDLCVersionMinimum.m ├── CDLoadCommand.h ├── CDLoadCommand.m ├── CDMachOFile.h ├── CDMachOFile.m ├── CDMachOFileDataCursor.h ├── CDMachOFileDataCursor.m ├── CDMethodType.h ├── CDMethodType.m ├── CDMultiFileVisitor.h ├── CDMultiFileVisitor.m ├── CDOCCategory.h ├── CDOCCategory.m ├── CDOCClass.h ├── CDOCClass.m ├── CDOCClassReference.h ├── CDOCClassReference.m ├── CDOCInstanceVariable.h ├── CDOCInstanceVariable.m ├── CDOCMethod.h ├── CDOCMethod.m ├── CDOCModule.h ├── CDOCModule.m ├── CDOCProperty.h ├── CDOCProperty.m ├── CDOCProtocol.h ├── CDOCProtocol.m ├── CDOCSymtab.h ├── CDOCSymtab.m ├── CDObjectiveC1Processor.h ├── CDObjectiveC1Processor.m ├── CDObjectiveC2Processor.h ├── CDObjectiveC2Processor.m ├── CDObjectiveCProcessor.h ├── CDObjectiveCProcessor.m ├── CDProtocolUniquer.h ├── CDProtocolUniquer.m ├── CDRelocationInfo.h ├── CDRelocationInfo.m ├── CDSearchPathState.h ├── CDSearchPathState.m ├── CDSection.h ├── CDSection.m ├── CDStructureInfo.h ├── CDStructureInfo.m ├── CDStructureTable.h ├── CDStructureTable.m ├── CDSymbol.h ├── CDSymbol.m ├── CDSymbolsGeneratorVisitor.h ├── CDSymbolsGeneratorVisitor.m ├── CDTextClassDumpVisitor.h ├── CDTextClassDumpVisitor.m ├── CDTopoSortNode.h ├── CDTopoSortNode.m ├── CDTopologicalSortProtocol.h ├── CDType.h ├── CDType.m ├── CDTypeController.h ├── CDTypeController.m ├── CDTypeFormatter.h ├── CDTypeFormatter.m ├── CDTypeLexer.h ├── CDTypeLexer.m ├── CDTypeName.h ├── CDTypeName.m ├── CDTypeParser.h ├── CDTypeParser.m ├── CDVisitor.h ├── CDVisitor.m ├── CDVisitorPropertyState.h ├── CDVisitorPropertyState.m ├── CDXMLParserSharedBase.h ├── CDXMLParserSharedBase.m ├── CDXibStoryBoardProcessor.h ├── CDXibStoryBoardProcessor.m ├── CDXibStoryboardParser.h ├── CDXibStoryboardParser.m ├── MachObjC-Prefix.pch ├── NSArray-CDExtensions.h ├── NSArray-CDExtensions.m ├── NSData-CDExtensions.h ├── NSData-CDExtensions.m ├── NSError-CDExtensions.h ├── NSError-CDExtensions.m ├── NSScanner-CDExtensions.h ├── NSScanner-CDExtensions.m ├── NSString-CDExtensions.h ├── NSString-CDExtensions.m ├── ULEB128.h ├── ULEB128.m ├── cd_objc2.h ├── class-dump.m ├── deprotect-Prefix.pch └── deprotect.m ├── Symbol mapping ├── CDSymbolMapper.h └── CDSymbolMapper.m ├── System Protocols Dumping ├── CDSystemProtocolsProcessor.h └── CDSystemProtocolsProcessor.m ├── ThirdPartyLicenses.txt ├── UnitTests ├── TestBlockSignature.m ├── TestCDArchFromName.m ├── TestCDArchUses64BitABI.m ├── TestCDNameForCPUType.m ├── TestFatFile_Intel32_64.m ├── TestFatFile_Intel32_64_lib64.m ├── TestFatFile_Intel64_32.m ├── TestFatFile_armv7_v7s.m ├── TestThinFile_Intel64.m ├── TestThinFile_Intel64_lib64.m ├── UnitTests-Info.plist ├── UnitTests-Prefix.pch └── en.lproj │ └── InfoPlist.strings ├── ppios-rename Spec ├── CDCoreDataModelParserSpec.m ├── CDSymbolsMapperSpec.m ├── CDSymoblsGeneratorVisitorSpec.m ├── CDSystemProtocolsProcessorSpec.m ├── CDXibStoryboardParserSpec.m ├── CustomCellTableViewCell_xib.txt ├── Main_iPhone_storyboard.txt ├── contents └── podsProject.json ├── ppios-rename-Prefix.pch ├── ppios-rename.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── class-dump.xccheckout │ └── xcuserdata │ │ └── nygard.xcuserdatad │ │ └── WorkspaceSettings.xcsettings ├── xcshareddata │ └── xcschemes │ │ ├── MachObjC.xcscheme │ │ └── ppios-rename.xcscheme └── xcuserdata │ └── nygard.xcuserdatad │ └── xcschemes │ ├── MachObjC.xcscheme │ ├── all.xcscheme │ ├── class-dump.xcscheme │ ├── deprotect.xcscheme │ ├── formatType.xcscheme │ └── xcschememanagement.plist └── test ├── .gitignore ├── apps ├── BoxSim-support │ ├── BoxSim.app.dSYM │ │ └── Contents │ │ │ ├── Info.plist │ │ │ └── Resources │ │ │ └── DWARF │ │ │ └── BoxSim │ ├── README │ ├── symbolicated.crash │ ├── symbols.map │ └── unsymbolicated.crash └── BoxSim │ ├── BoxSim-Prefix.pch │ ├── BoxSim.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── BoxSim.xcscheme │ ├── BoxSim │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── BoxSim.xcdatamodeld │ │ ├── .xccurrentversion │ │ └── BoxSim.xcdatamodel │ │ │ └── contents │ ├── Info.plist │ ├── TextDisplay.h │ ├── ViewController.h │ ├── ViewController.m │ └── main.m │ ├── BoxSimTests │ ├── BoxSimTests.m │ └── Info.plist │ ├── BoxSimUITests │ ├── BoxSimUITests.m │ └── Info.plist │ └── Makefile └── tests ├── check-documentation.sh ├── common-assertions.sh ├── common.sh ├── test-double-obfuscation-protection.sh ├── test-filters-and-exclusions.sh ├── test-new-options.sh ├── test-obfuscate-sources.sh ├── test-post-obfuscation-behavior.sh └── test-suite.sh /.gitignore: -------------------------------------------------------------------------------- 1 | xcuserdata 2 | *.xcarchive/ 3 | /.idea/ 4 | /build/ 5 | /Pods/ 6 | /ppios-rename.xcworkspace/ 7 | DerivedData 8 | /*._*/ 9 | /v*.*.*/ 10 | -------------------------------------------------------------------------------- /CDUnitTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.stevenygard.CDUnitTests 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleSignature 16 | ???? 17 | CFBundleVersion 18 | 1.0 19 | 20 | 21 | -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIdentifier 8 | com.preemptive.ppios-rename 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | ppios-rename 13 | 14 | 15 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2016-2020 PreEmptive Solutions, LLC 2 | # See LICENSE.txt for licensing information 3 | 4 | PROJECT_NAME=PPiOS-Rename 5 | NUMERIC_VERSION=1.6.0 6 | VERSION=v$(NUMERIC_VERSION) 7 | PROGRAM_NAME=ppios-rename 8 | 9 | TARGET=Release 10 | #TARGET=Debug 11 | BUILD_DIR=build 12 | PROGRAM="$(shell pwd)/$(BUILD_DIR)/Build/Products/$(TARGET)/$(PROGRAM_NAME)" 13 | README="$(shell pwd)/README.md" 14 | GIT_CMD=git rev-parse --short HEAD 15 | GIT_HASH_CHECK=$(GIT_CMD) &> /dev/null 16 | GIT_HASH=$(shell $(GIT_HASH_CHECK) && $(GIT_CMD) | sed 's,^,-,') 17 | BUILD_NUMBER_CHECK=! test -z "$${BUILD_NUMBER}" 18 | BUILD_NUMBER=$(shell $(BUILD_NUMBER_CHECK) && echo $${BUILD_NUMBER} | sed 's,^,-,') 19 | DIST_DIR=$(PROJECT_NAME)-$(VERSION) 20 | FULL_VERSION=$(VERSION)$(GIT_HASH)$(BUILD_NUMBER) 21 | ARCHIVE_DIR=$(FULL_VERSION) 22 | DIST_PACKAGE=$(ARCHIVE_DIR)/$(PROJECT_NAME)-$(FULL_VERSION).tgz 23 | WORKSPACE=ppios-rename.xcworkspace 24 | 25 | XCODEBUILD_OPTIONS=\ 26 | -workspace $(WORKSPACE) \ 27 | -scheme ppios-rename \ 28 | -configuration $(TARGET) \ 29 | -derivedDataPath $(BUILD_DIR) 30 | 31 | .PHONY: default 32 | default: all 33 | 34 | .PHONY: all 35 | all: Pods $(WORKSPACE) program 36 | 37 | # convenience target 38 | .PHONY: it 39 | it: clean all check 40 | 41 | $(WORKSPACE) Pods Podfile.lock: Podfile 42 | pod install 43 | 44 | .PHONY: program 45 | program: Pods clean build 46 | 47 | # "test" appears to mean "build for testing and test", so the unit tests. Do that first, then make the real thing. 48 | .PHONY: unittest 49 | unittest: Pods 50 | xcodebuild $(XCODEBUILD_OPTIONS) CLASS_DUMP_VERSION=$(NUMERIC_VERSION)$(GIT_HASH) test \ 51 | | tee xcodebuild-$@.log | xcpretty ; exit "$${PIPESTATUS[0]}" 52 | 53 | .PHONY: build 54 | build: 55 | xcodebuild $(XCODEBUILD_OPTIONS) CLASS_DUMP_VERSION=$(NUMERIC_VERSION)$(GIT_HASH) clean build \ 56 | | tee xcodebuild-$@.log | xcpretty ; exit "$${PIPESTATUS[0]}" 57 | 58 | .PHONY: check 59 | check: 60 | ( cd test/tests ; PPIOS_RENAME=$(PROGRAM) README=$(README) NUMERIC_VERSION=$(NUMERIC_VERSION) ./test-suite.sh ) 61 | 62 | .PHONY: archive 63 | archive: package-check distclean unittest program check archive-dir $(DIST_PACKAGE) copy-symbols 64 | 65 | .PHONY: package-check 66 | package-check: 67 | @$(GIT_HASH_CHECK) || echo "Info: git hash unavailable, omitting from package name" 68 | @$(BUILD_NUMBER_CHECK) || echo "Info: BUILD_NUMBER unset, omitting from package name" 69 | 70 | .PHONY: archive-dir 71 | archive-dir: 72 | mkdir -p $(ARCHIVE_DIR) 73 | 74 | $(DIST_PACKAGE): 75 | mkdir -p $(DIST_DIR) 76 | cp $(PROGRAM) \ 77 | README.md \ 78 | LICENSE.txt \ 79 | ThirdPartyLicenses.txt \ 80 | CHANGELOG.md \ 81 | $(DIST_DIR) 82 | tar -cvpzf $@ --options gzip:compression-level=9 $(DIST_DIR) 83 | 84 | .PHONY: copy-symbols 85 | copy-symbols: 86 | cp -r $(PROGRAM).dSYM $(ARCHIVE_DIR)/ 87 | 88 | .PHONY: clean 89 | clean: 90 | $(RM) -r $(BUILD_DIR) 91 | 92 | .PHONY: distclean 93 | distclean: clean 94 | $(RM) -r Pods $(DIST_DIR)* v?.?.?-* 95 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | source "https://github.com/CocoaPods/Old-Specs" 2 | platform :osx, '10.8' 3 | 4 | target :UnitTests do 5 | pod 'Kiwi' 6 | end 7 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Kiwi (2.3.0) 3 | 4 | DEPENDENCIES: 5 | - Kiwi 6 | 7 | SPEC REPOS: 8 | https://github.com/CocoaPods/Old-Specs: 9 | - Kiwi 10 | 11 | SPEC CHECKSUMS: 12 | Kiwi: 4c3988bd551f80f6ca0009f302f7c1a2e3777bf2 13 | 14 | PODFILE CHECKSUM: c3c2eb4605f372c09bc80aa574760a0658292232 15 | 16 | COCOAPODS: 1.9.3 17 | -------------------------------------------------------------------------------- /Source/CDBalanceFormatter.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @interface CDBalanceFormatter : NSObject 7 | 8 | - (id)initWithString:(NSString *)str; 9 | 10 | - (void)parse:(NSString *)open index:(NSUInteger)openIndex level:(NSUInteger)level; 11 | 12 | - (NSString *)format; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Source/CDClassDump.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | /************************************************* 4 | Copyright 2016-2018 PreEmptive Solutions, LLC 5 | See LICENSE.txt for licensing information 6 | *************************************************/ 7 | 8 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 9 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 10 | 11 | #import "CDFile.h" // For CDArch 12 | 13 | #define NOT_MACHO_OR_FAT_MESSAGE "Input file (%s) is neither a Mach-O file nor a fat archive." 14 | #define STATIC_LIBRARY_MESSAGE "If you are trying to obfuscate a static library, please review the " \ 15 | "'Obfuscating Static Libraries' section of the documentation." 16 | 17 | @class CDFile; 18 | @class CDTypeController; 19 | @class CDVisitor; 20 | @class CDSearchPathState; 21 | 22 | @interface CDClassDump : NSObject 23 | 24 | @property (readonly) CDSearchPathState *searchPathState; 25 | @property (copy, nonatomic) NSArray *forceRecursiveAnalyze; 26 | 27 | @property (strong) NSString *sdkRoot; 28 | @property (strong) NSString *headersRoot; 29 | 30 | @property (readonly) NSArray *machOFiles; 31 | @property (readonly) NSArray *objcProcessors; 32 | 33 | @property (assign) CDArch targetArch; 34 | 35 | @property (nonatomic, readonly) BOOL containsObjectiveCData; 36 | @property (nonatomic, readonly) BOOL hasEncryptedFiles; 37 | @property (nonatomic, readonly) BOOL hasObjectiveCRuntimeInfo; 38 | 39 | @property (readonly) CDTypeController *typeController; 40 | 41 | - (BOOL)loadFile:(CDFile *)file error:(NSError **)error depth:(int)depth; 42 | - (int)processObjectiveCData; 43 | 44 | - (void)recursivelyVisit:(CDVisitor *)visitor; 45 | 46 | - (void)appendHeaderToString:(NSMutableString *)resultString; 47 | 48 | - (void)registerTypes; 49 | 50 | - (void)showHeader; 51 | - (void)showLoadCommands; 52 | 53 | - (int)obfuscateSourcesUsingMap:(NSString *)symbolsPath 54 | symbolsHeaderFile:(NSString *)symbolsHeaderFile 55 | workingDirectory:(NSString *)workingDirectory 56 | xibDirectory:(NSString *)xibDirectory; 57 | 58 | @end 59 | 60 | extern NSString *CDErrorDomain_ClassDump; 61 | extern NSString *CDErrorKey_Exception; 62 | 63 | 64 | -------------------------------------------------------------------------------- /Source/CDClassDumpVisitor.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDTextClassDumpVisitor.h" 7 | 8 | @interface CDClassDumpVisitor : CDTextClassDumpVisitor 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Source/CDClassFrameworkVisitor.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDVisitor.h" 7 | 8 | // This builds up a dictionary mapping class names to a framework names. 9 | // It is only used by CDMultiFileVisitor to generate individual imports when creating separate header files. 10 | 11 | // Some protocols appear in multiple frameworks. This just records the last framework that contained a reference, which 12 | // produces incorrect results. For example, -r AppKit.framework, and Foundation.framework is processed before several 13 | // others, including Symbolication. 14 | 15 | // If we follow framework dependancies, the earliest reference to NSCopying is CoreFoundation, but NSCopying is really 16 | // defined in Foundation. 17 | 18 | // But it turns out that we can just use forward references for protocols. 19 | 20 | @interface CDClassFrameworkVisitor : CDVisitor 21 | 22 | // NSString (class name) -> NSString (framework name) 23 | @property (nonatomic, readonly) NSDictionary *frameworkNamesByClassName; 24 | 25 | // NSString (protocol name) -> NSString (framework name) 26 | @property (nonatomic, readonly) NSDictionary *frameworkNamesByProtocolName; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Source/CDCoreDataModelParser.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | Copyright 2016 PreEmptive Solutions, LLC 3 | See LICENSE.txt for licensing information 4 | ********************************************/ 5 | 6 | #import 7 | #import "CDXMLParserSharedBase.h" 8 | 9 | @class GDataXMLElement; 10 | 11 | 12 | @interface CDCoreDataModelParser : CDXMLParserSharedBase 13 | @end 14 | -------------------------------------------------------------------------------- /Source/CDCoreDataModelParser.m: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | Copyright 2016 PreEmptive Solutions, LLC 3 | See LICENSE.txt for licensing information 4 | ********************************************/ 5 | 6 | #import "CDCoreDataModelParser.h" 7 | #import "GDataXMLNode.h" 8 | 9 | 10 | @implementation CDCoreDataModelParser 11 | 12 | - (void)addSymbolsFromNode:(GDataXMLElement *)element toArray:(NSMutableArray *)symbolsArray { 13 | NSArray *childNodes = element.children; 14 | 15 | // Get the class name 16 | GDataXMLNode *className = [element attributeForName:@"representedClassName"]; 17 | if (className) { 18 | [symbolsArray addObject:[NSString stringWithFormat:@"!%@", className.stringValue]]; 19 | } 20 | 21 | // Get the class name 22 | GDataXMLNode *parentClassName = [element attributeForName:@"parentEntity"]; 23 | if (parentClassName) { 24 | [symbolsArray addObject:[NSString stringWithFormat:@"!%@", parentClassName.stringValue]]; 25 | } 26 | 27 | // Recursively process rest of the elements 28 | for (GDataXMLElement *childNode in childNodes) { 29 | // Skip comments 30 | if ([childNode isKindOfClass:[GDataXMLElement class]]) { 31 | [self addSymbolsFromNode:childNode toArray:symbolsArray]; 32 | } 33 | } 34 | } 35 | 36 | - (void)obfuscateElement:(GDataXMLElement *)element usingSymbols:(NSDictionary *)symbols { 37 | // TODO implement later 38 | } 39 | 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Source/CDCoreDataModelProcessor.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | Copyright 2016 PreEmptive Solutions, LLC 3 | See LICENSE.txt for licensing information 4 | ********************************************/ 5 | 6 | #import 7 | 8 | 9 | @interface CDCoreDataModelProcessor : NSObject 10 | - (NSArray *)coreDataModelSymbolsToExclude; 11 | @end 12 | -------------------------------------------------------------------------------- /Source/CDCoreDataModelProcessor.m: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | Copyright 2016 PreEmptive Solutions, LLC 3 | See LICENSE.txt for licensing information 4 | ********************************************/ 5 | 6 | #import "CDCoreDataModelProcessor.h" 7 | #import "CDCoreDataModelParser.h" 8 | 9 | 10 | @implementation CDCoreDataModelProcessor 11 | 12 | - (NSArray *)coreDataModelSymbolsToExclude { 13 | NSMutableArray *coreDataModelSymbols = [NSMutableArray array]; 14 | CDCoreDataModelParser *parser = [[CDCoreDataModelParser alloc] init]; 15 | 16 | __weak CDCoreDataModelProcessor *weakSelf = self; 17 | 18 | 19 | void (^modelCallback)(NSURL *) = ^(NSURL *url){ 20 | NSLog(@"Fetching symbols from CoreData model at path %@", url); 21 | [coreDataModelSymbols addObjectsFromArray:[parser symbolsInData:[NSData dataWithContentsOfURL:url]]]; 22 | }; 23 | 24 | void (^xcdatamodelCallback)(NSURL *) = ^(NSURL *url){ 25 | [weakSelf findFileWithSuffix:@"contents" inDirectoryURL:url foundCallback:modelCallback]; 26 | }; 27 | 28 | void (^xcdatamodeldCallback)(NSURL *) = ^(NSURL *url){ 29 | [weakSelf findDirectoryWithSuffix:@".xcdatamodel/" inDirectoryURL:url foundCallback:xcdatamodelCallback]; 30 | }; 31 | 32 | 33 | [self findDirectoryWithSuffix:@".xcdatamodeld/" inDirectoryURL:[NSURL URLWithString:@"."] foundCallback:xcdatamodeldCallback]; 34 | 35 | return coreDataModelSymbols; 36 | } 37 | 38 | - (void)findFileWithSuffix:(NSString *)string inDirectoryURL:(NSURL *)URL foundCallback:(void (^)(NSURL *))callback { 39 | [self findFilesOrDirectoryWithString:string isDirectory:NO URL:URL callback:callback]; 40 | } 41 | 42 | - (void)findDirectoryWithSuffix:(NSString *)string inDirectoryURL:(NSURL *)URL foundCallback:(void (^)(NSURL *))callback { 43 | [self findFilesOrDirectoryWithString:string isDirectory:YES URL:URL callback:callback]; 44 | } 45 | 46 | - (void)findFilesOrDirectoryWithString:(NSString *)string isDirectory:(BOOL)directory URL:(NSURL *)URL callback:(void (^)(NSURL *))callback { 47 | NSFileManager *fileManager = [NSFileManager defaultManager]; 48 | NSArray *keys = [NSArray arrayWithObject:NSURLIsDirectoryKey]; 49 | 50 | NSDirectoryEnumerator *enumerator = [fileManager 51 | enumeratorAtURL:URL 52 | includingPropertiesForKeys:keys 53 | options:0 54 | errorHandler:^(NSURL *url, NSError *error) { 55 | // Handle the error. 56 | // Return YES if the enumeration should continue after the error. 57 | return YES; 58 | }]; 59 | 60 | for (NSURL *url in enumerator) { 61 | NSError *error; 62 | NSNumber *isDirectory = nil; 63 | 64 | if ([url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error] && [isDirectory boolValue] == directory) { 65 | if ([url.absoluteString hasSuffix:string]) { 66 | if (callback) { 67 | callback(url); 68 | } 69 | } 70 | } 71 | } 72 | } 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /Source/CDDataCursor.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @interface CDDataCursor : NSObject 7 | 8 | - (id)initWithData:(NSData *)data; 9 | 10 | @property (readonly) NSData *data; 11 | - (const void *)bytes; 12 | 13 | @property (nonatomic, assign) NSUInteger offset; 14 | 15 | - (void)advanceByLength:(NSUInteger)length; 16 | - (NSUInteger)remaining; 17 | 18 | - (uint8_t)readByte; 19 | 20 | - (uint16_t)readLittleInt16; 21 | - (uint32_t)readLittleInt32; 22 | - (uint64_t)readLittleInt64; 23 | 24 | - (uint16_t)readBigInt16; 25 | - (uint32_t)readBigInt32; 26 | - (uint64_t)readBigInt64; 27 | 28 | - (float)readLittleFloat32; 29 | - (float)readBigFloat32; 30 | 31 | - (double)readLittleFloat64; 32 | //- (double)readBigFloat64; 33 | 34 | - (void)appendBytesOfLength:(NSUInteger)length intoData:(NSMutableData *)data; 35 | - (void)readBytesOfLength:(NSUInteger)length intoBuffer:(void *)buf; 36 | - (BOOL)isAtEnd; 37 | 38 | - (NSString *)readCString; 39 | - (NSString *)readStringOfLength:(NSUInteger)length encoding:(NSStringEncoding)encoding; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Source/CDExtensions.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDTopoSortNode.h" 7 | #import "NSArray-CDExtensions.h" 8 | #import "NSData-CDExtensions.h" 9 | #import "NSData-CDExtensions.h" 10 | #import "NSError-CDExtensions.h" 11 | #import "NSScanner-CDExtensions.h" 12 | #import "NSString-CDExtensions.h" 13 | -------------------------------------------------------------------------------- /Source/CDFatArch.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDFile.h" // For CDArch 7 | 8 | @class CDDataCursor; 9 | @class CDFatFile, CDMachOFile; 10 | 11 | @interface CDFatArch : NSObject 12 | 13 | - (id)initWithMachOFile:(CDMachOFile *)machOFile; 14 | - (id)initWithDataCursor:(CDDataCursor *)cursor; 15 | 16 | @property (assign) cpu_type_t cputype; 17 | @property (assign) cpu_subtype_t cpusubtype; 18 | @property (assign) uint32_t offset; 19 | @property (assign) uint32_t size; 20 | @property (assign) uint32_t align; 21 | 22 | @property (nonatomic, readonly) cpu_type_t maskedCPUType; 23 | @property (nonatomic, readonly) cpu_subtype_t maskedCPUSubtype; 24 | @property (nonatomic, readonly) BOOL uses64BitABI; 25 | @property (nonatomic, readonly) BOOL uses64BitLibraries; 26 | 27 | @property (weak) CDFatFile *fatFile; 28 | 29 | @property (nonatomic, readonly) CDArch arch; 30 | @property (nonatomic, readonly) NSString *archName; 31 | 32 | @property (nonatomic, readonly) CDMachOFile *machOFile; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Source/CDFatFile.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDFile.h" 7 | 8 | @class CDFatArch; 9 | 10 | @interface CDFatFile : CDFile 11 | 12 | @property (readonly) NSMutableArray *arches; 13 | @property (nonatomic, readonly) NSArray *archNames; 14 | 15 | - (void)addArchitecture:(CDFatArch *)fatArch; 16 | - (BOOL)containsArchitecture:(CDArch)arch; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Source/CDFile.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #include // For cpu_type_t, cpu_subtype_t 7 | 8 | typedef struct { 9 | cpu_type_t cputype; 10 | cpu_subtype_t cpusubtype; 11 | } CDArch; 12 | 13 | @class CDMachOFile, CDSearchPathState; 14 | 15 | NSString *CDImportNameForPath(NSString *path); 16 | NSString *CDNameForCPUType(cpu_type_t cputype, cpu_subtype_t cpusubtype); 17 | CDArch CDArchFromName(NSString *name); 18 | BOOL CDArchUses64BitABI(CDArch arch); 19 | BOOL CDArchUses64BitLibraries(CDArch arch); 20 | 21 | @interface CDFile : NSObject 22 | 23 | // Returns CDFatFile or CDMachOFile 24 | + (id)fileWithContentsOfFile:(NSString *)filename searchPathState:(CDSearchPathState *)searchPathState; 25 | 26 | - (id)initWithData:(NSData *)data filename:(NSString *)filename searchPathState:(CDSearchPathState *)searchPathState; 27 | 28 | @property (readonly) NSString *filename; 29 | @property (readonly) NSData *data; 30 | @property (readonly) CDSearchPathState *searchPathState; 31 | 32 | - (BOOL)bestMatchForLocalArch:(CDArch *)oArchPtr; 33 | - (BOOL)bestMatchForArch:(CDArch *)ioArchPtr; 34 | - (CDMachOFile *)machOFileWithArch:(CDArch)arch; 35 | 36 | @property (nonatomic, readonly) NSString *architectureNameDescription; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Source/CDFindMethodVisitor.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDVisitor.h" 7 | 8 | // This limits the output to methods matching the search string. Some context is included, so that you can see which class, category, or protocol 9 | // contains the method. 10 | 11 | @interface CDFindMethodVisitor : CDVisitor 12 | 13 | @property (strong) NSString *searchString; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Source/CDLCDataInCode.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCLinkeditData.h" 7 | 8 | @interface CDLCDataInCode : CDLCLinkeditData 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Source/CDLCDataInCode.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCDataInCode.h" 7 | 8 | #import "CDMachOFile.h" 9 | 10 | @implementation CDLCDataInCode 11 | { 12 | } 13 | 14 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 15 | { 16 | if ((self = [super initWithDataCursor:cursor])) { 17 | } 18 | 19 | return self; 20 | } 21 | 22 | #pragma mark - 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Source/CDLCDyldInfo.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCDyldInfo : CDLoadCommand 9 | 10 | - (NSString *)symbolNameForAddress:(NSUInteger)address; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Source/CDLCDylib.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCDylib : CDLoadCommand 9 | 10 | @property (readonly) NSString *path; 11 | @property (nonatomic, readonly) uint32_t timestamp; 12 | @property (nonatomic, readonly) uint32_t currentVersion; 13 | @property (nonatomic, readonly) uint32_t compatibilityVersion; 14 | 15 | @property (nonatomic, readonly) NSString *formattedCurrentVersion; 16 | @property (nonatomic, readonly) NSString *formattedCompatibilityVersion; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Source/CDLCDylib.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | /******************************************** 4 | Copyright 2016 PreEmptive Solutions, LLC 5 | See LICENSE.txt for licensing information 6 | ********************************************/ 7 | 8 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 9 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 10 | 11 | #import "CDLCDylib.h" 12 | 13 | #import "CDFatFile.h" 14 | #import "CDMachOFile.h" 15 | 16 | static NSString *CDDylibVersionString(uint32_t version) 17 | { 18 | return [NSString stringWithFormat:@"%d.%d.%d", version >> 16, (version >> 8) & 0xff, version & 0xff]; 19 | } 20 | 21 | @implementation CDLCDylib 22 | { 23 | struct dylib_command _dylibCommand; 24 | NSString *_path; 25 | } 26 | 27 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 28 | { 29 | if ((self = [super initWithDataCursor:cursor])) { 30 | _dylibCommand.cmd = [cursor readInt32]; 31 | _dylibCommand.cmdsize = [cursor readInt32]; 32 | 33 | _dylibCommand.dylib.name.offset = [cursor readInt32]; 34 | _dylibCommand.dylib.timestamp = [cursor readInt32]; 35 | _dylibCommand.dylib.current_version = [cursor readInt32]; 36 | _dylibCommand.dylib.compatibility_version = [cursor readInt32]; 37 | 38 | NSUInteger length = _dylibCommand.cmdsize - sizeof(_dylibCommand); 39 | //NSLog(@"expected length: %u", length); 40 | 41 | _path = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding]; 42 | //NSLog(@"path: %@", path); 43 | } 44 | 45 | return self; 46 | } 47 | 48 | #pragma mark - 49 | 50 | - (uint32_t)cmd; 51 | { 52 | return _dylibCommand.cmd; 53 | } 54 | 55 | - (uint32_t)cmdsize; 56 | { 57 | return _dylibCommand.cmdsize; 58 | } 59 | 60 | - (uint32_t)timestamp; 61 | { 62 | return _dylibCommand.dylib.timestamp; 63 | } 64 | 65 | - (uint32_t)currentVersion; 66 | { 67 | return _dylibCommand.dylib.current_version; 68 | } 69 | 70 | - (uint32_t)compatibilityVersion; 71 | { 72 | return _dylibCommand.dylib.compatibility_version; 73 | } 74 | 75 | - (NSString *)formattedCurrentVersion; 76 | { 77 | return CDDylibVersionString(self.currentVersion); 78 | } 79 | 80 | - (NSString *)formattedCompatibilityVersion; 81 | { 82 | return CDDylibVersionString(self.compatibilityVersion); 83 | } 84 | 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /Source/CDLCDylinker.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCDylinker : CDLoadCommand 9 | 10 | @property (readonly) NSString *name; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Source/CDLCDylinker.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCDylinker.h" 7 | 8 | @implementation CDLCDylinker 9 | { 10 | struct dylinker_command _dylinkerCommand; 11 | NSString *_name; 12 | } 13 | 14 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 15 | { 16 | if ((self = [super initWithDataCursor:cursor])) { 17 | _dylinkerCommand.cmd = [cursor readInt32]; 18 | _dylinkerCommand.cmdsize = [cursor readInt32]; 19 | 20 | _dylinkerCommand.name.offset = [cursor readInt32]; 21 | 22 | NSUInteger length = _dylinkerCommand.cmdsize - sizeof(_dylinkerCommand); 23 | //NSLog(@"expected length: %u", length); 24 | 25 | _name = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding]; 26 | //NSLog(@"name: %@", name); 27 | } 28 | 29 | return self; 30 | } 31 | 32 | #pragma mark - 33 | 34 | - (uint32_t)cmd; 35 | { 36 | return _dylinkerCommand.cmd; 37 | } 38 | 39 | - (uint32_t)cmdsize; 40 | { 41 | return _dylinkerCommand.cmdsize; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /Source/CDLCDynamicSymbolTable.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @class CDRelocationInfo; 9 | 10 | @interface CDLCDynamicSymbolTable : CDLoadCommand 11 | 12 | - (void)loadSymbols; 13 | 14 | - (CDRelocationInfo *)relocationEntryWithOffset:(NSUInteger)offset; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Source/CDLCEncryptionInfo.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCEncryptionInfo : CDLoadCommand 9 | 10 | @property (nonatomic, readonly) uint32_t cryptoff; 11 | @property (nonatomic, readonly) uint32_t cryptsize; 12 | @property (nonatomic, readonly) uint32_t cryptid; 13 | 14 | @property (nonatomic, readonly) BOOL isEncrypted; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Source/CDLCEncryptionInfo.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCEncryptionInfo.h" 7 | 8 | // This is used on iOS. 9 | 10 | @implementation CDLCEncryptionInfo 11 | { 12 | struct encryption_info_command_64 _encryptionInfoCommand; 13 | } 14 | 15 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 16 | { 17 | if ((self = [super initWithDataCursor:cursor])) { 18 | _encryptionInfoCommand.cmd = [cursor readInt32]; 19 | _encryptionInfoCommand.cmdsize = [cursor readInt32]; 20 | 21 | _encryptionInfoCommand.cryptoff = [cursor readInt32]; 22 | _encryptionInfoCommand.cryptsize = [cursor readInt32]; 23 | _encryptionInfoCommand.cryptid = [cursor readInt32]; 24 | if (_encryptionInfoCommand.cmd == LC_ENCRYPTION_INFO_64) { 25 | _encryptionInfoCommand.pad = [cursor readInt32]; 26 | } 27 | } 28 | 29 | return self; 30 | } 31 | 32 | #pragma mark - 33 | 34 | - (uint32_t)cmd; 35 | { 36 | return _encryptionInfoCommand.cmd; 37 | } 38 | 39 | - (uint32_t)cmdsize; 40 | { 41 | return _encryptionInfoCommand.cmdsize; 42 | } 43 | 44 | - (uint32_t)cryptoff; 45 | { 46 | return _encryptionInfoCommand.cryptoff; 47 | } 48 | 49 | - (uint32_t)cryptsize; 50 | { 51 | return _encryptionInfoCommand.cryptsize; 52 | } 53 | 54 | - (uint32_t)cryptid; 55 | { 56 | return _encryptionInfoCommand.cryptid; 57 | } 58 | 59 | - (BOOL)isEncrypted; 60 | { 61 | return _encryptionInfoCommand.cryptid != 0; 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /Source/CDLCFunctionStarts.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCLinkeditData.h" 7 | 8 | @interface CDLCFunctionStarts : CDLCLinkeditData 9 | 10 | @property (nonatomic, readonly) NSArray *functionStarts; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Source/CDLCFunctionStarts.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCFunctionStarts.h" 7 | 8 | #import "ULEB128.h" 9 | 10 | @implementation CDLCFunctionStarts 11 | { 12 | NSArray *_functionStarts; 13 | } 14 | 15 | #pragma mark - 16 | 17 | - (NSArray *)functionStarts; 18 | { 19 | if (_functionStarts == nil) { 20 | NSData *functionStartsData = [self linkeditData]; 21 | const uint8_t *start = (uint8_t *)[functionStartsData bytes]; 22 | const uint8_t *end = start + [functionStartsData length]; 23 | uint64_t startAddress; 24 | uint64_t previousAddress = 0; 25 | NSMutableArray *functionStarts = [[NSMutableArray alloc] init]; 26 | while ((startAddress = read_uleb128(&start, end))) { 27 | [functionStarts addObject:@(startAddress + previousAddress)]; 28 | previousAddress += startAddress; 29 | } 30 | _functionStarts = [functionStarts copy]; 31 | } 32 | return _functionStarts; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Source/CDLCLinkeditData.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCLinkeditData : CDLoadCommand 9 | 10 | @property (nonatomic, readonly) NSData *linkeditData; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Source/CDLCLinkeditData.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCLinkeditData.h" 7 | 8 | #import "CDMachOFile.h" 9 | 10 | @implementation CDLCLinkeditData 11 | { 12 | struct linkedit_data_command _linkeditDataCommand; 13 | NSData *_linkeditData; 14 | } 15 | 16 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 17 | { 18 | if ((self = [super initWithDataCursor:cursor])) { 19 | _linkeditDataCommand.cmd = [cursor readInt32]; 20 | _linkeditDataCommand.cmdsize = [cursor readInt32]; 21 | 22 | _linkeditDataCommand.dataoff = [cursor readInt32]; 23 | _linkeditDataCommand.datasize = [cursor readInt32]; 24 | } 25 | 26 | return self; 27 | } 28 | 29 | #pragma mark - 30 | 31 | - (uint32_t)cmd; 32 | { 33 | return _linkeditDataCommand.cmd; 34 | } 35 | 36 | - (uint32_t)cmdsize; 37 | { 38 | return _linkeditDataCommand.cmdsize; 39 | } 40 | 41 | - (NSData *)linkeditData; 42 | { 43 | if (_linkeditData == NULL) { 44 | _linkeditData = [[NSData alloc] initWithBytes:[self.machOFile bytesAtOffset:_linkeditDataCommand.dataoff] length:_linkeditDataCommand.datasize]; 45 | } 46 | 47 | return _linkeditData; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Source/CDLCMain.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCMain : CDLoadCommand 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Source/CDLCMain.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCMain.h" 7 | 8 | @implementation CDLCMain 9 | { 10 | struct entry_point_command _entryPointCommand; 11 | } 12 | 13 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 14 | { 15 | if ((self = [super initWithDataCursor:cursor])) { 16 | _entryPointCommand.cmd = [cursor readInt32]; 17 | _entryPointCommand.cmdsize = [cursor readInt32]; 18 | _entryPointCommand.entryoff = [cursor readInt64]; 19 | _entryPointCommand.stacksize = [cursor readInt64]; 20 | } 21 | 22 | return self; 23 | } 24 | 25 | #pragma mark - 26 | 27 | - (uint32_t)cmd; 28 | { 29 | return _entryPointCommand.cmd; 30 | } 31 | 32 | - (uint32_t)cmdsize; 33 | { 34 | return _entryPointCommand.cmdsize; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Source/CDLCPrebindChecksum.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCPrebindChecksum : CDLoadCommand 9 | 10 | @property (nonatomic, readonly) uint32_t cksum; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Source/CDLCPrebindChecksum.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCPrebindChecksum.h" 7 | 8 | @implementation CDLCPrebindChecksum 9 | { 10 | struct prebind_cksum_command _prebindChecksumCommand; 11 | } 12 | 13 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 14 | { 15 | if ((self = [super initWithDataCursor:cursor])) { 16 | _prebindChecksumCommand.cmd = [cursor readInt32]; 17 | _prebindChecksumCommand.cmdsize = [cursor readInt32]; 18 | _prebindChecksumCommand.cksum = [cursor readInt32]; 19 | } 20 | 21 | return self; 22 | } 23 | 24 | #pragma mark - 25 | 26 | - (uint32_t)cmd; 27 | { 28 | return _prebindChecksumCommand.cmd; 29 | } 30 | 31 | - (uint32_t)cmdsize; 32 | { 33 | return _prebindChecksumCommand.cmdsize; 34 | } 35 | 36 | - (uint32_t)cksum; 37 | { 38 | return _prebindChecksumCommand.cksum; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Source/CDLCPreboundDylib.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCPreboundDylib : CDLoadCommand 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Source/CDLCPreboundDylib.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCPreboundDylib.h" 7 | 8 | #import "CDFatFile.h" 9 | #import "CDMachOFile.h" 10 | 11 | @implementation CDLCPreboundDylib 12 | { 13 | struct prebound_dylib_command _preboundDylibCommand; 14 | } 15 | 16 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 17 | { 18 | if ((self = [super initWithDataCursor:cursor])) { 19 | //NSLog(@"current offset: %u", [cursor offset]); 20 | _preboundDylibCommand.cmd = [cursor readInt32]; 21 | _preboundDylibCommand.cmdsize = [cursor readInt32]; 22 | //NSLog(@"cmdsize: %u", preboundDylibCommand.cmdsize); 23 | 24 | _preboundDylibCommand.name.offset = [cursor readInt32]; 25 | _preboundDylibCommand.nmodules = [cursor readInt32]; 26 | _preboundDylibCommand.linked_modules.offset = [cursor readInt32]; 27 | 28 | if (_preboundDylibCommand.cmdsize > 20) { 29 | // Don't need this info right now. 30 | [cursor advanceByLength:_preboundDylibCommand.cmdsize - 20]; 31 | } 32 | } 33 | 34 | return self; 35 | } 36 | 37 | #pragma mark - 38 | 39 | - (uint32_t)cmd; 40 | { 41 | return _preboundDylibCommand.cmd; 42 | } 43 | 44 | - (uint32_t)cmdsize; 45 | { 46 | return _preboundDylibCommand.cmdsize; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Source/CDLCRoutines32.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCRoutines32 : CDLoadCommand 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Source/CDLCRoutines32.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCRoutines32.h" 7 | 8 | @implementation CDLCRoutines32 9 | { 10 | struct routines_command _routinesCommand; 11 | } 12 | 13 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 14 | { 15 | if ((self = [super initWithDataCursor:cursor])) { 16 | _routinesCommand.cmd = [cursor readInt32]; 17 | _routinesCommand.cmdsize = [cursor readInt32]; 18 | 19 | _routinesCommand.init_address = [cursor readInt32]; 20 | _routinesCommand.init_module = [cursor readInt32]; 21 | _routinesCommand.reserved1 = [cursor readInt32]; 22 | _routinesCommand.reserved2 = [cursor readInt32]; 23 | _routinesCommand.reserved3 = [cursor readInt32]; 24 | _routinesCommand.reserved4 = [cursor readInt32]; 25 | _routinesCommand.reserved5 = [cursor readInt32]; 26 | _routinesCommand.reserved6 = [cursor readInt32]; 27 | } 28 | 29 | return self; 30 | } 31 | 32 | #pragma mark - 33 | 34 | - (uint32_t)cmd; 35 | { 36 | return _routinesCommand.cmd; 37 | } 38 | 39 | - (uint32_t)cmdsize; 40 | { 41 | return _routinesCommand.cmdsize; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /Source/CDLCRoutines64.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCRoutines64 : CDLoadCommand 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Source/CDLCRoutines64.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCRoutines64.h" 7 | 8 | @implementation CDLCRoutines64 9 | { 10 | struct routines_command_64 _routinesCommand; 11 | } 12 | 13 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 14 | { 15 | if ((self = [super initWithDataCursor:cursor])) { 16 | _routinesCommand.cmd = [cursor readInt32]; 17 | _routinesCommand.cmdsize = [cursor readInt32]; 18 | 19 | _routinesCommand.init_address = [cursor readInt64]; 20 | _routinesCommand.init_module = [cursor readInt64]; 21 | _routinesCommand.reserved1 = [cursor readInt64]; 22 | _routinesCommand.reserved2 = [cursor readInt64]; 23 | _routinesCommand.reserved3 = [cursor readInt64]; 24 | _routinesCommand.reserved4 = [cursor readInt64]; 25 | _routinesCommand.reserved5 = [cursor readInt64]; 26 | _routinesCommand.reserved6 = [cursor readInt64]; 27 | } 28 | 29 | return self; 30 | } 31 | 32 | #pragma mark - 33 | 34 | - (uint32_t)cmd; 35 | { 36 | return _routinesCommand.cmd; 37 | } 38 | 39 | - (uint32_t)cmdsize; 40 | { 41 | return _routinesCommand.cmdsize; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /Source/CDLCRunPath.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCRunPath : CDLoadCommand 9 | 10 | @property (readonly) NSString *path; 11 | @property (nonatomic, readonly) NSString *resolvedRunPath; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Source/CDLCRunPath.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCRunPath.h" 7 | 8 | #import "CDMachOFile.h" 9 | #import "CDSearchPathState.h" 10 | 11 | @implementation CDLCRunPath 12 | { 13 | struct rpath_command _rpathCommand; 14 | NSString *_path; 15 | } 16 | 17 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 18 | { 19 | if ((self = [super initWithDataCursor:cursor])) { 20 | _rpathCommand.cmd = [cursor readInt32]; 21 | _rpathCommand.cmdsize = [cursor readInt32]; 22 | 23 | _rpathCommand.path.offset = [cursor readInt32]; 24 | 25 | NSUInteger length = _rpathCommand.cmdsize - sizeof(_rpathCommand); 26 | //NSLog(@"expected length: %u", length); 27 | 28 | _path = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding]; 29 | //NSLog(@"path: %@", _path); 30 | } 31 | 32 | return self; 33 | } 34 | 35 | #pragma mark - 36 | 37 | - (uint32_t)cmd; 38 | { 39 | return _rpathCommand.cmd; 40 | } 41 | 42 | - (uint32_t)cmdsize; 43 | { 44 | return _rpathCommand.cmdsize; 45 | } 46 | 47 | - (NSString *)resolvedRunPath; 48 | { 49 | NSString *loaderPathPrefix = @"@loader_path"; 50 | NSString *executablePathPrefix = @"@executable_path"; 51 | 52 | if ([self.path hasPrefix:loaderPathPrefix]) { 53 | NSString *loaderPath = [self.machOFile.filename stringByDeletingLastPathComponent]; 54 | NSString *str = [[self.path stringByReplacingOccurrencesOfString:loaderPathPrefix withString:loaderPath] stringByStandardizingPath]; 55 | 56 | return str; 57 | } 58 | 59 | if ([self.path hasPrefix:executablePathPrefix]) { 60 | NSString *str = @""; 61 | NSString *executablePath = self.machOFile.searchPathState.executablePath; 62 | if (executablePath) 63 | str = [[self.path stringByReplacingOccurrencesOfString:executablePathPrefix withString:executablePath] stringByStandardizingPath]; 64 | 65 | return str; 66 | } 67 | 68 | return self.path; 69 | } 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /Source/CDLCSegment.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @class CDSection; 9 | 10 | #define CDSegmentProtectedMagic_None 0 11 | #define CDSegmentProtectedMagic_AES 0xc2286295 12 | #define CDSegmentProtectedMagic_Blowfish 0x2e69cf40 13 | 14 | typedef enum : NSUInteger { 15 | CDSegmentEncryptionType_None = 0, 16 | CDSegmentEncryptionType_AES = 1, // 10.5 and earlier (AES) 17 | CDSegmentEncryptionType_Blowfish = 2, // 10.6 (Blowfish) 18 | CDSegmentEncryptionType_Unknown 19 | } CDSegmentEncryptionType; 20 | 21 | extern NSString *CDSegmentEncryptionTypeName(CDSegmentEncryptionType type); 22 | 23 | @interface CDLCSegment : CDLoadCommand 24 | 25 | @property (strong) NSString *name; 26 | @property (strong) NSArray *sections; 27 | 28 | @property (nonatomic, readonly) NSUInteger vmaddr; 29 | @property (nonatomic, readonly) NSUInteger fileoff; 30 | @property (nonatomic, readonly) NSUInteger filesize; 31 | @property (nonatomic, readonly) vm_prot_t initprot; 32 | @property (nonatomic, readonly) uint32_t flags; 33 | @property (nonatomic, readonly) BOOL isProtected; 34 | 35 | @property (nonatomic, readonly) CDSegmentEncryptionType encryptionType; 36 | @property (nonatomic, readonly) BOOL canDecrypt; 37 | 38 | - (NSString *)flagDescription; 39 | 40 | - (BOOL)containsAddress:(NSUInteger)address; 41 | - (CDSection *)sectionContainingAddress:(NSUInteger)address; 42 | - (CDSection *)sectionWithName:(NSString *)name; 43 | - (NSUInteger)fileOffsetForAddress:(NSUInteger)address; 44 | - (NSUInteger)segmentOffsetForAddress:(NSUInteger)address; 45 | 46 | - (void)writeSectionData; 47 | 48 | - (NSData *)decryptedData; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Source/CDLCSourceVersion.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCSourceVersion : CDLoadCommand 9 | 10 | @property (nonatomic, readonly) NSString *sourceVersionString; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Source/CDLCSourceVersion.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCSourceVersion.h" 7 | 8 | #import "CDMachOFile.h" 9 | 10 | @implementation CDLCSourceVersion 11 | { 12 | struct source_version_command _sourceVersionCommand; 13 | } 14 | 15 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 16 | { 17 | if ((self = [super initWithDataCursor:cursor])) { 18 | _sourceVersionCommand.cmd = [cursor readInt32]; 19 | _sourceVersionCommand.cmdsize = [cursor readInt32]; 20 | _sourceVersionCommand.version = [cursor readInt64]; 21 | } 22 | 23 | return self; 24 | } 25 | 26 | #pragma mark - 27 | 28 | - (uint32_t)cmd; 29 | { 30 | return _sourceVersionCommand.cmd; 31 | } 32 | 33 | - (uint32_t)cmdsize; 34 | { 35 | return _sourceVersionCommand.cmdsize; 36 | } 37 | 38 | - (NSString *)sourceVersionString; 39 | { 40 | // A.B.C.D.E packed as a24.b10.c10.d10.e10 41 | uint32_t a = (_sourceVersionCommand.version >> 40); 42 | uint32_t b = (_sourceVersionCommand.version >> 30) & 0x3f; 43 | uint32_t c = (_sourceVersionCommand.version >> 20) & 0x3f; 44 | uint32_t d = (_sourceVersionCommand.version >> 10) & 0x3f; 45 | uint32_t e = _sourceVersionCommand.version & 0x3f; 46 | 47 | return [NSString stringWithFormat:@"%u.%u.%u.%u.%u", a, b, c, d, e]; 48 | } 49 | 50 | - (void)appendToString:(NSMutableString *)resultString verbose:(BOOL)isVerbose; 51 | { 52 | [super appendToString:resultString verbose:isVerbose]; 53 | 54 | [resultString appendFormat:@" Source version: %@\n", self.sourceVersionString]; 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /Source/CDLCSubClient.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCSubClient : CDLoadCommand 9 | 10 | @property (readonly) NSString *name; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Source/CDLCSubClient.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCSubClient.h" 7 | 8 | @implementation CDLCSubClient 9 | { 10 | struct sub_client_command _command; 11 | NSString *_name; 12 | } 13 | 14 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 15 | { 16 | if ((self = [super initWithDataCursor:cursor])) { 17 | _command.cmd = [cursor readInt32]; 18 | _command.cmdsize = [cursor readInt32]; 19 | 20 | uint32_t strOffset = [cursor readInt32]; 21 | NSParameterAssert(strOffset == 12); 22 | 23 | NSUInteger length = _command.cmdsize - sizeof(_command); 24 | //NSLog(@"expected length: %u", length); 25 | 26 | _name = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding]; 27 | //NSLog(@"name: %@", _name); 28 | } 29 | 30 | return self; 31 | } 32 | 33 | #pragma mark - 34 | 35 | - (uint32_t)cmd; 36 | { 37 | return _command.cmd; 38 | } 39 | 40 | - (uint32_t)cmdsize; 41 | { 42 | return _command.cmdsize; 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Source/CDLCSubFramework.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCSubFramework : CDLoadCommand 9 | 10 | @property (readonly) NSString *name; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Source/CDLCSubFramework.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCSubFramework.h" 7 | 8 | @implementation CDLCSubFramework 9 | { 10 | struct sub_framework_command _command; 11 | NSString *_name; 12 | } 13 | 14 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 15 | { 16 | if ((self = [super initWithDataCursor:cursor])) { 17 | _command.cmd = [cursor readInt32]; 18 | _command.cmdsize = [cursor readInt32]; 19 | 20 | uint32_t strOffset = [cursor readInt32]; 21 | NSParameterAssert(strOffset == 12); 22 | 23 | NSUInteger length = _command.cmdsize - sizeof(_command); 24 | //NSLog(@"expected length: %u", length); 25 | 26 | _name = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding]; 27 | //NSLog(@"name: %@", _name); 28 | } 29 | 30 | return self; 31 | } 32 | 33 | #pragma mark - 34 | 35 | - (uint32_t)cmd; 36 | { 37 | return _command.cmd; 38 | } 39 | 40 | - (uint32_t)cmdsize; 41 | { 42 | return _command.cmdsize; 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Source/CDLCSubLibrary.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCSubLibrary : CDLoadCommand 9 | 10 | @property (readonly) NSString *name; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Source/CDLCSubLibrary.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCSubLibrary.h" 7 | 8 | @implementation CDLCSubLibrary 9 | { 10 | struct sub_library_command _command; 11 | NSString *_name; 12 | } 13 | 14 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 15 | { 16 | if ((self = [super initWithDataCursor:cursor])) { 17 | _command.cmd = [cursor readInt32]; 18 | _command.cmdsize = [cursor readInt32]; 19 | 20 | NSUInteger length = _command.cmdsize - sizeof(_command); 21 | //NSLog(@"expected length: %u", length); 22 | 23 | _name = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding]; 24 | //NSLog(@"name: %@", _name); 25 | } 26 | 27 | return self; 28 | } 29 | 30 | #pragma mark - 31 | 32 | - (uint32_t)cmd; 33 | { 34 | return _command.cmd; 35 | } 36 | 37 | - (uint32_t)cmdsize; 38 | { 39 | return _command.cmdsize; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Source/CDLCSubUmbrella.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCSubUmbrella : CDLoadCommand 9 | 10 | @property (readonly) NSString *name; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Source/CDLCSubUmbrella.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCSubUmbrella.h" 7 | 8 | @implementation CDLCSubUmbrella 9 | { 10 | struct sub_umbrella_command _command; 11 | NSString *_name; 12 | } 13 | 14 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 15 | { 16 | if ((self = [super initWithDataCursor:cursor])) { 17 | _command.cmd = [cursor readInt32]; 18 | _command.cmdsize = [cursor readInt32]; 19 | 20 | NSUInteger length = _command.cmdsize - sizeof(_command); 21 | //NSLog(@"expected length: %u", length); 22 | 23 | _name = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding]; 24 | //NSLog(@"name: %@", _name); 25 | } 26 | 27 | return self; 28 | } 29 | 30 | #pragma mark - 31 | 32 | - (uint32_t)cmd; 33 | { 34 | return _command.cmd; 35 | } 36 | 37 | - (uint32_t)cmdsize; 38 | { 39 | return _command.cmdsize; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Source/CDLCSymbolTable.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @class CDSymbol; 9 | 10 | @interface CDLCSymbolTable : CDLoadCommand 11 | 12 | - (void)loadSymbols; 13 | 14 | @property (nonatomic, readonly) uint32_t symoff; 15 | @property (nonatomic, readonly) uint32_t nsyms; 16 | @property (nonatomic, readonly) uint32_t stroff; 17 | @property (nonatomic, readonly) uint32_t strsize; 18 | 19 | @property (nonatomic, readonly) NSUInteger baseAddress; 20 | @property (nonatomic, readonly) NSArray *symbols; 21 | 22 | - (CDSymbol *)symbolForClassName:(NSString *)className; 23 | - (CDSymbol *)symbolForExternalClassName:(NSString *)className; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Source/CDLCTwoLevelHints.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCTwoLevelHints : CDLoadCommand 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Source/CDLCTwoLevelHints.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCTwoLevelHints.h" 7 | 8 | #import "CDMachOFile.h" 9 | 10 | @implementation CDLCTwoLevelHints 11 | { 12 | struct twolevel_hints_command _hintsCommand; 13 | } 14 | 15 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 16 | { 17 | if ((self = [super initWithDataCursor:cursor])) { 18 | _hintsCommand.cmd = [cursor readInt32]; 19 | _hintsCommand.cmdsize = [cursor readInt32]; 20 | _hintsCommand.offset = [cursor readInt32]; 21 | _hintsCommand.nhints = [cursor readInt32]; 22 | } 23 | 24 | return self; 25 | } 26 | 27 | #pragma mark - 28 | 29 | - (uint32_t)cmd; 30 | { 31 | return _hintsCommand.cmd; 32 | } 33 | 34 | - (uint32_t)cmdsize; 35 | { 36 | return _hintsCommand.cmdsize; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Source/CDLCUUID.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCUUID : CDLoadCommand 9 | 10 | @property (nonatomic, readonly) NSUUID *UUID; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Source/CDLCUUID.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCUUID.h" 7 | 8 | #import "CDMachOFile.h" 9 | 10 | @implementation CDLCUUID 11 | { 12 | struct uuid_command _uuidCommand; 13 | 14 | NSUUID *_UUID; 15 | } 16 | 17 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 18 | { 19 | if ((self = [super initWithDataCursor:cursor])) { 20 | _uuidCommand.cmd = [cursor readInt32]; 21 | _uuidCommand.cmdsize = [cursor readInt32]; 22 | for (NSUInteger index = 0; index < sizeof(_uuidCommand.uuid); index++) { 23 | _uuidCommand.uuid[index] = [cursor readByte]; 24 | } 25 | _UUID = [[NSUUID alloc] initWithUUIDBytes:_uuidCommand.uuid]; 26 | } 27 | 28 | return self; 29 | } 30 | 31 | #pragma mark - 32 | 33 | - (uint32_t)cmd; 34 | { 35 | return _uuidCommand.cmd; 36 | } 37 | 38 | - (uint32_t)cmdsize; 39 | { 40 | return _uuidCommand.cmdsize; 41 | } 42 | 43 | - (void)appendToString:(NSMutableString *)resultString verbose:(BOOL)isVerbose; 44 | { 45 | [super appendToString:resultString verbose:isVerbose]; 46 | 47 | [resultString appendString:@" uuid "]; 48 | [resultString appendString:[self.UUID UUIDString]]; 49 | [resultString appendString:@"\n"]; 50 | } 51 | 52 | - (NSString *)extraDescription; 53 | { 54 | return [self.UUID UUIDString]; 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /Source/CDLCUnixThread.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCUnixThread : CDLoadCommand 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Source/CDLCUnixThread.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCUnixThread.h" 7 | 8 | // For now, this is all I need. There is no data in here sensitive to its position in the file. 9 | 10 | @implementation CDLCUnixThread 11 | { 12 | struct load_command _loadCommand; 13 | 14 | NSData *_commandData; 15 | } 16 | 17 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 18 | { 19 | if ((self = [super initWithDataCursor:cursor])) { 20 | _loadCommand.cmd = [cursor readInt32]; 21 | _loadCommand.cmdsize = [cursor readInt32]; 22 | 23 | if (_loadCommand.cmdsize > 8) { 24 | NSMutableData *commandData = [[NSMutableData alloc] init]; 25 | [cursor appendBytesOfLength:_loadCommand.cmdsize - 8 intoData:commandData]; 26 | _commandData = [commandData copy]; 27 | } else { 28 | _commandData = nil; 29 | } 30 | } 31 | 32 | return self; 33 | } 34 | 35 | #pragma mark - 36 | 37 | - (uint32_t)cmd; 38 | { 39 | return _loadCommand.cmd; 40 | } 41 | 42 | - (uint32_t)cmdsize; 43 | { 44 | return _loadCommand.cmdsize; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /Source/CDLCUnknown.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCUnknown : CDLoadCommand 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Source/CDLCUnknown.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCUnknown.h" 7 | 8 | static BOOL debug = NO; 9 | 10 | @implementation CDLCUnknown 11 | { 12 | struct load_command _loadCommand; 13 | 14 | NSData *_commandData; 15 | } 16 | 17 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 18 | { 19 | if ((self = [super initWithDataCursor:cursor])) { 20 | if (debug) NSLog(@"offset: %lu", [cursor offset]); 21 | _loadCommand.cmd = [cursor readInt32]; 22 | _loadCommand.cmdsize = [cursor readInt32]; 23 | if (debug) NSLog(@"cmdsize: %u", _loadCommand.cmdsize); 24 | 25 | if (_loadCommand.cmdsize > 8) { 26 | NSMutableData *commandData = [[NSMutableData alloc] init]; 27 | [cursor appendBytesOfLength:_loadCommand.cmdsize - 8 intoData:commandData]; 28 | _commandData = [commandData copy]; 29 | } else { 30 | _commandData = nil; 31 | } 32 | } 33 | 34 | return self; 35 | } 36 | 37 | #pragma mark - 38 | 39 | - (uint32_t)cmd; 40 | { 41 | return _loadCommand.cmd; 42 | } 43 | 44 | - (uint32_t)cmdsize; 45 | { 46 | return _loadCommand.cmdsize; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Source/CDLCVersionMinimum.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCVersionMinimum : CDLoadCommand 9 | 10 | @property (nonatomic, readonly) NSString *minimumVersionString; 11 | @property (nonatomic, readonly) NSString *SDKVersionString; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Source/CDLCVersionMinimum.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDLCVersionMinimum.h" 7 | 8 | #import "CDMachOFile.h" 9 | 10 | @implementation CDLCVersionMinimum 11 | { 12 | struct version_min_command _versionMinCommand; 13 | } 14 | 15 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 16 | { 17 | if ((self = [super initWithDataCursor:cursor])) { 18 | _versionMinCommand.cmd = [cursor readInt32]; 19 | _versionMinCommand.cmdsize = [cursor readInt32]; 20 | _versionMinCommand.version = [cursor readInt32]; 21 | _versionMinCommand.sdk = [cursor readInt32]; 22 | } 23 | 24 | return self; 25 | } 26 | 27 | #pragma mark - 28 | 29 | - (uint32_t)cmd; 30 | { 31 | return _versionMinCommand.cmd; 32 | } 33 | 34 | - (uint32_t)cmdsize; 35 | { 36 | return _versionMinCommand.cmdsize; 37 | } 38 | 39 | - (NSString *)minimumVersionString; 40 | { 41 | uint32_t x = (_versionMinCommand.version >> 16); 42 | uint32_t y = (_versionMinCommand.version >> 8) & 0xff; 43 | uint32_t z = _versionMinCommand.version & 0xff; 44 | 45 | return [NSString stringWithFormat:@"%u.%u.%u", x, y, z]; 46 | } 47 | 48 | - (NSString *)SDKVersionString; 49 | { 50 | uint32_t x = (_versionMinCommand.sdk >> 16); 51 | uint32_t y = (_versionMinCommand.sdk >> 8) & 0xff; 52 | uint32_t z = _versionMinCommand.sdk & 0xff; 53 | 54 | return [NSString stringWithFormat:@"%u.%u.%u", x, y, z]; 55 | } 56 | 57 | - (void)appendToString:(NSMutableString *)resultString verbose:(BOOL)isVerbose; 58 | { 59 | [super appendToString:resultString verbose:isVerbose]; 60 | 61 | [resultString appendFormat:@" Minimum version: %@\n", self.minimumVersionString]; 62 | [resultString appendFormat:@" SDK version: %@\n", self.SDKVersionString]; 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /Source/CDLoadCommand.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | // Importing these here saves us from importing them in the implementation of every load command. 7 | #include 8 | #import "CDMachOFileDataCursor.h" 9 | 10 | @class CDMachOFile; 11 | 12 | @interface CDLoadCommand : NSObject 13 | 14 | + (id)loadCommandWithDataCursor:(CDMachOFileDataCursor *)cursor; 15 | 16 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 17 | 18 | - (NSString *)extraDescription; 19 | 20 | @property (weak, readonly) CDMachOFile *machOFile; 21 | @property (readonly) NSUInteger commandOffset; 22 | 23 | @property (nonatomic, readonly) uint32_t cmd; 24 | @property (nonatomic, readonly) uint32_t cmdsize; 25 | @property (nonatomic, readonly) BOOL mustUnderstandToExecute; 26 | 27 | @property (nonatomic, readonly) NSString *commandName; 28 | 29 | - (void)appendToString:(NSMutableString *)resultString verbose:(BOOL)isVerbose; 30 | 31 | - (void)machOFileDidReadLoadCommands:(CDMachOFile *)machOFile; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Source/CDMachOFileDataCursor.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | /******************************************** 4 | Copyright 2020 PreEmptive Solutions, LLC 5 | See LICENSE.txt for licensing information 6 | ********************************************/ 7 | 8 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 9 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 10 | 11 | #import "CDDataCursor.h" 12 | 13 | @class CDMachOFile, CDSection; 14 | 15 | @interface CDMachOFileDataCursor : CDDataCursor 16 | 17 | - (id)initWithFile:(CDMachOFile *)machOFile; 18 | - (id)initWithFile:(CDMachOFile *)machOFile offset:(NSUInteger)offset; 19 | - (id)initWithFile:(CDMachOFile *)machOFile address:(NSUInteger)address; 20 | 21 | - (id)initWithSection:(CDSection *)section; 22 | 23 | @property (nonatomic, weak, readonly) CDMachOFile *machOFile; 24 | 25 | - (void)setAddress:(NSUInteger)address; 26 | 27 | // Read using the current byteOrder 28 | - (uint16_t)readInt16; 29 | - (uint32_t)readInt32; 30 | - (uint64_t)readInt64; 31 | 32 | - (uint32_t)peekInt32; 33 | 34 | // Read using the current byteOrder and ptrSize (from the machOFile) 35 | - (uint64_t)readPtr; 36 | - (uint64_t)readPtr:(bool)small; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Source/CDMethodType.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @class CDType; 7 | 8 | @interface CDMethodType : NSObject 9 | 10 | - (id)initWithType:(CDType *)type offset:(NSString *)offset; 11 | 12 | @property (readonly) CDType *type; 13 | @property (readonly) NSString *offset; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Source/CDMethodType.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDMethodType.h" 7 | 8 | #import "CDType.h" 9 | 10 | @implementation CDMethodType 11 | { 12 | CDType *_type; 13 | NSString *_offset; 14 | } 15 | 16 | - (id)initWithType:(CDType *)type offset:(NSString *)offset; 17 | { 18 | if ((self = [super init])) { 19 | _type = type; 20 | _offset = offset; 21 | } 22 | 23 | return self; 24 | } 25 | 26 | #pragma mark - Debugging 27 | 28 | - (NSString *)description; 29 | { 30 | return [NSString stringWithFormat:@"[%@] type: %@, offset: %@", NSStringFromClass([self class]), self.type, self.offset]; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Source/CDMultiFileVisitor.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDTextClassDumpVisitor.h" 7 | 8 | #import "CDTypeController.h" // For CDTypeControllerDelegate protocol 9 | 10 | // This generates separate files for each class. Files are created in the 'outputPath' directory. 11 | 12 | @interface CDMultiFileVisitor : CDTextClassDumpVisitor 13 | 14 | @property (strong) NSString *outputPath; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Source/CDOCCategory.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDOCProtocol.h" 7 | 8 | @class CDOCClassReference; 9 | 10 | @interface CDOCCategory : CDOCProtocol 11 | 12 | @property (strong) CDOCClassReference *classRef; 13 | @property (strong, readonly) NSString *className; 14 | 15 | - (NSString *)methodSearchContext; 16 | - (void)recursivelyVisit:(CDVisitor *)visitor; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Source/CDOCCategory.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | /******************************************** 4 | Copyright 2016 PreEmptive Solutions, LLC 5 | See LICENSE.txt for licensing information 6 | ********************************************/ 7 | 8 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 9 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 10 | 11 | #import "CDOCCategory.h" 12 | 13 | #import "CDClassDump.h" 14 | #import "CDOCMethod.h" 15 | #import "CDVisitor.h" 16 | #import "CDVisitorPropertyState.h" 17 | #import "CDOCClass.h" 18 | #import "CDOCClassReference.h" 19 | 20 | @implementation CDOCCategory 21 | 22 | #pragma mark - Superclass overrides 23 | 24 | - (NSString *)sortableName; 25 | { 26 | return [NSString stringWithFormat:@"%@ (%@)", self.className, self.name]; 27 | } 28 | 29 | #pragma mark - 30 | 31 | - (NSString *)className 32 | { 33 | return [_classRef className]; 34 | } 35 | 36 | - (NSString *)methodSearchContext; 37 | { 38 | NSMutableString *resultString = [NSMutableString string]; 39 | 40 | [resultString appendFormat:@"@interface %@ (%@)", self.className, self.name]; 41 | 42 | if ([self.protocols count] > 0) 43 | [resultString appendFormat:@" <%@>", self.protocolsString]; 44 | 45 | return resultString; 46 | } 47 | 48 | - (void)recursivelyVisit:(CDVisitor *)visitor; 49 | { 50 | CDVisitorPropertyState *propertyState = [[CDVisitorPropertyState alloc] initWithProperties:self.properties]; 51 | 52 | [visitor willVisitCategory:self]; 53 | 54 | //[aVisitor willVisitPropertiesOfCategory:self]; 55 | //[self visitProperties:aVisitor]; 56 | //[aVisitor didVisitPropertiesOfCategory:self]; 57 | 58 | [self visitMethods:visitor propertyState:propertyState]; 59 | // This can happen when... the accessors are implemented on the main class. Odd case, but we should still emit the remaining properties. 60 | // Should mostly be dynamic properties 61 | [visitor visitRemainingProperties:propertyState]; 62 | [visitor didVisitCategory:self]; 63 | } 64 | 65 | #pragma mark - CDTopologicalSort protocol 66 | 67 | - (NSString *)identifier; 68 | { 69 | return self.sortableName; 70 | } 71 | 72 | - (NSArray *)dependancies; 73 | { 74 | if (self.className == nil) 75 | return @[]; 76 | 77 | return @[self.className]; 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /Source/CDOCClass.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | /******************************************** 4 | Copyright 2018 PreEmptive Solutions, LLC 5 | See LICENSE.txt for licensing information 6 | ********************************************/ 7 | 8 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 9 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 10 | 11 | #import "CDOCProtocol.h" 12 | 13 | #import "CDTopologicalSortProtocol.h" 14 | 15 | @class CDOCClassReference; 16 | 17 | @interface CDOCClass : CDOCProtocol 18 | 19 | @property (strong) CDOCClassReference *superClassRef; 20 | @property (copy, readonly) NSString *superClassName; 21 | @property (strong) NSArray *instanceVariables; 22 | @property (assign) BOOL isExported; 23 | @property (assign) BOOL isSwiftClass; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Source/CDOCClassReference.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import 7 | 8 | @class CDOCClass, CDSymbol; 9 | 10 | /*! 11 | * CDOCClassReference acts as a proxy object to a class that may be external. It can thus be repesented 12 | * as one of: a \c CDOCClass object (for internal classes), a \c CDSymbol object (for external classes), 13 | * or an \c NSString of the class name (for ObjC1 compatibility). The class name can then be inferred from 14 | * any of these representations. 15 | */ 16 | @interface CDOCClassReference : NSObject 17 | 18 | @property (strong) CDOCClass *classObject; 19 | @property (strong) CDSymbol *classSymbol; 20 | @property (nonatomic, copy) NSString *className; // inferred from classObject / classSymbol if not set directly 21 | @property (nonatomic, readonly, getter = isExternalClass) BOOL externalClass; 22 | 23 | - (instancetype)initWithClassObject:(CDOCClass *)classObject; 24 | - (instancetype)initWithClassSymbol:(CDSymbol *)symbol; 25 | - (instancetype)initWithClassName:(NSString *)className; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Source/CDOCClassReference.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDOCClassReference.h" 7 | #import "CDOCClass.h" 8 | #import "CDSymbol.h" 9 | 10 | @implementation CDOCClassReference 11 | 12 | - (instancetype)initWithClassSymbol:(CDSymbol *)symbol; 13 | { 14 | if ((self = [super init])) { 15 | _classSymbol = symbol; 16 | } 17 | 18 | return self; 19 | } 20 | 21 | - (instancetype)initWithClassObject:(CDOCClass *)classObject; 22 | { 23 | if ((self = [super init])) { 24 | _classObject = classObject; 25 | } 26 | 27 | return self; 28 | } 29 | 30 | - (instancetype)initWithClassName:(NSString *)className; 31 | { 32 | if ((self = [super init])) { 33 | _className = [className copy]; 34 | } 35 | 36 | return self; 37 | } 38 | 39 | - (NSString *)className; 40 | { 41 | if (_className != nil) 42 | return _className; 43 | else if (_classObject != nil) 44 | return [_classObject name]; 45 | else if (_classSymbol != nil) 46 | return [CDSymbol classNameFromSymbolName:[_classSymbol name]]; 47 | else 48 | return nil; 49 | } 50 | 51 | - (BOOL)isExternalClass; 52 | { 53 | return (!_classObject && (!_classSymbol || [_classSymbol isExternal])); 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Source/CDOCInstanceVariable.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @class CDType, CDTypeController; 7 | 8 | @interface CDOCInstanceVariable : NSObject 9 | 10 | - (id)initWithName:(NSString *)name typeString:(NSString *)typeString offset:(NSUInteger)offset; 11 | 12 | @property (readonly) NSString *name; 13 | @property (readonly) NSString *typeString; 14 | @property (readonly) NSUInteger offset; 15 | 16 | // Lazily parses the typeString. Returns nil and sets the parseError if parsing failed. Does not try to parse again in the event of an error. 17 | @property (nonatomic, readonly) CDType *type; 18 | 19 | // This is set after the typeString has been parsed if there was an error. Doesn't trigger parsing. 20 | @property (readonly) NSError *parseError; 21 | 22 | - (void)appendToString:(NSMutableString *)resultString typeController:(CDTypeController *)typeController; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Source/CDOCInstanceVariable.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | /******************************************** 4 | Copyright 2018 PreEmptive Solutions, LLC 5 | See LICENSE.txt for licensing information 6 | ********************************************/ 7 | 8 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 9 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 10 | 11 | #import "CDOCInstanceVariable.h" 12 | 13 | #import "CDClassDump.h" 14 | #import "CDTypeFormatter.h" 15 | #import "CDTypeParser.h" 16 | #import "CDTypeController.h" 17 | #import "CDType.h" 18 | 19 | static BOOL debug = NO; 20 | 21 | @interface CDOCInstanceVariable () 22 | @property (assign) BOOL hasParsedType; 23 | @end 24 | 25 | #pragma mark - 26 | 27 | @implementation CDOCInstanceVariable 28 | { 29 | NSString *_name; 30 | NSString *_typeString; 31 | NSUInteger _offset; 32 | 33 | BOOL _hasParsedType; 34 | CDType *_type; 35 | NSError *_parseError; 36 | } 37 | 38 | - (id)initWithName:(NSString *)name typeString:(NSString *)typeString offset:(NSUInteger)offset; 39 | { 40 | if ((self = [super init])) { 41 | _name = name; 42 | _typeString = typeString; 43 | _offset = offset; 44 | 45 | _hasParsedType = NO; 46 | _type = nil; 47 | _parseError = nil; 48 | } 49 | 50 | return self; 51 | } 52 | 53 | #pragma mark - Debugging 54 | 55 | - (NSString *)description; 56 | { 57 | return [NSString stringWithFormat:@"[%@] name: %@, typeString: '%@', offset: %lu", 58 | NSStringFromClass([self class]), self.name, self.typeString, self.offset]; 59 | } 60 | 61 | #pragma mark - 62 | 63 | - (CDType *)type; 64 | { 65 | if (self.hasParsedType == NO && self.parseError == nil) { 66 | CDTypeParser *parser = [[CDTypeParser alloc] initWithString:self.typeString]; 67 | NSError *error; 68 | _type = [parser parseType:&error]; 69 | if (_type == nil) { 70 | if (debug) { 71 | NSLog(@"Warning: Parsing instance variable type failed, %@", self.name); 72 | } 73 | _parseError = error; 74 | } else { 75 | self.hasParsedType = YES; 76 | } 77 | } 78 | 79 | return _type; 80 | } 81 | 82 | - (void)appendToString:(NSMutableString *)resultString typeController:(CDTypeController *)typeController; 83 | { 84 | CDType *type = [self type]; // Parses it, if necessary; 85 | if (self.parseError != nil) { 86 | [resultString appendFormat:@" // Error parsing type: %@, name: %@", self.typeString, self.name]; 87 | } else { 88 | NSString *formattedString = [[typeController ivarTypeFormatter] formatVariable:self.name type:type]; 89 | NSParameterAssert(formattedString != nil); 90 | [resultString appendString:formattedString]; 91 | [resultString appendString:@";"]; 92 | if ([typeController shouldShowIvarOffsets]) { 93 | [resultString appendFormat:@"\t// %ld = 0x%lx", self.offset, self.offset]; 94 | } 95 | } 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /Source/CDOCMethod.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @class CDTypeController; 7 | 8 | @interface CDOCMethod : NSObject 9 | 10 | - (id)initWithName:(NSString *)name typeString:(NSString *)typeString; 11 | - (id)initWithName:(NSString *)name typeString:(NSString *)typeString address:(NSUInteger)address; 12 | 13 | @property (readonly) NSString *name; 14 | @property (readonly) NSString *typeString; 15 | @property (assign) NSUInteger address; 16 | 17 | - (NSArray *)parsedMethodTypes; 18 | 19 | - (void)appendToString:(NSMutableString *)resultString typeController:(CDTypeController *)typeController; 20 | 21 | - (NSComparisonResult)ascendingCompareByName:(CDOCMethod *)other; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Source/CDOCModule.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @class CDOCSymtab; 7 | 8 | @interface CDOCModule : NSObject 9 | 10 | @property (assign) uint32_t version; 11 | @property (strong) NSString *name; 12 | @property (strong) CDOCSymtab *symtab; 13 | 14 | - (NSString *)formattedString; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Source/CDOCModule.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDOCModule.h" 7 | 8 | #import "CDObjectiveC1Processor.h" 9 | #import "CDOCSymtab.h" 10 | 11 | @implementation CDOCModule 12 | { 13 | uint32_t _version; 14 | NSString *_name; 15 | CDOCSymtab *_symtab; 16 | } 17 | 18 | - (id)init; 19 | { 20 | if ((self = [super init])) { 21 | _version = 0; 22 | _name = nil; 23 | _symtab = nil; 24 | } 25 | 26 | return self; 27 | } 28 | 29 | #pragma mark - Debugging 30 | 31 | - (NSString *)description; 32 | { 33 | return [NSString stringWithFormat:@"[%@] name: %@, version: %u, symtab: %@", NSStringFromClass([self class]), self.name, self.version, self.symtab]; 34 | } 35 | 36 | #pragma mark - 37 | 38 | - (NSString *)formattedString; 39 | { 40 | return [NSString stringWithFormat:@"//\n// %@\n//\n", self.name]; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /Source/CDOCProperty.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @class CDType; 7 | 8 | @interface CDOCProperty : NSObject 9 | 10 | - (id)initWithName:(NSString *)name attributes:(NSString *)attributes; 11 | 12 | @property (readonly) NSString *name; 13 | @property (readonly) NSString *attributeString; 14 | @property (readonly) CDType *type; 15 | @property (readonly) NSArray *attributes; 16 | 17 | @property (strong) NSString *attributeStringAfterType; 18 | 19 | @property (nonatomic, readonly) NSString *defaultGetter; 20 | @property (nonatomic, readonly) NSString *defaultSetter; 21 | 22 | @property (strong) NSString *customGetter; 23 | @property (strong) NSString *customSetter; 24 | 25 | @property (nonatomic, readonly) NSString *getter; 26 | @property (nonatomic, readonly) NSString *setter; 27 | 28 | @property (readonly) BOOL isReadOnly; 29 | @property (readonly) BOOL isDynamic; 30 | 31 | - (NSComparisonResult)ascendingCompareByName:(CDOCProperty *)other; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Source/CDOCProtocol.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @class CDTypeController; 7 | @class CDVisitor, CDVisitorPropertyState; 8 | @class CDOCMethod, CDOCProperty; 9 | 10 | @interface CDOCProtocol : NSObject 11 | 12 | @property (strong) NSString *name; 13 | 14 | @property (readonly) NSArray *protocols; 15 | - (void)addProtocol:(CDOCProtocol *)protocol; 16 | - (void)removeProtocol:(CDOCProtocol *)protocol; 17 | @property (nonatomic, readonly) NSArray *protocolNames; 18 | @property (nonatomic, readonly) NSString *protocolsString; 19 | 20 | @property (nonatomic, readonly) NSArray *classMethods; // TODO: NSArray vs. NSMutableArray 21 | - (void)addClassMethod:(CDOCMethod *)method; 22 | 23 | @property (nonatomic, readonly) NSArray *instanceMethods; 24 | - (void)addInstanceMethod:(CDOCMethod *)method; 25 | 26 | @property (nonatomic, readonly) NSArray *optionalClassMethods; 27 | - (void)addOptionalClassMethod:(CDOCMethod *)method; 28 | 29 | @property (nonatomic, readonly) NSArray *optionalInstanceMethods; 30 | - (void)addOptionalInstanceMethod:(CDOCMethod *)method; 31 | 32 | @property (nonatomic, readonly) NSArray *properties; 33 | - (void)addProperty:(CDOCProperty *)property; 34 | 35 | @property (nonatomic, readonly) BOOL hasMethods; 36 | 37 | - (void)registerTypesWithObject:(CDTypeController *)typeController phase:(NSUInteger)phase; 38 | - (void)registerTypesFromMethods:(NSArray *)methods withObject:(CDTypeController *)typeController phase:(NSUInteger)phase; 39 | 40 | - (NSComparisonResult)ascendingCompareByName:(CDOCProtocol *)other; 41 | 42 | - (NSString *)methodSearchContext; 43 | - (void)recursivelyVisit:(CDVisitor *)visitor; 44 | 45 | - (void)visitMethods:(CDVisitor *)visitor propertyState:(CDVisitorPropertyState *)propertyState; 46 | 47 | - (void)mergeMethodsFromProtocol:(CDOCProtocol *)other; 48 | - (void)mergePropertiesFromProtocol:(CDOCProtocol *)other; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Source/CDOCSymtab.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @class CDOCCategory, CDOCClass; 7 | 8 | @interface CDOCSymtab : NSObject 9 | 10 | @property (readonly) NSMutableArray *classes; 11 | - (void)addClass:(CDOCClass *)aClass; 12 | 13 | @property (readonly) NSMutableArray *categories; 14 | - (void)addCategory:(CDOCCategory *)category; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Source/CDOCSymtab.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDOCSymtab.h" 7 | 8 | #import "CDOCCategory.h" 9 | #import "CDOCClass.h" 10 | 11 | @implementation CDOCSymtab 12 | { 13 | NSMutableArray *_classes; 14 | NSMutableArray *_categories; 15 | } 16 | 17 | - (id)init; 18 | { 19 | if ((self = [super init])) { 20 | _classes = [[NSMutableArray alloc] init]; 21 | _categories = [[NSMutableArray alloc] init]; 22 | } 23 | 24 | return self; 25 | } 26 | 27 | #pragma mark - Debugging 28 | 29 | - (NSString *)description; 30 | { 31 | return [NSString stringWithFormat:@"[%@] classes: %@, categories: %@", NSStringFromClass([self class]), self.classes, self.categories]; 32 | } 33 | 34 | #pragma mark - 35 | 36 | - (void)addClass:(CDOCClass *)aClass; 37 | { 38 | [self.classes addObject:aClass]; 39 | } 40 | 41 | - (void)addCategory:(CDOCCategory *)category; 42 | { 43 | [self.categories addObject:category]; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Source/CDObjectiveC1Processor.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDObjectiveCProcessor.h" 7 | 8 | @interface CDObjectiveC1Processor : CDObjectiveCProcessor 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /Source/CDObjectiveC2Processor.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | /******************************************** 4 | Copyright 2020 PreEmptive Solutions, LLC 5 | See LICENSE.txt for licensing information 6 | ********************************************/ 7 | 8 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 9 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 10 | 11 | #import "CDObjectiveCProcessor.h" 12 | 13 | #define METHOD_LIST_T_RESERVED_BITS 0x7FFF0003 14 | #define METHOD_LIST_T_SMALL_METHOD_FLAG 0x80000000 15 | #define METHOD_LIST_T_ENTSIZE_MASK (METHOD_LIST_T_RESERVED_BITS|METHOD_LIST_T_SMALL_METHOD_FLAG) 16 | 17 | @interface CDObjectiveC2Processor : CDObjectiveCProcessor 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Source/CDObjectiveCProcessor.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | /******************************************** 4 | Copyright 2018 PreEmptive Solutions, LLC 5 | See LICENSE.txt for licensing information 6 | ********************************************/ 7 | 8 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 9 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 10 | 11 | @class CDMachOFile, CDSection, CDTypeController; 12 | @class CDVisitor; 13 | @class CDOCClass, CDOCCategory; 14 | @class CDProtocolUniquer; 15 | 16 | @interface CDObjectiveCProcessor : NSObject 17 | 18 | - (id)initWithMachOFile:(CDMachOFile *)machOFile; 19 | 20 | @property (readonly) CDMachOFile *machOFile; 21 | @property (nonatomic, readonly) BOOL hasObjectiveCData; 22 | 23 | @property (nonatomic, readonly) CDSection *objcImageInfoSection; 24 | @property (nonatomic, readonly) NSString *garbageCollectionStatus; 25 | 26 | - (void)addClass:(CDOCClass *)aClass withAddress:(uint64_t)address; 27 | - (CDOCClass *)classWithAddress:(uint64_t)address; 28 | 29 | - (void)addClassesFromArray:(NSArray *)array; 30 | - (void)addCategoriesFromArray:(NSArray *)array; 31 | 32 | - (void)addCategory:(CDOCCategory *)category; 33 | 34 | - (int)process; 35 | - (void)loadProtocols; 36 | - (int)loadClasses; 37 | - (void)loadCategories; 38 | 39 | - (void)registerTypesWithObject:(CDTypeController *)typeController phase:(NSUInteger)phase; 40 | - (void)recursivelyVisit:(CDVisitor *)visitor; 41 | 42 | - (NSArray *)protocolAddressListAtAddress:(uint64_t)address; 43 | 44 | @property (readonly) CDProtocolUniquer *protocolUniquer; 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Source/CDProtocolUniquer.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @class CDOCProtocol; 7 | 8 | @interface CDProtocolUniquer : NSObject 9 | 10 | // Gather 11 | - (CDOCProtocol *)protocolWithAddress:(uint64_t)address; 12 | - (void)setProtocol:(CDOCProtocol *)protocol withAddress:(uint64_t)address; 13 | 14 | // Process 15 | - (void)createUniquedProtocols; 16 | 17 | // Results 18 | - (NSArray *)uniqueProtocolsAtAddresses:(NSArray *)addresses; 19 | - (NSArray *)uniqueProtocolsSortedByName; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Source/CDRelocationInfo.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #include 7 | 8 | typedef enum : NSUInteger { 9 | CDRelocationInfoSize_8Bit = 0, 10 | CDRelocationInfoSize_16Bit = 1, 11 | CDRelocationInfoSize_32Bit = 2, 12 | CDRelocationInfoSize_64Bit = 3, 13 | } CDRelocationSize; 14 | 15 | @interface CDRelocationInfo : NSObject 16 | 17 | - (id)initWithInfo:(struct relocation_info)info; 18 | 19 | @property (nonatomic, readonly) NSUInteger offset; 20 | @property (nonatomic, readonly) CDRelocationSize size; 21 | @property (nonatomic, readonly) uint32_t symbolnum; 22 | @property (nonatomic, readonly) BOOL isExtern; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Source/CDRelocationInfo.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDRelocationInfo.h" 7 | 8 | @implementation CDRelocationInfo 9 | { 10 | struct relocation_info _rinfo; 11 | } 12 | 13 | - (id)initWithInfo:(struct relocation_info)info; 14 | { 15 | if ((self = [super init])) { 16 | _rinfo = info; 17 | } 18 | 19 | return self; 20 | } 21 | 22 | #pragma mark - Debugging 23 | 24 | - (NSString *)description; 25 | { 26 | return [NSString stringWithFormat:@"<%@:%p> addr/off: %08x, sym #: %5u, pcrel? %u, len: %u, extern? %u, type: %x", 27 | NSStringFromClass([self class]), self, 28 | _rinfo.r_address, _rinfo.r_symbolnum, _rinfo.r_pcrel, _rinfo.r_length, _rinfo.r_extern, _rinfo.r_type]; 29 | } 30 | 31 | #pragma mark - 32 | 33 | - (NSUInteger)offset; 34 | { 35 | return _rinfo.r_address; 36 | } 37 | 38 | - (CDRelocationSize)size; 39 | { 40 | return _rinfo.r_length; 41 | } 42 | 43 | - (uint32_t)symbolnum; 44 | { 45 | return _rinfo.r_symbolnum; 46 | } 47 | 48 | - (BOOL)isExtern; 49 | { 50 | return _rinfo.r_extern == 1; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Source/CDSearchPathState.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @interface CDSearchPathState : NSObject 7 | 8 | @property (nonatomic, strong) NSString *executablePath; 9 | 10 | - (void)pushSearchPaths:(NSArray *)searchPaths; 11 | - (void)popSearchPaths; 12 | 13 | - (NSArray *)searchPaths; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Source/CDSearchPathState.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDSearchPathState.h" 7 | 8 | @interface CDSearchPathState () 9 | @property (readonly) NSMutableArray *searchPathStack; 10 | @end 11 | 12 | #pragma mark - 13 | 14 | @implementation CDSearchPathState 15 | { 16 | NSString *_executablePath; 17 | NSMutableArray *_searchPathStack; 18 | } 19 | 20 | - (id)init; 21 | { 22 | if ((self = [super init])) { 23 | _executablePath = nil; 24 | _searchPathStack = [[NSMutableArray alloc] init]; 25 | } 26 | 27 | return self; 28 | } 29 | 30 | #pragma mark - 31 | 32 | - (void)pushSearchPaths:(NSArray *)searchPaths; 33 | { 34 | [self.searchPathStack addObject:searchPaths]; 35 | } 36 | 37 | - (void)popSearchPaths; 38 | { 39 | if ([self.searchPathStack count] > 0) { 40 | [self.searchPathStack removeLastObject]; 41 | } else { 42 | NSLog(@"Warning: Unbalanced popSearchPaths"); 43 | } 44 | } 45 | 46 | - (NSArray *)searchPaths; 47 | { 48 | NSMutableArray *result = [NSMutableArray array]; 49 | for (NSArray *group in self.searchPathStack) { 50 | [result addObjectsFromArray:group]; 51 | } 52 | 53 | return [result copy]; 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Source/CDSection.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @class CDMachOFileDataCursor; 7 | @class CDLCSegment; 8 | 9 | @interface CDSection : NSObject 10 | 11 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor segment:(CDLCSegment *)segment; 12 | 13 | @property (weak, readonly) CDLCSegment *segment; 14 | 15 | @property (nonatomic, readonly) NSData *data; 16 | 17 | @property (nonatomic, readonly) NSString *segmentName; 18 | @property (nonatomic, readonly) NSString *sectionName; 19 | 20 | @property (nonatomic, readonly) NSUInteger addr; 21 | @property (nonatomic, readonly) NSUInteger size; 22 | 23 | - (BOOL)containsAddress:(NSUInteger)address; 24 | - (NSUInteger)fileOffsetForAddress:(NSUInteger)address; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Source/CDStructureInfo.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @class CDType; 7 | 8 | @interface CDStructureInfo : NSObject 9 | 10 | - (id)initWithType:(CDType *)type; 11 | 12 | - (NSString *)shortDescription; 13 | 14 | @property (readonly) CDType *type; 15 | 16 | @property (assign) NSUInteger referenceCount; 17 | - (void)addReferenceCount:(NSUInteger)count; 18 | 19 | @property (assign) BOOL isUsedInMethod; 20 | @property (strong) NSString *typedefName; 21 | 22 | - (void)generateTypedefName:(NSString *)baseName; 23 | 24 | @property (nonatomic, readonly) NSString *name; 25 | 26 | - (NSComparisonResult)ascendingCompareByStructureDepth:(CDStructureInfo *)other; 27 | - (NSComparisonResult)descendingCompareByStructureDepth:(CDStructureInfo *)other; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Source/CDStructureTable.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @class CDType, CDTypeController, CDTypeFormatter; 7 | 8 | @interface CDStructureTable : NSObject 9 | 10 | @property (strong) NSString *identifier; 11 | @property (strong) NSString *anonymousBaseName; 12 | @property (assign) BOOL shouldDebug; 13 | 14 | @property (weak) CDTypeController *typeController; 15 | 16 | // Phase 0 17 | - (void)phase0RegisterStructure:(CDType *)structure usedInMethod:(BOOL)isUsedInMethod; 18 | - (void)finishPhase0; 19 | 20 | // Phase 1 21 | - (void)runPhase1; 22 | - (void)phase1RegisterStructure:(CDType *)structure; 23 | - (void)finishPhase1; 24 | @property (nonatomic, readonly) NSUInteger phase1_maxDepth; 25 | 26 | // Phase 2 27 | - (void)runPhase2AtDepth:(NSUInteger)depth; 28 | - (CDType *)phase2ReplacementForType:(CDType *)type; 29 | 30 | - (void)finishPhase2; 31 | 32 | // Phase 3 33 | - (void)phase2ReplacementOnPhase0; 34 | 35 | - (void)buildPhase3Exceptions; 36 | - (void)runPhase3; 37 | - (void)phase3RegisterStructure:(CDType *)structure 38 | count:(NSUInteger)referenceCount 39 | usedInMethod:(BOOL)isUsedInMethod; 40 | - (void)finishPhase3; 41 | - (CDType *)phase3ReplacementForType:(CDType *)type; 42 | 43 | // Other 44 | 45 | // Called by CDTypeController prior to calling the next two methods. 46 | - (void)generateTypedefNames; 47 | - (void)generateMemberNames; 48 | 49 | // Called by CDTypeController 50 | - (void)appendNamedStructuresToString:(NSMutableString *)resultString 51 | formatter:(CDTypeFormatter *)typeFormatter 52 | markName:(NSString *)markName; 53 | 54 | // Called by CDTypeController 55 | - (void)appendTypedefsToString:(NSMutableString *)resultString 56 | formatter:(CDTypeFormatter *)typeFormatter 57 | markName:(NSString *)markName; 58 | 59 | - (BOOL)shouldExpandType:(CDType *)type; 60 | - (NSString *)typedefNameForType:(CDType *)type; 61 | 62 | // Debugging 63 | - (void)debugName:(NSString *)name; 64 | - (void)debugAnon:(NSString *)str; 65 | - (void)logPhase0Info; 66 | - (void)logPhase2Info; 67 | - (void)logPhase3Info; 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /Source/CDSymbol.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #include 7 | 8 | extern NSString *const ObjCClassSymbolPrefix; 9 | 10 | @class CDMachOFile, CDSection, CDLCDylib; 11 | 12 | @interface CDSymbol : NSObject 13 | 14 | - (id)initWithName:(NSString *)name machOFile:(CDMachOFile *)machOFile nlist32:(struct nlist)nlist32; 15 | - (id)initWithName:(NSString *)name machOFile:(CDMachOFile *)machOFile nlist64:(struct nlist_64)nlist64; 16 | 17 | @property (nonatomic, readonly) uint64_t value; 18 | @property (readonly) NSString *name; 19 | @property (nonatomic, readonly) CDSection *section; 20 | @property (nonatomic, readonly) CDLCDylib *dylibLoadCommand; 21 | 22 | @property (nonatomic, readonly) BOOL isExternal; 23 | @property (nonatomic, readonly) BOOL isPrivateExternal; 24 | @property (nonatomic, readonly) NSUInteger stab; 25 | @property (nonatomic, readonly) NSUInteger type; 26 | @property (nonatomic, readonly) BOOL isDefined; 27 | @property (nonatomic, readonly) BOOL isAbsolute; 28 | @property (nonatomic, readonly) BOOL isInSection; 29 | @property (nonatomic, readonly) BOOL isPrebound; 30 | @property (nonatomic, readonly) BOOL isIndirect; 31 | @property (nonatomic, readonly) BOOL isCommon; 32 | @property (nonatomic, readonly) BOOL isInTextSection; 33 | @property (nonatomic, readonly) BOOL isInDataSection; 34 | @property (nonatomic, readonly) BOOL isInBssSection; 35 | @property (nonatomic, readonly) NSUInteger referenceType; 36 | @property (nonatomic, readonly) NSString *referenceTypeName; 37 | @property (nonatomic, readonly) NSString *shortTypeDescription; 38 | @property (nonatomic, readonly) NSString *longTypeDescription; 39 | 40 | - (NSComparisonResult)compare:(CDSymbol *)other; 41 | - (NSComparisonResult)compareByName:(CDSymbol *)other; 42 | 43 | + (NSString *)classNameFromSymbolName:(NSString *)symbolName; 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Source/CDSymbolsGeneratorVisitor.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | Copyright 2016-2017 PreEmptive Solutions, LLC 3 | See LICENSE.txt for licensing information 4 | ********************************************/ 5 | 6 | #import "CDVisitor.h" 7 | 8 | 9 | @interface CDSymbolsGeneratorVisitor : CDVisitor 10 | @property (nonatomic, copy) NSArray *classFilters; 11 | @property (nonatomic, copy) NSArray *exclusionPatterns; 12 | @property (nonatomic, readonly) NSDictionary *symbols; 13 | @property (nonatomic, copy) NSString *diagnosticFilesPrefix; 14 | @property (nonatomic, copy) NSString *frameworkName; 15 | 16 | + (void)appendDefineTo:(NSMutableString *)stringBuilder 17 | renaming:(NSString *)oldName 18 | to:(NSString *)newName; 19 | 20 | + (void)writeSymbols:(NSDictionary *)symbols 21 | symbolsHeaderFile:(NSString *)symbolsHeaderFile; 22 | @end 23 | -------------------------------------------------------------------------------- /Source/CDTextClassDumpVisitor.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDVisitor.h" 7 | 8 | // Has a mutable string for storing output, and method to write it to standard out. 9 | // symbol references are for... ? 10 | 11 | @interface CDTextClassDumpVisitor : CDVisitor 12 | 13 | @property (readonly) NSMutableString *resultString; 14 | 15 | - (void)writeResultToStandardOutput; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Source/CDTopoSortNode.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDTopologicalSortProtocol.h" 7 | 8 | typedef enum : NSUInteger { 9 | CDNodeColor_White = 0, 10 | CDNodeColor_Gray = 1, 11 | CDNodeColor_Black = 2, 12 | } CDNodeColor; 13 | 14 | @interface CDTopoSortNode : NSObject 15 | 16 | - (id)initWithObject:(id )object; 17 | 18 | @property (nonatomic, readonly) NSString *identifier; 19 | @property (readonly) id sortableObject; 20 | 21 | - (NSArray *)dependancies; 22 | - (void)addDependancy:(NSString *)identifier; 23 | - (void)removeDependancy:(NSString *)identifier; 24 | - (void)addDependanciesFromArray:(NSArray *)identifiers; 25 | @property (nonatomic, readonly) NSString *dependancyDescription; 26 | 27 | @property (assign) CDNodeColor color; 28 | 29 | - (NSComparisonResult)ascendingCompareByIdentifier:(CDTopoSortNode *)other; 30 | - (void)topologicallySortNodes:(NSDictionary *)nodesByIdentifier intoArray:(NSMutableArray *)sortedArray; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Source/CDTopoSortNode.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDTopoSortNode.h" 7 | 8 | @implementation CDTopoSortNode 9 | { 10 | id _sortableObject; 11 | 12 | NSMutableSet *_dependancies; 13 | CDNodeColor _color; 14 | } 15 | 16 | - (id)initWithObject:(id )object; 17 | { 18 | if ((self = [super init])) { 19 | _sortableObject = object; 20 | _dependancies = [[NSMutableSet alloc] init]; 21 | _color = CDNodeColor_White; 22 | 23 | [self addDependanciesFromArray:[_sortableObject dependancies]]; 24 | } 25 | 26 | return self; 27 | } 28 | 29 | #pragma mark - Debugging 30 | 31 | - (NSString *)description; 32 | { 33 | return [NSString stringWithFormat:@"%@ (%lu) depends on %@", self.identifier, self.color, self.dependancyDescription]; 34 | } 35 | 36 | #pragma mark - 37 | 38 | - (NSString *)identifier; 39 | { 40 | return self.sortableObject.identifier; 41 | } 42 | 43 | - (NSArray *)dependancies; 44 | { 45 | return [_dependancies allObjects]; 46 | } 47 | 48 | - (void)addDependancy:(NSString *)identifier; 49 | { 50 | [_dependancies addObject:identifier]; 51 | } 52 | 53 | - (void)removeDependancy:(NSString *)identifier; 54 | { 55 | [_dependancies removeObject:identifier]; 56 | } 57 | 58 | - (void)addDependanciesFromArray:(NSArray *)identifiers; 59 | { 60 | [_dependancies addObjectsFromArray:identifiers]; 61 | } 62 | 63 | - (NSString *)dependancyDescription; 64 | { 65 | return [[_dependancies allObjects] componentsJoinedByString:@", "]; 66 | } 67 | 68 | #pragma mark - Sorting 69 | 70 | - (NSComparisonResult)ascendingCompareByIdentifier:(CDTopoSortNode *)other; 71 | { 72 | return [self.identifier compare:other.identifier]; 73 | } 74 | 75 | - (void)topologicallySortNodes:(NSDictionary *)nodesByIdentifier intoArray:(NSMutableArray *)sortedArray; 76 | { 77 | NSArray *dependantIdentifiers = [self dependancies]; 78 | 79 | for (NSString *identifier in dependantIdentifiers) { 80 | CDTopoSortNode *node = nodesByIdentifier[identifier]; 81 | if (node.color == CDNodeColor_White) { 82 | node.color = CDNodeColor_Gray; 83 | [node topologicallySortNodes:nodesByIdentifier intoArray:sortedArray]; 84 | } else if (node.color == CDNodeColor_Gray) { 85 | NSLog(@"Warning: Possible circular reference? %@ -> %@", self.identifier, node.identifier); 86 | } 87 | } 88 | 89 | [sortedArray addObject:[self sortableObject]]; 90 | self.color = CDNodeColor_Black; 91 | } 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /Source/CDTopologicalSortProtocol.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | // A rather clunky way to avoid warnings in CDTopoSortNode.m regarding -retain not implemented by protocols 7 | @protocol CDTopologicalSort 8 | @property (nonatomic, readonly) NSString *identifier; 9 | @property (nonatomic, readonly) NSArray *dependancies; 10 | @end 11 | -------------------------------------------------------------------------------- /Source/CDType.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @class CDTypeController, CDTypeFormatter, CDTypeName; 7 | 8 | @interface CDType : NSObject 9 | 10 | - (id)initSimpleType:(int)type; 11 | - (id)initIDType:(CDTypeName *)name; 12 | - (id)initIDType:(CDTypeName *)name withProtocols:(NSArray *)protocols; 13 | - (id)initIDTypeWithProtocols:(NSArray *)protocols; 14 | - (id)initStructType:(CDTypeName *)name members:(NSArray *)members; 15 | - (id)initUnionType:(CDTypeName *)name members:(NSArray *)members; 16 | - (id)initBitfieldType:(NSString *)bitfieldSize; 17 | - (id)initArrayType:(CDType *)type count:(NSString *)count; 18 | - (id)initPointerType:(CDType *)type; 19 | - (id)initFunctionPointerType; 20 | - (id)initBlockTypeWithTypes:(NSArray *)types; 21 | - (id)initModifier:(int)modifier type:(CDType *)type; 22 | 23 | @property (strong) NSString *variableName; 24 | 25 | @property (nonatomic, readonly) int primitiveType; 26 | @property (nonatomic, readonly) BOOL isIDType; 27 | @property (nonatomic, readonly) BOOL isNamedObject; 28 | @property (nonatomic, readonly) BOOL isTemplateType; 29 | 30 | @property (nonatomic, readonly) CDType *subtype; 31 | @property (nonatomic, readonly) CDTypeName *typeName; 32 | @property (nonatomic, readonly) NSArray *protocols; 33 | 34 | @property (nonatomic, readonly) NSArray *members; 35 | @property (nonatomic, readonly) NSArray *types; 36 | 37 | @property (nonatomic, readonly) int typeIgnoringModifiers; 38 | @property (nonatomic, readonly) NSUInteger structureDepth; 39 | 40 | - (NSString *)formattedString:(NSString *)previousName formatter:(CDTypeFormatter *)typeFormatter level:(NSUInteger)level; 41 | 42 | @property (nonatomic, readonly) NSString *typeString; 43 | @property (nonatomic, readonly) NSString *bareTypeString; 44 | @property (nonatomic, readonly) NSString *reallyBareTypeString; 45 | @property (nonatomic, readonly) NSString *keyTypeString; 46 | 47 | 48 | - (BOOL)canMergeWithType:(CDType *)otherType; 49 | - (void)mergeWithType:(CDType *)otherType; 50 | 51 | @property (nonatomic, readonly) NSArray *memberVariableNames; 52 | - (void)generateMemberNames; 53 | 54 | // Phase 0 55 | - (void)phase:(NSUInteger)phase registerTypesWithObject:(CDTypeController *)typeController usedInMethod:(BOOL)isUsedInMethod; 56 | - (void)phase0RecursivelyFixStructureNames:(BOOL)flag; 57 | 58 | // Phase 1 59 | - (void)phase1RegisterStructuresWithObject:(CDTypeController *)typeController; 60 | 61 | // Phase 2 62 | - (void)phase2MergeWithTypeController:(CDTypeController *)typeController debug:(BOOL)phase2Debug; 63 | 64 | // Phase 3 65 | - (void)phase3RegisterMembersWithTypeController:(CDTypeController *)typeController; 66 | - (void)phase3MergeWithTypeController:(CDTypeController *)typeController; 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /Source/CDTypeController.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | /******************************************** 4 | Copyright 2016 PreEmptive Solutions, LLC 5 | See LICENSE.txt for licensing information 6 | ********************************************/ 7 | 8 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 9 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 10 | 11 | @protocol CDTypeControllerDelegate; 12 | 13 | @class CDClassDump, CDType, CDTypeFormatter; 14 | 15 | @interface CDTypeController : NSObject 16 | 17 | - (id)initWithClassDump:(CDClassDump *)classDump; 18 | 19 | @property (weak) id delegate; 20 | 21 | @property (readonly) CDTypeFormatter *ivarTypeFormatter; 22 | @property (readonly) CDTypeFormatter *methodTypeFormatter; 23 | @property (readonly) CDTypeFormatter *propertyTypeFormatter; 24 | @property (readonly) CDTypeFormatter *structDeclarationTypeFormatter; 25 | 26 | @property (nonatomic, readonly) BOOL shouldShowIvarOffsets; 27 | @property (nonatomic, readonly) BOOL shouldShowMethodAddresses; 28 | @property (nonatomic, readonly) BOOL targetArchUses64BitABI; 29 | 30 | @property (nonatomic, assign) BOOL hasUnknownFunctionPointers; 31 | @property (nonatomic, assign) BOOL hasUnknownBlocks; 32 | 33 | - (CDType *)typeFormatter:(CDTypeFormatter *)typeFormatter replacementForType:(CDType *)type; 34 | - (NSString *)typeFormatter:(CDTypeFormatter *)typeFormatter typedefNameForStructure:(CDType *)structureType level:(NSUInteger)level; 35 | - (void)typeFormatter:(CDTypeFormatter *)typeFormatter didReferenceClassName:(NSString *)name; 36 | - (void)typeFormatter:(CDTypeFormatter *)typeFormatter didReferenceProtocolNames:(NSArray *)names; 37 | 38 | - (void)appendStructuresToString:(NSMutableString *)resultString; 39 | 40 | // Phase 0 - initiated from -[CDClassDump registerTypes] 41 | - (void)phase0RegisterStructure:(CDType *)structure usedInMethod:(BOOL)isUsedInMethod; 42 | 43 | // Run phase 1+ 44 | - (void)workSomeMagic; 45 | 46 | // Phase 1 47 | - (void)phase1RegisterStructure:(CDType *)structure; 48 | 49 | - (void)endPhase:(NSUInteger)phase; 50 | 51 | - (CDType *)phase2ReplacementForType:(CDType *)type; 52 | 53 | - (void)phase3RegisterStructure:(CDType *)structure; 54 | - (CDType *)phase3ReplacementForType:(CDType *)type; 55 | 56 | - (BOOL)shouldExpandType:(CDType *)type; 57 | - (NSString *)typedefNameForType:(CDType *)type; 58 | 59 | @end 60 | 61 | #pragma mark - 62 | 63 | @protocol CDTypeControllerDelegate 64 | @optional 65 | - (void)typeController:(CDTypeController *)typeController didReferenceClassName:(NSString *)name; 66 | - (void)typeController:(CDTypeController *)typeController didReferenceProtocolNames:(NSArray *)names; 67 | @end 68 | -------------------------------------------------------------------------------- /Source/CDTypeFormatter.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | /******************************************** 4 | Copyright 2016 PreEmptive Solutions, LLC 5 | See LICENSE.txt for licensing information 6 | ********************************************/ 7 | 8 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 9 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 10 | 11 | @class CDType, CDTypeController; 12 | 13 | @interface CDTypeFormatter : NSObject 14 | 15 | @property (weak) CDTypeController *typeController; 16 | 17 | @property (assign) NSUInteger baseLevel; 18 | @property (assign) BOOL shouldExpand; 19 | @property (assign) BOOL shouldAutoExpand; 20 | @property (assign) BOOL shouldShowLexing; 21 | 22 | - (NSString *)formatVariable:(NSString *)name type:(CDType *)type; 23 | - (NSString *)formatMethodName:(NSString *)name typeString:(NSString *)typeString; 24 | 25 | - (NSString *)typedefNameForStructure:(CDType *)structureType level:(NSUInteger)level; 26 | 27 | - (void)formattingDidReferenceClassName:(NSString *)name; 28 | - (void)formattingDidReferenceProtocolNames:(NSArray *)names; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Source/CDTypeLexer.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #define TK_EOS 0 7 | #define TK_NUMBER 257 8 | #define TK_IDENTIFIER 258 9 | #define T_NAMED_OBJECT 259 10 | #define TK_QUOTED_STRING 260 11 | #define TK_TEMPLATE_TYPE TK_IDENTIFIER 12 | #define T_FUNCTION_POINTER_TYPE 1001 13 | #define T_BLOCK_TYPE 1002 14 | 15 | typedef enum : NSUInteger { 16 | CDTypeLexerState_Normal = 0, 17 | CDTypeLexerState_Identifier = 1, 18 | CDTypeLexerState_TemplateTypes = 2, 19 | } CDTypeLexerState; 20 | 21 | @interface CDTypeLexer : NSObject 22 | 23 | - (id)initWithString:(NSString *)string; 24 | 25 | @property (readonly) NSScanner *scanner; 26 | @property (nonatomic, assign) CDTypeLexerState state; 27 | @property (assign) BOOL shouldShowLexing; 28 | 29 | @property (nonatomic, readonly) NSString *string; 30 | - (int)scanNextToken; 31 | 32 | @property (strong) NSString *lexText; 33 | 34 | @property (nonatomic, readonly) unichar peekChar; 35 | @property (nonatomic, readonly) NSString *remainingString; 36 | @property (nonatomic, readonly) NSString *peekIdentifier; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Source/CDTypeName.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @interface CDTypeName : NSObject 7 | 8 | @property (strong) NSString *name; 9 | @property (readonly) NSMutableArray *templateTypes; 10 | @property (strong) NSString *suffix; 11 | @property (nonatomic, readonly) BOOL isTemplateType; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Source/CDTypeName.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDTypeName.h" 7 | 8 | @implementation CDTypeName 9 | { 10 | NSString *_name; 11 | NSMutableArray *_templateTypes; 12 | NSString *_suffix; 13 | } 14 | 15 | - (id)init; 16 | { 17 | if ((self = [super init])) { 18 | _name = nil; 19 | _templateTypes = [[NSMutableArray alloc] init]; 20 | _suffix = nil; 21 | } 22 | 23 | return self; 24 | } 25 | 26 | #pragma mark - NSCopying 27 | 28 | - (id)copyWithZone:(NSZone *)zone; 29 | { 30 | CDTypeName *copy = [[CDTypeName alloc] init]; 31 | copy.name = self.name; 32 | copy.suffix = self.suffix; 33 | 34 | for (CDTypeName *subtype in self.templateTypes) { 35 | CDTypeName *subcopy = [subtype copy]; 36 | [copy.templateTypes addObject:subcopy]; 37 | } 38 | 39 | return copy; 40 | } 41 | 42 | #pragma mark - 43 | 44 | - (BOOL)isEqual:(id)otherObject; 45 | { 46 | if ([otherObject isKindOfClass:[self class]] == NO) 47 | return NO; 48 | 49 | return [[self description] isEqual:[otherObject description]]; 50 | } 51 | 52 | #pragma mark - Debugging 53 | 54 | - (NSString *)description; 55 | { 56 | if ([self.templateTypes count] == 0) { 57 | return self.name ? self.name : @""; 58 | } 59 | 60 | if (self.suffix != nil) 61 | return [NSString stringWithFormat:@"%@<%@>%@", self.name, [self.templateTypes componentsJoinedByString:@", "], self.suffix]; 62 | 63 | return [NSString stringWithFormat:@"%@<%@>", self.name, [self.templateTypes componentsJoinedByString:@", "]]; 64 | } 65 | 66 | #pragma mark - 67 | 68 | - (BOOL)isTemplateType; 69 | { 70 | return [self.templateTypes count] > 0; 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /Source/CDTypeParser.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @class CDType, CDTypeLexer; 7 | 8 | extern NSString *CDExceptionName_SyntaxError; 9 | extern NSString *CDErrorDomain_TypeParser; 10 | 11 | extern NSString *CDErrorKey_Type; 12 | extern NSString *CDErrorKey_RemainingString; 13 | extern NSString *CDErrorKey_MethodOrVariable; 14 | extern NSString *CDErrorKey_LocalizedLongDescription; 15 | 16 | #define CDTypeParserCode_Default 0 17 | #define CDTypeParserCode_SyntaxError 1 18 | 19 | @interface CDTypeParser : NSObject 20 | 21 | - (id)initWithString:(NSString *)string; 22 | 23 | @property (readonly) CDTypeLexer *lexer; 24 | 25 | - (NSArray *)parseMethodType:(NSError **)error; 26 | - (CDType *)parseType:(NSError **)error; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Source/CDVisitor.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | /******************************************** 4 | Copyright 2016 PreEmptive Solutions, LLC 5 | See LICENSE.txt for licensing information 6 | ********************************************/ 7 | 8 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 9 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 10 | 11 | @class CDClassDump, CDObjectiveCProcessor, CDOCProtocol, CDOCMethod, CDOCInstanceVariable, CDOCClass, CDOCCategory, CDOCProperty; 12 | @class CDVisitorPropertyState; 13 | 14 | @interface CDVisitor : NSObject 15 | 16 | @property (strong) CDClassDump *classDump; 17 | 18 | - (void)willBeginVisiting; 19 | - (void)didEndVisiting; 20 | 21 | - (void)willVisitObjectiveCProcessor:(CDObjectiveCProcessor *)processor; 22 | - (void)visitObjectiveCProcessor:(CDObjectiveCProcessor *)processor; 23 | - (void)didVisitObjectiveCProcessor:(CDObjectiveCProcessor *)processor; 24 | 25 | - (void)willVisitProtocol:(CDOCProtocol *)protocol; 26 | - (void)didVisitProtocol:(CDOCProtocol *)protocol; 27 | 28 | - (void)willVisitPropertiesOfProtocol:(CDOCProtocol *)protocol; 29 | - (void)didVisitPropertiesOfProtocol:(CDOCProtocol *)protocol; 30 | 31 | - (void)willVisitOptionalMethods; 32 | - (void)didVisitOptionalMethods; 33 | 34 | - (void)willVisitClass:(CDOCClass *)aClass; 35 | - (void)didVisitClass:(CDOCClass *)aClass; 36 | 37 | - (void)willVisitIvarsOfClass:(CDOCClass *)aClass; 38 | - (void)didVisitIvarsOfClass:(CDOCClass *)aClass; 39 | 40 | - (void)willVisitPropertiesOfClass:(CDOCClass *)aClass; 41 | - (void)didVisitPropertiesOfClass:(CDOCClass *)aClass; 42 | 43 | - (void)willVisitCategory:(CDOCCategory *)category; 44 | - (void)didVisitCategory:(CDOCCategory *)category; 45 | 46 | - (void)willVisitPropertiesOfCategory:(CDOCCategory *)category; 47 | - (void)didVisitPropertiesOfCategory:(CDOCCategory *)category; 48 | 49 | - (void)visitClassMethod:(CDOCMethod *)method; 50 | - (void)visitInstanceMethod:(CDOCMethod *)method propertyState:(CDVisitorPropertyState *)propertyState; 51 | - (void)visitIvar:(CDOCInstanceVariable *)ivar; 52 | - (void)visitProperty:(CDOCProperty *)property; 53 | 54 | - (void)visitRemainingProperties:(CDVisitorPropertyState *)propertyState; 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Source/CDVisitor.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | /******************************************** 4 | Copyright 2016 PreEmptive Solutions, LLC 5 | See LICENSE.txt for licensing information 6 | ********************************************/ 7 | 8 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 9 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 10 | 11 | #import "CDVisitor.h" 12 | 13 | #import "CDClassDump.h" 14 | 15 | @implementation CDVisitor 16 | { 17 | CDClassDump *_classDump; 18 | } 19 | 20 | - (id)init; 21 | { 22 | return self; 23 | } 24 | 25 | #pragma mark - 26 | 27 | - (void)willBeginVisiting; 28 | { 29 | } 30 | 31 | - (void)didEndVisiting; 32 | { 33 | } 34 | 35 | // Called before visiting. 36 | - (void)willVisitObjectiveCProcessor:(CDObjectiveCProcessor *)processor; 37 | { 38 | } 39 | 40 | // This gets called before visiting the children, but only if it has children it will visit. 41 | - (void)visitObjectiveCProcessor:(CDObjectiveCProcessor *)processor; 42 | { 43 | } 44 | 45 | - (void)willVisitPropertiesOfProtocol:(CDOCProtocol *)protocol; 46 | { 47 | } 48 | 49 | - (void)didVisitPropertiesOfProtocol:(CDOCProtocol *)protocol; 50 | { 51 | } 52 | 53 | - (void)willVisitOptionalMethods; 54 | { 55 | } 56 | 57 | - (void)didVisitOptionalMethods; 58 | { 59 | } 60 | 61 | // Called after visiting. 62 | - (void)didVisitObjectiveCProcessor:(CDObjectiveCProcessor *)processor; 63 | { 64 | } 65 | 66 | - (void)willVisitProtocol:(CDOCProtocol *)protocol; 67 | { 68 | } 69 | 70 | - (void)didVisitProtocol:(CDOCProtocol *)protocol; 71 | { 72 | } 73 | 74 | - (void)willVisitClass:(CDOCClass *)aClass; 75 | { 76 | } 77 | 78 | - (void)didVisitClass:(CDOCClass *)aClass; 79 | { 80 | } 81 | 82 | - (void)willVisitIvarsOfClass:(CDOCClass *)aClass; 83 | { 84 | } 85 | 86 | - (void)didVisitIvarsOfClass:(CDOCClass *)aClass; 87 | { 88 | } 89 | 90 | - (void)willVisitPropertiesOfClass:(CDOCClass *)aClass; 91 | { 92 | } 93 | 94 | - (void)didVisitPropertiesOfClass:(CDOCClass *)aClass; 95 | { 96 | } 97 | 98 | - (void)willVisitCategory:(CDOCCategory *)category; 99 | { 100 | } 101 | 102 | - (void)didVisitCategory:(CDOCCategory *)category; 103 | { 104 | } 105 | 106 | - (void)willVisitPropertiesOfCategory:(CDOCCategory *)category; 107 | { 108 | } 109 | 110 | - (void)didVisitPropertiesOfCategory:(CDOCCategory *)category; 111 | { 112 | } 113 | 114 | - (void)visitClassMethod:(CDOCMethod *)method; 115 | { 116 | } 117 | 118 | - (void)visitInstanceMethod:(CDOCMethod *)method propertyState:(CDVisitorPropertyState *)propertyState; 119 | { 120 | } 121 | 122 | - (void)visitIvar:(CDOCInstanceVariable *)ivar; 123 | { 124 | } 125 | 126 | - (void)visitProperty:(CDOCProperty *)property; 127 | { 128 | } 129 | 130 | - (void)visitRemainingProperties:(CDVisitorPropertyState *)propertyState; 131 | { 132 | } 133 | 134 | @end 135 | -------------------------------------------------------------------------------- /Source/CDVisitorPropertyState.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @class CDOCProperty; 7 | 8 | @interface CDVisitorPropertyState : NSObject 9 | 10 | - (id)initWithProperties:(NSArray *)properties; 11 | 12 | - (CDOCProperty *)propertyForAccessor:(NSString *)str; 13 | 14 | - (BOOL)hasUsedProperty:(CDOCProperty *)property; 15 | - (void)useProperty:(CDOCProperty *)property; 16 | 17 | @property (nonatomic, readonly) NSArray *remainingProperties; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Source/CDVisitorPropertyState.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "CDVisitorPropertyState.h" 7 | 8 | #import "CDOCProperty.h" 9 | 10 | @interface CDVisitorPropertyState () 11 | @end 12 | 13 | #pragma mark - 14 | 15 | @implementation CDVisitorPropertyState 16 | { 17 | NSMutableDictionary *_propertiesByAccessor; // NSString (accessor) -> CDOCProperty 18 | NSMutableDictionary *_propertiesByName; // NSString (property name) -> CDOCProperty 19 | } 20 | 21 | - (id)initWithProperties:(NSArray *)properties; 22 | { 23 | if ((self = [super init])) { 24 | _propertiesByAccessor = [[NSMutableDictionary alloc] init]; 25 | _propertiesByName = [[NSMutableDictionary alloc] init]; 26 | 27 | for (CDOCProperty *property in properties) { 28 | //NSLog(@"property: %@, getter: %@, setter: %@", [property name], [property getter], [property setter]); 29 | _propertiesByName[property.name] = property; 30 | _propertiesByAccessor[property.getter] = property; 31 | if (property.isReadOnly == NO) 32 | _propertiesByAccessor[property.setter] = property; 33 | } 34 | } 35 | 36 | return self; 37 | } 38 | 39 | #pragma mark - Debugging 40 | 41 | - (void)log; 42 | { 43 | NSLog(@"propertiesByAccessor: %@", _propertiesByAccessor); 44 | NSLog(@"propertiesByName: %@", _propertiesByName); 45 | } 46 | 47 | #pragma mark - 48 | 49 | - (CDOCProperty *)propertyForAccessor:(NSString *)str; 50 | { 51 | return _propertiesByAccessor[str]; 52 | } 53 | 54 | - (BOOL)hasUsedProperty:(CDOCProperty *)property; 55 | { 56 | return _propertiesByName[property.name] == nil; 57 | } 58 | 59 | - (void)useProperty:(CDOCProperty *)property; 60 | { 61 | [_propertiesByName removeObjectForKey:property.name]; 62 | } 63 | 64 | - (NSArray *)remainingProperties; 65 | { 66 | return [[_propertiesByName allValues] sortedArrayUsingSelector:@selector(ascendingCompareByName:)]; 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /Source/CDXMLParserSharedBase.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | Copyright 2016 PreEmptive Solutions, LLC 3 | See LICENSE.txt for licensing information 4 | ********************************************/ 5 | 6 | #import 7 | 8 | @class GDataXMLElement; 9 | 10 | @interface CDXMLParserSharedBase : NSObject 11 | - (NSArray *)symbolsInData:(NSData *)data; 12 | 13 | - (NSData *)obfuscatedXmlData:(NSData *)data symbols:(NSDictionary *)symbols; 14 | 15 | - (void)addSymbolsFromNode:(GDataXMLElement *)xmlDictionary toArray:(NSMutableArray *)symbolsArray; 16 | - (void)obfuscateElement:(GDataXMLElement *)element usingSymbols:(NSDictionary *)symbols; 17 | @end 18 | -------------------------------------------------------------------------------- /Source/CDXMLParserSharedBase.m: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | Copyright 2016 PreEmptive Solutions, LLC 3 | See LICENSE.txt for licensing information 4 | ********************************************/ 5 | 6 | #import "CDXMLParserSharedBase.h" 7 | #import "GDataXMLNode.h" 8 | 9 | 10 | @implementation CDXMLParserSharedBase 11 | 12 | - (NSArray *)symbolsInData:(NSData *)data { 13 | NSMutableArray *array = [NSMutableArray array]; 14 | 15 | GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data error:nil]; 16 | 17 | [self addSymbolsFromNode:doc.rootElement toArray:array]; 18 | 19 | return array; 20 | } 21 | 22 | - (NSData *)obfuscatedXmlData:(NSData *)data symbols:(NSDictionary *)symbols { 23 | GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data error:nil]; 24 | 25 | [self obfuscateElement:doc.rootElement usingSymbols:symbols]; 26 | 27 | return doc.XMLData; 28 | } 29 | 30 | - (void)addSymbolsFromNode:(GDataXMLElement *)xmlDictionary toArray:(NSMutableArray *)symbolsArray {} 31 | - (void)obfuscateElement:(GDataXMLElement *)element usingSymbols:(NSDictionary *)symbols {} 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Source/CDXibStoryBoardProcessor.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | @interface CDXibStoryBoardProcessor : NSObject 5 | @property(nonatomic, copy) NSString *xibBaseDirectory; 6 | 7 | - (void)obfuscateFilesUsingSymbols:(NSDictionary *)symbols; 8 | @end 9 | -------------------------------------------------------------------------------- /Source/CDXibStoryBoardProcessor.m: -------------------------------------------------------------------------------- 1 | #import "CDXibStoryBoardProcessor.h" 2 | #import "CDXibStoryboardParser.h" 3 | 4 | 5 | @implementation CDXibStoryBoardProcessor 6 | 7 | - (void)obfuscateFilesUsingSymbols:(NSDictionary *)symbols { 8 | NSFileManager *fileManager = [NSFileManager defaultManager]; 9 | NSArray *keys = @[NSURLIsDirectoryKey]; 10 | NSURL *directoryURL; 11 | if (self.xibBaseDirectory) { 12 | directoryURL = [NSURL URLWithString:self.xibBaseDirectory]; 13 | } else { 14 | directoryURL = [NSURL URLWithString:@"."]; 15 | } 16 | 17 | NSDirectoryEnumerator *enumerator = [fileManager 18 | enumeratorAtURL:directoryURL 19 | includingPropertiesForKeys:keys 20 | options:0 21 | errorHandler:^(NSURL *url, NSError *error) { 22 | // Handle the error. 23 | // Return YES if the enumeration should continue after the error. 24 | return YES; 25 | }]; 26 | 27 | CDXibStoryboardParser *parser = [[CDXibStoryboardParser alloc] init]; 28 | for (NSURL *url in enumerator) { 29 | NSError *error; 30 | NSNumber *isDirectory = nil; 31 | if ([url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error] && ![isDirectory boolValue]) { 32 | if ([url.absoluteString hasSuffix:@".xib"] || [url.absoluteString hasSuffix:@".storyboard"]) { 33 | NSLog(@"Obfuscating IB file at path %@", url); 34 | NSData *data = [parser obfuscatedXmlData:[NSData dataWithContentsOfURL:url] symbols:symbols]; 35 | [data writeToURL:url atomically:YES]; 36 | } 37 | } 38 | } 39 | } 40 | 41 | 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /Source/CDXibStoryboardParser.h: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | Copyright 2016 PreEmptive Solutions, LLC 3 | See LICENSE.txt for licensing information 4 | ********************************************/ 5 | 6 | #import 7 | #import "CDXMLParserSharedBase.h" 8 | 9 | 10 | @interface CDXibStoryboardParser : CDXMLParserSharedBase 11 | @end 12 | -------------------------------------------------------------------------------- /Source/MachObjC-Prefix.pch: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | Copyright 2016-2017 PreEmptive Solutions, LLC 3 | See LICENSE.txt for licensing information 4 | *************************************************/ 5 | 6 | // 7 | // Prefix header for all source files of the 'libMachObjC' target in the 'ppios-rename' project. 8 | // 9 | 10 | #ifdef __OBJC__ 11 | #import 12 | #import "CDExtensions.h" 13 | #define __cmd __PRETTY_FUNCTION__ 14 | #endif 15 | -------------------------------------------------------------------------------- /Source/NSArray-CDExtensions.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @interface NSArray (CDExtensions) 7 | 8 | - (NSArray *)reversedArray; 9 | 10 | @end 11 | 12 | @interface NSArray (CDTopoSort) 13 | 14 | - (NSArray *)topologicallySortedArray; 15 | 16 | @end 17 | 18 | @interface NSMutableArray (CDTopoSort) 19 | 20 | - (void)sortTopologically; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Source/NSArray-CDExtensions.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "NSArray-CDExtensions.h" 7 | 8 | @implementation NSArray (CDExtensions) 9 | 10 | - (NSArray *)reversedArray; 11 | { 12 | return [[self reverseObjectEnumerator] allObjects]; 13 | } 14 | 15 | @end 16 | 17 | #pragma mark - 18 | 19 | @implementation NSArray (CDTopoSort) 20 | 21 | - (NSArray *)topologicallySortedArray; 22 | { 23 | NSMutableDictionary *nodesByName = [[NSMutableDictionary alloc] init]; 24 | 25 | for (id object in self) { 26 | CDTopoSortNode *node = [[CDTopoSortNode alloc] initWithObject:object]; 27 | [node addDependanciesFromArray:[object dependancies]]; 28 | 29 | if (nodesByName[node.identifier] != nil) 30 | NSLog(@"Warning: Duplicate identifier (%@) in %s", node.identifier, __cmd); 31 | nodesByName[node.identifier] = node; 32 | } 33 | 34 | NSMutableArray *sortedArray = [NSMutableArray array]; 35 | 36 | NSArray *allNodes = [[nodesByName allValues] sortedArrayUsingSelector:@selector(ascendingCompareByIdentifier:)]; 37 | for (CDTopoSortNode *node in allNodes) { 38 | if (node.color == CDNodeColor_White) 39 | [node topologicallySortNodes:nodesByName intoArray:sortedArray]; 40 | } 41 | 42 | 43 | return sortedArray; 44 | } 45 | 46 | @end 47 | 48 | #pragma mark - 49 | 50 | @implementation NSMutableArray (CDTopoSort) 51 | 52 | - (void)sortTopologically; 53 | { 54 | NSArray *sortedArray = [self topologicallySortedArray]; 55 | assert([self count] == [sortedArray count]); 56 | 57 | [self removeAllObjects]; 58 | [self addObjectsFromArray:sortedArray]; 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /Source/NSData-CDExtensions.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @interface NSData (CDExtensions) 7 | 8 | - (NSString *)hexString; 9 | - (NSData *)SHA1Digest; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /Source/NSData-CDExtensions.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "NSData-CDExtensions.h" 7 | 8 | #import 9 | 10 | @implementation NSData (CDExtensions) 11 | 12 | - (NSString *)hexString; 13 | { 14 | NSMutableString *str = [NSMutableString string]; 15 | const uint8_t *ptr = [self bytes]; 16 | for (NSUInteger index = 0; index < [self length]; index++) { 17 | [str appendFormat:@"%02x", *ptr++]; 18 | } 19 | 20 | return str; 21 | } 22 | 23 | - (NSData *)SHA1Digest; 24 | { 25 | NSParameterAssert([self length] <= UINT32_MAX); 26 | 27 | unsigned char digest[CC_SHA1_DIGEST_LENGTH]; 28 | CC_SHA1([self bytes], (CC_LONG)[self length], digest); 29 | 30 | return [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH]; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Source/NSError-CDExtensions.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @interface NSError (CDExtensions) 7 | 8 | @end 9 | 10 | extern NSString *NSErrorDomain_ClassDump; 11 | -------------------------------------------------------------------------------- /Source/NSError-CDExtensions.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import "NSError-CDExtensions.h" 7 | 8 | NSString *NSErrorDomain_ClassDump = @"com.stevenygard.MachObjC.ErrorDomain"; 9 | 10 | @implementation NSError (CDExtensions) 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Source/NSScanner-CDExtensions.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @interface NSScanner (CDExtensions) 7 | 8 | + (NSCharacterSet *)cdOtherCharacterSet; 9 | + (NSCharacterSet *)cdIdentifierStartCharacterSet; 10 | + (NSCharacterSet *)cdIdentifierCharacterSet; 11 | + (NSCharacterSet *)cdTemplateTypeCharacterSet; 12 | 13 | - (NSString *)peekCharacter; 14 | - (unichar)peekChar; 15 | - (BOOL)scanCharacter:(unichar *)value; 16 | - (BOOL)scanCharacterFromSet:(NSCharacterSet *)set intoString:(NSString **)value; 17 | - (BOOL)my_scanCharactersFromSet:(NSCharacterSet *)set intoString:(NSString **)value; 18 | 19 | - (BOOL)scanIdentifierIntoString:(NSString **)stringPointer; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Source/NSString-CDExtensions.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | @interface NSString (CDExtensions) 7 | 8 | + (NSString *)stringWithFileSystemRepresentation:(const char *)str; 9 | + (NSString *)spacesIndentedToLevel:(NSUInteger)level; 10 | + (NSString *)spacesIndentedToLevel:(NSUInteger)level spacesPerLevel:(NSUInteger)spacesPerLevel; 11 | + (NSString *)stringWithUnichar:(unichar)character; 12 | 13 | - (BOOL)isFirstLetterUppercase; 14 | 15 | - (void)print; 16 | 17 | - (NSString *)executablePathForFilename; 18 | 19 | - (NSString *)SHA1DigestString; 20 | 21 | - (BOOL)hasUnderscoreCapitalPrefix; 22 | - (NSString *)capitalizeFirstCharacter; 23 | - (NSString *)lowercaseFirstCharacter; 24 | 25 | @end 26 | 27 | @interface NSMutableString (CDExtensions) 28 | 29 | - (void)appendSpacesIndentedToLevel:(NSUInteger)level; 30 | - (void)appendSpacesIndentedToLevel:(NSUInteger)level spacesPerLevel:(NSUInteger)spacesPerLevel; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Source/ULEB128.h: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | // http://en.wikipedia.org/wiki/LEB128 7 | // http://web.mit.edu/rhel-doc/3/rhel-as-en-3/uleb128.html 8 | // uleb128 stands for "unsigned little endian base 128." 9 | // This is a compact, variable length representation of numbers used by the DWARF symbolic debugging format. 10 | 11 | // Top bit of byte is set until last byte. 12 | // Other 7 bits are the "slice". 13 | // Basically, it represents the low order bits 7 at a time, and can stop when the rest of the bits would be zero. 14 | // This needs to modify ptr. 15 | 16 | // For example, uleb with these bytes: e8 d7 15 17 | // 0xe8 = 1110 1000 18 | // 0xd7 = 1101 0111 19 | // 0x15 = 0001 0101 20 | 21 | // .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... 22 | // 0xe8 1 1101000 .... .... .... .... .... .... .... .... .... .... .... .... .... .... .110 1000 23 | // 0xd7 1 1010111 .... .... .... .... .... .... .... .... .... .... .... .... ..10 1011 1110 1000 24 | // 0x15 0 0010101 .... .... .... .... .... .... .... .... .... .... .... .... ..10 1011 1110 1000 25 | // 0x15 0 0010101 .... .... .... .... .... .... .... .... .... .... ...0 0101 0110 1011 1110 1000 26 | // Result is: 0x056be8 27 | // So... 24 bits to encode 64 bits 28 | 29 | uint64_t read_uleb128(const uint8_t **ptrptr, const uint8_t *end); 30 | 31 | int64_t read_sleb128(const uint8_t **ptrptr, const uint8_t *end); 32 | -------------------------------------------------------------------------------- /Source/ULEB128.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | /******************************************** 4 | Copyright 2016 PreEmptive Solutions, LLC 5 | See LICENSE.txt for licensing information 6 | ********************************************/ 7 | 8 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 9 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 10 | 11 | #import "ULEB128.h" 12 | 13 | uint64_t read_uleb128(const uint8_t **ptrptr, const uint8_t *end) 14 | { 15 | const uint8_t *ptr = *ptrptr; 16 | uint64_t result = 0; 17 | int bit = 0; 18 | 19 | //NSLog(@"read_uleb128()"); 20 | do { 21 | NSCAssert(ptr != end, @"Malformed uleb128", nil); 22 | 23 | //NSLog(@"byte: %02x", *ptr); 24 | uint64_t slice = *ptr & 0x7f; 25 | 26 | if (bit >= 64 || slice << bit >> bit != slice) { 27 | NSLog(@"uleb128 too big"); 28 | exit(88); 29 | } else { 30 | result |= (slice << bit); 31 | bit += 7; 32 | } 33 | } 34 | while ((*ptr++ & 0x80) != 0); 35 | 36 | *ptrptr = ptr; 37 | return result; 38 | } 39 | 40 | int64_t read_sleb128(const uint8_t **ptrptr, const uint8_t *end) 41 | { 42 | const uint8_t *ptr = *ptrptr; 43 | 44 | int64_t result = 0; 45 | int bit = 0; 46 | uint8_t byte; 47 | 48 | //NSLog(@"read_sleb128()"); 49 | do { 50 | NSCAssert(ptr != end, @"Malformed sleb128", nil); 51 | 52 | byte = *ptr++; 53 | //NSLog(@"%02x", byte); 54 | result |= ((byte & 0x7f) << bit); 55 | bit += 7; 56 | } while ((byte & 0x80) != 0); 57 | 58 | //NSLog(@"result before sign extend: %ld", result); 59 | // sign extend negative numbers 60 | // This essentially clears out from -1 the low order bits we've already set, and combines that with our bits. 61 | if ( (byte & 0x40) != 0 ) 62 | result |= (-1LL) << bit; 63 | 64 | //NSLog(@"result after sign extend: %ld", result); 65 | 66 | //NSLog(@"ptr before: %p, after: %p", *ptrptr, ptr); 67 | *ptrptr = ptr; 68 | return result; 69 | } 70 | -------------------------------------------------------------------------------- /Source/cd_objc2.h: -------------------------------------------------------------------------------- 1 | struct cd_objc2_list_header { 2 | uint32_t entsize; 3 | uint32_t count; 4 | }; 5 | 6 | struct cd_objc2_image_info { 7 | uint32_t version; 8 | uint32_t flags; 9 | }; 10 | 11 | 12 | // 13 | // 64-bit, also holding 32-bit 14 | // 15 | 16 | struct cd_objc2_class { 17 | uint64_t isa; 18 | uint64_t superclass; 19 | uint64_t cache; 20 | uint64_t vtable; 21 | uint64_t data; // points to class_ro_t 22 | uint64_t reserved1; 23 | uint64_t reserved2; 24 | uint64_t reserved3; 25 | }; 26 | 27 | struct cd_objc2_class_ro_t { 28 | uint32_t flags; 29 | uint32_t instanceStart; 30 | uint32_t instanceSize; 31 | uint32_t reserved; // *** this field does not exist in the 32-bit version *** 32 | uint64_t ivarLayout; 33 | uint64_t name; 34 | uint64_t baseMethods; 35 | uint64_t baseProtocols; 36 | uint64_t ivars; 37 | uint64_t weakIvarLayout; 38 | uint64_t baseProperties; 39 | }; 40 | 41 | struct cd_objc2_method { 42 | uint64_t name; 43 | uint64_t types; 44 | uint64_t imp; 45 | }; 46 | 47 | struct cd_objc2_ivar { 48 | uint64_t offset; 49 | uint64_t name; 50 | uint64_t type; 51 | uint32_t alignment; 52 | uint32_t size; 53 | }; 54 | 55 | struct cd_objc2_property { 56 | uint64_t name; 57 | uint64_t attributes; 58 | }; 59 | 60 | struct cd_objc2_protocol { 61 | uint64_t isa; 62 | uint64_t name; 63 | uint64_t protocols; 64 | uint64_t instanceMethods; 65 | uint64_t classMethods; 66 | uint64_t optionalInstanceMethods; 67 | uint64_t optionalClassMethods; 68 | uint64_t instanceProperties; // So far, always 0 69 | uint32_t size; // sizeof(cd_objc2_protocol) 70 | uint32_t flags; 71 | uint64_t extendedMethodTypes; 72 | }; 73 | 74 | struct cd_objc2_category { 75 | uint64_t name; 76 | uint64_t class; 77 | uint64_t instanceMethods; 78 | uint64_t classMethods; 79 | uint64_t protocols; 80 | uint64_t instanceProperties; 81 | uint64_t v7; 82 | uint64_t v8; 83 | }; 84 | -------------------------------------------------------------------------------- /Source/deprotect-Prefix.pch: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | Copyright 2016 PreEmptive Solutions, LLC 3 | See LICENSE.txt for licensing information 4 | ********************************************/ 5 | 6 | // 7 | // Prefix header for all source files of the 'deprotect' target in the 'deprotect' project 8 | // 9 | 10 | #ifdef __OBJC__ 11 | #import 12 | #import "CDExtensions.h" 13 | #endif 14 | -------------------------------------------------------------------------------- /Symbol mapping/CDSymbolMapper.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class CDSymbolsGeneratorVisitor; 4 | 5 | 6 | @interface CDSymbolMapper : NSObject 7 | 8 | - (void)writeSymbolsFromSymbolsVisitor:(CDSymbolsGeneratorVisitor *)visitor toFile:(NSString *)file; 9 | 10 | - (NSString *)processCrashDump:(NSString *)crashDump withSymbols:(NSDictionary *)symbols; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Symbol mapping/CDSymbolMapper.m: -------------------------------------------------------------------------------- 1 | #import "CDSymbolMapper.h" 2 | #import "CDSymbolsGeneratorVisitor.h" 3 | 4 | @implementation CDSymbolMapper 5 | 6 | - (void)writeSymbolsFromSymbolsVisitor:(CDSymbolsGeneratorVisitor *)visitor toFile:(NSString *)file { 7 | NSMutableDictionary *invertedSymbols = [NSMutableDictionary dictionary]; 8 | for (NSString *key in [visitor.symbols allKeys]) { 9 | invertedSymbols[visitor.symbols[key]] = key; 10 | } 11 | 12 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:invertedSymbols options:NSJSONWritingPrettyPrinted error:nil]; 13 | [jsonData writeToFile:file atomically:YES]; 14 | } 15 | 16 | - (NSString *)processCrashDump:(NSString *)crashDump withSymbols:(NSDictionary *)symbols { 17 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\[.*\\]" options:NSRegularExpressionCaseInsensitive error:nil]; 18 | NSMutableString *mutableCrashDump = [crashDump mutableCopy]; 19 | NSArray *matches = [regex matchesInString:crashDump options:NSMatchingReportCompletion range:NSMakeRange(0, mutableCrashDump.length)]; 20 | for (NSTextCheckingResult *result in matches) { 21 | NSString *match = [crashDump substringWithRange:result.range]; 22 | NSString *symbolicatedCrash = [self realMethodForString:match range:result.range symbols:symbols]; 23 | [mutableCrashDump replaceOccurrencesOfString:match withString:symbolicatedCrash options:0 range:NSMakeRange(0, mutableCrashDump.length)]; 24 | } 25 | return mutableCrashDump; 26 | } 27 | 28 | - (NSString *)realMethodForString:(NSString *)mutableCrashDump range:(NSRange)range symbols:(NSDictionary *)symbols { 29 | NSString *match = mutableCrashDump; 30 | match = [match stringByReplacingOccurrencesOfString:@"[" withString:@""]; 31 | match = [match stringByReplacingOccurrencesOfString:@"]" withString:@""]; 32 | NSArray *components = [match componentsSeparatedByString:@" "]; 33 | NSString *className = [components firstObject]; 34 | 35 | NSString *methodName = [components lastObject]; 36 | NSArray *methodComponents = [methodName componentsSeparatedByString:@":"]; 37 | NSString *realMethodName = @""; 38 | for (NSString *component in methodComponents) { 39 | NSString *symbol = symbols[component]; 40 | if (symbol) { 41 | realMethodName = [NSString stringWithFormat:@"%@:%@", realMethodName, symbol]; 42 | } else { 43 | realMethodName = [NSString stringWithFormat:@"%@:%@", realMethodName, component]; 44 | } 45 | } 46 | if (realMethodName.length > 0) { 47 | realMethodName = [realMethodName substringFromIndex:1]; 48 | } 49 | 50 | NSString *realClassName = className; 51 | NSString *classSymbol = symbols[className]; 52 | if (classSymbol) { 53 | realClassName = classSymbol; 54 | } 55 | return [NSString stringWithFormat:@"[%@ %@]", realClassName, realMethodName]; 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /System Protocols Dumping/CDSystemProtocolsProcessor.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | @interface CDSystemProtocolsProcessor : NSObject 5 | - (id)initWithSdkPath:(NSString *)sdkPath; 6 | - (NSArray *)systemProtocolsSymbolsToExclude; 7 | @end 8 | -------------------------------------------------------------------------------- /System Protocols Dumping/CDSystemProtocolsProcessor.m: -------------------------------------------------------------------------------- 1 | #import "CDSystemProtocolsProcessor.h" 2 | 3 | 4 | @implementation CDSystemProtocolsProcessor { 5 | NSString *_sdkPath; 6 | } 7 | 8 | - (id)initWithSdkPath:(NSString *)sdkPath { 9 | self = [super init]; 10 | if (self) { 11 | _sdkPath = sdkPath; 12 | } 13 | 14 | return self; 15 | } 16 | 17 | - (NSArray *)systemProtocolsSymbolsToExclude { 18 | NSPipe *pipe = [NSPipe pipe]; 19 | NSFileHandle *file = pipe.fileHandleForReading; 20 | 21 | NSTask *task = [[NSTask alloc] init]; 22 | task.launchPath = @"/usr/bin/find"; 23 | task.currentDirectoryPath = [_sdkPath stringByAppendingString:@"/System/Library/Frameworks"]; 24 | task.arguments = @[@".", @"-name", @"*.h", @"-exec", 25 | @"sed", @"-n", @"-e", @"s/.*@protocol[ \\t]*\\([a-zA-Z_][a-zA-Z0-9_]*\\).*/\\1/p", @"{}", @"+"]; 26 | task.environment = @{@"LANG": @"C", 27 | @"LC_CTYPE": @"C", 28 | @"LC_ALL": @"C"}; 29 | task.standardOutput = pipe; 30 | [task launch]; 31 | [task waitUntilExit]; 32 | 33 | NSData *data = [file readDataToEndOfFile]; 34 | [file closeFile]; 35 | 36 | if (data.length) { 37 | NSString *output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 38 | NSMutableSet *set = [NSMutableSet setWithArray:[output componentsSeparatedByString:@"\n"]]; 39 | 40 | // It is possible that this approach to finding the protocols may result in the empty string 41 | // being spuriously included in the list. Remove it. 42 | [set removeObject:@""]; 43 | 44 | // Add NSObject protocol from /usr/include/objc/NSObject.h 45 | [set addObject:@"NSObject"]; 46 | 47 | // In /usr/include/os/object.h there is a #define macro for creating @protocol declarations. 48 | // Resolving what protocols are declared in system headers in this way is outside of scope. 49 | 50 | return [set allObjects]; 51 | } 52 | 53 | return nil; 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /UnitTests/TestCDArchFromName.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import 7 | 8 | #import "CDFile.h" 9 | 10 | @interface TestCDArchFromName : XCTestCase 11 | @end 12 | 13 | @implementation TestCDArchFromName 14 | 15 | - (void)setUp; 16 | { 17 | [super setUp]; 18 | 19 | // Set-up code here. 20 | } 21 | 22 | - (void)tearDown; 23 | { 24 | // Tear-down code here. 25 | 26 | [super tearDown]; 27 | } 28 | 29 | #pragma mark - ARM 30 | 31 | - (void)test_armv6; 32 | { 33 | CDArch arch = CDArchFromName(@"armv6"); 34 | XCTAssertEqual(arch.cputype, CPU_TYPE_ARM, @"The cputype for 'armv6' should be ARM"); 35 | XCTAssertEqual(arch.cpusubtype, CPU_SUBTYPE_ARM_V6, @"The cpusubtype for 'armv6' should be ARM_V6"); 36 | } 37 | 38 | - (void)test_armv7; 39 | { 40 | CDArch arch = CDArchFromName(@"armv7"); 41 | XCTAssertEqual(arch.cputype, CPU_TYPE_ARM, @"The cputype for 'armv7' should be ARM"); 42 | XCTAssertEqual(arch.cpusubtype, CPU_SUBTYPE_ARM_V7, @"The cpusubtype for 'armv7' should be ARM_V7"); 43 | } 44 | 45 | - (void)test_armv7s; 46 | { 47 | CDArch arch = CDArchFromName(@"armv7s"); 48 | XCTAssertEqual(arch.cputype, CPU_TYPE_ARM, @"The cputype for 'armv7s' should be ARM"); 49 | XCTAssertEqual(arch.cpusubtype, 11, @"The cpusubtype for 'armv7s' should be 11"); 50 | } 51 | 52 | - (void)test_arm64; 53 | { 54 | CDArch arch = CDArchFromName(@"arm64"); 55 | XCTAssertEqual(arch.cputype, CPU_TYPE_ARM | CPU_ARCH_ABI64, @"The cputype for 'arm64' should be ARM with 64-bit mask"); 56 | XCTAssertEqual(arch.cpusubtype, CPU_SUBTYPE_ARM_ALL, @"The cpusubtype for 'arm64' should be CPU_SUBTYPE_ARM_ALL"); 57 | } 58 | 59 | #pragma mark - Intel x86 60 | 61 | - (void)test_i386; 62 | { 63 | CDArch arch = CDArchFromName(@"i386"); 64 | XCTAssertEqual(arch.cputype, CPU_TYPE_X86, @"The cputype for 'i386' should be X86"); 65 | XCTAssertEqual(arch.cpusubtype, CPU_SUBTYPE_386, @"The cpusubtype for 'i386' should be 386"); 66 | } 67 | 68 | - (void)test_x86_64; 69 | { 70 | CDArch arch = CDArchFromName(@"x86_64"); 71 | XCTAssertEqual(arch.cputype, CPU_TYPE_X86_64, @"The cputype for 'x86_64' should be X86_64"); 72 | XCTAssertEqual(arch.cpusubtype, CPU_SUBTYPE_386, @"The cpusubtype for 'x86_64' should be 386"); 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /UnitTests/TestCDArchUses64BitABI.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import 7 | 8 | #import "CDFile.h" 9 | 10 | @interface TestCDArchUses64BitABI : XCTestCase 11 | @end 12 | 13 | @implementation TestCDArchUses64BitABI 14 | 15 | - (void)setUp; 16 | { 17 | [super setUp]; 18 | 19 | // Set-up code here. 20 | } 21 | 22 | - (void)tearDown; 23 | { 24 | // Tear-down code here. 25 | 26 | [super tearDown]; 27 | } 28 | 29 | #pragma mark - Intel x86 30 | 31 | - (void)test_i386; 32 | { 33 | CDArch arch = { CPU_TYPE_X86, CPU_SUBTYPE_386 }; 34 | XCTAssertFalse(CDArchUses64BitABI(arch), @"i386 does not use 64 bit ABI"); 35 | } 36 | 37 | - (void)test_x86_64; 38 | { 39 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 }; 40 | XCTAssertTrue(CDArchUses64BitABI(arch), @"x86_64 uses 64 bit ABI"); 41 | } 42 | 43 | - (void)test_x86_64_lib64; 44 | { 45 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 | CPU_SUBTYPE_LIB64 }; 46 | XCTAssertTrue(CDArchUses64BitABI(arch), @"x86_64 (with LIB64 capability bit) uses 64 bit ABI"); 47 | } 48 | 49 | - (void)test_x86_64_plusOtherCapablity 50 | { 51 | CDArch arch = { CPU_TYPE_X86_64 | 0x40000000, CPU_SUBTYPE_386 }; 52 | XCTAssertTrue(CDArchUses64BitABI(arch), @"x86_64 (with other capability bit) uses 64 bit ABI"); 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /UnitTests/TestCDNameForCPUType.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import 7 | 8 | #import "CDFile.h" 9 | 10 | @interface TestCDNameForCPUType : XCTestCase 11 | @end 12 | 13 | @implementation TestCDNameForCPUType 14 | 15 | - (void)setUp; 16 | { 17 | [super setUp]; 18 | 19 | // Set-up code here. 20 | } 21 | 22 | - (void)tearDown; 23 | { 24 | // Tear-down code here. 25 | 26 | [super tearDown]; 27 | } 28 | 29 | #pragma mark - ARM 30 | 31 | - (void)test_armv6; 32 | { 33 | XCTAssertEqualObjects(CDNameForCPUType(CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6), @"armv6", @"The name for ARM subtype CPU_SUBTYPE_ARM_V6 should be 'armv6'"); 34 | } 35 | 36 | - (void)test_armv7; 37 | { 38 | XCTAssertEqualObjects(CDNameForCPUType(CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7), @"armv7", @"The name for ARM subtype CPU_SUBTYPE_ARM_V7 should be 'armv7'"); 39 | } 40 | 41 | - (void)test_armv7s; 42 | { 43 | XCTAssertEqualObjects(CDNameForCPUType(CPU_TYPE_ARM, 11), @"armv7s", @"The name for ARM subtype 11 should be 'armv7s'"); 44 | } 45 | 46 | - (void)test_arm64; 47 | { 48 | XCTAssertEqualObjects(CDNameForCPUType(CPU_TYPE_ARM | CPU_ARCH_ABI64, CPU_SUBTYPE_ARM_ALL), @"arm64", @"The name for ARM 64-bit subtype CPU_SUBTYPE_ARM_ALL should be 'arm64'"); 49 | } 50 | 51 | #pragma mark - Intel x86 52 | 53 | - (void)test_i386; 54 | { 55 | XCTAssertEqualObjects(CDNameForCPUType(CPU_TYPE_X86, CPU_SUBTYPE_386), @"i386", @"The name for X86 subtype CPU_SUBTYPE_386 should be 'i386'"); 56 | } 57 | 58 | - (void)test_x86_64; 59 | { 60 | XCTAssertEqualObjects(CDNameForCPUType(CPU_TYPE_X86_64, CPU_SUBTYPE_386), @"x86_64", @"The name for X86_64 subtype CPU_SUBTYPE_386 should be 'x86_64'"); 61 | } 62 | 63 | - (void)test_x86_64_lib64; 64 | { 65 | XCTAssertEqualObjects(CDNameForCPUType(CPU_TYPE_X86_64, CPU_SUBTYPE_386|CPU_SUBTYPE_LIB64), @"x86_64", @"The name for X86_64 subtype CPU_SUBTYPE_386 with capability bits should be 'x86_64'"); 66 | } 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /UnitTests/TestFatFile_Intel32_64.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | /******************************************** 4 | Copyright 2016 PreEmptive Solutions, LLC 5 | See LICENSE.txt for licensing information 6 | ********************************************/ 7 | 8 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 9 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 10 | 11 | #import 12 | 13 | #import "CDFatArch.h" 14 | #import "CDFatFile.h" 15 | #import "CDMachOFile.h" 16 | 17 | @interface TestFatFile_Intel32_64 : XCTestCase 18 | @end 19 | 20 | @implementation TestFatFile_Intel32_64 21 | { 22 | CDFatFile *_fatFile; 23 | CDFatArch *_arch_i386; 24 | CDFatArch *_arch_x86_64; 25 | CDMachOFile *_macho_i386; 26 | CDMachOFile *_macho_x86_64; 27 | } 28 | 29 | - (void)setUp; 30 | { 31 | [super setUp]; 32 | 33 | // Set-up code here. 34 | _fatFile = [[CDFatFile alloc] init]; 35 | 36 | _macho_i386 = [[CDMachOFile alloc] init]; 37 | _macho_i386.cputype = CPU_TYPE_X86; 38 | _macho_i386.cpusubtype = CPU_SUBTYPE_386; 39 | 40 | _arch_i386 = [[CDFatArch alloc] initWithMachOFile:_macho_i386]; 41 | [_fatFile addArchitecture:_arch_i386]; 42 | 43 | _macho_x86_64 = [[CDMachOFile alloc] init]; 44 | _macho_x86_64.cputype = CPU_TYPE_X86_64; 45 | _macho_x86_64.cpusubtype = CPU_SUBTYPE_386; 46 | 47 | _arch_x86_64 = [[CDFatArch alloc] initWithMachOFile:_macho_x86_64]; 48 | [_fatFile addArchitecture:_arch_x86_64]; 49 | } 50 | 51 | - (void)tearDown; 52 | { 53 | // Tear-down code here. 54 | _fatFile = nil; 55 | _arch_i386 = nil; 56 | _arch_x86_64 = nil; 57 | _macho_i386 = nil; 58 | _macho_x86_64 = nil; 59 | 60 | [super tearDown]; 61 | } 62 | 63 | #pragma mark - 64 | 65 | - (void)test_bestMatchIntel64; 66 | { 67 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 }; 68 | 69 | BOOL result = [_fatFile bestMatchForArch:&arch]; 70 | XCTAssertTrue(result, @"Didn't find a best match for x86_64"); 71 | XCTAssertTrue(arch.cputype == CPU_TYPE_X86_64, @"Best match cputype should be CPU_TYPE_X86_64"); 72 | XCTAssertTrue(arch.cpusubtype == CPU_SUBTYPE_386, @"Best match cpusubtype should be CPU_SUBTYPE_386"); 73 | } 74 | 75 | 76 | - (void)test_machOFileWithArch_x86_64; 77 | { 78 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 }; 79 | CDMachOFile *machOFile = [_fatFile machOFileWithArch:arch]; 80 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil", NULL); 81 | XCTAssertEqual(machOFile, _macho_x86_64, @"Didn't find correct Mach-O file"); 82 | } 83 | 84 | - (void)test_machOFileWithArch_i386; 85 | { 86 | CDArch arch = { CPU_TYPE_X86, CPU_SUBTYPE_386 }; 87 | CDMachOFile *machOFile = [_fatFile machOFileWithArch:arch]; 88 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil"); 89 | XCTAssertEqual(machOFile, _macho_i386, @"Didn't find correct Mach-O file"); 90 | } 91 | 92 | @end 93 | -------------------------------------------------------------------------------- /UnitTests/TestFatFile_Intel32_64_lib64.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | /******************************************** 4 | Copyright 2016 PreEmptive Solutions, LLC 5 | See LICENSE.txt for licensing information 6 | ********************************************/ 7 | 8 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 9 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 10 | 11 | #import 12 | 13 | #import "CDFatArch.h" 14 | #import "CDFatFile.h" 15 | #import "CDMachOFile.h" 16 | 17 | @interface TestFatFile_Intel32_64_lib64 : XCTestCase 18 | @end 19 | 20 | @implementation TestFatFile_Intel32_64_lib64 21 | { 22 | CDFatFile *_fatFile; 23 | CDFatArch *_arch_i386; 24 | CDFatArch *_arch_x86_64; 25 | CDMachOFile *_macho_i386; 26 | CDMachOFile *_macho_x86_64; 27 | } 28 | 29 | - (void)setUp; 30 | { 31 | [super setUp]; 32 | 33 | // Set-up code here. 34 | _fatFile = [[CDFatFile alloc] init]; 35 | 36 | _macho_i386 = [[CDMachOFile alloc] init]; 37 | _macho_i386.cputype = CPU_TYPE_X86; 38 | _macho_i386.cpusubtype = CPU_SUBTYPE_386; 39 | 40 | _arch_i386 = [[CDFatArch alloc] initWithMachOFile:_macho_i386]; 41 | [_fatFile addArchitecture:_arch_i386]; 42 | 43 | _macho_x86_64 = [[CDMachOFile alloc] init]; 44 | _macho_x86_64.cputype = CPU_TYPE_X86_64; 45 | _macho_x86_64.cpusubtype = CPU_SUBTYPE_386 | CPU_SUBTYPE_LIB64; 46 | 47 | _arch_x86_64 = [[CDFatArch alloc] initWithMachOFile:_macho_x86_64]; 48 | [_fatFile addArchitecture:_arch_x86_64]; 49 | } 50 | 51 | - (void)tearDown; 52 | { 53 | // Tear-down code here. 54 | _fatFile = nil; 55 | _arch_i386 = nil; 56 | _arch_x86_64 = nil; 57 | _macho_i386 = nil; 58 | _macho_x86_64 = nil; 59 | 60 | [super tearDown]; 61 | } 62 | 63 | #pragma mark - 64 | 65 | - (void)test_bestMatchIntel64; 66 | { 67 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 }; 68 | 69 | BOOL result = [_fatFile bestMatchForArch:&arch]; 70 | XCTAssertTrue(result, @"Didn't find a best match for x86_64"); 71 | XCTAssertTrue(arch.cputype == CPU_TYPE_X86_64, @"Best match cputype should be CPU_TYPE_X86_64"); 72 | XCTAssertTrue(arch.cpusubtype == (cpu_subtype_t)(CPU_SUBTYPE_386 | CPU_SUBTYPE_LIB64), @"Best match cpusubtype should be CPU_SUBTYPE_386"); 73 | } 74 | 75 | 76 | - (void)test_machOFileWithArch_x86_64; 77 | { 78 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 }; 79 | CDMachOFile *machOFile = [_fatFile machOFileWithArch:arch]; 80 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil", NULL); 81 | XCTAssertEqual(machOFile, _macho_x86_64, @"Didn't find correct Mach-O file"); 82 | } 83 | 84 | - (void)test_machOFileWithArch_i386; 85 | { 86 | CDArch arch = { CPU_TYPE_X86, CPU_SUBTYPE_386 }; 87 | CDMachOFile *machOFile = [_fatFile machOFileWithArch:arch]; 88 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil"); 89 | XCTAssertEqual(machOFile, _macho_i386, @"Didn't find correct Mach-O file"); 90 | } 91 | 92 | @end 93 | -------------------------------------------------------------------------------- /UnitTests/TestFatFile_Intel64_32.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | /******************************************** 4 | Copyright 2016 PreEmptive Solutions, LLC 5 | See LICENSE.txt for licensing information 6 | ********************************************/ 7 | 8 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 9 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 10 | 11 | #import 12 | 13 | #import "CDFatArch.h" 14 | #import "CDFatFile.h" 15 | #import "CDMachOFile.h" 16 | 17 | @interface TestFatFile_Intel64_32 : XCTestCase 18 | @end 19 | 20 | @implementation TestFatFile_Intel64_32 21 | { 22 | CDFatFile *_fatFile; 23 | CDFatArch *_arch_i386; 24 | CDFatArch *_arch_x86_64; 25 | CDMachOFile *_macho_i386; 26 | CDMachOFile *_macho_x86_64; 27 | } 28 | 29 | - (void)setUp; 30 | { 31 | [super setUp]; 32 | 33 | // Set-up code here. 34 | _fatFile = [[CDFatFile alloc] init]; 35 | 36 | _macho_x86_64 = [[CDMachOFile alloc] init]; 37 | _macho_x86_64.cputype = CPU_TYPE_X86_64; 38 | _macho_x86_64.cpusubtype = CPU_SUBTYPE_386; 39 | 40 | _arch_x86_64 = [[CDFatArch alloc] initWithMachOFile:_macho_x86_64]; 41 | [_fatFile addArchitecture:_arch_x86_64]; 42 | 43 | _macho_i386 = [[CDMachOFile alloc] init]; 44 | _macho_i386.cputype = CPU_TYPE_X86; 45 | _macho_i386.cpusubtype = CPU_SUBTYPE_386; 46 | 47 | _arch_i386 = [[CDFatArch alloc] initWithMachOFile:_macho_i386]; 48 | [_fatFile addArchitecture:_arch_i386]; 49 | } 50 | 51 | - (void)tearDown; 52 | { 53 | // Tear-down code here. 54 | _fatFile = nil; 55 | _arch_i386 = nil; 56 | _arch_x86_64 = nil; 57 | _macho_i386 = nil; 58 | _macho_x86_64 = nil; 59 | 60 | [super tearDown]; 61 | } 62 | 63 | #pragma mark - 64 | 65 | - (void)test_bestMatchIntel64; 66 | { 67 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 }; 68 | 69 | BOOL result = [_fatFile bestMatchForArch:&arch]; 70 | XCTAssertTrue(result, @"Didn't find a best match for x86_64"); 71 | XCTAssertTrue(arch.cputype == CPU_TYPE_X86_64, @"Best match cputype should be CPU_TYPE_X86_64"); 72 | XCTAssertTrue(arch.cpusubtype == CPU_SUBTYPE_386, @"Best match cpusubtype should be CPU_SUBTYPE_386"); 73 | } 74 | 75 | - (void)test_machOFileWithArch_x86_64; 76 | { 77 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 }; 78 | CDMachOFile *machOFile = [_fatFile machOFileWithArch:arch]; 79 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil", NULL); 80 | XCTAssertEqual(machOFile, _macho_x86_64, @"Didn't find correct Mach-O file", NULL); 81 | } 82 | 83 | - (void)test_machOFileWithArch_i386; 84 | { 85 | CDArch arch = { CPU_TYPE_X86, CPU_SUBTYPE_386 }; 86 | CDMachOFile *machOFile = [_fatFile machOFileWithArch:arch]; 87 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil", NULL); 88 | XCTAssertEqual(machOFile, _macho_i386, @"Didn't find correct Mach-O file"); 89 | } 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /UnitTests/TestFatFile_armv7_v7s.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import 7 | 8 | #import "CDFatArch.h" 9 | #import "CDFatFile.h" 10 | #import "CDMachOFile.h" 11 | 12 | @interface TestFatFile_armv7_v7s : XCTestCase 13 | @end 14 | 15 | @implementation TestFatFile_armv7_v7s 16 | { 17 | CDFatFile *_fatFile; 18 | CDFatArch *_arch_v7; 19 | CDFatArch *_arch_v7s; 20 | CDMachOFile *_macho_v7; 21 | CDMachOFile *_macho_v7s; 22 | } 23 | 24 | - (void)setUp; 25 | { 26 | [super setUp]; 27 | 28 | // Set-up code here. 29 | _fatFile = [[CDFatFile alloc] init]; 30 | 31 | _macho_v7 = [[CDMachOFile alloc] init]; 32 | _macho_v7.cputype = CPU_TYPE_ARM; 33 | _macho_v7.cpusubtype = CPU_SUBTYPE_ARM_V7; 34 | 35 | _arch_v7 = [[CDFatArch alloc] initWithMachOFile:_macho_v7]; 36 | [_fatFile addArchitecture:_arch_v7]; 37 | 38 | _macho_v7s = [[CDMachOFile alloc] init]; 39 | _macho_v7s.cputype = CPU_TYPE_ARM; 40 | _macho_v7s.cpusubtype = 11; 41 | 42 | _arch_v7s = [[CDFatArch alloc] initWithMachOFile:_macho_v7s]; 43 | [_fatFile addArchitecture:_arch_v7s]; 44 | } 45 | 46 | - (void)tearDown; 47 | { 48 | // Tear-down code here. 49 | _fatFile = nil; 50 | _arch_v7 = nil; 51 | _arch_v7s = nil; 52 | _macho_v7 = nil; 53 | _macho_v7s = nil; 54 | 55 | [super tearDown]; 56 | } 57 | 58 | #pragma mark - 59 | 60 | - (void)test_machOFileWithArch_armv7; 61 | { 62 | CDArch arch = { CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 }; 63 | CDMachOFile *machOFile = [_fatFile machOFileWithArch:arch]; 64 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil", NULL); 65 | XCTAssertEqual(machOFile, _macho_v7, @"Didn't find correct Mach-O file"); 66 | } 67 | 68 | - (void)test_machOFileWithArch_armv7s; 69 | { 70 | CDArch arch = { CPU_TYPE_ARM, 11 }; 71 | CDMachOFile *machOFile = [_fatFile machOFileWithArch:arch]; 72 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil"); 73 | XCTAssertEqual(machOFile, _macho_v7s, @"Didn't find correct Mach-O file"); 74 | } 75 | 76 | @end 77 | -------------------------------------------------------------------------------- /UnitTests/TestThinFile_Intel64.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import 7 | 8 | #import "CDFatArch.h" 9 | #import "CDFatFile.h" 10 | #import "CDMachOFile.h" 11 | 12 | @interface TestThinFile_Intel64 : XCTestCase 13 | @end 14 | 15 | @implementation TestThinFile_Intel64 16 | { 17 | CDMachOFile *_macho_x86_64; 18 | } 19 | 20 | - (void)setUp; 21 | { 22 | [super setUp]; 23 | 24 | // Set-up code here. 25 | _macho_x86_64 = [[CDMachOFile alloc] init]; 26 | _macho_x86_64.cputype = CPU_TYPE_X86_64; 27 | _macho_x86_64.cpusubtype = CPU_SUBTYPE_386; 28 | } 29 | 30 | - (void)tearDown; 31 | { 32 | // Tear-down code here. 33 | _macho_x86_64 = nil; 34 | 35 | [super tearDown]; 36 | } 37 | 38 | #pragma mark - 39 | 40 | - (void)test_bestMatchIntel64; 41 | { 42 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 }; 43 | 44 | BOOL result = [_macho_x86_64 bestMatchForArch:&arch]; 45 | XCTAssertTrue(result, @"Didn't find a best match for x86_64"); 46 | XCTAssertTrue(arch.cputype == CPU_TYPE_X86_64, @"Best match cputype should be CPU_TYPE_X86_64"); 47 | XCTAssertTrue(arch.cpusubtype == CPU_SUBTYPE_386, @"Best match cpusubtype should be CPU_SUBTYPE_386"); 48 | } 49 | 50 | - (void)test_machOFileWithArch_x86_64; 51 | { 52 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 }; 53 | CDMachOFile *machOFile = [_macho_x86_64 machOFileWithArch:arch]; 54 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil", NULL); 55 | XCTAssertEqual(machOFile, _macho_x86_64, @"Didn't find correct Mach-O file", NULL); 56 | } 57 | 58 | - (void)test_machOFileWithArch_i386; 59 | { 60 | CDArch arch = { CPU_TYPE_X86, CPU_SUBTYPE_386 }; 61 | CDMachOFile *machOFile = [_macho_x86_64 machOFileWithArch:arch]; 62 | XCTAssertNil(machOFile, @"The Mach-O file should be nil", NULL); 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /UnitTests/TestThinFile_Intel64_lib64.m: -------------------------------------------------------------------------------- 1 | // -*- mode: ObjC -*- 2 | 3 | // This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files. 4 | // Copyright (C) 1997-1998, 2000-2001, 2004-2015 Steve Nygard. 5 | 6 | #import 7 | 8 | #import "CDFatArch.h" 9 | #import "CDFatFile.h" 10 | #import "CDMachOFile.h" 11 | 12 | @interface TestThinFile_Intel64_lib64 : XCTestCase 13 | @end 14 | 15 | @implementation TestThinFile_Intel64_lib64 16 | { 17 | CDMachOFile *_macho_x86_64; 18 | } 19 | 20 | - (void)setUp; 21 | { 22 | [super setUp]; 23 | 24 | // Set-up code here. 25 | _macho_x86_64 = [[CDMachOFile alloc] init]; 26 | _macho_x86_64.cputype = CPU_TYPE_X86_64; 27 | _macho_x86_64.cpusubtype = CPU_SUBTYPE_386 | CPU_SUBTYPE_LIB64; // For example, /Applications/Utilities/Grab.app on 10.8 28 | } 29 | 30 | - (void)tearDown; 31 | { 32 | // Tear-down code here. 33 | _macho_x86_64 = nil; 34 | 35 | [super tearDown]; 36 | } 37 | 38 | #pragma mark - 39 | 40 | - (void)test_bestMatchIntel64; 41 | { 42 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 }; 43 | 44 | BOOL result = [_macho_x86_64 bestMatchForArch:&arch]; 45 | XCTAssertTrue(result, @"Didn't find a best match for x86_64"); 46 | XCTAssertTrue(arch.cputype == CPU_TYPE_X86_64, @"Best match cputype should be CPU_TYPE_X86_64"); 47 | XCTAssertTrue(arch.cpusubtype == (cpu_subtype_t)(CPU_SUBTYPE_386 | CPU_SUBTYPE_LIB64), @"Best match cpusubtype should be CPU_SUBTYPE_386"); 48 | } 49 | 50 | - (void)test_machOFileWithArch_x86_64; 51 | { 52 | CDArch arch = { CPU_TYPE_X86_64, CPU_SUBTYPE_386 }; 53 | CDMachOFile *machOFile = [_macho_x86_64 machOFileWithArch:arch]; 54 | XCTAssertNotNil(machOFile, @"The Mach-O file shouldn't be nil", NULL); 55 | XCTAssertEqual(machOFile, _macho_x86_64, @"Didn't find correct Mach-O file", NULL); 56 | } 57 | 58 | - (void)test_machOFileWithArch_i386; 59 | { 60 | CDArch arch = { CPU_TYPE_X86, CPU_SUBTYPE_386 }; 61 | CDMachOFile *machOFile = [_macho_x86_64 machOFileWithArch:arch]; 62 | XCTAssertNil(machOFile, @"The Mach-O file should be nil", NULL); 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /UnitTests/UnitTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /UnitTests/UnitTests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #endif 10 | -------------------------------------------------------------------------------- /UnitTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /ppios-rename Spec/CDCoreDataModelParserSpec.m: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | Copyright 2016 PreEmptive Solutions, LLC 3 | See LICENSE.txt for licensing information 4 | ********************************************/ 5 | 6 | #import 7 | 8 | #import "CDCoreDataModelParser.h" 9 | 10 | SPEC_BEGIN(CDCoreDataModelParserSpec) 11 | 12 | describe(@"CDCoreDataModelParser", ^{ 13 | __block CDCoreDataModelParser *parser; 14 | 15 | 16 | __block NSURL *fileUrl; 17 | NSString *className = @"TestEntityA"; 18 | NSString *parentClass = @"TestParentEntity"; 19 | 20 | beforeEach(^{ 21 | parser = [[CDCoreDataModelParser alloc] init]; 22 | for (NSBundle *bundle in [NSBundle allBundles]) { 23 | NSURL *url = [bundle URLForResource:@"contents" withExtension:nil]; 24 | if (url) { 25 | fileUrl = url; 26 | } 27 | } 28 | }); 29 | 30 | describe(@"parsing core data model", ^{ 31 | it(@"should generate symbol for class name", ^{ 32 | NSArray *symbols = [parser symbolsInData:[NSData dataWithContentsOfURL:fileUrl]]; 33 | 34 | [[symbols should] contain:[NSString stringWithFormat:@"!%@", className]]; 35 | }); 36 | 37 | it(@"should generate symbol for parent class name", ^{ 38 | NSArray *symbols = [parser symbolsInData:[NSData dataWithContentsOfURL:fileUrl]]; 39 | 40 | [[symbols should] contain:[NSString stringWithFormat:@"!%@", parentClass]]; 41 | }); 42 | }); 43 | }); 44 | 45 | SPEC_END 46 | -------------------------------------------------------------------------------- /ppios-rename Spec/CDSymbolsMapperSpec.m: -------------------------------------------------------------------------------- 1 | /******************************************** 2 | Copyright 2016 PreEmptive Solutions, LLC 3 | See LICENSE.txt for licensing information 4 | ********************************************/ 5 | 6 | #import 7 | 8 | #import "CDSymbolMapper.h" 9 | 10 | SPEC_BEGIN(CDSymbolMapperSpec) 11 | 12 | describe(@"CDSymbolMapper", ^{ 13 | __block CDSymbolMapper *mapper; 14 | 15 | beforeEach(^{ 16 | mapper = [[CDSymbolMapper alloc] init]; 17 | }); 18 | 19 | describe(@"processing crash dump", ^{ 20 | 21 | NSString *className = @"TestClass"; 22 | NSString *obfuscatedClass = @"abc"; 23 | NSString *methodName = @"initWithSomething"; 24 | NSString *obfusctedMethodName = @"cde"; 25 | NSString *unknownMethod = @"count"; 26 | 27 | NSString *otherClassName = @"TestClass2"; 28 | NSString *otherObfuscatedClass = @"abcd"; 29 | NSString *otherMethodName = @"initWithSomethingElse"; 30 | NSString *otherObfuscatedMethodName = @"cde2"; 31 | 32 | NSString *crashDump = [NSString stringWithFormat:@"-[%@ %@:%@:]\n-[%@ %@:]", obfuscatedClass, obfusctedMethodName, unknownMethod, otherObfuscatedClass, otherObfuscatedMethodName]; 33 | NSString *realName = [NSString stringWithFormat:@"-[%@ %@:%@:]\n-[%@ %@:]", className, methodName, unknownMethod, otherClassName, otherMethodName]; 34 | NSDictionary *symbols = @{ 35 | obfuscatedClass : className, 36 | obfusctedMethodName : methodName, 37 | otherObfuscatedClass : otherClassName, 38 | otherObfuscatedMethodName : otherMethodName 39 | }; 40 | 41 | it(@"should replace known symbols", ^{ 42 | NSString *result = [mapper processCrashDump:crashDump withSymbols:symbols]; 43 | 44 | [[result shouldNot] beNil]; 45 | NSUInteger classLocation = [result rangeOfString:className].location; 46 | [[theValue(classLocation) shouldNot] equal:theValue(NSNotFound)]; 47 | 48 | NSUInteger methodLocation = [result rangeOfString:methodName].location; 49 | [[theValue(methodLocation) shouldNot] equal:theValue(NSNotFound)]; 50 | }); 51 | 52 | it(@"should not replace unknown symbols", ^{ 53 | NSString *result = [mapper processCrashDump:crashDump withSymbols:symbols]; 54 | 55 | [[result shouldNot] beNil]; 56 | NSUInteger classLocation = [result rangeOfString:unknownMethod].location; 57 | [[theValue(classLocation) shouldNot] equal:theValue(NSNotFound)]; 58 | }); 59 | 60 | it(@"should replace all symbols according to the map", ^{ 61 | NSString *result = [mapper processCrashDump:crashDump withSymbols:symbols]; 62 | 63 | [[result shouldNot] beNil]; 64 | [[result should] equal:realName]; 65 | }); 66 | }); 67 | }); 68 | 69 | SPEC_END 70 | -------------------------------------------------------------------------------- /ppios-rename Spec/CDSystemProtocolsProcessorSpec.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import "CDSystemProtocolsProcessor.h" 3 | 4 | SPEC_BEGIN(CDSystemProtocolsProcessorSpec) 5 | describe(@"CDSystemProtocolsProcessor", ^{ 6 | __block CDSystemProtocolsProcessor* parser; 7 | 8 | beforeEach(^{ 9 | // This is an integration test disguised as a unit test -- not everyone has Xcode at the default location. 10 | NSPipe *pipe = [NSPipe pipe]; 11 | NSFileHandle *handle = pipe.fileHandleForReading; 12 | 13 | NSTask *task = [NSTask new]; 14 | task.launchPath = @"/usr/bin/xcode-select"; 15 | task.arguments = @[@"-p"]; 16 | task.standardOutput = pipe; 17 | 18 | [task launch]; 19 | 20 | NSData *xcodePathData = [handle readDataToEndOfFile]; 21 | [handle closeFile]; 22 | 23 | NSString *xcodePathRaw = [[NSString alloc] initWithData:xcodePathData encoding:NSUTF8StringEncoding]; 24 | NSString *xcodePath = [xcodePathRaw stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 25 | NSArray *sdkRoots = @[[xcodePath stringByAppendingString:@"/Platforms/iPhoneOS.platform/Developer/SDKs/"], 26 | @"/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/"]; 27 | 28 | for (NSString *sdkRoot in sdkRoots) { 29 | NSArray* sdkPaths = [[NSFileManager defaultManager] 30 | contentsOfDirectoryAtPath:sdkRoot 31 | error:NULL]; 32 | 33 | for (NSString *sdkPath in sdkPaths) { 34 | if ([sdkPath hasPrefix:@"iPhoneOS"]) { 35 | parser = [[CDSystemProtocolsProcessor alloc] initWithSdkPath:[sdkRoot stringByAppendingString:sdkPath]]; 36 | return; 37 | } 38 | } 39 | } 40 | }); 41 | 42 | describe(@"retrieving protocol symbols to exclude", ^{ 43 | __block NSArray *symbols; 44 | beforeAll(^{ 45 | symbols = [parser systemProtocolsSymbolsToExclude]; 46 | }); 47 | 48 | it(@"should contain UIWebViewDelegate, UIPickerViewDelegate, UITableViewDelegate, UITableViewDataSource, UINavigationControllerDelegate", ^{ 49 | [[symbols should] contain:@"UIWebViewDelegate"]; 50 | [[symbols should] contain:@"UIPickerViewDelegate"]; 51 | [[symbols should] contain:@"UITableViewDelegate"]; 52 | [[symbols should] contain:@"UITableViewDataSource"]; 53 | [[symbols should] contain:@"UINavigationControllerDelegate"]; 54 | }); 55 | }); 56 | }); 57 | SPEC_END 58 | -------------------------------------------------------------------------------- /ppios-rename Spec/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ppios-rename-Prefix.pch: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | Copyright 2016-2017 PreEmptive Solutions, LLC 3 | See LICENSE.txt for licensing information 4 | *************************************************/ 5 | 6 | // 7 | // Prefix header for all source files of the 'ppios-rename' target in the 'ppios-rename' project. 8 | // 9 | 10 | #ifdef __OBJC__ 11 | #import 12 | #import "CDExtensions.h" 13 | #define __cmd __PRETTY_FUNCTION__ 14 | #endif 15 | -------------------------------------------------------------------------------- /ppios-rename.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ppios-rename.xcodeproj/project.xcworkspace/xcshareddata/class-dump.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 8915283E-924B-4880-A1E8-0907F2008DB6 9 | IDESourceControlProjectName 10 | class-dump 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 45528B6B-D07A-4F2D-A84A-EC3FA5E78900 14 | ssh://github.com/preemptive/ppios-rename.git 15 | 16 | IDESourceControlProjectPath 17 | class-dump.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 45528B6B-D07A-4F2D-A84A-EC3FA5E78900 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | ssh://github.com/preemptive/ppios-rename.git 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | 45528B6B-D07A-4F2D-A84A-EC3FA5E78900 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 45528B6B-D07A-4F2D-A84A-EC3FA5E78900 36 | IDESourceControlWCCName 37 | class-dump 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /ppios-rename.xcodeproj/project.xcworkspace/xcuserdata/nygard.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceUserSettings_BuildLocationStyle 6 | 0 7 | IDEWorkspaceUserSettings_BuildSubfolderNameStyle 8 | 0 9 | IDEWorkspaceUserSettings_DerivedDataLocationStyle 10 | 0 11 | IDEWorkspaceUserSettings_HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 12 | 13 | IDEWorkspaceUserSettings_IssueFilterStyle 14 | 0 15 | IDEWorkspaceUserSettings_LiveSourceIssuesEnabled 16 | 17 | IDEWorkspaceUserSettings_SnapshotAutomaticallyBeforeSignificantChanges 18 | 19 | IDEWorkspaceUserSettings_SnapshotLocationStyle 20 | 0 21 | 22 | 23 | -------------------------------------------------------------------------------- /ppios-rename.xcodeproj/xcshareddata/xcschemes/MachObjC.xcscheme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/preemptive/PPiOS-Rename/2c17ee25c41da70860acbb5f440357c7db8f55ef/ppios-rename.xcodeproj/xcshareddata/xcschemes/MachObjC.xcscheme -------------------------------------------------------------------------------- /ppios-rename.xcodeproj/xcuserdata/nygard.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MachObjC.xcscheme 8 | 9 | orderHint 10 | 1 11 | 12 | all.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | class-dump.xcscheme 18 | 19 | orderHint 20 | 2 21 | 22 | deprotect.xcscheme 23 | 24 | orderHint 25 | 3 26 | 27 | formatType.xcscheme 28 | 29 | orderHint 30 | 4 31 | 32 | 33 | SuppressBuildableAutocreation 34 | 35 | 011E483D1604DF3700722F8D 36 | 37 | primary 38 | 39 | 40 | 012FF1890CDB886C00F31E61 41 | 42 | primary 43 | 44 | 45 | 013182B00CDF6EE400EC5A2C 46 | 47 | primary 48 | 49 | 50 | 013D1EFA13A5A0F100BF0A67 51 | 52 | primary 53 | 54 | 55 | 013D1F1013A5AE5A00BF0A67 56 | 57 | primary 58 | 59 | 60 | 013E8CE814EA0285002BDB6D 61 | 62 | primary 63 | 64 | 65 | 013E8CEE14EA04E0002BDB6D 66 | 67 | primary 68 | 69 | 70 | 01549F710903BF88002FA8F1 71 | 72 | primary 73 | 74 | 75 | 0165B8B01827137D00CC647F 76 | 77 | primary 78 | 79 | 80 | 01A9A4BC0FF19B2F00475772 81 | 82 | primary 83 | 84 | 85 | 01A9A4C40FF19BAE00475772 86 | 87 | primary 88 | 89 | 90 | 01B02CFE13A5B0DC0047BC53 91 | 92 | primary 93 | 94 | 95 | 01B02D2E13A5B5D50047BC53 96 | 97 | primary 98 | 99 | 100 | 01EB825E13A590D9003EDE60 101 | 102 | primary 103 | 104 | 105 | 01F5238E1001D19A0006B272 106 | 107 | primary 108 | 109 | 110 | 01F524FF1001F3E60006B272 111 | 112 | primary 113 | 114 | 115 | 8DD76F960486AA7600D96B5E 116 | 117 | primary 118 | 119 | 120 | DAF6959411E62A4F009AF361 121 | 122 | primary 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | /results/ 2 | -------------------------------------------------------------------------------- /test/apps/BoxSim-support/BoxSim.app.dSYM/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIdentifier 8 | com.apple.xcode.dsym.com.preemptive.ppios.test.BoxSim 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundlePackageType 12 | dSYM 13 | CFBundleSignature 14 | ???? 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleVersion 18 | 1 19 | 20 | 21 | -------------------------------------------------------------------------------- /test/apps/BoxSim-support/BoxSim.app.dSYM/Contents/Resources/DWARF/BoxSim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/preemptive/PPiOS-Rename/2c17ee25c41da70860acbb5f440357c7db8f55ef/test/apps/BoxSim-support/BoxSim.app.dSYM/Contents/Resources/DWARF/BoxSim -------------------------------------------------------------------------------- /test/apps/BoxSim-support/README: -------------------------------------------------------------------------------- 1 | #Copyright 2016-2017 PreEmptive Solutions, LLC 2 | #See LICENSE.txt for licensing information 3 | 4 | In order to regenerate the contents of this directory: 5 | 6 | 1. Prepare the test sources: 7 | cd test/apps/BoxSim 8 | make build 9 | ppios-rename --analyze -F '!BSClassO' build/Build/Products/Release-iphoneos/BoxSim.app 10 | ppios-rename --obfuscate-sources 11 | 12 | 2. In Xcode, archive the project (You may need to add signing credentials). 13 | 3. Export to an .ipa, without rebuilding from bitcode. 14 | 4. Deploy to a device via iTunes. 15 | 5. Invoke a crash by tapping "Just Go" three times. 16 | 6. In Xcode, review the crash logs on the device. 17 | 7. Select the crash log, very quickly copy the unsymbolicated text with Command-A, Command-C, and paste this into 'unsymbolicated.crash'. 18 | 8. Wait for Xcode to symbolicate the crash and copy that text to 'symbolicated.crash'. 19 | 9. Copy the .dSYM from the archives (~/Library/Developer/Xcode/Archives/{Date}/BoxSim {Date}, {Time}.xcarchive/dSYMs/BoxSim.app.dSYM). 20 | -------------------------------------------------------------------------------- /test/apps/BoxSim/BoxSim-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // BoxSim-Prefix.pch 3 | // BoxSim 4 | // 5 | // Created by Mike Richter on 4/13/16. 6 | // Copyright © 2016 PreEmptive Solutions LLC. All rights reserved. 7 | // 8 | 9 | #ifndef BoxSim_Prefix_pch 10 | #define BoxSim_Prefix_pch 11 | 12 | // Include any system framework and library headers here that should be included in all compilation units. 13 | // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. 14 | 15 | #endif /* BoxSim_Prefix_pch */ 16 | -------------------------------------------------------------------------------- /test/apps/BoxSim/BoxSim.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/apps/BoxSim/BoxSim/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // BoxSim 4 | // 5 | // Copyright 2016 PreEmptive Solutions, LLC 6 | // See LICENSE.txt for licensing information 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (strong, nonatomic) UIWindow *window; 15 | 16 | @property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext; 17 | @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel; 18 | @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; 19 | 20 | - (void)saveContext; 21 | - (NSURL *)applicationDocumentsDirectory; 22 | 23 | 24 | @end 25 | 26 | -------------------------------------------------------------------------------- /test/apps/BoxSim/BoxSim/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "83.5x83.5", 66 | "scale" : "2x" 67 | } 68 | ], 69 | "info" : { 70 | "version" : 1, 71 | "author" : "xcode" 72 | } 73 | } -------------------------------------------------------------------------------- /test/apps/BoxSim/BoxSim/Base.lproj/LaunchScreen.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 | -------------------------------------------------------------------------------- /test/apps/BoxSim/BoxSim/BoxSim.xcdatamodeld/.xccurrentversion: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | _XCCurrentVersionName 6 | BoxSim.xcdatamodel 7 | 8 | 9 | -------------------------------------------------------------------------------- /test/apps/BoxSim/BoxSim/BoxSim.xcdatamodeld/BoxSim.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /test/apps/BoxSim/BoxSim/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /test/apps/BoxSim/BoxSim/TextDisplay.h: -------------------------------------------------------------------------------- 1 | // 2 | // TextDisplay.h 3 | // BoxSim 4 | // 5 | // Copyright 2016 PreEmptive Solutions, LLC 6 | // See LICENSE.txt for licensing information 7 | // 8 | 9 | #ifndef TextDisplay_h 10 | #define TextDisplay_h 11 | 12 | @interface TextDisplay : NSObject 13 | - (void)write:(NSString *)text; 14 | @end 15 | 16 | #endif // TextDisplay_h 17 | -------------------------------------------------------------------------------- /test/apps/BoxSim/BoxSim/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // BoxSim 4 | // 5 | // Copyright 2016 PreEmptive Solutions, LLC 6 | // See LICENSE.txt for licensing information 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /test/apps/BoxSim/BoxSimTests/BoxSimTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // BoxSimTests.m 3 | // BoxSimTests 4 | // 5 | // Copyright 2016 PreEmptive Solutions, LLC 6 | // See LICENSE.txt for licensing information 7 | // 8 | 9 | #import 10 | 11 | @interface BoxSimTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation BoxSimTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /test/apps/BoxSim/BoxSimTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /test/apps/BoxSim/BoxSimUITests/BoxSimUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // BoxSimUITests.m 3 | // BoxSimUITests 4 | // 5 | // Copyright 2016 PreEmptive Solutions, LLC 6 | // See LICENSE.txt for licensing information 7 | // 8 | 9 | #import 10 | 11 | @interface BoxSimUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation BoxSimUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /test/apps/BoxSim/BoxSimUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /test/apps/BoxSim/Makefile: -------------------------------------------------------------------------------- 1 | #Copyright 2016 PreEmptive Solutions, LLC 2 | #See LICENSE.txt for licensing information 3 | 4 | buildDir=build 5 | targetName=BoxSim 6 | configuration=Release 7 | targetAppName="$(buildDir)/Build/Products/$(configuration)-iphoneos/$(targetName).app" 8 | 9 | .PHONY: default 10 | default: 11 | @echo "Usage: make " 12 | @echo "" 13 | @echo " buildDir=$(buildDir)" 14 | @echo " targetName=$(targetName)" 15 | @echo " configuration=$(configuration)" 16 | @echo " targetAppName=$(targetAppName)" 17 | @echo "" 18 | @exit 1 19 | 20 | .PHONY: build 21 | build: 22 | xcodebuild \ 23 | -project "$(targetName).xcodeproj" \ 24 | -scheme "$(targetName)" \ 25 | -configuration "$(configuration)" \ 26 | -derivedDataPath $(buildDir) \ 27 | clean build 28 | 29 | .PHONY: show 30 | show: 31 | otool -o -v "$(targetAppName)" | grep 'imp 0x' | grep '\[' | awk '{print $$3 " " $$4}' | sort | uniq 32 | 33 | .PHONY: clean 34 | clean: 35 | $(RM) -r $(buildDir) symbols*.h symbols*.map excludes-*.list 36 | -------------------------------------------------------------------------------- /test/tests/check-documentation.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #Copyright 2016-2018 PreEmptive Solutions, LLC 4 | #See LICENSE.txt for licensing information 5 | 6 | targetAppName=BoxSim 7 | thisDirectory="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 8 | testRoot="$(dirname "${thisDirectory}")" 9 | . "${testRoot}/tests/common.sh" 10 | 11 | oneTimeSetUp() { 12 | checkForPPiOSRename 13 | } 14 | 15 | oneTimeTearDown() { 16 | return 17 | } 18 | 19 | setUp() { 20 | return 21 | } 22 | 23 | tearDown() { 24 | return 25 | } 26 | 27 | TEST "PPiOS-Rename version referenced in README.md is current" 28 | verify test -f "${README}" 29 | verifyFails test -z "${NUMERIC_VERSION}" 30 | 31 | # Find all of the version numbers "x.y.z" in the document, and put them on separate lines. 32 | # Exceptions to the rules about version checking must be handled explicitly. 33 | # Some lines that follow that have trailing backslashes are newlines embedded in the sed 34 | # replacement text, do not indent or otherwise alter. 35 | versionNumbers=$(cat "${README}" \ 36 | | sed -n 's,\([1-9][0-9]*[.][0-9][0-9]*\([.][0-9][0-9]*\)*\),\ 37 | \1\ 38 | ,pg' | grep '[1-9][0-9]*[.][0-9][0-9]*\([.][0-9][0-9]*\)*') 39 | 40 | # Remove all of the instances of the expected version number 41 | badVersionNumbers="$(echo "${versionNumbers}" | grep -v "$(echo "^${NUMERIC_VERSION}\$" | sed 's,[.],[.],g')")" 42 | 43 | # Verify that nothing is left 44 | verify test -z "${badVersionNumbers}" 45 | 46 | report 47 | -------------------------------------------------------------------------------- /test/tests/common-assertions.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env false 2 | # this script is intended to be sourced by other scripts, not run directly 3 | 4 | #Copyright 2017 PreEmptive Solutions, LLC 5 | #See LICENSE.txt for licensing information 6 | 7 | assertDeobfuscatedCrashdump() { 8 | verify grep -- '-\[BSClassP doSomethingP:]' "$1" 9 | verify grep -- '-\[BSClassO doSomethingO:]' "$1" 10 | verify grep -- '+\[BSClassN doSomethingInClassN:]' "$1" 11 | verify grep -- '-\[BSClassM doSomethingM:]' "$1" 12 | verify grep -- '-\[ViewController justGoAction:]' "$1" 13 | } 14 | -------------------------------------------------------------------------------- /test/tests/test-double-obfuscation-protection.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #Copyright 2016 PreEmptive Solutions, LLC 4 | #See LICENSE.txt for licensing information 5 | 6 | targetAppName=BoxSim 7 | thisDirectory="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 8 | testRoot="$(dirname "${thisDirectory}")" 9 | . "${testRoot}/tests/common.sh" 10 | 11 | 12 | original="${apps}/${targetAppName}" 13 | work="${sandbox}/${targetAppName}" 14 | buildLog="${results}/build.log" 15 | buildDir=build 16 | program="${work}/${buildDir}/Build/Products/Release-iphoneos/${targetAppName}.app/${targetAppName}" 17 | 18 | 19 | oneTimeSetUp() { 20 | checkForPPiOSRename 21 | checkOriginalIsClean 22 | } 23 | 24 | oneTimeTearDown() { 25 | rmFromSandbox "${work}" 26 | } 27 | 28 | setUp() { 29 | rsyncInSandbox -a --delete "${original}/" "${work}" 30 | pushd "${work}" > /dev/null 31 | } 32 | 33 | tearDown() { 34 | popd > /dev/null 35 | } 36 | 37 | 38 | TEST "Normal obfuscated build" 39 | run make build 40 | assertSucceeds 41 | run "${PPIOS_RENAME}" --analyze "${program}" 42 | assertSucceeds 43 | run "${PPIOS_RENAME}" --obfuscate-sources 44 | assertSucceeds 45 | run make build 46 | assertSucceeds 47 | run nm "${program}" 48 | verifyFails grep BSClass "${lastRun}" 49 | 50 | TEST "Analyzing obfuscated build fails with error (BAOBA)" 51 | run make build 52 | assertSucceeds 53 | run "${PPIOS_RENAME}" --analyze "${program}" 54 | assertSucceeds 55 | run "${PPIOS_RENAME}" --obfuscate-sources 56 | assertSucceeds 57 | run make build 58 | assertSucceeds 59 | run "${PPIOS_RENAME}" --analyze "${program}" 60 | assertFails 61 | verify grep "Error: Analyzing an already obfuscated binary. This will result in an unobfuscated binary. Please see the documentation for details." "${lastRun}" 62 | 63 | TEST "Analyzing obfuscated build fails with error (BAOBA), even with few symbols" 64 | run make build 65 | assertSucceeds 66 | run "${PPIOS_RENAME}" --analyze -F '!*' -F BSClassB -x BSClassB -x squaredB "${program}" 67 | assertSucceeds 68 | run "${PPIOS_RENAME}" --obfuscate-sources 69 | assertSucceeds 70 | run make build 71 | assertSucceeds 72 | run "${PPIOS_RENAME}" --analyze -F '!*' -F BSClassB -x BSClassB -x squaredB "${program}" 73 | assertFails 74 | verify grep "Error: Analyzing an already obfuscated binary. This will result in an unobfuscated binary. Please see the documentation for details." "${lastRun}" 75 | 76 | TEST "Building double-obfuscated sources yields failing build (BAOAOB)" 77 | verifyFails test -e "${buildDir}" 78 | run make build 79 | assertSucceeds 80 | run "${PPIOS_RENAME}" --analyze "${program}" 81 | assertSucceeds 82 | run "${PPIOS_RENAME}" --obfuscate-sources 83 | assertSucceeds 84 | run "${PPIOS_RENAME}" --analyze "${program}" 85 | assertSucceeds 86 | run "${PPIOS_RENAME}" --obfuscate-sources 87 | assertSucceeds 88 | run make build 89 | assertFails 90 | verify grep "Double obfuscation detected. This will result in an unobfuscated binary. Please see the documentation for details." "${lastRun}" 91 | 92 | report 93 | -------------------------------------------------------------------------------- /test/tests/test-suite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #Copyright 2016 PreEmptive Solutions, LLC 4 | #See LICENSE.txt for licensing information 5 | 6 | set -e 7 | 8 | export PPIOS_RENAME="${PPIOS_RENAME:-ppios-rename}" 9 | echo "Testing:" 10 | type "${PPIOS_RENAME}" | sed 's,.* is , ,' 11 | 12 | ./test-double-obfuscation-protection.sh 13 | ./test-filters-and-exclusions.sh 14 | ./test-new-options.sh 15 | ./test-obfuscate-sources.sh 16 | ./test-post-obfuscation-behavior.sh 17 | ./check-documentation.sh 18 | --------------------------------------------------------------------------------