mirror of
https://github.com/darlinghq/MachO-Kit.git
synced 2024-11-23 04:19:45 +00:00
Parse UTF-16 CFStrings
This commit is contained in:
parent
b6d97f0329
commit
0d4db1ec4a
@ -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 */,
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user