Skip to content

Commit

Permalink
Merge pull request nygard#78 from BlueCocoa/master
Browse files Browse the repository at this point in the history
  • Loading branch information
manicmaniac committed Dec 8, 2021
2 parents 2f400a5 + 8849a88 commit ed6fad5
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 31 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ The latest version and information is available at:
The source code is also available from my Github repository at:

/~https://github.com/nygard/class-dump

"Swift support"
==========

I added "Swift support" for class-dump.

Now, this tool can dump Objective-C headers even the MachO file uses Swift and ObjC at the same time.
Notice, only ObjC headers can be dumped!

LAST, THIS IS AN EXPERIMENTAL VERSION.

我为class-dump添加了"Swift支持"。

现在,这个工具可以dump出可执行文件的Objective-C头文件,即使那个MachO文件同时使用了Swift和ObjC。请注意只有ObjC类的头文件可以被dump出来!

最后,这只是一个试验版本。

Usage
-----
Expand Down
76 changes: 64 additions & 12 deletions Source/CDDataCursor.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,27 @@ - (const void *)bytes;

- (void)setOffset:(NSUInteger)newOffset;
{
if (newOffset <= [_data length]) {
_offset = newOffset;
} else {
[NSException raise:NSRangeException format:@"Trying to seek past end of data."];
if (newOffset == -'S') {
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
_offset = -'S';
}
else
{
if (newOffset <= [_data length]) {
_offset = newOffset;
} else {
[NSException raise:NSRangeException format:@"Trying to seek past end of data."];
}
}
}

- (void)advanceByLength:(NSUInteger)length;
{
if (_offset == -'S') {
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
_offset += 10;
return;
}
if (_offset + length <= [_data length]) {
_offset += length;
} else {
Expand All @@ -56,7 +68,10 @@ - (NSUInteger)remaining;
- (uint8_t)readByte;
{
uint8_t result;

if (_offset == -'S') {
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
return 0;
}
if (_offset + sizeof(result) <= [_data length]) {
result = OSReadLittleInt16([_data bytes], _offset) & 0xFF;
_offset += sizeof(result);
Expand All @@ -71,7 +86,10 @@ - (uint8_t)readByte;
- (uint16_t)readLittleInt16;
{
uint16_t result;

if (_offset == -'S') {
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
return 0;
}
if (_offset + sizeof(result) <= [_data length]) {
result = OSReadLittleInt16([_data bytes], _offset);
_offset += sizeof(result);
Expand All @@ -86,7 +104,10 @@ - (uint16_t)readLittleInt16;
- (uint32_t)readLittleInt32;
{
uint32_t result;

if (_offset == -'S') {
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
return 0;
}
if (_offset + sizeof(result) <= [_data length]) {
result = OSReadLittleInt32([_data bytes], _offset);
_offset += sizeof(result);
Expand All @@ -101,7 +122,10 @@ - (uint32_t)readLittleInt32;
- (uint64_t)readLittleInt64;
{
uint64_t result;

if (_offset == -'S') {
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
return 0;
}
if (_offset + sizeof(result) <= [_data length]) {
// uint8_t *ptr = [_data bytes] + _offset;
// 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]);
Expand All @@ -118,7 +142,10 @@ - (uint64_t)readLittleInt64;
- (uint16_t)readBigInt16;
{
uint16_t result;

if (_offset == -'S') {
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
return 0;
}
if (_offset + sizeof(result) <= [_data length]) {
result = OSReadBigInt16([_data bytes], _offset);
_offset += sizeof(result);
Expand All @@ -133,7 +160,10 @@ - (uint16_t)readBigInt16;
- (uint32_t)readBigInt32;
{
uint32_t result;

if (_offset == -'S') {
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
return 0;
}
if (_offset + sizeof(result) <= [_data length]) {
result = OSReadBigInt32([_data bytes], _offset);
_offset += sizeof(result);
Expand All @@ -148,7 +178,10 @@ - (uint32_t)readBigInt32;
- (uint64_t)readBigInt64;
{
uint64_t result;

if (_offset == -'S') {
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
return 0;
}
if (_offset + sizeof(result) <= [_data length]) {
result = OSReadBigInt64([_data bytes], _offset);
_offset += sizeof(result);
Expand Down Expand Up @@ -192,6 +225,10 @@ - (double)readLittleFloat64;

- (void)appendBytesOfLength:(NSUInteger)length intoData:(NSMutableData *)data;
{
if (_offset == -'S') {
NSLog(@"Warning: Maybe meet a Swift object at %s",__cmd);
return;
}
if (_offset + length <= [_data length]) {
[data appendBytes:(uint8_t *)[_data bytes] + _offset length:length];
_offset += length;
Expand All @@ -202,6 +239,10 @@ - (void)appendBytesOfLength:(NSUInteger)length intoData:(NSMutableData *)data;

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

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

Expand All @@ -234,7 +279,10 @@ - (NSString *)readStringOfLength:(NSUInteger)length encoding:(NSStringEncoding)e
NSLog(@"Error: malloc() failed.");
return nil;
}

if (_offset == -'S') {
NSLog(@"Warning: Maybe meet a Swift object at 1 of %s",__cmd);
return @"Swift";
}
strncpy(buf, (const char *)[_data bytes] + _offset, length);
buf[length] = 0;

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

Expand Down
5 changes: 5 additions & 0 deletions Source/CDLCDyldInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ - (id)initWithDataCursor:(CDMachOFileDataCursor *)cursor;
_dyldInfoCommand.export_off = [cursor readInt32];
_dyldInfoCommand.export_size = [cursor readInt32];

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') {
NSLog(@"Warning: Meet Swift object at %s",__cmd);
return nil;
}

#if 0
NSLog(@" cmdsize: %08x", _dyldInfoCommand.cmdsize);
NSLog(@" rebase_off: %08x", _dyldInfoCommand.rebase_off);
Expand Down
17 changes: 11 additions & 6 deletions Source/CDMachOFile.m
Original file line number Diff line number Diff line change
Expand Up @@ -331,9 +331,9 @@ - (NSString *)stringAtAddress:(NSUInteger)address;

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

if ([segment isProtected]) {
Expand All @@ -349,7 +349,10 @@ - (NSString *)stringAtAddress:(NSUInteger)address;
NSUInteger offset = [self dataOffsetForAddress:address];
if (offset == 0)
return nil;

if (offset == -'S') {
NSLog(@"Warning: Meet Swift object at %s",__cmd);
return @"Swift";
}
ptr = (uint8_t *)[self.data bytes] + offset;

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

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

// if ([segment isProtected]) {
Expand Down
33 changes: 20 additions & 13 deletions Source/CDObjectiveC2Processor.m
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,17 @@ - (CDOCProtocol *)protocolAtAddress:(uint64_t)address;
{
if (address == 0)
return nil;

CDOCProtocol *protocol = [self.protocolUniquer protocolWithAddress:address];
if (protocol == nil) {
protocol = [[CDOCProtocol alloc] init];
[self.protocolUniquer setProtocol:protocol withAddress:address];

CDMachOFileDataCursor *cursor = [[CDMachOFileDataCursor alloc] initWithFile:self.machOFile address:address];
if ([cursor offset] == -'S') {
NSLog(@"Warning: Meet Swift object at %s",__cmd);
return nil;
}
NSParameterAssert([cursor offset] != 0);

struct cd_objc2_protocol objc2Protocol;
objc2Protocol.isa = [cursor readPtr];
objc2Protocol.name = [cursor readPtr];
Expand Down Expand Up @@ -320,18 +322,23 @@ - (NSArray *)loadPropertiesAtAddress:(uint64_t)address;

listHeader.entsize = [cursor readInt32];
listHeader.count = [cursor readInt32];
NSParameterAssert(listHeader.entsize == 2 * [self.machOFile ptrSize]);

for (uint32_t index = 0; index < listHeader.count; index++) {
struct cd_objc2_property objc2Property;

objc2Property.name = [cursor readPtr];
objc2Property.attributes = [cursor readPtr];
NSString *name = [self.machOFile stringAtAddress:objc2Property.name];
NSString *attributes = [self.machOFile stringAtAddress:objc2Property.attributes];

CDOCProperty *property = [[CDOCProperty alloc] initWithName:name attributes:attributes];
[properties addObject:property];
if (listHeader.entsize == 2 * [self.machOFile ptrSize]) {
for (uint32_t index = 0; index < listHeader.count; index++) {
struct cd_objc2_property objc2Property;

objc2Property.name = [cursor readPtr];
objc2Property.attributes = [cursor readPtr];
NSString *name = [self.machOFile stringAtAddress:objc2Property.name];
NSString *attributes = [self.machOFile stringAtAddress:objc2Property.attributes];

CDOCProperty *property = [[CDOCProperty alloc] initWithName:name attributes:attributes];
[properties addObject:property];
}
}
else
{
return nil;
}
}

Expand Down

0 comments on commit ed6fad5

Please sign in to comment.