Skip to content

Commit ed6fad5

Browse files
committed
Merge pull request nygard#78 from BlueCocoa/master
2 parents 2f400a5 + 8849a88 commit ed6fad5

File tree

5 files changed

+116
-31
lines changed

5 files changed

+116
-31
lines changed

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,22 @@ The latest version and information is available at:
1313
The source code is also available from my Github repository at:
1414

1515
https://github.com/nygard/class-dump
16+
17+
"Swift support"
18+
==========
19+
20+
I added "Swift support" for class-dump.
21+
22+
Now, this tool can dump Objective-C headers even the MachO file uses Swift and ObjC at the same time.
23+
Notice, only ObjC headers can be dumped!
24+
25+
LAST, THIS IS AN EXPERIMENTAL VERSION.
26+
27+
我为class-dump添加了"Swift支持"。
28+
29+
现在,这个工具可以dump出可执行文件的Objective-C头文件,即使那个MachO文件同时使用了Swift和ObjC。请注意只有ObjC类的头文件可以被dump出来!
30+
31+
最后,这只是一个试验版本。
1632

1733
Usage
1834
-----

Source/CDDataCursor.m

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,27 @@ - (const void *)bytes;
3030

3131
- (void)setOffset:(NSUInteger)newOffset;
3232
{
33-
if (newOffset <= [_data length]) {
34-
_offset = newOffset;
35-
} else {
36-
[NSException raise:NSRangeException format:@"Trying to seek past end of data."];
33+
if (newOffset == -'S') {
34+
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
35+
_offset = -'S';
36+
}
37+
else
38+
{
39+
if (newOffset <= [_data length]) {
40+
_offset = newOffset;
41+
} else {
42+
[NSException raise:NSRangeException format:@"Trying to seek past end of data."];
43+
}
3744
}
3845
}
3946

4047
- (void)advanceByLength:(NSUInteger)length;
4148
{
49+
if (_offset == -'S') {
50+
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
51+
_offset += 10;
52+
return;
53+
}
4254
if (_offset + length <= [_data length]) {
4355
_offset += length;
4456
} else {
@@ -56,7 +68,10 @@ - (NSUInteger)remaining;
5668
- (uint8_t)readByte;
5769
{
5870
uint8_t result;
59-
71+
if (_offset == -'S') {
72+
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
73+
return 0;
74+
}
6075
if (_offset + sizeof(result) <= [_data length]) {
6176
result = OSReadLittleInt16([_data bytes], _offset) & 0xFF;
6277
_offset += sizeof(result);
@@ -71,7 +86,10 @@ - (uint8_t)readByte;
7186
- (uint16_t)readLittleInt16;
7287
{
7388
uint16_t result;
74-
89+
if (_offset == -'S') {
90+
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
91+
return 0;
92+
}
7593
if (_offset + sizeof(result) <= [_data length]) {
7694
result = OSReadLittleInt16([_data bytes], _offset);
7795
_offset += sizeof(result);
@@ -86,7 +104,10 @@ - (uint16_t)readLittleInt16;
86104
- (uint32_t)readLittleInt32;
87105
{
88106
uint32_t result;
89-
107+
if (_offset == -'S') {
108+
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
109+
return 0;
110+
}
90111
if (_offset + sizeof(result) <= [_data length]) {
91112
result = OSReadLittleInt32([_data bytes], _offset);
92113
_offset += sizeof(result);
@@ -101,7 +122,10 @@ - (uint32_t)readLittleInt32;
101122
- (uint64_t)readLittleInt64;
102123
{
103124
uint64_t result;
104-
125+
if (_offset == -'S') {
126+
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
127+
return 0;
128+
}
105129
if (_offset + sizeof(result) <= [_data length]) {
106130
// uint8_t *ptr = [_data bytes] + _offset;
107131
// NSLog(@"%016llx: %02x %02x %02x %02x %02x %02x %02x %02x", _offset, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]);
@@ -118,7 +142,10 @@ - (uint64_t)readLittleInt64;
118142
- (uint16_t)readBigInt16;
119143
{
120144
uint16_t result;
121-
145+
if (_offset == -'S') {
146+
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
147+
return 0;
148+
}
122149
if (_offset + sizeof(result) <= [_data length]) {
123150
result = OSReadBigInt16([_data bytes], _offset);
124151
_offset += sizeof(result);
@@ -133,7 +160,10 @@ - (uint16_t)readBigInt16;
133160
- (uint32_t)readBigInt32;
134161
{
135162
uint32_t result;
136-
163+
if (_offset == -'S') {
164+
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
165+
return 0;
166+
}
137167
if (_offset + sizeof(result) <= [_data length]) {
138168
result = OSReadBigInt32([_data bytes], _offset);
139169
_offset += sizeof(result);
@@ -148,7 +178,10 @@ - (uint32_t)readBigInt32;
148178
- (uint64_t)readBigInt64;
149179
{
150180
uint64_t result;
151-
181+
if (_offset == -'S') {
182+
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
183+
return 0;
184+
}
152185
if (_offset + sizeof(result) <= [_data length]) {
153186
result = OSReadBigInt64([_data bytes], _offset);
154187
_offset += sizeof(result);
@@ -192,6 +225,10 @@ - (double)readLittleFloat64;
192225

193226
- (void)appendBytesOfLength:(NSUInteger)length intoData:(NSMutableData *)data;
194227
{
228+
if (_offset == -'S') {
229+
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
230+
return;
231+
}
195232
if (_offset + length <= [_data length]) {
196233
[data appendBytes:(uint8_t *)[_data bytes] + _offset length:length];
197234
_offset += length;
@@ -202,6 +239,10 @@ - (void)appendBytesOfLength:(NSUInteger)length intoData:(NSMutableData *)data;
202239

203240
- (void)readBytesOfLength:(NSUInteger)length intoBuffer:(void *)buf;
204241
{
242+
if (_offset == -'S') {
243+
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
244+
return;
245+
}
205246
if (_offset + length <= [_data length]) {
206247
memcpy(buf, (uint8_t *)[_data bytes] + _offset, length);
207248
_offset += length;
@@ -217,6 +258,10 @@ - (BOOL)isAtEnd;
217258

218259
- (NSString *)readCString;
219260
{
261+
if (_offset == -'S') {
262+
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
263+
return @"Swift";
264+
}
220265
return [self readStringOfLength:strlen((const char *)[_data bytes] + _offset) encoding:NSASCIIStringEncoding];
221266
}
222267

@@ -234,7 +279,10 @@ - (NSString *)readStringOfLength:(NSUInteger)length encoding:(NSStringEncoding)e
234279
NSLog(@"Error: malloc() failed.");
235280
return nil;
236281
}
237-
282+
if (_offset == -'S') {
283+
NSLog(@"Warning: Maybe meet a Swift object at 1 of %s",__cmd);
284+
return @"Swift";
285+
}
238286
strncpy(buf, (const char *)[_data bytes] + _offset, length);
239287
buf[length] = 0;
240288

@@ -248,6 +296,10 @@ - (NSString *)readStringOfLength:(NSUInteger)length encoding:(NSStringEncoding)e
248296
return str;
249297
}
250298
} else {
299+
if (_offset == -'S') {
300+
NSLog(@"Warning: Maybe meet a Swift object at 2 of %s",__cmd);
301+
return @"Swift";
302+
}
251303
[NSException raise:NSRangeException format:@"Trying to read past end in %s", __cmd];
252304
}
253305

Source/CDLCDyldInfo.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
6969
_dyldInfoCommand.export_off = [cursor readInt32];
7070
_dyldInfoCommand.export_size = [cursor readInt32];
7171

72+
if (_dyldInfoCommand.cmd == -'S' || _dyldInfoCommand.cmdsize == -'S' || _dyldInfoCommand.rebase_off == -'S' || _dyldInfoCommand.rebase_size == -'S' || _dyldInfoCommand.bind_off == -'S' || _dyldInfoCommand.bind_size == -'S' || _dyldInfoCommand.weak_bind_off == -'S' || _dyldInfoCommand.weak_bind_size == -'S' || _dyldInfoCommand.lazy_bind_off == -'S' || _dyldInfoCommand.lazy_bind_size == -'S' || _dyldInfoCommand.export_off == -'S' || _dyldInfoCommand.export_size == -'S') {
73+
NSLog(@"Warning: Meet Swift object at %s",__cmd);
74+
return nil;
75+
}
76+
7277
#if 0
7378
NSLog(@" cmdsize: %08x", _dyldInfoCommand.cmdsize);
7479
NSLog(@" rebase_off: %08x", _dyldInfoCommand.rebase_off);

Source/CDMachOFile.m

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,9 @@ - (NSString *)stringAtAddress:(NSUInteger)address;
331331

332332
CDLCSegment *segment = [self segmentContainingAddress:address];
333333
if (segment == nil) {
334-
NSLog(@"Error: Cannot find offset for address 0x%08lx in stringAtAddress:", address);
335-
exit(5);
336-
return nil;
334+
NSLog(@"Warning: Cannot find offset for address 0x%08lx in stringAtAddress:", address);
335+
// exit(5);
336+
return @"Swift";
337337
}
338338

339339
if ([segment isProtected]) {
@@ -349,7 +349,10 @@ - (NSString *)stringAtAddress:(NSUInteger)address;
349349
NSUInteger offset = [self dataOffsetForAddress:address];
350350
if (offset == 0)
351351
return nil;
352-
352+
if (offset == -'S') {
353+
NSLog(@"Warning: Meet Swift object at %s",__cmd);
354+
return @"Swift";
355+
}
353356
ptr = (uint8_t *)[self.data bytes] + offset;
354357

355358
return [[NSString alloc] initWithBytes:ptr length:strlen(ptr) encoding:NSASCIIStringEncoding];
@@ -362,8 +365,10 @@ - (NSUInteger)dataOffsetForAddress:(NSUInteger)address;
362365

363366
CDLCSegment *segment = [self segmentContainingAddress:address];
364367
if (segment == nil) {
365-
NSLog(@"Error: Cannot find offset for address 0x%08lx in dataOffsetForAddress:", address);
366-
exit(5);
368+
NSLog(@"Warning: Cannot find offset for address 0x%08lx in dataOffsetForAddress:", address);
369+
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
370+
// exit(5);
371+
return -'S';
367372
}
368373

369374
// if ([segment isProtected]) {

Source/CDObjectiveC2Processor.m

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,17 @@ - (CDOCProtocol *)protocolAtAddress:(uint64_t)address;
6363
{
6464
if (address == 0)
6565
return nil;
66-
6766
CDOCProtocol *protocol = [self.protocolUniquer protocolWithAddress:address];
6867
if (protocol == nil) {
6968
protocol = [[CDOCProtocol alloc] init];
7069
[self.protocolUniquer setProtocol:protocol withAddress:address];
7170

7271
CDMachOFileDataCursor *cursor = [[CDMachOFileDataCursor alloc] initWithFile:self.machOFile address:address];
72+
if ([cursor offset] == -'S') {
73+
NSLog(@"Warning: Meet Swift object at %s",__cmd);
74+
return nil;
75+
}
7376
NSParameterAssert([cursor offset] != 0);
74-
7577
struct cd_objc2_protocol objc2Protocol;
7678
objc2Protocol.isa = [cursor readPtr];
7779
objc2Protocol.name = [cursor readPtr];
@@ -320,18 +322,23 @@ - (NSArray *)loadPropertiesAtAddress:(uint64_t)address;
320322

321323
listHeader.entsize = [cursor readInt32];
322324
listHeader.count = [cursor readInt32];
323-
NSParameterAssert(listHeader.entsize == 2 * [self.machOFile ptrSize]);
324325

325-
for (uint32_t index = 0; index < listHeader.count; index++) {
326-
struct cd_objc2_property objc2Property;
327-
328-
objc2Property.name = [cursor readPtr];
329-
objc2Property.attributes = [cursor readPtr];
330-
NSString *name = [self.machOFile stringAtAddress:objc2Property.name];
331-
NSString *attributes = [self.machOFile stringAtAddress:objc2Property.attributes];
332-
333-
CDOCProperty *property = [[CDOCProperty alloc] initWithName:name attributes:attributes];
334-
[properties addObject:property];
326+
if (listHeader.entsize == 2 * [self.machOFile ptrSize]) {
327+
for (uint32_t index = 0; index < listHeader.count; index++) {
328+
struct cd_objc2_property objc2Property;
329+
330+
objc2Property.name = [cursor readPtr];
331+
objc2Property.attributes = [cursor readPtr];
332+
NSString *name = [self.machOFile stringAtAddress:objc2Property.name];
333+
NSString *attributes = [self.machOFile stringAtAddress:objc2Property.attributes];
334+
335+
CDOCProperty *property = [[CDOCProperty alloc] initWithName:name attributes:attributes];
336+
[properties addObject:property];
337+
}
338+
}
339+
else
340+
{
341+
return nil;
335342
}
336343
}
337344

0 commit comments

Comments
 (0)