├── .gitignore ├── README.md ├── Research ├── FIRST-2016-130.pdf ├── ios.png └── macos.png ├── build_debug.sh ├── build_release.sh ├── class-dump-Prefix.pch ├── classdump ├── classdump.h └── classdump.m ├── classdumpc.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ ├── classdumpc-ios.xcscheme │ ├── classdumpc-macos.xcscheme │ ├── classdumpc-tvos.xcscheme │ ├── libclassdump-ios.xcscheme │ └── libclassdump.xcscheme ├── classdumpios ├── .gitignore ├── CDUnitTests-Info.plist ├── CHANGELOG.md ├── Classes │ ├── Core │ │ ├── CDClassDump.h │ │ └── CDClassDump.m │ ├── Cursors │ │ ├── CDDataCursor.h │ │ ├── CDDataCursor.m │ │ ├── CDMachOFileDataCursor.h │ │ └── CDMachOFileDataCursor.m │ ├── Extensions │ │ ├── CDExtensions.h │ │ ├── NSArray-CDExtensions.h │ │ ├── NSArray-CDExtensions.m │ │ ├── NSData+Flip.h │ │ ├── NSData+Flip.mm │ │ ├── NSData-CDExtensions.h │ │ ├── NSData-CDExtensions.m │ │ ├── NSError-CDExtensions.h │ │ ├── NSError-CDExtensions.m │ │ ├── NSScanner-CDExtensions.h │ │ ├── NSScanner-CDExtensions.m │ │ ├── NSString-CDExtensions.h │ │ ├── NSString-CDExtensions.m │ │ └── ext.h │ ├── Extras │ │ ├── ULEB128.h │ │ ├── ULEB128.m │ │ ├── blowfish.c │ │ ├── blowfish.h │ │ └── cd_objc2.h │ ├── FileManagement │ │ ├── CDFatArch.h │ │ ├── CDFatArch.m │ │ ├── CDFatFile.h │ │ ├── CDFatFile.m │ │ ├── CDFile.h │ │ ├── CDFile.m │ │ ├── CDMachOFile.h │ │ └── CDMachOFile.m │ ├── LoadCommands │ │ ├── CDLCBuildVersion.h │ │ ├── CDLCBuildVersion.m │ │ ├── CDLCChainedFixups.h │ │ ├── CDLCChainedFixups.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 │ │ ├── CDLCExportTRIEData.h │ │ ├── CDLCExportTRIEData.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 │ ├── OC │ │ ├── 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 │ ├── ObjC │ │ ├── CDObjectiveC1Processor.h │ │ ├── CDObjectiveC1Processor.m │ │ ├── CDObjectiveC2Processor.h │ │ ├── CDObjectiveC2Processor.m │ │ ├── CDObjectiveCProcessor.h │ │ └── CDObjectiveCProcessor.m │ ├── Structure │ │ ├── CDBalanceFormatter.h │ │ ├── CDBalanceFormatter.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 │ │ ├── CDTopoSortNode.h │ │ ├── CDTopoSortNode.m │ │ └── CDTopologicalSortProtocol.h │ ├── Type │ │ ├── CDMethodType.h │ │ ├── CDMethodType.m │ │ ├── CDType.h │ │ ├── CDType.m │ │ ├── CDTypeController.h │ │ ├── CDTypeController.m │ │ ├── CDTypeFormatter.h │ │ ├── CDTypeFormatter.m │ │ ├── CDTypeLexer.h │ │ ├── CDTypeLexer.m │ │ ├── CDTypeName.h │ │ ├── CDTypeName.m │ │ ├── CDTypeParser.h │ │ └── CDTypeParser.m │ ├── Visitors │ │ ├── CDClassDumpVisitor.h │ │ ├── CDClassDumpVisitor.m │ │ ├── CDClassFrameworkVisitor.h │ │ ├── CDClassFrameworkVisitor.m │ │ ├── CDFindMethodVisitor.h │ │ ├── CDFindMethodVisitor.m │ │ ├── CDMultiFileVisitor.h │ │ ├── CDMultiFileVisitor.m │ │ ├── CDTextClassDumpVisitor.h │ │ ├── CDTextClassDumpVisitor.m │ │ ├── CDVisitor.h │ │ ├── CDVisitor.m │ │ ├── CDVisitorPropertyState.h │ │ └── CDVisitorPropertyState.m │ └── class-dump.m ├── Info.plist ├── MachObjC-Prefix.pch ├── Makefile ├── Makefile.ios ├── README.md ├── classdumpios ├── control ├── ent.plist └── keys.txt └── samples ├── sample.out ├── sample1.out ├── sample3.out ├── sample_ios.out ├── sample_ios_old.out ├── sample_ios_standard.out ├── sample_ios_swift.out ├── sample_macos_normal.out └── sample_swift.out /.gitignore: -------------------------------------------------------------------------------- 1 | PrivateHeaders/ 2 | *.xcodeproj/project.xcworkspace/xcuserdata/*.xcuserdatad/ 3 | *.xcodeproj/xcuserdata/* 4 | build/ 5 | -------------------------------------------------------------------------------- /Research/FIRST-2016-130.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lechium/classdumpios/69313e369d2d3ff9f76d52b5546a38f0e4bcb0e5/Research/FIRST-2016-130.pdf -------------------------------------------------------------------------------- /Research/ios.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lechium/classdumpios/69313e369d2d3ff9f76d52b5546a38f0e4bcb0e5/Research/ios.png -------------------------------------------------------------------------------- /Research/macos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lechium/classdumpios/69313e369d2d3ff9f76d52b5546a38f0e4bcb0e5/Research/macos.png -------------------------------------------------------------------------------- /build_debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/zsh -x 2 | 3 | XCP=$(/usr/bin/which xcpretty) 4 | 5 | if [ -z $XCP ]; then 6 | xcodebuild -target classdumpc -configuration Debug 7 | xcodebuild -target classdump -configuration Debug 8 | xcodebuild -target classdump-ios -configuration Debug 9 | xcodebuild -target classdump-tvos -configuration Debug 10 | xcodebuild -target classdumpc-ios -configuration Debug 11 | xcodebuild -target classdumpc-tvos -configuration Debug 12 | else 13 | xcodebuild -target classdumpc -configuration Debug | $XCP 14 | xcodebuild -target classdump -configuration Debug | $XCP 15 | xcodebuild -target classdump-ios -configuration Debug | $XCP 16 | xcodebuild -target classdump-tvos -configuration Debug | $XCP 17 | xcodebuild -target classdumpc-ios -configuration Debug | $XCP 18 | xcodebuild -target classdumpc-tvos -configuration Debug | $XCP 19 | fi 20 | -------------------------------------------------------------------------------- /build_release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | XCP=$(/usr/bin/which xcpretty) 4 | 5 | if [ -z $XCP ]; then 6 | xcodebuild -target classdumpc -configuration Release 7 | xcodebuild -target classdump -configuration Release 8 | xcodebuild -target classdump-tvos -configuration Release 9 | xcodebuild -target classdump-ios -configuration Release 10 | xcodebuild -target classdumpc-ios -configuration Release 11 | xcodebuild -target classdumpc-tvos -configuration Release 12 | else 13 | xcodebuild -target classdumpc -configuration Release | $XCP 14 | xcodebuild -target classdump -configuration Release | $XCP 15 | xcodebuild -target classdump-ios -configuration Release | $XCP 16 | xcodebuild -target classdump-tvos -configuration Release | $XCP 17 | xcodebuild -target classdumpc-ios -configuration Release | $XCP 18 | xcodebuild -target classdumpc-tvos -configuration Release | $XCP 19 | fi 20 | 21 | rm classdumpc-release 22 | cp build/Release/classdumpc classdumpc-release 23 | -------------------------------------------------------------------------------- /class-dump-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'class-dump' target in the 'class-dump' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import "CDExtensions.h" 8 | #import "CDClassDump.h" 9 | #define DLog(format, ...) CFShow((__bridge CFStringRef)[NSString stringWithFormat:format, ## __VA_ARGS__]); 10 | #define CAUGHT_EXCEPTION_LOG DLog(@"exception caught: %@", exception); 11 | #define CDLLog(L, format, ...) [CDClassDump logLevel:L stringWithFormat:format, ## __VA_ARGS__] 12 | #define CDLog(L, format, ...) [CDClassDump logLevel:L string:[NSString stringWithFormat:format, ## __VA_ARGS__]] 13 | #define VerboseLog(format, ...)CDLog(1,format, ## __VA_ARGS__) 14 | #define InfoLog(format, ...)CDLog(0,format, ## __VA_ARGS__) 15 | //#pragma clang diagnostic push 16 | #pragma clang diagnostic ignored "-Wformat" 17 | #define OLog(a,b) DLog(@"%@: %016llx (%lu)", a, b, b) 18 | #define OILog(a,b) InfoLog(@"%@: %016llx (%lu)", a, b, b) 19 | #define ODLog(a,b) VerboseLog(@"%@: %016llx (%lu)", a, b, b) 20 | //#pragma clang diagnostic pop 21 | #define ILOG_CMD InfoLog(@"%s", __PRETTY_FUNCTION__) 22 | #define VLOG_CMD VerboseLog(@"%s", __PRETTY_FUNCTION__) 23 | #define LOG_CMD DLog(@"%s", __PRETTY_FUNCTION__) 24 | #define _cmds __PRETTY_FUNCTION__ 25 | #endif 26 | -------------------------------------------------------------------------------- /classdump/classdump.h: -------------------------------------------------------------------------------- 1 | // 2 | // classdump.h 3 | // classdump 4 | // 5 | // Created by Kevin Bradley on 6/21/22. 6 | // 7 | 8 | #import 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #import "NSString-CDExtensions.h" 19 | 20 | #import "CDClassDump.h" 21 | #import "CDFindMethodVisitor.h" 22 | #import "CDClassDumpVisitor.h" 23 | #import "CDMultiFileVisitor.h" 24 | #import "CDFile.h" 25 | #import "CDMachOFile.h" 26 | #import "CDFatFile.h" 27 | #import "CDFatArch.h" 28 | #import "CDSearchPathState.h" 29 | 30 | @interface classdump : NSObject 31 | @property (readwrite, assign) BOOL verbose; 32 | + (id)sharedInstance; 33 | - (NSInteger)performClassDumpOnFile:(NSString *)file withEntitlements:(BOOL)dumpEnt toFolder:(NSString *)outputPath; 34 | - (NSInteger)performClassDumpOnFile:(NSString *)file toFolder:(NSString *)outputPath; 35 | - (CDClassDump *)classDumpInstanceFromFile:(NSString *)file; 36 | - (NSDictionary *)getFileEntitlements:(NSString *)file; 37 | @end 38 | -------------------------------------------------------------------------------- /classdumpc.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /classdumpc.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /classdumpc.xcodeproj/xcshareddata/xcschemes/classdumpc-ios.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /classdumpc.xcodeproj/xcshareddata/xcschemes/classdumpc-macos.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /classdumpc.xcodeproj/xcshareddata/xcschemes/classdumpc-tvos.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /classdumpc.xcodeproj/xcshareddata/xcschemes/libclassdump-ios.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /classdumpc.xcodeproj/xcshareddata/xcschemes/libclassdump.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 57 | 58 | 59 | 60 | 62 | 63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /classdumpios/.gitignore: -------------------------------------------------------------------------------- 1 | .theos 2 | .vscode 3 | packages -------------------------------------------------------------------------------- /classdumpios/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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Core/CDClassDump.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-2019 Steve Nygard. 5 | 6 | #include 7 | #import "CDFile.h" // For CDArch 8 | #import "CDFindMethodVisitor.h" 9 | #import "CDClassDumpVisitor.h" 10 | #import "CDMultiFileVisitor.h" 11 | #import "CDFile.h" 12 | #import "CDMachOFile.h" 13 | #import "CDFatFile.h" 14 | #import "CDFatArch.h" 15 | #import "CDSearchPathState.h" 16 | 17 | #define CLASS_DUMP_BASE_VERSION "4.2.0 (64 bit)" 18 | 19 | #ifdef DEBUG 20 | #define CLASS_DUMP_VERSION CLASS_DUMP_BASE_VERSION " (iOS port by DreamDevLost, Updated by Kevin Bradley.)(Debug version compiled " __DATE__ " " __TIME__ ")" 21 | #else 22 | #define CLASS_DUMP_VERSION CLASS_DUMP_BASE_VERSION 23 | #endif 24 | 25 | @class CDFile; 26 | @class CDTypeController; 27 | @class CDVisitor; 28 | @class CDSearchPathState; 29 | 30 | @interface CDClassDump : NSObject 31 | 32 | @property (readonly) CDSearchPathState *searchPathState; 33 | 34 | @property (assign) BOOL shouldProcessRecursively; 35 | @property (assign) BOOL shouldSortClasses; 36 | @property (assign) BOOL shouldSortClassesByInheritance; 37 | @property (assign) BOOL shouldSortMethods; 38 | @property (assign) BOOL shouldShowIvarOffsets; 39 | @property (assign) BOOL shouldShowMethodAddresses; 40 | @property (assign) BOOL shouldShowHeader; 41 | @property (assign) BOOL verbose; 42 | @property (assign) BOOL stopAfterPreProcessor; 43 | @property (assign) BOOL shallow; 44 | @property (assign) BOOL dumpEntitlements; 45 | 46 | @property (strong) NSRegularExpression *regularExpression; 47 | - (BOOL)shouldShowName:(NSString *)name; 48 | 49 | @property (strong) NSString *sdkRoot; 50 | 51 | @property (readonly) NSArray *machOFiles; 52 | @property (readonly) NSArray *objcProcessors; 53 | 54 | @property (assign) CDArch targetArch; 55 | 56 | @property (nonatomic, readonly) BOOL containsObjectiveCData; 57 | @property (nonatomic, readonly) BOOL hasEncryptedFiles; 58 | @property (nonatomic, readonly) BOOL hasObjectiveCRuntimeInfo; 59 | 60 | @property (readonly) CDTypeController *typeController; 61 | 62 | - (BOOL)loadFile:(CDFile *)file error:(NSError **)error; 63 | - (void)processObjectiveCData; 64 | 65 | - (void)recursivelyVisit:(CDVisitor *)visitor; 66 | 67 | - (void)appendHeaderToString:(NSMutableString *)resultString; 68 | 69 | - (void)registerTypes; 70 | 71 | - (void)showHeader; 72 | - (void)showLoadCommands; 73 | + (void)logLevel:(NSInteger)level stringWithFormat:(NSString *)fmt, ...; 74 | + (void)logLevel:(NSInteger)level string:(NSString *)string; 75 | + (BOOL)isVerbose; 76 | + (BOOL)isDebug; 77 | + (BOOL)printFixupData; 78 | @end 79 | 80 | extern NSString *CDErrorDomain_ClassDump; 81 | extern NSString *CDErrorKey_Exception; 82 | 83 | -------------------------------------------------------------------------------- /classdumpios/Classes/Cursors/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Cursors/CDMachOFileDataCursor.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-2019 Steve Nygard. 5 | 6 | #import "CDDataCursor.h" 7 | 8 | @class CDMachOFile, CDSection; 9 | 10 | @interface CDMachOFileDataCursor : CDDataCursor 11 | 12 | - (id)initWithFile:(CDMachOFile *)machOFile; 13 | - (id)initWithFile:(CDMachOFile *)machOFile offset:(NSUInteger)offset; 14 | - (id)initWithFile:(CDMachOFile *)machOFile address:(NSUInteger)address; 15 | 16 | - (id)initWithSection:(CDSection *)section; 17 | 18 | @property (nonatomic, readonly) CDMachOFile *machOFile; 19 | 20 | - (void)setAddress:(NSUInteger)address; 21 | 22 | // Read using the current byteOrder 23 | - (uint16_t)readInt16; 24 | - (uint32_t)readInt32; 25 | - (uint64_t)readInt64; 26 | 27 | - (uint32_t)peekInt32; 28 | 29 | // Read using the current byteOrder and ptrSize (from the machOFile) 30 | - (uint64_t)readPtr; 31 | - (uint64_t)readPtr:(bool)small; 32 | - (uint64_t)peekPtr; 33 | - (uint64_t)peekPtr:(bool)small; 34 | @end 35 | -------------------------------------------------------------------------------- /classdumpios/Classes/Cursors/CDMachOFileDataCursor.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-2019 Steve Nygard. 5 | 6 | #import "CDMachOFileDataCursor.h" 7 | 8 | #import "CDMachOFile.h" 9 | #import "CDLCSegment.h" 10 | #import "CDSection.h" 11 | 12 | @implementation CDMachOFileDataCursor 13 | { 14 | CDMachOFile *_machOFile; 15 | NSUInteger _ptrSize; 16 | CDByteOrder _byteOrder; 17 | } 18 | 19 | - (id)initWithFile:(CDMachOFile *)machOFile; 20 | { 21 | VerboseLog(@"[CDMachOFileDataCursor initWithFile: %@]", machOFile); 22 | return [self initWithFile:machOFile offset:0]; 23 | } 24 | 25 | - (id)initWithFile:(CDMachOFile *)machOFile offset:(NSUInteger)offset; 26 | { 27 | if (offset == 0){ 28 | offset = 4096; 29 | } 30 | VerboseLog(@"[CDMachOFileDataCursor initWithFile: %@ offset: 0x%08lx]", machOFile, offset); 31 | 32 | if ((self = [super initWithData:machOFile.data])) { 33 | self.machOFile = machOFile; 34 | [self setOffset:offset]; 35 | } 36 | 37 | return self; 38 | } 39 | 40 | - (id)initWithFile:(CDMachOFile *)machOFile address:(NSUInteger)address; 41 | { 42 | VerboseLog(@"[CDMachOFileDataCursor initWithFile: %@ address: 0x%08lx]", machOFile, address); 43 | if ((self = [super initWithData:machOFile.data])) { 44 | self.machOFile = machOFile; 45 | [self setAddress:address]; 46 | } 47 | 48 | return self; 49 | } 50 | 51 | - (id)initWithSection:(CDSection *)section; 52 | { 53 | if ((self = [super initWithData:[section data]])) { 54 | self.machOFile = section.segment.machOFile; 55 | } 56 | 57 | return self; 58 | } 59 | 60 | #pragma mark - 61 | 62 | - (void)setMachOFile:(CDMachOFile *)machOFile; 63 | { 64 | _machOFile = machOFile; 65 | _ptrSize = machOFile.ptrSize; 66 | _byteOrder = machOFile.byteOrder; 67 | } 68 | 69 | - (void)setAddress:(NSUInteger)address; 70 | { 71 | //VerboseLog(@"%s 0x%08lx", _cmds, address); 72 | NSUInteger dataOffset = [_machOFile dataOffsetForAddress:address]; 73 | VerboseLog(@"dataOffset: 0x%08lx for address: 0x%08lx", dataOffset, address); 74 | if (dataOffset == 0) dataOffset = address; 75 | [self setOffset:dataOffset]; 76 | } 77 | 78 | #pragma mark - Read using the current byteOrder 79 | 80 | - (uint16_t)readInt16; 81 | { 82 | if (_byteOrder == CDByteOrder_LittleEndian) 83 | return [self readLittleInt16]; 84 | 85 | return [self readBigInt16]; 86 | } 87 | 88 | - (uint32_t)readInt32; 89 | { 90 | if (_byteOrder == CDByteOrder_LittleEndian) 91 | return [self readLittleInt32]; 92 | 93 | return [self readBigInt32]; 94 | } 95 | 96 | - (uint64_t)readInt64; 97 | { 98 | if (_byteOrder == CDByteOrder_LittleEndian) 99 | return [self readLittleInt64]; 100 | 101 | return [self readBigInt64]; 102 | } 103 | 104 | - (uint32_t)peekInt32; 105 | { 106 | NSUInteger savedOffset = self.offset; 107 | uint32_t val = [self readInt32]; 108 | self.offset = savedOffset; 109 | 110 | return val; 111 | } 112 | 113 | - (uint64_t)peekPtr { 114 | NSUInteger savedOffset = self.offset; 115 | uint64_t val = 0; 116 | switch (_ptrSize) { 117 | case sizeof(uint32_t): val = [self readInt32]; 118 | case sizeof(uint64_t): val = [self readInt64]; 119 | } 120 | //uint32_t val = [self readInt32]; 121 | self.offset = savedOffset; 122 | 123 | return val; 124 | } 125 | 126 | - (uint64_t)readPtr; 127 | { 128 | switch (_ptrSize) { 129 | case sizeof(uint32_t): return [self readInt32]; 130 | case sizeof(uint64_t): return [self readInt64]; 131 | } 132 | [NSException raise:NSInternalInconsistencyException format:@"The ptrSize must be either 4 (32-bit) or 8 (64-bit)"]; 133 | return 0; 134 | } 135 | 136 | - (uint64_t)readPtr:(bool)small; 137 | { 138 | // "small" pointers are signed 32-bit values 139 | if (small) { 140 | // The pointers are relative to the location in the image, so get the offset before reading the offset: 141 | return [self offset] + [self readInt32]; 142 | } else { 143 | return [self readPtr]; 144 | } 145 | } 146 | 147 | - (uint64_t)peekPtr:(bool)small { 148 | // "small" pointers are signed 32-bit values 149 | if (small) { 150 | // The pointers are relative to the location in the image, so get the offset before reading the offset: 151 | return [self offset] + [self peekInt32]; 152 | } else { 153 | return [self peekPtr]; 154 | } 155 | } 156 | 157 | @end 158 | -------------------------------------------------------------------------------- /classdumpios/Classes/Extensions/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Extensions/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Extensions/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-2019 Steve Nygard. 5 | 6 | #import "NSArray-CDExtensions.h" 7 | 8 | #import "CDTopologicalSortProtocol.h" 9 | #import "CDTopoSortNode.h" 10 | 11 | @implementation NSArray (CDExtensions) 12 | 13 | - (NSArray *)reversedArray; 14 | { 15 | return [[self reverseObjectEnumerator] allObjects]; 16 | } 17 | 18 | @end 19 | 20 | #pragma mark - 21 | 22 | @implementation NSArray (CDTopoSort) 23 | 24 | - (NSArray *)topologicallySortedArray; 25 | { 26 | NSMutableDictionary *nodesByName = [[NSMutableDictionary alloc] init]; 27 | 28 | for (id object in self) { 29 | CDTopoSortNode *node = [[CDTopoSortNode alloc] initWithObject:object]; 30 | [node addDependanciesFromArray:[object dependancies]]; 31 | 32 | if (nodesByName[node.identifier] != nil) { 33 | DLog(@"Warning: Duplicate identifier (%@) in %s", node.identifier, _cmds); 34 | } 35 | if (node.identifier){ 36 | nodesByName[node.identifier] = node; 37 | } 38 | } 39 | 40 | NSMutableArray *sortedArray = [NSMutableArray array]; 41 | 42 | NSArray *allNodes = [[nodesByName allValues] sortedArrayUsingSelector:@selector(ascendingCompareByIdentifier:)]; 43 | for (CDTopoSortNode *node in allNodes) { 44 | if (node.color == CDNodeColor_White) 45 | [node topologicallySortNodes:nodesByName intoArray:sortedArray]; 46 | } 47 | 48 | 49 | return sortedArray; 50 | } 51 | 52 | @end 53 | 54 | #pragma mark - 55 | 56 | @implementation NSMutableArray (CDTopoSort) 57 | 58 | - (void)sortTopologically; 59 | { 60 | NSArray *sortedArray = [self topologicallySortedArray]; 61 | assert([self count] == [sortedArray count]); 62 | 63 | [self removeAllObjects]; 64 | [self addObjectsFromArray:sortedArray]; 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /classdumpios/Classes/Extensions/NSData+Flip.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | @interface NSData (myAdditions) 5 | - (NSString *)stringFromHexData; 6 | - (NSData *)byteFlipped; 7 | + (NSData *)dataFromStringHex:(NSString *)command; 8 | - (NSData *)reverse; 9 | - (NSString *)decimalString; 10 | + (NSData *)littleEndianHexFromInt:(NSUInteger)inputNumber; 11 | @end 12 | 13 | 14 | -------------------------------------------------------------------------------- /classdumpios/Classes/Extensions/NSData+Flip.mm: -------------------------------------------------------------------------------- 1 | #import "NSData+Flip.h" 2 | 3 | static NSString *CYDHex(NSData *data, bool reverse) { 4 | if (data == nil) 5 | return nil; 6 | 7 | size_t length([data length]); 8 | uint8_t bytes[length]; 9 | #pragma clang diagnostic push 10 | #pragma clang diagnostic ignored "-Wdeprecated-declarations" 11 | [data getBytes:bytes]; 12 | #pragma clang diagnostic pop 13 | char string[length * 2 + 1]; 14 | for (size_t i(0); i != length; ++i) 15 | sprintf(string + i * 2, "%.2x", bytes[reverse ? length - i - 1 : i]); 16 | 17 | return [NSString stringWithUTF8String:string]; 18 | } 19 | 20 | static NSString *HexToDec(NSString *hexValue) { 21 | if (hexValue == nil) 22 | return nil; 23 | 24 | unsigned long long dec; 25 | NSScanner *scan = [NSScanner scannerWithString:hexValue]; 26 | if ([scan scanHexLongLong:&dec]) { 27 | return [NSString stringWithFormat:@"%llu", dec]; 28 | } 29 | return nil; 30 | } 31 | @implementation NSData (myAdditions) 32 | 33 | - (NSString *)stringFromHexData { 34 | NSString *hexString = CYDHex(self, FALSE); 35 | return hexString; 36 | } 37 | 38 | + (NSData *)littleEndianHexFromInt:(NSUInteger)inputNumber { 39 | NSString *hexString = [NSString stringWithFormat:@"%.8lx",(unsigned long)inputNumber]; 40 | return [[NSData dataFromStringHex:hexString] reverse]; 41 | } 42 | 43 | + (NSData *)dataFromStringHex:(NSString *)command { 44 | command = [command stringByReplacingOccurrencesOfString:@" " withString:@""]; 45 | NSMutableData *commandToSend= [[NSMutableData alloc] init]; 46 | unsigned char whole_byte; 47 | char byte_chars[3] = {'\0','\0','\0'}; 48 | int i; 49 | for (i=0; i < [command length]/2; i++) { 50 | byte_chars[0] = [command characterAtIndex:i*2]; 51 | byte_chars[1] = [command characterAtIndex:i*2+1]; 52 | whole_byte = strtol(byte_chars, NULL, 16); 53 | [commandToSend appendBytes:&whole_byte length:1]; 54 | } 55 | 56 | return commandToSend; 57 | } 58 | 59 | - (NSData *)reverse { 60 | return [NSData dataFromStringHex:CYDHex(self, TRUE)]; 61 | } 62 | 63 | - (NSString *)decimalString { 64 | NSString *stringData = CYDHex(self, TRUE); 65 | return HexToDec(stringData); 66 | } 67 | 68 | -(NSData *) byteFlipped { 69 | NSMutableData *newData = [[NSMutableData alloc] init]; 70 | const char *_data = (char *)[self bytes]; 71 | NSUInteger stringLength = [self length]; 72 | NSUInteger x = 0; 73 | for( x=stringLength-1; x>=0; x-- ){ 74 | char currentByte = _data[x]; 75 | [newData appendBytes:¤tByte length:1]; 76 | } 77 | return newData; 78 | } 79 | @end 80 | -------------------------------------------------------------------------------- /classdumpios/Classes/Extensions/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-2019 Steve Nygard. 5 | 6 | @interface NSData (CDExtensions) 7 | 8 | - (NSString *)hexString; 9 | - (NSData *)SHA1Digest; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /classdumpios/Classes/Extensions/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Extensions/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-2019 Steve Nygard. 5 | 6 | @interface NSError (CDExtensions) 7 | 8 | @end 9 | 10 | extern NSString *NSErrorDomain_ClassDump; 11 | -------------------------------------------------------------------------------- /classdumpios/Classes/Extensions/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Extensions/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Extensions/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-2019 Steve Nygard. 5 | 6 | #import 7 | 8 | @interface NSMutableDictionary (CDExtensions) 9 | - (NSString *)stringRepresentation; 10 | @end 11 | 12 | @interface NSDictionary (CDExtensions) 13 | - (NSString *)stringRepresentation; 14 | @end 15 | 16 | @interface NSString (CDExtensions) 17 | 18 | - (id)dictionaryRepresentation; 19 | + (NSString *)stringWithFileSystemRepresentation:(const char *)str; 20 | + (NSString *)spacesIndentedToLevel:(NSUInteger)level; 21 | + (NSString *)spacesIndentedToLevel:(NSUInteger)level spacesPerLevel:(NSUInteger)spacesPerLevel; 22 | + (NSString *)stringWithUnichar:(unichar)character; 23 | 24 | - (BOOL)isFirstLetterUppercase; 25 | 26 | - (void)print; 27 | 28 | - (NSString *)executablePathForFilename; 29 | 30 | - (NSString *)SHA1DigestString; 31 | 32 | - (BOOL)hasUnderscoreCapitalPrefix; 33 | - (NSString *)capitalizeFirstCharacter; 34 | 35 | @end 36 | 37 | @interface NSMutableString (CDExtensions) 38 | 39 | - (void)appendSpacesIndentedToLevel:(NSUInteger)level; 40 | - (void)appendSpacesIndentedToLevel:(NSUInteger)level spacesPerLevel:(NSUInteger)spacesPerLevel; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /classdumpios/Classes/Extensions/ext.h: -------------------------------------------------------------------------------- 1 | #include "NSString-CDExtensions.h" 2 | #include "NSArray-CDExtensions.h" 3 | #include "NSData-CDExtensions.h" 4 | #include "NSError-CDExtensions.h" 5 | #include "NSScanner-CDExtensions.h" 6 | 7 | //#import "blowfish.h" -------------------------------------------------------------------------------- /classdumpios/Classes/Extras/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Extras/ULEB128.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-2019 Steve Nygard. 5 | 6 | #import "ULEB128.h" 7 | 8 | uint64_t read_uleb128(const uint8_t **ptrptr, const uint8_t *end) 9 | { 10 | const uint8_t *ptr = *ptrptr; 11 | uint64_t result = 0; 12 | int bit = 0; 13 | 14 | //DLog(@"read_uleb128()"); 15 | do { 16 | NSCAssert(ptr != end, @"Malformed uleb128", nil); 17 | 18 | //DLog(@"byte: %02x", *ptr); 19 | uint64_t slice = *ptr & 0x7f; 20 | 21 | if (bit >= 64 || slice << bit >> bit != slice) { 22 | DLog(@"uleb128 too big"); 23 | exit(88); 24 | } else { 25 | result |= (slice << bit); 26 | bit += 7; 27 | } 28 | } 29 | while ((*ptr++ & 0x80) != 0); 30 | 31 | #if 0 32 | static NSUInteger maxlen = 0; 33 | if (maxlen < ptr - *ptrptr) { 34 | const uint8_t *ptr2 = *ptrptr; 35 | 36 | NSMutableArray *byteStrs = [NSMutableArray array]; 37 | do { 38 | [byteStrs addObject:[NSString stringWithFormat:@"%02x", *ptr2]]; 39 | } while (++ptr2 < ptr); 40 | //DLog(@"max uleb length now: %u (%@)", ptr - *ptrptr, [byteStrs componentsJoinedByString:@" "]); 41 | //DLog(@"sizeof(uint64_t): %u, sizeof(uintptr_t): %u", sizeof(uint64_t), sizeof(uintptr_t)); 42 | maxlen = ptr - *ptrptr; 43 | } 44 | #endif 45 | 46 | *ptrptr = ptr; 47 | return result; 48 | } 49 | 50 | int64_t read_sleb128(const uint8_t **ptrptr, const uint8_t *end) 51 | { 52 | const uint8_t *ptr = *ptrptr; 53 | 54 | int64_t result = 0; 55 | int bit = 0; 56 | uint8_t byte; 57 | 58 | //DLog(@"read_sleb128()"); 59 | do { 60 | NSCAssert(ptr != end, @"Malformed sleb128", nil); 61 | 62 | byte = *ptr++; 63 | //DLog(@"%02x", byte); 64 | result |= ((byte & 0x7f) << bit); 65 | bit += 7; 66 | } while ((byte & 0x80) != 0); 67 | 68 | //DLog(@"result before sign extend: %ld", result); 69 | // sign extend negative numbers 70 | // This essentially clears out from -1 the low order bits we've already set, and combines that with our bits. 71 | if ( (byte & 0x40) != 0 ) 72 | result |= (-1LL) << bit; 73 | 74 | //DLog(@"result after sign extend: %ld", result); 75 | 76 | //DLog(@"ptr before: %p, after: %p", *ptrptr, ptr); 77 | *ptrptr = ptr; 78 | return result; 79 | } 80 | -------------------------------------------------------------------------------- /classdumpios/Classes/Extras/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 | -------------------------------------------------------------------------------- /classdumpios/Classes/FileManagement/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-2019 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 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/FileManagement/CDFatArch.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-2019 Steve Nygard. 5 | 6 | #import "CDFatArch.h" 7 | 8 | #include 9 | #import "CDDataCursor.h" 10 | #import "CDFatFile.h" 11 | #import "CDMachOFile.h" 12 | 13 | @implementation CDFatArch 14 | { 15 | CDFatFile *_fatFile; 16 | 17 | // This is essentially struct fat_arch, but this way our property accessors can be synthesized. 18 | cpu_type_t _cputype; 19 | cpu_subtype_t _cpusubtype; 20 | uint32_t _offset; 21 | uint32_t _size; 22 | uint32_t _align; 23 | 24 | CDMachOFile *_machOFile; // Lazily create this. 25 | } 26 | 27 | - (id)initWithMachOFile:(CDMachOFile *)machOFile; 28 | { 29 | if ((self = [super init])) { 30 | _machOFile = machOFile; 31 | NSParameterAssert([machOFile.data length] < 0x100000000); 32 | 33 | _cputype = _machOFile.cputype; 34 | _cpusubtype = _machOFile.cpusubtype; 35 | _offset = 0; // Would be filled in when this is written to disk 36 | _size = (uint32_t)[_machOFile.data length]; 37 | _align = 12; // 2**12 = 4096 (0x1000) 38 | } 39 | 40 | return self; 41 | } 42 | 43 | - (id)initWithDataCursor:(CDDataCursor *)cursor; 44 | { 45 | if ((self = [super init])) { 46 | _cputype = [cursor readBigInt32]; 47 | _cpusubtype = [cursor readBigInt32]; 48 | _offset = [cursor readBigInt32]; 49 | _size = [cursor readBigInt32]; 50 | _align = [cursor readBigInt32]; 51 | 52 | //DLog(@"self: %@", self); 53 | } 54 | 55 | return self; 56 | } 57 | 58 | #pragma mark - Debugging 59 | 60 | - (NSString *)description; 61 | { 62 | return [NSString stringWithFormat:@"64 bit ABI? %d, cputype: 0x%08x, cpusubtype: 0x%08x, offset: 0x%08x (%8u), size: 0x%08x (%8u), align: 2^%u (%x), arch name: %@", 63 | self.uses64BitABI, self.cputype, self.cpusubtype, self.offset, self.offset, self.size, self.size, 64 | self.align, 1 << self.align, self.archName]; 65 | } 66 | 67 | #pragma mark - 68 | 69 | - (cpu_type_t)maskedCPUType; 70 | { 71 | return self.cputype & ~CPU_ARCH_MASK; 72 | } 73 | 74 | - (cpu_subtype_t)maskedCPUSubtype; 75 | { 76 | return self.cpusubtype & ~CPU_SUBTYPE_MASK; 77 | } 78 | 79 | - (BOOL)uses64BitABI; 80 | { 81 | return CDArchUses64BitABI(self.arch); 82 | } 83 | 84 | - (BOOL)uses64BitLibraries; 85 | { 86 | return CDArchUses64BitLibraries(self.arch); 87 | } 88 | 89 | - (CDArch)arch; 90 | { 91 | CDArch arch = { self.cputype, self.cpusubtype }; 92 | 93 | return arch; 94 | } 95 | 96 | // Must not return nil. 97 | - (NSString *)archName; 98 | { 99 | return CDNameForCPUType(self.cputype, self.cpusubtype); 100 | } 101 | 102 | - (CDMachOFile *)machOFile; 103 | { 104 | if (_machOFile == nil) { 105 | NSData *data = [NSData dataWithBytesNoCopy:((uint8_t *)[self.fatFile.data bytes] + self.offset) length:self.size freeWhenDone:NO]; 106 | _machOFile = [[CDMachOFile alloc] initWithData:data filename:self.fatFile.filename searchPathState:self.fatFile.searchPathState]; 107 | } 108 | 109 | return _machOFile; 110 | } 111 | 112 | @end 113 | -------------------------------------------------------------------------------- /classdumpios/Classes/FileManagement/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/FileManagement/CDFatFile.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-2019 Steve Nygard. 5 | 6 | #import "CDFatFile.h" 7 | 8 | #include 9 | #include 10 | 11 | #import "CDDataCursor.h" 12 | #import "CDFatArch.h" 13 | #import "CDMachOFile.h" 14 | 15 | @implementation CDFatFile 16 | { 17 | NSMutableArray *_arches; 18 | } 19 | 20 | - (id)init; 21 | { 22 | if ((self = [super init])) { 23 | _arches = [[NSMutableArray alloc] init]; 24 | } 25 | 26 | return self; 27 | } 28 | 29 | - (id)initWithData:(NSData *)data filename:(NSString *)filename searchPathState:(CDSearchPathState *)searchPathState; 30 | { 31 | if ((self = [super initWithData:data filename:filename searchPathState:searchPathState])) { 32 | CDDataCursor *cursor = [[CDDataCursor alloc] initWithData:data]; 33 | 34 | struct fat_header header; 35 | header.magic = [cursor readBigInt32]; 36 | 37 | //DLog(@"(testing fat) magic: 0x%x", header.magic); 38 | if (header.magic != FAT_MAGIC) { 39 | return nil; 40 | } 41 | 42 | _arches = [[NSMutableArray alloc] init]; 43 | 44 | header.nfat_arch = [cursor readBigInt32]; 45 | //DLog(@"nfat_arch: %u", header.nfat_arch); 46 | for (NSUInteger index = 0; index < header.nfat_arch; index++) { 47 | CDFatArch *arch = [[CDFatArch alloc] initWithDataCursor:cursor]; 48 | arch.fatFile = self; 49 | [_arches addObject:arch]; 50 | } 51 | } 52 | 53 | return self; 54 | } 55 | 56 | #pragma mark - Debugging 57 | 58 | - (NSString *)description; 59 | { 60 | return [NSString stringWithFormat:@"<%@:%p> %lu arches", NSStringFromClass([self class]), self, [self.arches count]]; 61 | } 62 | 63 | #pragma mark - 64 | 65 | 66 | // Case 1: no arch specified 67 | // - check main file for these, then lock down on that arch: 68 | // - local arch, 64 bit 69 | // - local arch, 32 bit 70 | // - any arch, 64 bit 71 | // - any arch, 32 bit 72 | // 73 | // Case 2: you specified a specific arch (i386, x86_64, ppc, ppc7400, ppc64, etc.) 74 | // - only that arch 75 | // 76 | // In either case, we can ignore the cpu subtype 77 | 78 | // Returns YES on success, NO on failure. 79 | - (BOOL)bestMatchForArch:(CDArch *)ioArchPtr; 80 | { 81 | cpu_type_t targetType = ioArchPtr->cputype & ~CPU_ARCH_MASK; 82 | 83 | // Target architecture, 64 bit 84 | for (CDFatArch *fatArch in self.arches) { 85 | if (fatArch.maskedCPUType == targetType && fatArch.uses64BitABI) { 86 | if (ioArchPtr != NULL) *ioArchPtr = fatArch.arch; 87 | return YES; 88 | } 89 | } 90 | 91 | // Target architecture, 32 bit 92 | for (CDFatArch *fatArch in self.arches) { 93 | if (fatArch.maskedCPUType == targetType && fatArch.uses64BitABI == NO) { 94 | if (ioArchPtr != NULL) *ioArchPtr = fatArch.arch; 95 | return YES; 96 | } 97 | } 98 | 99 | // Any architecture, 64 bit 100 | for (CDFatArch *fatArch in self.arches) { 101 | if (fatArch.uses64BitABI) { 102 | if (ioArchPtr != NULL) *ioArchPtr = fatArch.arch; 103 | return YES; 104 | } 105 | } 106 | 107 | // Any architecture, 32 bit 108 | for (CDFatArch *fatArch in self.arches) { 109 | if (fatArch.uses64BitABI == NO) { 110 | if (ioArchPtr != NULL) *ioArchPtr = fatArch.arch; 111 | return YES; 112 | } 113 | } 114 | 115 | // Any architecture 116 | if ([self.arches count] > 0) { 117 | if (ioArchPtr != NULL) *ioArchPtr = [self.arches[0] arch]; 118 | return YES; 119 | } 120 | 121 | return NO; 122 | } 123 | 124 | - (CDFatArch *)fatArchWithArch:(CDArch)cdarch; 125 | { 126 | for (CDFatArch *arch in self.arches) { 127 | if (arch.cputype == cdarch.cputype && arch.maskedCPUSubtype == (cdarch.cpusubtype & ~CPU_SUBTYPE_MASK)) 128 | return arch; 129 | } 130 | 131 | return nil; 132 | } 133 | 134 | - (CDMachOFile *)machOFileWithArch:(CDArch)cdarch; 135 | { 136 | return [[self fatArchWithArch:cdarch] machOFile]; 137 | } 138 | 139 | - (NSArray *)archNames; 140 | { 141 | NSMutableArray *archNames = [NSMutableArray array]; 142 | for (CDFatArch *arch in self.arches) 143 | [archNames addObject:arch.archName]; 144 | 145 | return archNames; 146 | } 147 | 148 | - (NSString *)architectureNameDescription; 149 | { 150 | return [self.archNames componentsJoinedByString:@", "]; 151 | } 152 | 153 | #pragma mark - 154 | 155 | - (void)addArchitecture:(CDFatArch *)fatArch; 156 | { 157 | fatArch.fatFile = self; 158 | [self.arches addObject:fatArch]; 159 | } 160 | 161 | - (BOOL)containsArchitecture:(CDArch)arch; 162 | { 163 | return [self fatArchWithArch:arch] != nil; 164 | } 165 | 166 | @end 167 | -------------------------------------------------------------------------------- /classdumpios/Classes/FileManagement/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/FileManagement/CDMachOFile.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-2019 Steve Nygard. 5 | 6 | #import "CDFile.h" 7 | 8 | #include // For cpu_type_t, cpu_subtype_t 9 | #include 10 | 11 | typedef enum : NSUInteger { 12 | CDByteOrder_LittleEndian = 0, 13 | CDByteOrder_BigEndian = 1, 14 | } CDByteOrder; 15 | 16 | @class CDLCSegment; 17 | @class CDLCBuildVersion, CDLCDyldInfo, CDLCDylib, CDMachOFile, CDLCSymbolTable, CDLCDynamicSymbolTable, CDLCVersionMinimum, CDLCSourceVersion, CDLCChainedFixups, CDLCExportTRIEData; 18 | 19 | @interface CDMachOFile : CDFile 20 | 21 | @property (readonly) CDByteOrder byteOrder; 22 | 23 | @property (readonly) uint32_t magic; 24 | @property (assign) cpu_type_t cputype; 25 | @property (assign) cpu_subtype_t cpusubtype; 26 | @property (readonly) uint32_t filetype; 27 | @property (readonly) uint32_t flags; 28 | 29 | @property (nonatomic, readonly) cpu_type_t maskedCPUType; 30 | @property (nonatomic, readonly) cpu_subtype_t maskedCPUSubtype; 31 | 32 | @property (readonly) NSArray *loadCommands; 33 | @property (readonly) NSArray *dylibLoadCommands; 34 | @property (readonly) NSArray *segments; 35 | @property (readonly) NSArray *runPaths; 36 | @property (readonly) NSArray *runPathCommands; 37 | @property (readonly) NSArray *dyldEnvironment; 38 | @property (readonly) NSArray *reExportedDylibs; 39 | 40 | @property (strong) CDLCSymbolTable *symbolTable; 41 | @property (strong) CDLCDynamicSymbolTable *dynamicSymbolTable; 42 | @property (strong) CDLCDyldInfo *dyldInfo; 43 | @property (strong) CDLCExportTRIEData *exportsTrie; 44 | @property (strong) CDLCChainedFixups *chainedFixups; 45 | @property (strong) CDLCDylib *dylibIdentifier; 46 | @property (strong) CDLCVersionMinimum *minVersionMacOSX; 47 | @property (strong) CDLCVersionMinimum *minVersionIOS; 48 | @property (strong) CDLCSourceVersion *sourceVersion; 49 | @property (strong) CDLCBuildVersion *buildVersion; 50 | 51 | @property (readonly) BOOL uses64BitABI; 52 | - (NSUInteger)ptrSize; 53 | 54 | - (NSString *)filetypeDescription; 55 | - (NSString *)flagDescription; 56 | 57 | - (CDLCSegment *)dataConstSegment; 58 | - (CDLCSegment *)segmentWithName:(NSString *)segmentName; 59 | - (CDLCSegment *)segmentContainingAddress:(NSUInteger)address; 60 | - (NSString *)stringAtAddress:(NSUInteger)address; 61 | 62 | - (NSUInteger)dataOffsetForAddress:(NSUInteger)address; 63 | 64 | - (const void *)bytes; 65 | - (const void *)bytesAtOffset:(NSUInteger)offset; 66 | 67 | @property (nonatomic, readonly) NSString *importBaseName; 68 | 69 | @property (nonatomic, readonly) BOOL isEncrypted; 70 | @property (nonatomic, readonly) BOOL hasProtectedSegments; 71 | @property (nonatomic, readonly) BOOL canDecryptAllSegments; 72 | 73 | - (NSString *)loadCommandString:(BOOL)isVerbose; 74 | - (NSString *)headerString:(BOOL)isVerbose; 75 | 76 | @property (nonatomic, readonly) NSUUID *UUID; 77 | @property (nonatomic, readonly) NSString *archName; 78 | 79 | - (Class)processorClass; 80 | - (void)logInfoForAddress:(NSUInteger)address; 81 | 82 | - (NSString *)externalClassNameForAddress:(NSUInteger)address; 83 | - (BOOL)hasRelocationEntryForAddress:(NSUInteger)address; 84 | 85 | // Checks compressed dyld info on 10.6 or later. 86 | - (BOOL)hasRelocationEntryForAddress2:(NSUInteger)address; 87 | - (NSString *)externalClassNameForAddress2:(NSUInteger)address; 88 | 89 | - (CDLCDylib *)dylibLoadCommandForLibraryOrdinal:(NSUInteger)ordinal; 90 | 91 | @property (nonatomic, readonly) BOOL hasObjectiveC1Data; 92 | @property (nonatomic, readonly) BOOL hasObjectiveC2Data; 93 | @property (nonatomic, readonly) Class processorClass; 94 | 95 | - (NSString *)entitlements; 96 | - (NSDictionary *)entitlementsDictionary; 97 | - (uint64_t)peekPtrAtOffset:(NSUInteger)offset ptrSize:(NSUInteger)ptr; 98 | - (uint64_t)preferredLoadAddress; 99 | - (uint64_t)fixupBasedAddress:(uint64_t)address; 100 | @end 101 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/CDLCBuildVersion.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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCBuildVersion : CDLoadCommand 9 | 10 | @property (nonatomic, readonly) NSString *buildVersionString; 11 | @property (nonatomic, readonly) NSArray *toolStrings; 12 | @end 13 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/CDLCBuildVersion.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-2019 Steve Nygard. 5 | 6 | #import "CDLCBuildVersion.h" 7 | 8 | #import "CDMachOFile.h" 9 | 10 | static NSString *NSStringFromBuildVersionPlatform(uint32_t platform) 11 | { 12 | //return @"iOS"; 13 | switch (platform) { 14 | case PLATFORM_MACOS: return @"macOS"; 15 | case PLATFORM_IOS: return @"iOS"; 16 | case PLATFORM_TVOS: return @"tvOS"; 17 | case PLATFORM_WATCHOS: return @"watchOS"; 18 | case PLATFORM_BRIDGEOS: return @"bridgeOS"; 19 | //case PLATFORM_IOSMAC: return @"iOS Mac"; 20 | case PLATFORM_IOSSIMULATOR: return @"iOS Simulator"; 21 | case PLATFORM_TVOSSIMULATOR: return @"tvOS Simulator"; 22 | case PLATFORM_WATCHOSSIMULATOR: return @"watchOS Simulator"; 23 | default: return [NSString stringWithFormat:@"Unknown platform %x", platform]; 24 | } 25 | } 26 | 27 | static NSString *NSStringFromBuildVersionTool(uint32_t tool) 28 | { 29 | switch (tool) { 30 | case TOOL_CLANG: return @"clang"; 31 | case TOOL_SWIFT: return @"swift"; 32 | case TOOL_LD: return @"ld"; 33 | default: return [NSString stringWithFormat:@"Unknown tool %x", tool]; 34 | } 35 | } 36 | 37 | static NSString *NSStringFromBuildVersionToolNotATuple(uint64_t tuple) 38 | { 39 | uint32_t tool = tuple >> 32; 40 | uint32_t version = tuple & 0xffffffff; 41 | return [NSString stringWithFormat:@"%@ %u.%u.%u", NSStringFromBuildVersionTool(tool), 42 | version >> 16, 43 | (version >> 8) & 0xff, 44 | version & 0xff]; 45 | } 46 | 47 | @implementation CDLCBuildVersion 48 | { 49 | struct build_version_command _buildVersionCommand; 50 | NSArray *_tools; 51 | } 52 | 53 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 54 | { 55 | if ((self = [super initWithDataCursor:cursor])) { 56 | _buildVersionCommand.cmd = [cursor readInt32]; 57 | _buildVersionCommand.cmdsize = [cursor readInt32]; 58 | _buildVersionCommand.platform = [cursor readInt32]; 59 | _buildVersionCommand.minos = [cursor readInt32]; 60 | _buildVersionCommand.sdk = [cursor readInt32]; 61 | _buildVersionCommand.ntools = [cursor readInt32]; 62 | NSMutableArray *tools = [NSMutableArray array]; 63 | for (NSUInteger index = 0; index < _buildVersionCommand.ntools; index++) { 64 | // ISO tuples. 65 | uint32_t tool = [cursor readInt32]; 66 | uint32_t version = [cursor readInt32]; 67 | uint64_t iso_tuples = ((uint64_t)tool << 32) | version; 68 | [tools addObject:@(iso_tuples)]; 69 | } 70 | _tools = [tools copy]; 71 | } 72 | 73 | return self; 74 | } 75 | 76 | #pragma mark - 77 | 78 | - (uint32_t)cmd; 79 | { 80 | return _buildVersionCommand.cmd; 81 | } 82 | 83 | - (uint32_t)cmdsize; 84 | { 85 | return _buildVersionCommand.cmdsize; 86 | } 87 | 88 | - (NSString *)buildVersionString; 89 | { 90 | return [NSString stringWithFormat:@"Platform: %@ %u.%u.%u, SDK: %u.%u.%u", 91 | NSStringFromBuildVersionPlatform(_buildVersionCommand.platform), 92 | _buildVersionCommand.minos >> 16, 93 | (_buildVersionCommand.minos >> 8) & 0xff, 94 | _buildVersionCommand.minos & 0xff, 95 | 96 | _buildVersionCommand.sdk >> 16, 97 | (_buildVersionCommand.sdk >> 8) & 0xff, 98 | _buildVersionCommand.sdk & 0xff]; 99 | } 100 | 101 | - (NSArray *)toolStrings; 102 | { 103 | NSMutableArray *tools = [NSMutableArray array]; 104 | // iso map 105 | for (NSNumber *tuple in _tools) { 106 | [tools addObject:NSStringFromBuildVersionToolNotATuple([tuple unsignedLongLongValue])]; 107 | } 108 | 109 | return [tools copy]; 110 | } 111 | 112 | - (void)appendToString:(NSMutableString *)resultString verbose:(BOOL)isVerbose; 113 | { 114 | [super appendToString:resultString verbose:isVerbose]; 115 | 116 | [resultString appendFormat:@" Build version: %@\n", self.buildVersionString]; 117 | } 118 | 119 | @end 120 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/CDLCChainedFixups.h: -------------------------------------------------------------------------------- 1 | // 2 | // CDLCChainedFixups.h 3 | // classdumpios 4 | // 5 | // Created by kevinbradley on 6/26/22. 6 | // 7 | 8 | //#import 9 | #import "CDLoadCommand.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface CDLCChainedFixups : CDLoadCommand 14 | - (NSUInteger)rebaseTargetFromAddress:(NSUInteger)address adjustment:(NSUInteger)adj; 15 | - (NSUInteger)rebaseTargetFromAddress:(NSUInteger)address; 16 | - (NSString *)symbolNameForAddress:(NSUInteger)address; 17 | - (NSString *)externalClassNameForAddress:(NSUInteger)address; 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLCLinkeditData.h" 7 | 8 | @interface CDLCDataInCode : CDLCLinkeditData 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCDyldInfo : CDLoadCommand 9 | 10 | - (NSString *)symbolNameForAddress:(NSUInteger)address; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | - (NSString *)path; 18 | @end 19 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/CDLCDylib.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-2019 Steve Nygard. 5 | 6 | #import "CDLCDylib.h" 7 | 8 | #import "CDFatFile.h" 9 | #import "CDMachOFile.h" 10 | 11 | static NSString *CDDylibVersionString(uint32_t version) 12 | { 13 | return [NSString stringWithFormat:@"%d.%d.%d", version >> 16, (version >> 8) & 0xff, version & 0xff]; 14 | } 15 | 16 | @implementation CDLCDylib 17 | { 18 | struct dylib_command _dylibCommand; 19 | NSString *_path; 20 | } 21 | 22 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 23 | { 24 | if ((self = [super initWithDataCursor:cursor])) { 25 | _dylibCommand.cmd = [cursor readInt32]; 26 | _dylibCommand.cmdsize = [cursor readInt32]; 27 | 28 | _dylibCommand.dylib.name.offset = [cursor readInt32]; 29 | _dylibCommand.dylib.timestamp = [cursor readInt32]; 30 | _dylibCommand.dylib.current_version = [cursor readInt32]; 31 | _dylibCommand.dylib.compatibility_version = [cursor readInt32]; 32 | 33 | NSUInteger length = _dylibCommand.cmdsize - sizeof(_dylibCommand); 34 | //DLog(@"expected length: %u", length); 35 | 36 | _path = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding]; 37 | //DLog(@"path: %@", path); 38 | } 39 | 40 | return self; 41 | } 42 | 43 | #pragma mark - 44 | 45 | - (uint32_t)cmd; 46 | { 47 | return _dylibCommand.cmd; 48 | } 49 | 50 | - (uint32_t)cmdsize; 51 | { 52 | return _dylibCommand.cmdsize; 53 | } 54 | 55 | - (uint32_t)timestamp; 56 | { 57 | return _dylibCommand.dylib.timestamp; 58 | } 59 | 60 | - (uint32_t)currentVersion; 61 | { 62 | return _dylibCommand.dylib.current_version; 63 | } 64 | 65 | - (uint32_t)compatibilityVersion; 66 | { 67 | return _dylibCommand.dylib.compatibility_version; 68 | } 69 | 70 | - (NSString *)formattedCurrentVersion; 71 | { 72 | return CDDylibVersionString(self.currentVersion); 73 | } 74 | 75 | - (NSString *)formattedCompatibilityVersion; 76 | { 77 | return CDDylibVersionString(self.compatibilityVersion); 78 | } 79 | 80 | - (NSString *)path { 81 | return _path; 82 | } 83 | 84 | - (NSString *)description { 85 | NSString *og = [super description]; 86 | return [NSString stringWithFormat:@"%@ %@ (compatibility version %@, current version %@)", og, 87 | self.path, CDDylibVersionString(self.compatibilityVersion), CDDylibVersionString(self.currentVersion)]; 88 | } 89 | 90 | #if 0 91 | - (NSString *)extraDescription; 92 | { 93 | return [NSString stringWithFormat:@"%@ (compatibility version %@, current version %@, timestamp %d [%@])", 94 | self.path, CDDylibVersionString(self.compatibilityVersion), CDDylibVersionString(self.currentVersion), 95 | self.timestamp, [NSDate dateWithTimeIntervalSince1970:self.timestamp]]; 96 | } 97 | #endif 98 | 99 | @end 100 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCDylinker : CDLoadCommand 9 | 10 | @property (readonly) NSString *name; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | //DLog(@"expected length: %u", length); 24 | @try { 25 | _name = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding]; 26 | } @catch (NSException *exception) { 27 | CAUGHT_EXCEPTION_LOG; 28 | _name = nil; 29 | } 30 | //DLog(@"name: %@", name); 31 | } 32 | 33 | return self; 34 | } 35 | 36 | #pragma mark - 37 | 38 | - (uint32_t)cmd; 39 | { 40 | return _dylinkerCommand.cmd; 41 | } 42 | 43 | - (uint32_t)cmdsize; 44 | { 45 | return _dylinkerCommand.cmdsize; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/CDLCExportTRIEData.h: -------------------------------------------------------------------------------- 1 | // 2 | // CDLCExportTRIEData.h 3 | // classdumpios 4 | // 5 | // Created by kevinbradley on 6/26/22. 6 | // 7 | 8 | //#import 9 | #import "CDLoadCommand.h" 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface CDLCExportTRIEData : CDLoadCommand 13 | - (uint64_t)getExportedSymbolLocation:(NSString *)symbol; 14 | @end 15 | 16 | NS_ASSUME_NONNULL_END 17 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLCLinkeditData.h" 7 | 8 | @interface CDLCFunctionStarts : CDLCLinkeditData 9 | 10 | @property (nonatomic, readonly) NSArray *functionStarts; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCLinkeditData : CDLoadCommand 9 | 10 | @property (nonatomic, readonly) NSData *linkeditData; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCMain : CDLoadCommand 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCPrebindChecksum : CDLoadCommand 9 | 10 | @property (nonatomic, readonly) uint32_t cksum; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCPreboundDylib : CDLoadCommand 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | //DLog(@"current offset: %u", [cursor offset]); 20 | _preboundDylibCommand.cmd = [cursor readInt32]; 21 | _preboundDylibCommand.cmdsize = [cursor readInt32]; 22 | //DLog(@"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 | @try { 31 | [cursor advanceByLength:_preboundDylibCommand.cmdsize - 20]; 32 | } @catch (NSException *exception) { 33 | CAUGHT_EXCEPTION_LOG; 34 | } 35 | } 36 | } 37 | 38 | return self; 39 | } 40 | 41 | #pragma mark - 42 | 43 | - (uint32_t)cmd; 44 | { 45 | return _preboundDylibCommand.cmd; 46 | } 47 | 48 | - (uint32_t)cmdsize; 49 | { 50 | return _preboundDylibCommand.cmdsize; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCRoutines32 : CDLoadCommand 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCRoutines64 : CDLoadCommand 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | //DLog(@"expected length: %u", length); 27 | 28 | _path = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding]; 29 | //DLog(@"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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | @property (nonatomic, readonly) NSUInteger baselineAdjustment; 35 | 36 | @property (nonatomic, readonly) CDSegmentEncryptionType encryptionType; 37 | @property (nonatomic, readonly) BOOL canDecrypt; 38 | 39 | - (NSString *)flagDescription; 40 | 41 | - (BOOL)containsAddress:(NSUInteger)address; 42 | - (CDSection *)sectionContainingAddress:(NSUInteger)address; 43 | - (CDSection *)sectionWithName:(NSString *)name; 44 | - (NSUInteger)fileOffsetForAddress:(NSUInteger)address; 45 | - (NSUInteger)segmentOffsetForAddress:(NSUInteger)address; 46 | 47 | - (void)writeSectionData; 48 | 49 | - (NSData *)decryptedData; 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCSourceVersion : CDLoadCommand 9 | 10 | @property (nonatomic, readonly) NSString *sourceVersionString; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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) & 0x3ff; 43 | uint32_t c = (_sourceVersionCommand.version >> 20) & 0x3ff; 44 | uint32_t d = (_sourceVersionCommand.version >> 10) & 0x3ff; 45 | uint32_t e = _sourceVersionCommand.version & 0x3ff; 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCSubClient : CDLoadCommand 9 | 10 | @property (readonly) NSString *name; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | #ifdef DEBUG 20 | uint32_t strOffset = [cursor readInt32]; 21 | NSParameterAssert(strOffset == 12); 22 | #endif 23 | NSUInteger length = _command.cmdsize - sizeof(_command); 24 | //DLog(@"expected length: %u", length); 25 | 26 | _name = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding]; 27 | //DLog(@"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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCSubFramework : CDLoadCommand 9 | 10 | @property (readonly) NSString *name; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | #ifdef DEBUG 20 | uint32_t strOffset = [cursor readInt32]; 21 | NSParameterAssert(strOffset == 12); 22 | #endif 23 | NSUInteger length = _command.cmdsize - sizeof(_command); 24 | //DLog(@"expected length: %u", length); 25 | 26 | _name = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding]; 27 | //DLog(@"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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCSubLibrary : CDLoadCommand 9 | 10 | @property (readonly) NSString *name; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | //DLog(@"expected length: %u", length); 22 | 23 | _name = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding]; 24 | //DLog(@"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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCSubUmbrella : CDLoadCommand 9 | 10 | @property (readonly) NSString *name; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | //DLog(@"expected length: %u", length); 22 | 23 | _name = [cursor readStringOfLength:length encoding:NSASCIIStringEncoding]; 24 | //DLog(@"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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCTwoLevelHints : CDLoadCommand 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCUUID : CDLoadCommand 9 | 10 | @property (nonatomic, readonly) NSUUID *UUID; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCUnixThread : CDLoadCommand 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLoadCommand.h" 7 | 8 | @interface CDLCUnknown : CDLoadCommand 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 Steve Nygard. 5 | 6 | #import "CDLCUnknown.h" 7 | 8 | @implementation CDLCUnknown 9 | { 10 | struct load_command _loadCommand; 11 | 12 | NSData *_commandData; 13 | } 14 | 15 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor; 16 | { 17 | if ((self = [super initWithDataCursor:cursor])) { 18 | VerboseLog(@"offset: %lu", [cursor offset]); 19 | _loadCommand.cmd = [cursor readInt32]; 20 | _loadCommand.cmdsize = [cursor readInt32]; 21 | VerboseLog(@"cmdsize: %u", _loadCommand.cmdsize); 22 | 23 | if (_loadCommand.cmdsize > 8) { 24 | NSMutableData *commandData = [[NSMutableData alloc] init]; 25 | @try { 26 | [cursor appendBytesOfLength:_loadCommand.cmdsize - 8 intoData:commandData]; 27 | _commandData = [commandData copy]; 28 | } @catch (NSException *exception) { 29 | CAUGHT_EXCEPTION_LOG; 30 | commandData = nil; 31 | } 32 | 33 | } else { 34 | _commandData = nil; 35 | } 36 | } 37 | 38 | return self; 39 | } 40 | 41 | #pragma mark - 42 | 43 | - (uint32_t)cmd; 44 | { 45 | return _loadCommand.cmd; 46 | } 47 | 48 | - (uint32_t)cmdsize; 49 | { 50 | return _loadCommand.cmdsize; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/LoadCommands/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-2019 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 (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 | -------------------------------------------------------------------------------- /classdumpios/Classes/OC/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-2019 Steve Nygard. 5 | 6 | #import "CDOCProtocol.h" 7 | #import "CDTopologicalSortProtocol.h" 8 | 9 | @class CDOCClassReference; 10 | 11 | @interface CDOCCategory : CDOCProtocol 12 | 13 | @property (strong) CDOCClassReference *classRef; 14 | @property (strong, readonly) NSString *className; 15 | 16 | - (NSString *)methodSearchContext; 17 | - (void)recursivelyVisit:(CDVisitor *)visitor; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /classdumpios/Classes/OC/CDOCCategory.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-2019 Steve Nygard. 5 | 6 | #import "CDOCCategory.h" 7 | 8 | #import "CDClassDump.h" 9 | #import "CDOCMethod.h" 10 | #import "CDVisitor.h" 11 | #import "CDVisitorPropertyState.h" 12 | #import "CDOCClass.h" 13 | #import "CDOCClassReference.h" 14 | 15 | @implementation CDOCCategory 16 | 17 | #pragma mark - Superclass overrides 18 | 19 | - (NSString *)sortableName; 20 | { 21 | return [NSString stringWithFormat:@"%@ (%@)", self.className, self.name]; 22 | } 23 | 24 | #pragma mark - 25 | 26 | - (NSString *)className 27 | { 28 | return [_classRef className]; 29 | } 30 | 31 | - (NSString *)methodSearchContext; 32 | { 33 | NSMutableString *resultString = [NSMutableString string]; 34 | 35 | [resultString appendFormat:@"@interface %@ (%@)", self.className, self.name]; 36 | 37 | if ([self.protocols count] > 0) 38 | [resultString appendFormat:@" <%@>", self.protocolsString]; 39 | 40 | return resultString; 41 | } 42 | 43 | - (void)recursivelyVisit:(CDVisitor *)visitor; 44 | { 45 | if ([visitor.classDump shouldShowName:self.name]) { 46 | CDVisitorPropertyState *propertyState = [[CDVisitorPropertyState alloc] initWithProperties:self.properties]; 47 | 48 | [visitor willVisitCategory:self]; 49 | 50 | //[aVisitor willVisitPropertiesOfCategory:self]; 51 | //[self visitProperties:aVisitor]; 52 | //[aVisitor didVisitPropertiesOfCategory:self]; 53 | 54 | [self visitMethods:visitor propertyState:propertyState]; 55 | // This can happen when... the accessors are implemented on the main class. Odd case, but we should still emit the remaining properties. 56 | // Should mostly be dynamic properties 57 | [visitor visitRemainingProperties:propertyState]; 58 | [visitor didVisitCategory:self]; 59 | } 60 | } 61 | 62 | #pragma mark - CDTopologicalSort protocol 63 | 64 | - (NSString *)identifier; 65 | { 66 | return self.sortableName; 67 | } 68 | 69 | - (NSArray *)dependancies; 70 | { 71 | if (self.className == nil) 72 | return @[]; 73 | 74 | return @[self.className]; 75 | } 76 | 77 | @end 78 | -------------------------------------------------------------------------------- /classdumpios/Classes/OC/CDOCClass.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-2019 Steve Nygard. 5 | 6 | #import "CDOCProtocol.h" 7 | 8 | #import "CDTopologicalSortProtocol.h" 9 | 10 | @class CDOCClassReference; 11 | 12 | @interface CDOCClass : CDOCProtocol 13 | 14 | @property (strong) CDOCClassReference *superClassRef; 15 | @property (copy, readonly) NSString *superClassName; 16 | @property (strong) NSArray *instanceVariables; 17 | @property (assign) BOOL isExported; 18 | @property (assign) BOOL isSwiftClass; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /classdumpios/Classes/OC/CDOCClass.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-2019 Steve Nygard. 5 | 6 | #import "CDOCClass.h" 7 | 8 | #import "CDClassDump.h" 9 | #import "CDOCInstanceVariable.h" 10 | #import "CDOCMethod.h" 11 | #import "CDType.h" 12 | #import "CDTypeController.h" 13 | #import "CDTypeParser.h" 14 | #import "CDVisitor.h" 15 | #import "CDVisitorPropertyState.h" 16 | #import "CDOCClassReference.h" 17 | 18 | @implementation CDOCClass 19 | { 20 | NSArray *_instanceVariables; 21 | 22 | BOOL _isExported; 23 | } 24 | 25 | - (id)init; 26 | { 27 | if ((self = [super init])) { 28 | _isExported = YES; 29 | } 30 | 31 | return self; 32 | } 33 | 34 | #pragma mark - Debugging 35 | 36 | - (NSString *)description; 37 | { 38 | return [NSString stringWithFormat:@"%@, exported: %@", [super description], self.isExported ? @"YES" : @"NO"]; 39 | } 40 | 41 | #pragma mark - 42 | 43 | - (NSString *)superClassName; 44 | { 45 | return [_superClassRef className]; 46 | } 47 | 48 | - (void)registerTypesWithObject:(CDTypeController *)typeController phase:(NSUInteger)phase; 49 | { 50 | [super registerTypesWithObject:typeController phase:phase]; 51 | 52 | for (CDOCInstanceVariable *instanceVariable in self.instanceVariables) { 53 | [instanceVariable.type phase:phase registerTypesWithObject:typeController usedInMethod:NO]; 54 | } 55 | } 56 | 57 | - (NSString *)methodSearchContext; 58 | { 59 | NSMutableString *resultString = [NSMutableString string]; 60 | 61 | [resultString appendFormat:@"@interface %@", self.name]; 62 | if (self.superClassName != nil) 63 | [resultString appendFormat:@" : %@", self.superClassName]; 64 | 65 | if ([self.protocols count] > 0) 66 | [resultString appendFormat:@" <%@>", self.protocolsString]; 67 | 68 | return resultString; 69 | } 70 | 71 | - (void)recursivelyVisit:(CDVisitor *)visitor; 72 | { 73 | if ([visitor.classDump shouldShowName:self.name]) { 74 | CDVisitorPropertyState *propertyState = [[CDVisitorPropertyState alloc] initWithProperties:self.properties]; 75 | 76 | [visitor willVisitClass:self]; 77 | 78 | [visitor willVisitIvarsOfClass:self]; 79 | for (CDOCInstanceVariable *instanceVariable in self.instanceVariables) 80 | [visitor visitIvar:instanceVariable]; 81 | [visitor didVisitIvarsOfClass:self]; 82 | 83 | //[visitor willVisitPropertiesOfClass:self]; 84 | //[self visitProperties:visitor]; 85 | //[visitor didVisitPropertiesOfClass:self]; 86 | 87 | [self visitMethods:visitor propertyState:propertyState]; 88 | // Should mostly be dynamic properties 89 | [visitor visitRemainingProperties:propertyState]; 90 | [visitor didVisitClass:self]; 91 | } 92 | } 93 | 94 | #pragma mark - CDTopologicalSort protocol 95 | 96 | - (NSString *)identifier; 97 | { 98 | return self.name; 99 | } 100 | 101 | - (NSArray *)dependancies; 102 | { 103 | if (self.superClassName == nil) 104 | return @[]; 105 | 106 | return @[self.superClassName]; 107 | } 108 | 109 | @end 110 | -------------------------------------------------------------------------------- /classdumpios/Classes/OC/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/OC/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/OC/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/OC/CDOCInstanceVariable.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-2019 Steve Nygard. 5 | 6 | #import "CDOCInstanceVariable.h" 7 | 8 | #import "CDClassDump.h" 9 | #import "CDTypeFormatter.h" 10 | #import "CDTypeParser.h" 11 | #import "CDTypeController.h" 12 | #import "CDType.h" 13 | 14 | @interface CDOCInstanceVariable () 15 | @property (assign) BOOL hasParsedType; 16 | @end 17 | 18 | #pragma mark - 19 | 20 | @implementation CDOCInstanceVariable 21 | { 22 | NSString *_name; 23 | NSString *_typeString; 24 | NSUInteger _offset; 25 | 26 | BOOL _hasParsedType; 27 | CDType *_type; 28 | NSError *_parseError; 29 | } 30 | 31 | - (id)initWithName:(NSString *)name typeString:(NSString *)typeString offset:(NSUInteger)offset; 32 | { 33 | if ((self = [super init])) { 34 | _name = name; 35 | _typeString = typeString; 36 | _offset = offset; 37 | 38 | _hasParsedType = NO; 39 | _type = nil; 40 | _parseError = nil; 41 | } 42 | 43 | return self; 44 | } 45 | 46 | #pragma mark - Debugging 47 | 48 | - (NSString *)description; 49 | { 50 | return [NSString stringWithFormat:@"[%@] name: %@, typeString: '%@', offset: %lu", 51 | NSStringFromClass([self class]), self.name, self.typeString, self.offset]; 52 | } 53 | 54 | #pragma mark - 55 | 56 | - (CDType *)type; 57 | { 58 | if (self.hasParsedType == NO && self.parseError == nil) { 59 | CDTypeParser *parser = [[CDTypeParser alloc] initWithString:self.typeString]; 60 | NSError *error; 61 | _type = [parser parseType:&error]; 62 | if (_type == nil) { 63 | DLog(@"Warning: Parsing instance variable type failed, %@", self.name); 64 | _parseError = error; 65 | } else { 66 | self.hasParsedType = YES; 67 | } 68 | } 69 | 70 | return _type; 71 | } 72 | 73 | - (void)appendToString:(NSMutableString *)resultString typeController:(CDTypeController *)typeController; 74 | { 75 | CDType *type = [self type]; // Parses it, if necessary; 76 | if (self.parseError != nil) { 77 | if ([self.typeString length] > 0) { 78 | [resultString appendFormat:@" // Error: parsing type: '%@', name: %@", self.typeString, self.name]; 79 | } else { 80 | [resultString appendFormat:@" // Error: Empty type, name: %@", self.name]; 81 | } 82 | } else { 83 | NSString *formattedString = [[typeController ivarTypeFormatter] formatVariable:self.name type:type]; 84 | NSParameterAssert(formattedString != nil); 85 | [resultString appendString:formattedString]; 86 | [resultString appendString:@";"]; 87 | if ([typeController shouldShowIvarOffsets]) { 88 | [resultString appendFormat:@"\t// %ld = 0x%lx", self.offset, self.offset]; 89 | } 90 | } 91 | } 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /classdumpios/Classes/OC/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/OC/CDOCMethod.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-2019 Steve Nygard. 5 | 6 | #import "CDOCMethod.h" 7 | 8 | #import "CDClassDump.h" 9 | #import "CDTypeFormatter.h" 10 | #import "CDTypeParser.h" 11 | #import "CDTypeController.h" 12 | 13 | @implementation CDOCMethod 14 | { 15 | NSString *_name; 16 | NSString *_typeString; 17 | NSUInteger _address; 18 | 19 | BOOL _hasParsedType; 20 | NSArray *_parsedMethodTypes; 21 | } 22 | 23 | - (id)init; 24 | { 25 | [NSException raise:@"RejectUnusedImplementation" format:@"-initWithName:typeString:imp: is the designated initializer"]; 26 | return nil; 27 | } 28 | 29 | - (id)initWithName:(NSString *)name typeString:(NSString *)typeString; 30 | { 31 | return [self initWithName:name typeString:typeString address:0]; 32 | } 33 | 34 | - (id)initWithName:(NSString *)name typeString:(NSString *)typeString address:(NSUInteger)address; 35 | { 36 | if ((self = [super init])) { 37 | _name = name; 38 | _typeString = typeString; 39 | _address = address; 40 | 41 | _hasParsedType = NO; 42 | _parsedMethodTypes = nil; 43 | } 44 | 45 | return self; 46 | } 47 | 48 | #pragma mark - NSCopying 49 | 50 | - (id)copyWithZone:(NSZone *)zone; 51 | { 52 | return [[CDOCMethod alloc] initWithName:self.name typeString:self.typeString address:self.address]; 53 | } 54 | 55 | #pragma mark - Debugging 56 | 57 | - (NSString *)description; 58 | { 59 | return [NSString stringWithFormat:@"[%@] name: %@, typeString: %@, address: 0x%016lx", 60 | NSStringFromClass([self class]), self.name, self.typeString, self.address]; 61 | } 62 | 63 | #pragma mark - 64 | 65 | - (NSArray *)parsedMethodTypes; 66 | { 67 | if (_hasParsedType == NO) { 68 | NSError *error = nil; 69 | 70 | CDTypeParser *parser = [[CDTypeParser alloc] initWithString:self.typeString]; 71 | _parsedMethodTypes = [parser parseMethodType:&error]; 72 | if (_parsedMethodTypes == nil) 73 | DLog(@"Warning: Parsing method types failed, %@", self.name); 74 | _hasParsedType = YES; 75 | } 76 | 77 | return _parsedMethodTypes; 78 | } 79 | 80 | - (void)appendToString:(NSMutableString *)resultString typeController:(CDTypeController *)typeController; 81 | { 82 | NSString *formattedString = [typeController.methodTypeFormatter formatMethodName:self.name typeString:self.typeString]; 83 | if (formattedString != nil) { 84 | [resultString appendString:formattedString]; 85 | [resultString appendString:@";"]; 86 | if (typeController.shouldShowMethodAddresses && self.address != 0) { 87 | if (typeController.targetArchUses64BitABI) 88 | [resultString appendFormat:@"\t// IMP=0x%016lx", self.address]; 89 | else 90 | [resultString appendFormat:@"\t// IMP=0x%08lx", self.address]; 91 | } 92 | } else 93 | [resultString appendFormat:@" // Error parsing type: %@, name: %@", self.typeString, self.name]; 94 | } 95 | 96 | #pragma mark - Sorting 97 | 98 | - (NSComparisonResult)ascendingCompareByName:(CDOCMethod *)other; 99 | { 100 | return [self.name compare:other.name]; 101 | } 102 | 103 | @end 104 | -------------------------------------------------------------------------------- /classdumpios/Classes/OC/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/OC/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/OC/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/OC/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/OC/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/OC/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/ObjC/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-2019 Steve Nygard. 5 | 6 | #import "CDObjectiveCProcessor.h" 7 | 8 | @interface CDObjectiveC1Processor : CDObjectiveCProcessor 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /classdumpios/Classes/ObjC/CDObjectiveC2Processor.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-2019 Steve Nygard. 5 | 6 | #import "CDObjectiveCProcessor.h" 7 | 8 | #define METHOD_LIST_T_RESERVED_BITS 0x7FFF0003 9 | #define METHOD_LIST_T_SMALL_METHOD_FLAG 0x80000000 10 | #define METHOD_LIST_T_ENTSIZE_MASK (METHOD_LIST_T_RESERVED_BITS|METHOD_LIST_T_SMALL_METHOD_FLAG) 11 | 12 | @interface CDObjectiveC2Processor : CDObjectiveCProcessor 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /classdumpios/Classes/ObjC/CDObjectiveCProcessor.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-2019 Steve Nygard. 5 | 6 | @class CDMachOFile, CDSection, CDTypeController; 7 | @class CDVisitor; 8 | @class CDOCClass, CDOCCategory; 9 | @class CDProtocolUniquer; 10 | 11 | @interface CDObjectiveCProcessor : NSObject 12 | 13 | - (id)initWithMachOFile:(CDMachOFile *)machOFile; 14 | 15 | @property (readonly) CDMachOFile *machOFile; 16 | @property (nonatomic, readonly) BOOL hasObjectiveCData; 17 | @property (readwrite, assign) BOOL shallow; 18 | 19 | @property (nonatomic, readonly) CDSection *objcImageInfoSection; 20 | @property (nonatomic, readonly) NSString *garbageCollectionStatus; 21 | 22 | - (void)addClass:(CDOCClass *)aClass withAddress:(uint64_t)address; 23 | - (CDOCClass *)classWithAddress:(uint64_t)address; 24 | 25 | - (void)addClassesFromArray:(NSArray *)array; 26 | - (void)addCategoriesFromArray:(NSArray *)array; 27 | 28 | - (void)addCategory:(CDOCCategory *)category; 29 | 30 | - (void)processStoppingEarly:(BOOL)stopEarly; 31 | - (void)process; 32 | - (void)loadProtocols; 33 | - (void)loadClasses; 34 | - (void)loadCategories; 35 | 36 | - (void)registerTypesWithObject:(CDTypeController *)typeController phase:(NSUInteger)phase; 37 | - (void)recursivelyVisit:(CDVisitor *)visitor; 38 | 39 | - (NSArray *)protocolAddressListAtAddress:(uint64_t)address; 40 | 41 | @property (readonly) CDProtocolUniquer *protocolUniquer; 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/CDBalanceFormatter.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-2019 Steve Nygard. 5 | 6 | #import "CDBalanceFormatter.h" 7 | 8 | @implementation CDBalanceFormatter 9 | { 10 | NSScanner *_scanner; 11 | NSCharacterSet *_openCloseSet; 12 | 13 | NSMutableString *_result; 14 | } 15 | 16 | - (id)initWithString:(NSString *)str; 17 | { 18 | if ((self = [super init])) { 19 | if (!str){ 20 | VerboseLog(@"%s NSScanner initWithString: %@", _cmds, str); 21 | } 22 | _scanner = [[NSScanner alloc] initWithString:str]; 23 | _openCloseSet = [NSCharacterSet characterSetWithCharactersInString:@"{}<>()"]; 24 | 25 | _result = [[NSMutableString alloc] init]; 26 | } 27 | 28 | return self; 29 | } 30 | 31 | #pragma mark - 32 | 33 | - (void)parse:(NSString *)open index:(NSUInteger)openIndex level:(NSUInteger)level; 34 | { 35 | NSString *opens[] = { @"{", @"<", @"(", nil}; 36 | NSString *closes[] = { @"}", @">", @")", nil}; 37 | BOOL foundOpen = NO; 38 | BOOL foundClose = NO; 39 | 40 | while ([_scanner isAtEnd] == NO) { 41 | NSString *pre; 42 | 43 | if ([_scanner scanUpToCharactersFromSet:_openCloseSet intoString:&pre]) { 44 | VerboseLog(@"pre = '%@'", pre); 45 | [_result appendFormat:@"%@%@\n", [NSString spacesIndentedToLevel:level], pre]; 46 | } 47 | VerboseLog(@"remaining: '%@'", [[_scanner string] substringFromIndex:[_scanner scanLocation]]); 48 | 49 | foundOpen = foundClose = NO; 50 | for (NSUInteger index = 0; index < 3; index++) { 51 | VerboseLog(@"Checking open %lu: '%@'", index, opens[index]); 52 | if ([_scanner scanString:opens[index] intoString:NULL]) { 53 | VerboseLog(@"Start %@", opens[index]); 54 | [_result appendSpacesIndentedToLevel:level]; 55 | [_result appendString:opens[index]]; 56 | [_result appendString:@"\n"]; 57 | 58 | [self parse:opens[index] index:[_scanner scanLocation] - 1 level:level + 1]; 59 | 60 | [_result appendSpacesIndentedToLevel:level]; 61 | [_result appendString:closes[index]]; 62 | [_result appendString:@"\n"]; 63 | foundOpen = YES; 64 | break; 65 | } 66 | 67 | VerboseLog(@"Checking close %lu: '%@'", index, closes[index]); 68 | if ([_scanner scanString:closes[index] intoString:NULL]) { 69 | if ([open isEqualToString:opens[index]]) { 70 | VerboseLog(@"End %@", closes[index]); 71 | } else { 72 | VerboseLog(@"ERROR: Unmatched end %@", closes[index]); 73 | } 74 | foundClose = YES; 75 | break; 76 | } 77 | } 78 | 79 | if (foundOpen == NO && foundClose == NO) { 80 | VerboseLog(@"Unknown @ %lu: %@", [_scanner scanLocation], [[_scanner string] substringFromIndex:[_scanner scanLocation]]); 81 | break; 82 | } 83 | 84 | if (foundClose) 85 | break; 86 | } 87 | } 88 | 89 | - (NSString *)format; 90 | { 91 | [self parse:nil index:0 level:0]; 92 | 93 | VerboseLog(@"result:\n%@", _result); 94 | 95 | return [NSString stringWithString:_result]; 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/CDProtocolUniquer.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-2019 Steve Nygard. 5 | 6 | #import "CDProtocolUniquer.h" 7 | 8 | #import "CDOCProtocol.h" 9 | #import "CDOCMethod.h" 10 | 11 | @implementation CDProtocolUniquer 12 | { 13 | NSMutableDictionary *_protocolsByAddress; // non-uniqued 14 | NSMutableDictionary *_uniqueProtocolsByName; 15 | NSMutableDictionary *_uniqueProtocolsByAddress; 16 | } 17 | 18 | - (id)init; 19 | { 20 | if ((self = [super init])) { 21 | _protocolsByAddress = [[NSMutableDictionary alloc] init]; 22 | _uniqueProtocolsByName = [[NSMutableDictionary alloc] init]; 23 | _uniqueProtocolsByAddress = [[NSMutableDictionary alloc] init]; 24 | } 25 | 26 | return self; 27 | } 28 | 29 | #pragma mark - Gather 30 | 31 | - (CDOCProtocol *)protocolWithAddress:(uint64_t)address; 32 | { 33 | NSNumber *key = [NSNumber numberWithUnsignedLongLong:address]; 34 | return _protocolsByAddress[key]; 35 | } 36 | 37 | - (void)setProtocol:(CDOCProtocol *)protocol withAddress:(uint64_t)address; 38 | { 39 | NSNumber *key = [NSNumber numberWithUnsignedLongLong:address]; 40 | _protocolsByAddress[key] = protocol; 41 | } 42 | 43 | #pragma mark - Process 44 | 45 | - (void)createUniquedProtocols; 46 | { 47 | [_uniqueProtocolsByName removeAllObjects]; 48 | [_uniqueProtocolsByAddress removeAllObjects]; 49 | 50 | // Now unique the protocols by name and store in protocolsByName 51 | 52 | for (NSNumber *key in [[_protocolsByAddress allKeys] sortedArrayUsingSelector:@selector(compare:)]) { 53 | CDOCProtocol *p1 = _protocolsByAddress[key]; 54 | VerboseLog(@"p1 name: %@", p1); 55 | if (p1.name == nil) { 56 | continue; 57 | } 58 | CDOCProtocol *uniqueProtocol = _uniqueProtocolsByName[p1.name]; 59 | if (uniqueProtocol == nil) { 60 | uniqueProtocol = [[CDOCProtocol alloc] init]; 61 | [uniqueProtocol setName:[p1 name]]; 62 | _uniqueProtocolsByName[uniqueProtocol.name] = uniqueProtocol; 63 | // adopted protocols still not set, will want uniqued instances 64 | } else { 65 | } 66 | if (key){ 67 | _uniqueProtocolsByAddress[key] = uniqueProtocol; 68 | } else { 69 | VerboseLog(@"no key for %@", uniqueProtocol); 70 | } 71 | } 72 | 73 | InfoLog(@"uniqued protocol names: %@", [[[_uniqueProtocolsByName allKeys] sortedArrayUsingSelector:@selector(compare:)] componentsJoinedByString:@", "]); 74 | 75 | // And finally fill in adopted protocols, instance and class methods. And properties. 76 | for (NSNumber *key in [[_protocolsByAddress allKeys] sortedArrayUsingSelector:@selector(compare:)]) { 77 | CDOCProtocol *p1 = _protocolsByAddress[key]; 78 | CDOCProtocol *uniqueProtocol = _uniqueProtocolsByName[p1.name]; 79 | 80 | // Add the uniqued adopted protocols 81 | for (CDOCProtocol *p2 in [p1 protocols]) { 82 | id prot = _uniqueProtocolsByName[p2.name]; 83 | if (prot) { 84 | [uniqueProtocol addProtocol:prot]; 85 | } 86 | } 87 | 88 | [uniqueProtocol mergeMethodsFromProtocol:p1]; 89 | [uniqueProtocol mergePropertiesFromProtocol:p1]; 90 | } 91 | 92 | InfoLog(@"protocolsByName: %@", _uniqueProtocolsByName); 93 | } 94 | 95 | #pragma mark - Results 96 | 97 | // These are useful after the call to -createUniqueProtocols 98 | 99 | - (NSArray *)uniqueProtocolsAtAddresses:(NSArray *)addresses; 100 | { 101 | InfoLog(@"%s: addresses: %@", _cmds, addresses); 102 | NSMutableArray *protocols = [NSMutableArray array]; 103 | 104 | for (NSNumber *protocolAddress in addresses) { 105 | CDOCProtocol *uniqueProtocol = _uniqueProtocolsByAddress[protocolAddress]; 106 | if (uniqueProtocol != nil) 107 | [protocols addObject:uniqueProtocol]; 108 | } 109 | 110 | return [protocols copy]; 111 | } 112 | 113 | - (NSArray *)uniqueProtocolsSortedByName; 114 | { 115 | return [[_uniqueProtocolsByName allValues] sortedArrayUsingSelector:@selector(ascendingCompareByName:)]; 116 | } 117 | 118 | @end 119 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/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-2019 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 | DLog(@"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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/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-2019 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 (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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/CDSection.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-2019 Steve Nygard. 5 | 6 | #import "CDSection.h" 7 | 8 | #include 9 | #import "CDMachOFile.h" 10 | #import "CDMachOFileDataCursor.h" 11 | #import "CDLCSegment.h" 12 | 13 | @implementation CDSection 14 | { 15 | struct section_64 _section; // 64-bit, also holding 32-bit 16 | } 17 | 18 | @synthesize data = _data; 19 | 20 | - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor segment:(CDLCSegment *)segment; 21 | { 22 | if ((self = [super init])) { 23 | _segment = segment; 24 | if (cursor.remaining <= 16) { 25 | NSLog(@"cursor remaining: %lu is bad, gonna crash. investigate later.", cursor.remaining); 26 | //return nil; 27 | } 28 | _sectionName = [cursor readStringOfLength:16 encoding:NSASCIIStringEncoding]; 29 | size_t sectionNameLength = [_sectionName lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; 30 | memcpy(_section.sectname, [_sectionName UTF8String], MIN(sectionNameLength, sizeof(_section.sectname))); 31 | size_t segmentNameLength = [_sectionName lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; 32 | _segmentName = [cursor readStringOfLength:16 encoding:NSASCIIStringEncoding]; 33 | memcpy(_section.segname, [_segmentName UTF8String], MIN(segmentNameLength, sizeof(_section.segname))); 34 | _section.addr = [cursor readPtr]; 35 | _section.size = [cursor readPtr]; 36 | _section.offset = [cursor readInt32]; 37 | uint32_t dyldOffset = (uint32_t)(_section.addr - segment.vmaddr + segment.fileoff); 38 | if (_section.offset > 0 && _section.offset != dyldOffset) { 39 | fprintf(stderr, "Warning: Invalid section offset 0x%08x replaced with 0x%08x in %s,%s\n", _section.offset, dyldOffset, [_segmentName UTF8String], [_sectionName UTF8String]); 40 | _section.offset = dyldOffset; 41 | } 42 | _section.align = [cursor readInt32]; 43 | _section.reloff = [cursor readInt32]; 44 | _section.nreloc = [cursor readInt32]; 45 | _section.flags = [cursor readInt32]; 46 | _section.reserved1 = [cursor readInt32]; 47 | _section.reserved2 = [cursor readInt32]; 48 | if (cursor.machOFile.uses64BitABI) { 49 | _section.reserved3 = [cursor readInt32]; 50 | } 51 | } 52 | 53 | return self; 54 | } 55 | 56 | #pragma mark - 57 | 58 | - (NSData *)data; 59 | { 60 | if (!_data) { 61 | _data = [[NSData alloc] initWithBytes:(uint8_t *)[self.segment.machOFile.data bytes] + _section.offset length:_section.size]; 62 | } 63 | return _data; 64 | } 65 | 66 | - (NSUInteger)addr; 67 | { 68 | return _section.addr; 69 | } 70 | 71 | - (NSUInteger)size; 72 | { 73 | return _section.size; 74 | } 75 | 76 | - (BOOL)containsAddress:(NSUInteger)address; 77 | { 78 | return (address >= _section.addr) && (address < _section.addr + _section.size); 79 | } 80 | 81 | - (NSUInteger)fileOffsetForAddress:(NSUInteger)address; 82 | { 83 | NSParameterAssert([self containsAddress:address]); 84 | NSUInteger offset = _section.offset + address - _section.addr; 85 | VerboseLog(@"%s %lu + %lu - %lu = %lu (%016llx)", _cmds, _section.offset, address, _section.addr, offset, offset); 86 | return offset; 87 | } 88 | 89 | #pragma mark - Debugging 90 | 91 | - (NSString *)description; 92 | { 93 | int padding = (int)self.segment.machOFile.ptrSize * 2; 94 | return [NSString stringWithFormat:@"<%@:%p> '%@,%-16s' addr: %0*llx, size: %0*llx", 95 | NSStringFromClass([self class]), self, 96 | self.segmentName, [self.sectionName UTF8String], 97 | padding, _section.addr, padding, _section.size]; 98 | } 99 | 100 | @end 101 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/CDStructureInfo.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-2019 Steve Nygard. 5 | 6 | #import "CDStructureInfo.h" 7 | 8 | #import "CDType.h" 9 | #import "CDTypeName.h" 10 | #import "NSString-CDExtensions.h" 11 | // If it's used in a method, then it should be declared at the top. (name or typedef) 12 | 13 | @implementation CDStructureInfo 14 | { 15 | CDType *_type; 16 | NSUInteger _referenceCount; 17 | BOOL _isUsedInMethod; 18 | NSString *_typedefName; 19 | } 20 | 21 | - (id)initWithType:(CDType *)type; 22 | { 23 | if ((self = [super init])) { 24 | _type = [type copy]; 25 | _referenceCount = 1; 26 | _isUsedInMethod = NO; 27 | _typedefName = nil; 28 | } 29 | 30 | return self; 31 | } 32 | 33 | #pragma mark - NSCopying 34 | 35 | - (id)copyWithZone:(NSZone *)zone; 36 | { 37 | CDStructureInfo *copy = [[CDStructureInfo alloc] initWithType:self.type]; // type gets copied 38 | copy.referenceCount = self.referenceCount; 39 | copy.isUsedInMethod = self.isUsedInMethod; 40 | copy.typedefName = self.typedefName; 41 | 42 | return copy; 43 | } 44 | 45 | #pragma mark - Debugging 46 | 47 | - (NSString *)description; 48 | { 49 | return [NSString stringWithFormat:@"<%@:%p> depth: %lu, refcount: %lu, isUsedInMethod: %u, type: %p", 50 | NSStringFromClass([self class]), self, 51 | self.type.structureDepth, self.referenceCount, self.isUsedInMethod, self.type]; 52 | } 53 | 54 | - (NSString *)shortDescription; 55 | { 56 | return [NSString stringWithFormat:@"%lu %lu m?%u %@ %@", self.type.structureDepth, self.referenceCount, self.isUsedInMethod, self.type.bareTypeString, self.type.typeString]; 57 | } 58 | 59 | #pragma mark - 60 | 61 | - (void)addReferenceCount:(NSUInteger)count; 62 | { 63 | self.referenceCount += count; 64 | } 65 | 66 | // Do this before generating member names. 67 | - (void)generateTypedefName:(NSString *)baseName; 68 | { 69 | NSString *digest = [self.type.typeString SHA1DigestString]; 70 | NSUInteger length = [digest length]; 71 | if (length > 8) 72 | digest = [digest substringFromIndex:length - 8]; 73 | 74 | self.typedefName = [NSString stringWithFormat:@"%@%@", baseName, digest]; 75 | //DLog(@"typedefName: %@", self.typedefName); 76 | } 77 | 78 | - (NSString *)name; 79 | { 80 | return [self.type.typeName description]; 81 | } 82 | 83 | #pragma mark - Sorting 84 | 85 | // Structure depth, reallyBareTypeString, typeString 86 | - (NSComparisonResult)ascendingCompareByStructureDepth:(CDStructureInfo *)other; 87 | { 88 | NSUInteger thisDepth = self.type.structureDepth; 89 | NSUInteger otherDepth = other.type.structureDepth; 90 | 91 | if (thisDepth < otherDepth) return NSOrderedAscending; 92 | if (thisDepth > otherDepth) return NSOrderedDescending; 93 | 94 | NSString *str1 = self.type.reallyBareTypeString; 95 | NSString *str2 = other.type.reallyBareTypeString; 96 | NSComparisonResult result = [str1 compare:str2]; 97 | if (result == NSOrderedSame) { 98 | str1 = self.type.typeString; 99 | str2 = other.type.typeString; 100 | result = [str1 compare:str2]; 101 | } 102 | 103 | return result; 104 | } 105 | 106 | - (NSComparisonResult)descendingCompareByStructureDepth:(CDStructureInfo *)other; 107 | { 108 | NSUInteger thisDepth = self.type.structureDepth; 109 | NSUInteger otherDepth = other.type.structureDepth; 110 | 111 | if (thisDepth < otherDepth) return NSOrderedDescending; 112 | if (thisDepth > otherDepth) return NSOrderedAscending; 113 | 114 | NSString *str1 = self.type.reallyBareTypeString; 115 | NSString *str2 = other.type.reallyBareTypeString; 116 | NSComparisonResult result = -[str1 compare:str2]; 117 | if (result == NSOrderedSame) { 118 | str1 = self.type.typeString; 119 | str2 = other.type.typeString; 120 | result = -[str1 compare:str2]; 121 | } 122 | 123 | return result; 124 | } 125 | 126 | @end 127 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/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-2019 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 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/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-2019 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 | DLog(@"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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Structure/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Type/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Type/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Type/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-2019 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 | 33 | @property (nonatomic, readonly) NSArray *members; 34 | @property (nonatomic, readonly) NSArray *types; 35 | 36 | @property (nonatomic, readonly) int typeIgnoringModifiers; 37 | @property (nonatomic, readonly) NSUInteger structureDepth; 38 | 39 | - (NSString *)formattedString:(NSString *)previousName formatter:(CDTypeFormatter *)typeFormatter level:(NSUInteger)level; 40 | 41 | @property (nonatomic, readonly) NSString *typeString; 42 | @property (nonatomic, readonly) NSString *bareTypeString; 43 | @property (nonatomic, readonly) NSString *reallyBareTypeString; 44 | @property (nonatomic, readonly) NSString *keyTypeString; 45 | 46 | 47 | - (BOOL)canMergeWithType:(CDType *)otherType; 48 | - (void)mergeWithType:(CDType *)otherType; 49 | 50 | @property (nonatomic, readonly) NSArray *memberVariableNames; 51 | - (void)generateMemberNames; 52 | 53 | // Phase 0 54 | - (void)phase:(NSUInteger)phase registerTypesWithObject:(CDTypeController *)typeController usedInMethod:(BOOL)isUsedInMethod; 55 | - (void)phase0RecursivelyFixStructureNames:(BOOL)flag; 56 | 57 | // Phase 1 58 | - (void)phase1RegisterStructuresWithObject:(CDTypeController *)typeController; 59 | 60 | // Phase 2 61 | - (void)phase2MergeWithTypeController:(CDTypeController *)typeController debug:(BOOL)phase2Debug; 62 | 63 | // Phase 3 64 | - (void)phase3RegisterMembersWithTypeController:(CDTypeController *)typeController; 65 | - (void)phase3MergeWithTypeController:(CDTypeController *)typeController; 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /classdumpios/Classes/Type/CDTypeController.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-2019 Steve Nygard. 5 | 6 | @protocol CDTypeControllerDelegate; 7 | 8 | @class CDClassDump, CDType, CDTypeFormatter; 9 | 10 | @interface CDTypeController : NSObject 11 | 12 | - (id)initWithClassDump:(CDClassDump *)classDump; 13 | 14 | @property id delegate; 15 | 16 | @property (readonly) CDTypeFormatter *ivarTypeFormatter; 17 | @property (readonly) CDTypeFormatter *methodTypeFormatter; 18 | @property (readonly) CDTypeFormatter *propertyTypeFormatter; 19 | @property (readonly) CDTypeFormatter *structDeclarationTypeFormatter; 20 | 21 | @property (nonatomic, readonly) BOOL shouldShowIvarOffsets; 22 | @property (nonatomic, readonly) BOOL shouldShowMethodAddresses; 23 | @property (nonatomic, readonly) BOOL targetArchUses64BitABI; 24 | 25 | @property (nonatomic, assign) BOOL hasUnknownFunctionPointers; 26 | @property (nonatomic, assign) BOOL hasUnknownBlocks; 27 | 28 | - (CDType *)typeFormatter:(CDTypeFormatter *)typeFormatter replacementForType:(CDType *)type; 29 | - (NSString *)typeFormatter:(CDTypeFormatter *)typeFormatter typedefNameForStructure:(CDType *)structureType level:(NSUInteger)level; 30 | - (void)typeFormatter:(CDTypeFormatter *)typeFormatter didReferenceClassName:(NSString *)name; 31 | - (void)typeFormatter:(CDTypeFormatter *)typeFormatter didReferenceProtocolNames:(NSArray *)names; 32 | 33 | - (void)appendStructuresToString:(NSMutableString *)resultString; 34 | 35 | // Phase 0 - initiated from -[CDClassDump registerTypes] 36 | - (void)phase0RegisterStructure:(CDType *)structure usedInMethod:(BOOL)isUsedInMethod; 37 | 38 | // Run phase 1+ 39 | - (void)workSomeMagic; 40 | 41 | // Phase 1 42 | - (void)phase1RegisterStructure:(CDType *)structure; 43 | 44 | - (void)endPhase:(NSUInteger)phase; 45 | 46 | - (CDType *)phase2ReplacementForType:(CDType *)type; 47 | 48 | - (void)phase3RegisterStructure:(CDType *)structure; 49 | - (CDType *)phase3ReplacementForType:(CDType *)type; 50 | 51 | - (BOOL)shouldShowName:(NSString *)name; 52 | - (BOOL)shouldExpandType:(CDType *)type; 53 | - (NSString *)typedefNameForType:(CDType *)type; 54 | 55 | @end 56 | 57 | #pragma mark - 58 | 59 | @protocol CDTypeControllerDelegate 60 | @optional 61 | - (void)typeController:(CDTypeController *)typeController didReferenceClassName:(NSString *)name; 62 | - (void)typeController:(CDTypeController *)typeController didReferenceProtocolNames:(NSArray *)names; 63 | @end 64 | -------------------------------------------------------------------------------- /classdumpios/Classes/Type/CDTypeFormatter.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-2019 Steve Nygard. 5 | 6 | @class CDType, CDTypeController; 7 | 8 | @interface CDTypeFormatter : NSObject 9 | 10 | @property CDTypeController *typeController; 11 | 12 | @property (assign) NSUInteger baseLevel; 13 | @property (assign) BOOL shouldExpand; 14 | @property (assign) BOOL shouldAutoExpand; 15 | @property (assign) BOOL shouldShowLexing; 16 | 17 | - (NSString *)formatVariable:(NSString *)name type:(CDType *)type; 18 | - (NSString *)formatMethodName:(NSString *)name typeString:(NSString *)typeString; 19 | 20 | - (NSString *)typedefNameForStructure:(CDType *)structureType level:(NSUInteger)level; 21 | 22 | - (void)formattingDidReferenceClassName:(NSString *)name; 23 | - (void)formattingDidReferenceProtocolNames:(NSArray *)names; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /classdumpios/Classes/Type/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Type/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Type/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Type/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Visitors/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-2019 Steve Nygard. 5 | 6 | #import "CDTextClassDumpVisitor.h" 7 | 8 | @interface CDClassDumpVisitor : CDTextClassDumpVisitor 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /classdumpios/Classes/Visitors/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Visitors/CDClassFrameworkVisitor.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-2019 Steve Nygard. 5 | 6 | #import "CDClassFrameworkVisitor.h" 7 | 8 | #import "CDMachOFile.h" 9 | #import "CDOCClass.h" 10 | #import "CDObjectiveCProcessor.h" 11 | #import "CDSymbol.h" 12 | #import "CDLCDylib.h" 13 | #import "CDOCCategory.h" 14 | #import "CDOCClassReference.h" 15 | 16 | @interface CDClassFrameworkVisitor () 17 | @property (strong) NSString *frameworkName; 18 | @end 19 | 20 | #pragma mark - 21 | 22 | @implementation CDClassFrameworkVisitor 23 | { 24 | NSMutableDictionary *_frameworkNamesByClassName; 25 | NSMutableDictionary *_frameworkNamesByProtocolName; 26 | NSString *_frameworkName; 27 | } 28 | 29 | - (id)init; 30 | { 31 | if ((self = [super init])) { 32 | _frameworkNamesByClassName = [[NSMutableDictionary alloc] init]; 33 | _frameworkNamesByProtocolName = [[NSMutableDictionary alloc] init]; 34 | } 35 | 36 | return self; 37 | } 38 | 39 | #pragma mark - 40 | 41 | - (void)willVisitObjectiveCProcessor:(CDObjectiveCProcessor *)processor; 42 | { 43 | self.frameworkName = processor.machOFile.importBaseName; 44 | } 45 | 46 | - (void)willVisitClass:(CDOCClass *)aClass; 47 | { 48 | [self addClassName:aClass.name referencedInFramework:self.frameworkName]; 49 | 50 | // We only need to add superclasses for external classes - classes defined in this binary will be visited on their own 51 | CDOCClassReference *superClassRef = [aClass superClassRef]; 52 | if ([superClassRef isExternalClass] && superClassRef.classSymbol != nil) { 53 | [self addClassForExternalSymbol:superClassRef.classSymbol]; 54 | } 55 | } 56 | 57 | - (void)willVisitProtocol:(CDOCProtocol *)protocol; 58 | { 59 | // TODO: (2012-02-28) Figure out what frameworks use each protocol, and try to pick the correct one. More difficult because, for example, NSCopying is found in many frameworks, and picking the last one isn't good enough. Perhaps a topological sort of the dependancies would be better. 60 | [self addProtocolName:protocol.name referencedInFramework:self.frameworkName]; 61 | } 62 | 63 | - (void)willVisitCategory:(CDOCCategory *)category; 64 | { 65 | CDOCClassReference *classRef = [category classRef]; 66 | if ([classRef isExternalClass] && classRef.classSymbol != nil) { 67 | [self addClassForExternalSymbol:classRef.classSymbol]; 68 | } 69 | } 70 | 71 | #pragma mark - 72 | 73 | - (void)addClassForExternalSymbol:(CDSymbol *)symbol; 74 | { 75 | NSString *frameworkName = CDImportNameForPath([[symbol dylibLoadCommand] path]); 76 | NSString *className = [CDSymbol classNameFromSymbolName:[symbol name]]; 77 | [self addClassName:className referencedInFramework:frameworkName]; 78 | } 79 | 80 | - (void)addClassName:(NSString *)name referencedInFramework:(NSString *)frameworkName; 81 | { 82 | if (name != nil && frameworkName != nil) 83 | _frameworkNamesByClassName[name] = frameworkName; 84 | } 85 | 86 | - (void)addProtocolName:(NSString *)name referencedInFramework:(NSString *)frameworkName; 87 | { 88 | if (name != nil && frameworkName != nil) 89 | _frameworkNamesByProtocolName[name] = frameworkName; 90 | } 91 | 92 | - (NSDictionary *)frameworkNamesByClassName; 93 | { 94 | return [_frameworkNamesByClassName copy]; 95 | } 96 | 97 | - (NSDictionary *)frameworkNamesByProtocolName; 98 | { 99 | return [_frameworkNamesByProtocolName copy]; 100 | } 101 | 102 | @end 103 | -------------------------------------------------------------------------------- /classdumpios/Classes/Visitors/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Visitors/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Visitors/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Visitors/CDVisitor.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-2019 Steve Nygard. 5 | 6 | @class CDClassDump, CDObjectiveCProcessor, CDOCProtocol, CDOCMethod, CDOCInstanceVariable, CDOCClass, CDOCCategory, CDOCProperty; 7 | @class CDVisitorPropertyState; 8 | 9 | @interface CDVisitor : NSObject 10 | 11 | @property (strong) CDClassDump *classDump; 12 | 13 | - (void)willBeginVisiting; 14 | - (void)didEndVisiting; 15 | 16 | - (void)willVisitObjectiveCProcessor:(CDObjectiveCProcessor *)processor; 17 | - (void)visitObjectiveCProcessor:(CDObjectiveCProcessor *)processor; 18 | - (void)didVisitObjectiveCProcessor:(CDObjectiveCProcessor *)processor; 19 | 20 | - (void)willVisitProtocol:(CDOCProtocol *)protocol; 21 | - (void)didVisitProtocol:(CDOCProtocol *)protocol; 22 | 23 | - (void)willVisitPropertiesOfProtocol:(CDOCProtocol *)protocol; 24 | - (void)didVisitPropertiesOfProtocol:(CDOCProtocol *)protocol; 25 | 26 | - (void)willVisitOptionalMethods; 27 | - (void)didVisitOptionalMethods; 28 | 29 | - (void)willVisitClass:(CDOCClass *)aClass; 30 | - (void)didVisitClass:(CDOCClass *)aClass; 31 | 32 | - (void)willVisitIvarsOfClass:(CDOCClass *)aClass; 33 | - (void)didVisitIvarsOfClass:(CDOCClass *)aClass; 34 | 35 | - (void)willVisitPropertiesOfClass:(CDOCClass *)aClass; 36 | - (void)didVisitPropertiesOfClass:(CDOCClass *)aClass; 37 | 38 | - (void)willVisitCategory:(CDOCCategory *)category; 39 | - (void)didVisitCategory:(CDOCCategory *)category; 40 | 41 | - (void)willVisitPropertiesOfCategory:(CDOCCategory *)category; 42 | - (void)didVisitPropertiesOfCategory:(CDOCCategory *)category; 43 | 44 | - (void)visitClassMethod:(CDOCMethod *)method; 45 | - (void)visitInstanceMethod:(CDOCMethod *)method propertyState:(CDVisitorPropertyState *)propertyState; 46 | - (void)visitIvar:(CDOCInstanceVariable *)ivar; 47 | - (void)visitProperty:(CDOCProperty *)property; 48 | 49 | - (void)visitRemainingProperties:(CDVisitorPropertyState *)propertyState; 50 | 51 | @property (assign) BOOL shouldShowStructureSection; 52 | @property (assign) BOOL shouldShowProtocolSection; 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /classdumpios/Classes/Visitors/CDVisitor.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-2019 Steve Nygard. 5 | 6 | #import "CDVisitor.h" 7 | 8 | #import "CDClassDump.h" 9 | 10 | @implementation CDVisitor 11 | { 12 | CDClassDump *_classDump; 13 | BOOL _shouldShowStructureSection; 14 | BOOL _shouldShowProtocolSection; 15 | } 16 | 17 | - (id)init; 18 | { 19 | if ((self = [super init])) { 20 | _shouldShowStructureSection = YES; 21 | _shouldShowProtocolSection = YES; 22 | } 23 | 24 | return self; 25 | } 26 | 27 | #pragma mark - 28 | 29 | - (void)willBeginVisiting; 30 | { 31 | } 32 | 33 | - (void)didEndVisiting; 34 | { 35 | } 36 | 37 | // Called before visiting. 38 | - (void)willVisitObjectiveCProcessor:(CDObjectiveCProcessor *)processor; 39 | { 40 | } 41 | 42 | // This gets called before visiting the children, but only if it has children it will visit. 43 | - (void)visitObjectiveCProcessor:(CDObjectiveCProcessor *)processor; 44 | { 45 | } 46 | 47 | - (void)willVisitPropertiesOfProtocol:(CDOCProtocol *)protocol; 48 | { 49 | } 50 | 51 | - (void)didVisitPropertiesOfProtocol:(CDOCProtocol *)protocol; 52 | { 53 | } 54 | 55 | - (void)willVisitOptionalMethods; 56 | { 57 | } 58 | 59 | - (void)didVisitOptionalMethods; 60 | { 61 | } 62 | 63 | // Called after visiting. 64 | - (void)didVisitObjectiveCProcessor:(CDObjectiveCProcessor *)processor; 65 | { 66 | } 67 | 68 | - (void)willVisitProtocol:(CDOCProtocol *)protocol; 69 | { 70 | } 71 | 72 | - (void)didVisitProtocol:(CDOCProtocol *)protocol; 73 | { 74 | } 75 | 76 | - (void)willVisitClass:(CDOCClass *)aClass; 77 | { 78 | } 79 | 80 | - (void)didVisitClass:(CDOCClass *)aClass; 81 | { 82 | } 83 | 84 | - (void)willVisitIvarsOfClass:(CDOCClass *)aClass; 85 | { 86 | } 87 | 88 | - (void)didVisitIvarsOfClass:(CDOCClass *)aClass; 89 | { 90 | } 91 | 92 | - (void)willVisitPropertiesOfClass:(CDOCClass *)aClass; 93 | { 94 | } 95 | 96 | - (void)didVisitPropertiesOfClass:(CDOCClass *)aClass; 97 | { 98 | } 99 | 100 | - (void)willVisitCategory:(CDOCCategory *)category; 101 | { 102 | } 103 | 104 | - (void)didVisitCategory:(CDOCCategory *)category; 105 | { 106 | } 107 | 108 | - (void)willVisitPropertiesOfCategory:(CDOCCategory *)category; 109 | { 110 | } 111 | 112 | - (void)didVisitPropertiesOfCategory:(CDOCCategory *)category; 113 | { 114 | } 115 | 116 | - (void)visitClassMethod:(CDOCMethod *)method; 117 | { 118 | } 119 | 120 | - (void)visitInstanceMethod:(CDOCMethod *)method propertyState:(CDVisitorPropertyState *)propertyState; 121 | { 122 | } 123 | 124 | - (void)visitIvar:(CDOCInstanceVariable *)ivar; 125 | { 126 | } 127 | 128 | - (void)visitProperty:(CDOCProperty *)property; 129 | { 130 | } 131 | 132 | - (void)visitRemainingProperties:(CDVisitorPropertyState *)propertyState; 133 | { 134 | } 135 | 136 | @end 137 | -------------------------------------------------------------------------------- /classdumpios/Classes/Visitors/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-2019 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 | -------------------------------------------------------------------------------- /classdumpios/Classes/Visitors/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-2019 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 | if ([property name] == nil){ 29 | InfoLog(@"property: %@, getter: %@, setter: %@", property, [property getter], [property setter]); 30 | } else { 31 | _propertiesByName[property.name] = property; 32 | _propertiesByAccessor[property.getter] = property; 33 | if (property.isReadOnly == NO) { 34 | _propertiesByAccessor[property.setter] = property; 35 | } 36 | } 37 | } 38 | } 39 | 40 | return self; 41 | } 42 | 43 | #pragma mark - Debugging 44 | 45 | - (void)log; 46 | { 47 | DLog(@"propertiesByAccessor: %@", _propertiesByAccessor); 48 | DLog(@"propertiesByName: %@", _propertiesByName); 49 | } 50 | 51 | #pragma mark - 52 | 53 | - (CDOCProperty *)propertyForAccessor:(NSString *)str; 54 | { 55 | return _propertiesByAccessor[str]; 56 | } 57 | 58 | - (BOOL)hasUsedProperty:(CDOCProperty *)property; 59 | { 60 | return _propertiesByName[property.name] == nil; 61 | } 62 | 63 | - (void)useProperty:(CDOCProperty *)property; 64 | { 65 | [_propertiesByName removeObjectForKey:property.name]; 66 | } 67 | 68 | - (NSArray *)remainingProperties; 69 | { 70 | return [[_propertiesByName allValues] sortedArrayUsingSelector:@selector(ascendingCompareByName:)]; 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /classdumpios/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIdentifier 8 | com.stevenygard.class-dump 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | class-dump 13 | 14 | 15 | -------------------------------------------------------------------------------- /classdumpios/MachObjC-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'libMachObjC' target in the 'class-dump' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import "CDExtensions.h" 8 | #define _cmd __PRETTY_FUNCTION__ 9 | #endif 10 | -------------------------------------------------------------------------------- /classdumpios/Makefile: -------------------------------------------------------------------------------- 1 | GO_EASY_ON_ME=1 2 | THEOS_DEVICE_IP=guest-room.local 3 | DEBUG=0 4 | #FINALPACKAGE=0 5 | #ARCH=arm64 6 | #export ARCH=arm64 7 | ARCHS=arm64 8 | 9 | target = appletv 10 | include $(THEOS)/makefiles/common.mk 11 | 12 | TOOL_NAME = classdumpios 13 | classdumpios_CFLAGS = -fobjc-arc -I. -include Classes/Extensions/ext.h -include ../class-dump-Prefix.pch -I$(wildcard *.*h) -I$(wildcard "Classes/**") -IClasses/Extensions -IClasses/Core 14 | classdumpios_CFLAGS += -IClasses/Cursors -IClasses/Extras -IClasses/Extensions -IClasses/FileManagement -IClasses/LoadCommands 15 | classdumpios_CFLAGS += -IClasses/OC -IClasses/ObjC -IClasses/Structure -IClasses/Type -IClasses/Visitors 16 | classdumpios_FILES = $(wildcard *.*m) $(wildcard Classes/*.m) $(wildcard Classes/Core/*.m) 17 | classdumpios_FILES += $(wildcard Classes/Cursors/*.m) $(wildcard Classes/Extensions/*.m) 18 | classdumpios_FILES += $(wildcard Classes/Extras/*.m) $(wildcard Classes/FileManagement/*.m) 19 | classdumpios_FILES += $(wildcard Classes/OC/*.m) $(wildcard Classes/LoadCommands/*.m) 20 | classdumpios_FILES += $(wildcard Classes/ObjC/*.m) $(wildcard Classes/Structure/*.m) 21 | classdumpios_FILES += $(wildcard Classes/Type/*.m) $(wildcard Classes/Visitors/*.m) 22 | classdumpios_CODESIGN_FLAGS=-Sent.plist 23 | include $(THEOS_MAKE_PATH)/tool.mk 24 | -------------------------------------------------------------------------------- /classdumpios/Makefile.ios: -------------------------------------------------------------------------------- 1 | GO_EASY_ON_ME=1 2 | THEOS_DEVICE_IP=guest-room.local 3 | DEBUG=1 4 | #FINALPACKAGE=0 5 | #ARCH=arm64 6 | #export ARCH=arm64 7 | ARCHS=arm64 8 | 9 | target = iphone 10 | include $(THEOS)/makefiles/common.mk 11 | 12 | TOOL_NAME = classdumpios 13 | classdumpios_CFLAGS = -fobjc-arc -I. -include Classes/Extensions/ext.h -include ../class-dump-Prefix.pch -I$(wildcard *.*h) -I$(wildcard "Classes/**") -IClasses/Extensions -IClasses/Core 14 | classdumpios_CFLAGS += -IClasses/Cursors -IClasses/Extras -IClasses/Extensions -IClasses/FileManagement -IClasses/LoadCommands 15 | classdumpios_CFLAGS += -IClasses/OC -IClasses/ObjC -IClasses/Structure -IClasses/Type -IClasses/Visitors 16 | classdumpios_FILES = $(wildcard *.*m) $(wildcard Classes/*.m) $(wildcard Classes/Core/*.m) 17 | classdumpios_FILES += $(wildcard Classes/Cursors/*.m) $(wildcard Classes/Extensions/*.m) 18 | classdumpios_FILES += $(wildcard Classes/Extras/*.m) $(wildcard Classes/FileManagement/*.m) 19 | classdumpios_FILES += $(wildcard Classes/OC/*.m) $(wildcard Classes/LoadCommands/*.m) 20 | classdumpios_FILES += $(wildcard Classes/ObjC/*.m) $(wildcard Classes/Structure/*.m) 21 | classdumpios_FILES += $(wildcard Classes/Type/*.m) $(wildcard Classes/Visitors/*.m) 22 | include $(THEOS_MAKE_PATH)/tool.mk 23 | -------------------------------------------------------------------------------- /classdumpios/README.md: -------------------------------------------------------------------------------- 1 | class-dump-c 2 | ========== 3 | 4 | It is no longer necessary to build using Theos, there are native build targets in the Xcode project as well now. 5 | 6 | This is a port for Theos build by me. 7 | 8 | class-dump is a command-line utility for examining the Objective-C 9 | segment of Mach-O files. It generates declarations for the classes, 10 | categories and protocols. This is the same information provided by 11 | using 'otool -ov', but presented as normal Objective-C declarations. 12 | 13 | The latest version and information is available at: 14 | 15 | http://stevenygard.com/projects/class-dump 16 | 17 | Usage 18 | ----- 19 | 20 | class-dump-c 4.2.0 (64 bit) 21 | Usage: classdumpc [options] 22 | 23 | where options are: 24 | -a show instance variable offsets 25 | -A show implementation addresses 26 | --arch choose a specific architecture from a universal binary (ppc, ppc64, i386, x86_64) 27 | -C only display classes matching regular expression 28 | -f find string in method name 29 | -H generate header files in current directory, or directory specified with -o 30 | -I sort classes, categories, and protocols by inheritance (overrides -s) 31 | -o output directory used for -H 32 | -r recursively expand frameworks and fixed VM shared libraries 33 | -s sort classes and categories by name 34 | -S sort methods by name 35 | -t suppress header in output, for testing 36 | -e dump the entitlements 37 | --list-arches list the arches in the file, then exit 38 | --sdk-ios specify iOS SDK version (will look in /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk 39 | --sdk-mac specify Mac OS X version (will look in /Developer/SDKs/MacOSX.sdk 40 | --sdk-root specify the full SDK root path (or use --sdk-ios/--sdk-mac for a shortcut) 41 | 42 | - class-dump-ios AppKit: 43 | 44 | classdumpios /System/Library/Frameworks/AppKit.framework 45 | 46 | - class-dump-ios UIKit: 47 | 48 | classdumpios /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/UIKit.framework 49 | 50 | - class-dump-ios UIKit and all the frameworks it uses: 51 | 52 | classdumpios /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/UIKit.framework -r --sdk-ios 4.3 53 | 54 | - class-dump-ios UIKit (and all the frameworks it uses) from developer tools that have been installed in /Dev42 instead of /Developer: 55 | 56 | classdumpios /Dev42/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/System/Library/Frameworks/UIKit.framework -r --sdk-root /Dev42/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk 57 | 58 | 59 | License 60 | ------- 61 | 62 | This file is part of class-dump, a utility for examining the 63 | Objective-C segment of Mach-O files. 64 | Copyright (C) 1997-2019 Steve Nygard. 65 | 66 | This program is free software; you can redistribute it and/or modify 67 | it under the terms of the GNU General Public License as published by 68 | the Free Software Foundation; either version 2 of the License, or 69 | (at your option) any later version. 70 | 71 | This program is distributed in the hope that it will be useful, 72 | but WITHOUT ANY WARRANTY; without even the implied warranty of 73 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 74 | GNU General Public License for more details. 75 | 76 | You should have received a copy of the GNU General Public License 77 | along with this program; if not, write to the Free Software 78 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 79 | -------------------------------------------------------------------------------- /classdumpios/classdumpios: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lechium/classdumpios/69313e369d2d3ff9f76d52b5546a38f0e4bcb0e5/classdumpios/classdumpios -------------------------------------------------------------------------------- /classdumpios/control: -------------------------------------------------------------------------------- 1 | Package: io.github.ddv.class-dump-ios 2 | Name: class-dump-ios 3 | Depends: 4 | Version: 1.0.1 5 | Architecture: appletvos-arm64 6 | Description: class-dump is a command-line utility for examining the Objective-C segment of Mach-O files. It generates declarations for the classes, categories and protocols. This is the same information provided by using 'otool -ov', but presented as normal Objective-C declarations. 7 | Maintainer: DreamDevLost 8 | Author: DreamDevLost 9 | Section: System 10 | Tag: role::hacker 11 | -------------------------------------------------------------------------------- /classdumpios/ent.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | platform-application 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /classdumpios/keys.txt: -------------------------------------------------------------------------------- 1 | APPNAME=class-dump 2 | SHORT_DESCRIPTION=a utility for examining the Objective-C segment of Mach-O files 3 | OWNER=Steve Nygard 4 | COPYRIGHT=Copyright (C) 1997-2019 Steve Nygard. 5 | -------------------------------------------------------------------------------- /samples/sample.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lechium/classdumpios/69313e369d2d3ff9f76d52b5546a38f0e4bcb0e5/samples/sample.out -------------------------------------------------------------------------------- /samples/sample1.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lechium/classdumpios/69313e369d2d3ff9f76d52b5546a38f0e4bcb0e5/samples/sample1.out -------------------------------------------------------------------------------- /samples/sample3.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lechium/classdumpios/69313e369d2d3ff9f76d52b5546a38f0e4bcb0e5/samples/sample3.out -------------------------------------------------------------------------------- /samples/sample_ios.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lechium/classdumpios/69313e369d2d3ff9f76d52b5546a38f0e4bcb0e5/samples/sample_ios.out -------------------------------------------------------------------------------- /samples/sample_ios_old.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lechium/classdumpios/69313e369d2d3ff9f76d52b5546a38f0e4bcb0e5/samples/sample_ios_old.out -------------------------------------------------------------------------------- /samples/sample_ios_standard.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lechium/classdumpios/69313e369d2d3ff9f76d52b5546a38f0e4bcb0e5/samples/sample_ios_standard.out -------------------------------------------------------------------------------- /samples/sample_ios_swift.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lechium/classdumpios/69313e369d2d3ff9f76d52b5546a38f0e4bcb0e5/samples/sample_ios_swift.out -------------------------------------------------------------------------------- /samples/sample_macos_normal.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lechium/classdumpios/69313e369d2d3ff9f76d52b5546a38f0e4bcb0e5/samples/sample_macos_normal.out -------------------------------------------------------------------------------- /samples/sample_swift.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lechium/classdumpios/69313e369d2d3ff9f76d52b5546a38f0e4bcb0e5/samples/sample_swift.out --------------------------------------------------------------------------------