forked from Polidea/ios-class-guard
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CDClassDumpVisitor.m
138 lines (115 loc) · 5.88 KB
/
CDClassDumpVisitor.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// -*- mode: ObjC -*-
// This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files.
// Copyright (C) 1997-1998, 2000-2001, 2004-2014 Steve Nygard.
#import "CDClassDumpVisitor.h"
#include <mach-o/arch.h>
#import "CDClassDump.h"
#import "CDObjectiveCProcessor.h"
#import "CDMachOFile.h"
#import "CDLCDylib.h"
#import "CDLCDylinker.h"
#import "CDLCEncryptionInfo.h"
#import "CDLCRunPath.h"
#import "CDLCSegment.h"
#import "CDLCSourceVersion.h"
#import "CDLCVersionMinimum.h"
#import "CDTypeController.h"
@implementation CDClassDumpVisitor
{
}
- (void)willBeginVisiting;
{
[super willBeginVisiting];
[self.classDump appendHeaderToString:self.resultString];
if (self.classDump.hasObjectiveCRuntimeInfo && self.shouldShowStructureSection) {
[self.classDump.typeController appendStructuresToString:self.resultString];
}
}
- (void)didEndVisiting;
{
[super didEndVisiting];
[self writeResultToStandardOutput];
}
- (void)visitObjectiveCProcessor:(CDObjectiveCProcessor *)processor;
{
CDMachOFile *machOFile = processor.machOFile;
[self.resultString appendString:@"#pragma mark -\n\n"];
[self.resultString appendString:@"//\n"];
[self.resultString appendFormat:@"// File: %@\n", machOFile.filename];
if (machOFile.UUID != nil) {
[self.resultString appendFormat:@"// UUID: %@\n", [machOFile.UUID UUIDString]];
}
[self.resultString appendString:@"//\n"];
[self.resultString appendFormat:@"// Arch: %@\n", CDNameForCPUType(machOFile.cputype, machOFile.cpusubtype)];
if (machOFile.filetype == MH_DYLIB) {
CDLCDylib *identifier = machOFile.dylibIdentifier;
if (identifier != nil) {
[self.resultString appendFormat:@"// Current version: %@\n", identifier.formattedCurrentVersion];
[self.resultString appendFormat:@"// Compatibility version: %@\n", identifier.formattedCompatibilityVersion];
}
}
if (machOFile.sourceVersion != nil)
[self.resultString appendFormat:@"// Source version: %@\n", machOFile.sourceVersion.sourceVersionString];
if (machOFile.minVersionMacOSX != nil) {
[self.resultString appendFormat:@"// Minimum Mac OS X version: %@\n", machOFile.minVersionMacOSX.minimumVersionString];
[self.resultString appendFormat:@"// SDK version: %@\n", machOFile.minVersionMacOSX.SDKVersionString];
}
if (machOFile.minVersionIOS != nil) {
[self.resultString appendFormat:@"// Minimum iOS version: %@\n", machOFile.minVersionIOS.minimumVersionString];
[self.resultString appendFormat:@"// SDK version: %@\n", machOFile.minVersionIOS.SDKVersionString];
}
if (processor.garbageCollectionStatus != nil) {
[self.resultString appendString:@"//\n"];
[self.resultString appendFormat:@"// Objective-C Garbage Collection: %@\n", processor.garbageCollectionStatus];
}
[machOFile.dyldEnvironment enumerateObjectsUsingBlock:^(CDLCDylinker *env, NSUInteger index, BOOL *stop){
if (index == 0) {
[self.resultString appendString:@"//\n"];
[self.resultString appendFormat:@"// dyld environment: %@\n", env.name];
} else {
[self.resultString appendFormat:@"// %@\n", env.name];
}
}];
if ([machOFile.runPathCommands count] > 0) {
[self.resultString appendString:@"//\n"];
for (CDLCRunPath *runPath in machOFile.runPathCommands) {
[self.resultString appendFormat:@"// Run path: %@\n", runPath.path];
[self.resultString appendFormat:@"// = %@\n", runPath.resolvedRunPath];
}
}
if (machOFile.isEncrypted) {
[self.resultString appendString:@"// This file is encrypted:\n"];
for (CDLoadCommand *loadCommand in machOFile.loadCommands) {
if ([loadCommand isKindOfClass:[CDLCEncryptionInfo class]]) {
CDLCEncryptionInfo *encryptionInfo = (CDLCEncryptionInfo *)loadCommand;
[self.resultString appendFormat:@"// cryptid: 0x%08x\n", encryptionInfo.cryptid];
[self.resultString appendFormat:@"// cryptoff: 0x%08x\n", encryptionInfo.cryptoff];
[self.resultString appendFormat:@"// cryptsize: 0x%08x\n", encryptionInfo.cryptsize];
}
}
} else if (machOFile.hasProtectedSegments) {
if (machOFile.canDecryptAllSegments) {
[self.resultString appendString:@"//\n"];
[self.resultString appendString:@"// This file has protected segments, decrypting.\n"];
} else {
[self.resultString appendString:@"//\n"];
[self.resultString appendString:@"// This file has protected segments that can't be decrypted:\n"];
[machOFile.loadCommands enumerateObjectsUsingBlock:^(CDLoadCommand *loadCommand, NSUInteger index, BOOL *stop){
if ([loadCommand isKindOfClass:[CDLCSegment class]]) {
CDLCSegment *segment = (CDLCSegment *)loadCommand;
if (segment.canDecrypt == NO) {
[self.resultString appendFormat:@"// Load command %lu, segment encryption: %@\n",
index, CDSegmentEncryptionTypeName(segment.encryptionType)];
}
}
}];
}
}
[self.resultString appendString:@"//\n\n"];
if (!self.classDump.hasObjectiveCRuntimeInfo) {
[self.resultString appendString:@"//\n"];
[self.resultString appendString:@"// This file does not contain any Objective-C runtime information.\n"];
[self.resultString appendString:@"//\n"];
}
}
@end