Parse UTF-16 CFStrings

This commit is contained in:
Devin Vaukz 2018-06-11 20:15:39 -07:00
parent b6d97f0329
commit 0d4db1ec4a
7 changed files with 93 additions and 52 deletions

View File

@ -471,8 +471,8 @@
D0A0D2361DE50B71003F0A08 /* MKObjCProtocolMethodTypesList.m in Sources */ = {isa = PBXBuildFile; fileRef = D0A0D2341DE50B71003F0A08 /* MKObjCProtocolMethodTypesList.m */; };
D0A0D2391DE82675003F0A08 /* MKPointerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = D0A0D2371DE82675003F0A08 /* MKPointerNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
D0A0D23A1DE82675003F0A08 /* MKPointerNode.m in Sources */ = {isa = PBXBuildFile; fileRef = D0A0D2381DE82675003F0A08 /* MKPointerNode.m */; };
D0A13712205B7F0900DC20BF /* MKCFStringsSection.h in Headers */ = {isa = PBXBuildFile; fileRef = D0A13710205B7F0900DC20BF /* MKCFStringsSection.h */; settings = {ATTRIBUTES = (Public, ); }; };
D0A13713205B7F0900DC20BF /* MKCFStringsSection.m in Sources */ = {isa = PBXBuildFile; fileRef = D0A13711205B7F0900DC20BF /* MKCFStringsSection.m */; };
D0A13712205B7F0900DC20BF /* MKCFStringSection.h in Headers */ = {isa = PBXBuildFile; fileRef = D0A13710205B7F0900DC20BF /* MKCFStringSection.h */; settings = {ATTRIBUTES = (Public, ); }; };
D0A13713205B7F0900DC20BF /* MKCFStringSection.m in Sources */ = {isa = PBXBuildFile; fileRef = D0A13711205B7F0900DC20BF /* MKCFStringSection.m */; };
D0A13717205B801900DC20BF /* MKCFString.h in Headers */ = {isa = PBXBuildFile; fileRef = D0A13715205B801900DC20BF /* MKCFString.h */; settings = {ATTRIBUTES = (Public, ); }; };
D0A13718205B801900DC20BF /* MKCFString.m in Sources */ = {isa = PBXBuildFile; fileRef = D0A13716205B801900DC20BF /* MKCFString.m */; };
D0A1D83E19E4EE170095870C /* context.c in Sources */ = {isa = PBXBuildFile; fileRef = D0A1D83919E4EE170095870C /* context.c */; };
@ -1427,8 +1427,8 @@
D0A0D2341DE50B71003F0A08 /* MKObjCProtocolMethodTypesList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKObjCProtocolMethodTypesList.m; sourceTree = "<group>"; };
D0A0D2371DE82675003F0A08 /* MKPointerNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MKPointerNode.h; sourceTree = "<group>"; };
D0A0D2381DE82675003F0A08 /* MKPointerNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MKPointerNode.m; sourceTree = "<group>"; };
D0A13710205B7F0900DC20BF /* MKCFStringsSection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MKCFStringsSection.h; sourceTree = "<group>"; };
D0A13711205B7F0900DC20BF /* MKCFStringsSection.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MKCFStringsSection.m; sourceTree = "<group>"; };
D0A13710205B7F0900DC20BF /* MKCFStringSection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MKCFStringSection.h; sourceTree = "<group>"; };
D0A13711205B7F0900DC20BF /* MKCFStringSection.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MKCFStringSection.m; sourceTree = "<group>"; };
D0A13715205B801900DC20BF /* MKCFString.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MKCFString.h; sourceTree = "<group>"; };
D0A13716205B801900DC20BF /* MKCFString.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MKCFString.m; sourceTree = "<group>"; };
D0A1D83919E4EE170095870C /* context.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = context.c; sourceTree = "<group>"; };
@ -2650,8 +2650,8 @@
D0A1370F205B7E2700DC20BF /* Sections */ = {
isa = PBXGroup;
children = (
D0A13710205B7F0900DC20BF /* MKCFStringsSection.h */,
D0A13711205B7F0900DC20BF /* MKCFStringsSection.m */,
D0A13710205B7F0900DC20BF /* MKCFStringSection.h */,
D0A13711205B7F0900DC20BF /* MKCFStringSection.m */,
);
path = Sections;
sourceTree = "<group>";
@ -3231,7 +3231,7 @@
D04AE10020C488FC0047BAE1 /* MKPointer+Node.h in Headers */,
D09F6C511A14847700AB21E3 /* MKMemoryMap.h in Headers */,
D01C74E51CA7335900648CA6 /* MKMachO+Bindings.h in Headers */,
D0A13712205B7F0900DC20BF /* MKCFStringsSection.h in Headers */,
D0A13712205B7F0900DC20BF /* MKCFStringSection.h in Headers */,
D01C75151CA749A900648CA6 /* MKBindDoBind.h in Headers */,
D0539BD81A2405DB00D3A5F0 /* MKDylinkerLoadCommand.h in Headers */,
D0F7EB9F1A631B9A00FA834F /* memory_map_task.h in Headers */,
@ -3879,7 +3879,7 @@
D066184D1CBB11E4006979A1 /* MKObjCClassIVarList.m in Sources */,
D03CD1631E4FD25300D76CFE /* MKObjCIVarOffset.m in Sources */,
D06618561CBB2BCD006979A1 /* MKObjCClassProperty.m in Sources */,
D0A13713205B7F0900DC20BF /* MKCFStringsSection.m in Sources */,
D0A13713205B7F0900DC20BF /* MKCFStringSection.m in Sources */,
D01731651C66BA9F007CB0A1 /* MKSharedCache+Images.m in Sources */,
D09A1957203007AE0053181B /* MKNodeFieldExportOptionsType.m in Sources */,
D0F74F20203D3CE80001A447 /* MKNodeFieldRebaseOpcodeType.m in Sources */,

View File

@ -1,7 +1,7 @@
//----------------------------------------------------------------------------//
//|
//| MachOKit - A Lightweight Mach-O Parsing Library
//! @file MKCFStringsSection.h
//! @file MKCFStringSection.h
//!
//! @author D.V.
//! @copyright Copyright (c) 2014-2015 D.V. All rights reserved.
@ -35,7 +35,7 @@
NS_ASSUME_NONNULL_BEGIN
//----------------------------------------------------------------------------//
@interface MKCFStringsSection : MKSection {
@interface MKCFStringSection : MKSection {
@package
NSArray<MKCFString*> *_strings;
}

View File

@ -1,7 +1,7 @@
//----------------------------------------------------------------------------//
//|
//| MachOKit - A Lightweight Mach-O Parsing Library
//| MKCFStringsSection.m
//| MKCFStringSection.m
//|
//| D.V.
//| Copyright (c) 2014-2015 D.V. All rights reserved.
@ -25,19 +25,22 @@
//| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//----------------------------------------------------------------------------//
#import "MKCFStringsSection.h"
#import "MKCFStringSection.h"
#import "MKInternal.h"
#import "MKSegment.h"
#import "MKCFString.h"
//----------------------------------------------------------------------------//
@implementation MKCFStringsSection
@implementation MKCFStringSection
@synthesize strings = _strings;
//|++++++++++++++++++++++++++++++++++++|//
+ (uint32_t)canInstantiateWithSectionLoadCommand:(id<MKLCSection>)sectionLoadCommand inSegment:(MKSegment*)segment
{
if (self != MKCFStringSection.class)
return 0;
if ([segment.name rangeOfString:@SEG_DATA].location == 0 &&
[sectionLoadCommand.sectname isEqualToString:@"__cfstring"])
return 50;

View File

@ -30,9 +30,9 @@
#import <MachOKit/MKOffsetNode.h>
#import <MachOKit/MKPointer.h>
#import <MachOKit/MKString.h>
@class MKObjCClass;
@class MKCString;
NS_ASSUME_NONNULL_BEGIN
@ -52,7 +52,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) uint32_t flags;
//!
@property (nonatomic, readonly) MKPointer<MKCString*> *string;
@property (nonatomic, readonly) MKPointer<id<MKString>> *string;
//!
@property (nonatomic, readonly) uint64_t length;

View File

@ -28,7 +28,6 @@
#import "MKCFString.h"
#import "MKInternal.h"
#import "MKPointer+Node.h"
#import "MKCString.h"
#import "MKObjCClass.h"
struct cf_string_64 {
@ -54,39 +53,43 @@ struct cf_string_32 {
self = [super initWithOffset:offset fromParent:parent error:error];
if (self == nil) return nil;
NSError *localError = nil;
id<MKDataModel> dataModel = self.dataModel;
NSAssert(dataModel != nil, @"Parent node must have a data model.");
size_t pointerSize = dataModel.pointerSize;
if (dataModel.pointerSize == 8)
{
NSError *memoryMapError = nil;
struct cf_string_64 var;
if ([self.memoryMap copyBytesAtOffset:offset fromAddress:parent.nodeContextAddress into:&var length:sizeof(var) requireFull:YES error:error] < sizeof(var))
{ [self release]; return nil; }
if ([self.memoryMap copyBytesAtOffset:offset fromAddress:parent.nodeContextAddress into:&var length:sizeof(var) requireFull:YES error:&memoryMapError] < sizeof(var)) {
MK_ERROR_OUT = [NSError mk_errorWithDomain:MKErrorDomain code:MK_EINTERNAL_ERROR underlyingError:memoryMapError description:@"Could not read __builtin_CFString."];
[self release]; return nil;
}
_isa = [[MKPointer alloc] initWithOffset:offsetof(typeof(var), isa) fromParent:self targetClass:MKObjCClass.class error:error];
_string = [[MKPointer alloc] initWithOffset:offsetof(typeof(var), string) fromParent:self targetClass:MKCString.class error:error];
_string = [[MKPointer alloc] initWithOffset:offsetof(typeof(var), string) fromParent:self targetClass:nil error:error];
_flags = (uint32_t)MKSwapLValue64(var.flags, dataModel);
_length = MKSwapLValue64(var.length, dataModel);
}
else if (dataModel.pointerSize == 4)
{
NSError *memoryMapError = nil;
struct cf_string_32 var;
if ([self.memoryMap copyBytesAtOffset:offset fromAddress:parent.nodeContextAddress into:&var length:sizeof(var) requireFull:YES error:error] < sizeof(var))
{ [self release]; return nil; }
if ([self.memoryMap copyBytesAtOffset:offset fromAddress:parent.nodeContextAddress into:&var length:sizeof(var) requireFull:YES error:&memoryMapError] < sizeof(var)) {
MK_ERROR_OUT = [NSError mk_errorWithDomain:MKErrorDomain code:MK_EINTERNAL_ERROR underlyingError:memoryMapError description:@"Could not read __builtin_CFString."];
[self release]; return nil;
}
_isa = [[MKPointer alloc] initWithOffset:offsetof(typeof(var), isa) fromParent:self targetClass:MKObjCClass.class error:error];
_string = [[MKPointer alloc] initWithOffset:offsetof(typeof(var), string) fromParent:self targetClass:MKCString.class error:error];
_string = [[MKPointer alloc] initWithOffset:offsetof(typeof(var), string) fromParent:self targetClass:nil error:error];
_flags = MKSwapLValue32(var.flags, dataModel);
_length = MKSwapLValue32(var.length, dataModel);
}
else
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Unsupported pointer size." userInfo:nil];
if (localError) {
MK_ERROR_OUT = localError;
[self release]; return nil;
{
NSString *reason = [NSString stringWithFormat:@"Unsupported pointer size [%zu].", pointerSize];
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil];
}
return self;
@ -102,7 +105,7 @@ struct cf_string_32 {
}
////
#pragma mark - Values
#pragma mark - String Values
////
@synthesize isa = _isa;
@ -121,27 +124,62 @@ struct cf_string_32 {
//|++++++++++++++++++++++++++++++++++++|//
- (MKNodeDescription*)layout
{
NSArray *fields;
struct cf_string_64 cf64;
struct cf_string_32 cf32;
if (self.dataModel.pointerSize == 8) {
struct cf_string_64 var;
fields = @[
[MKPrimativeNodeField fieldWithProperty:MK_PROPERTY(isa) description:@"ISA" offset:offsetof(typeof(var), isa) size:sizeof(var.isa)],
[MKPrimativeNodeField fieldWithProperty:MK_PROPERTY(flags) description:@"Flags" offset:offsetof(typeof(var), flags) size:sizeof(var.flags)],
[MKPrimativeNodeField fieldWithProperty:MK_PROPERTY(string) description:@"String" offset:offsetof(typeof(var), string) size:sizeof(var.string)],
[MKPrimativeNodeField fieldWithProperty:MK_PROPERTY(length) description:@"Length" offset:offsetof(typeof(var), length) size:sizeof(var.length)]
];
} else {
struct cf_string_32 var;
fields = @[
[MKPrimativeNodeField fieldWithProperty:MK_PROPERTY(isa) description:@"ISA" offset:offsetof(typeof(var), isa) size:sizeof(var.isa)],
[MKPrimativeNodeField fieldWithProperty:MK_PROPERTY(flags) description:@"Flags" offset:offsetof(typeof(var), flags) size:sizeof(var.flags)],
[MKPrimativeNodeField fieldWithProperty:MK_PROPERTY(string) description:@"String" offset:offsetof(typeof(var), string) size:sizeof(var.string)],
[MKPrimativeNodeField fieldWithProperty:MK_PROPERTY(length) description:@"Length" offset:offsetof(typeof(var), length) size:sizeof(var.length)]
];
}
size_t pointerSize = self.dataModel.pointerSize;
return [MKNodeDescription nodeDescriptionWithParentDescription:super.layout fields:fields];
#define FIELD_TYPE(type64, type32) (pointerSize == 8 ? type64.sharedInstance : type32.sharedInstance)
#define FIELD_OFFSET(field) (pointerSize == 8 ? offsetof(typeof(cf64), field) : offsetof(typeof(cf32), field))
#define FIELD_SIZE(field) (pointerSize == 8 ? sizeof(cf64.field) : sizeof(cf32.field))
MKNodeFieldBuilder *isa = [MKNodeFieldBuilder
builderWithProperty:MK_PROPERTY(isa)
type:[MKNodeFieldTypePointer pointerWithType:FIELD_TYPE(MKNodeFieldTypeUnsignedQuadWord, MKNodeFieldTypeUnsignedDoubleWord)]
offset:FIELD_OFFSET(isa)
size:FIELD_SIZE(isa)
];
isa.description = @"ISA";
isa.options = MKNodeFieldOptionDisplayAsDetail;
MKNodeFieldBuilder *flags = [MKNodeFieldBuilder
builderWithProperty:MK_PROPERTY(flags)
type:FIELD_TYPE(MKNodeFieldTypeUnsignedQuadWord, MKNodeFieldTypeUnsignedDoubleWord)
offset:FIELD_OFFSET(flags)
size:FIELD_SIZE(flags)
];
flags.description = @"Flags";
flags.options = MKNodeFieldOptionDisplayAsDetail;
flags.formatter = [NSFormatter mk_hexCompactFormatter];
MKNodeFieldBuilder *string = [MKNodeFieldBuilder
builderWithProperty:MK_PROPERTY(string)
type:[MKNodeFieldTypePointer pointerWithType:FIELD_TYPE(MKNodeFieldTypeUnsignedQuadWord, MKNodeFieldTypeUnsignedDoubleWord)]
offset:FIELD_OFFSET(string)
size:FIELD_SIZE(string)
];
string.description = @"String";
string.options = MKNodeFieldOptionDisplayAsDetail;
MKNodeFieldBuilder *length = [MKNodeFieldBuilder
builderWithProperty:MK_PROPERTY(length)
type:FIELD_TYPE(MKNodeFieldTypeUnsignedQuadWord, MKNodeFieldTypeUnsignedDoubleWord)
offset:FIELD_OFFSET(length)
size:FIELD_SIZE(length)
];
length.description = @"Length";
length.options = MKNodeFieldOptionDisplayAsDetail;
#undef FIELD_SIZE
#undef FIELD_OFFSET
#undef FIELD_TYPE
return [MKNodeDescription nodeDescriptionWithParentDescription:super.layout fields:@[
isa.build,
flags.build,
string.build,
length.build
]];
}
@end

View File

@ -196,7 +196,7 @@
#import <MachOKit/MKIndirectSymbol.h>
#import <MachOKit/MKCFString.h>
#import <MachOKit/MKCFStringsSection.h>
#import <MachOKit/MKCFStringSection.h>
#import <MachOKit/MKObjCElementList.h>
#import <MachOKit/MKObjCImageInfo.h>

View File

@ -187,7 +187,7 @@ Mach-O Kit currently supports executables, dynamic shared libraries (dylibs and
* `__objc_const`
* `__objc_data`
* CF Data
* CFString (*incomplete - needs further testing*)
* CFString
* CF-Specific Sections
* `__cfstring`