-
Notifications
You must be signed in to change notification settings - Fork 70
/
Copy pathBinaryDataHelper.m
158 lines (125 loc) · 5.32 KB
/
BinaryDataHelper.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//
// DataHelper.m
// APIScanner
//
// Created by Andrew Schenk on 9/6/10.
// Copyright 2010 Chimp Studios. All rights reserved.
//
#import "BinaryDataHelper.h"
#import "Constants.h"
@implementation BinaryDataHelper
+ (int)sizeOfSectionForKeyword:(NSString*)keyword inData:(NSData*)data
{
NSData *keyData = [keyword dataUsingEncoding:NSUTF8StringEncoding];
NSRange sectionRange = [data rangeOfData:keyData
options:NSDataSearchBackwards
range:NSMakeRange(0, [data length])];
NSData *sectionData = [data subdataWithRange:NSMakeRange(sectionRange.location, kSymByteLength+96)];
NSData *sizeData = [sectionData subdataWithRange:NSMakeRange(20+96, 4)];
NSString *totalSizeStr = [BinaryDataHelper stringWithHexBytesFromData:sizeData];
BOOL switchTwoBytes = YES;
if ([[totalSizeStr substringFromIndex:2] isEqualToString:@"0000"]) {
sizeData = [sectionData subdataWithRange:NSMakeRange(20+96, 2)];
switchTwoBytes = NO;
}
// NSLog(@"sizeData before endian switch -> %@", [sizeData description]);
NSData *stringsSize = [BinaryDataHelper switchDataToLittleEndian:sizeData twoBytes:switchTwoBytes];
NSString *sizeStr = [BinaryDataHelper stringWithHexBytesFromData:stringsSize];
return [BinaryDataHelper hexIntValueForString:sizeStr];
}
+ (int)offsetOfSectionForKeyword:(NSString*)keyword inData:(NSData*)data
{
NSData *keyData = [keyword dataUsingEncoding:NSUTF8StringEncoding];
NSRange sectionRange = [data rangeOfData:keyData
options:NSDataSearchBackwards
range:NSMakeRange(0, [data length])];
NSData *sectionData = [data subdataWithRange:NSMakeRange(sectionRange.location, kSymByteLength+96)];
NSData *offsetData = [sectionData subdataWithRange:NSMakeRange(16+96, 4)];
NSString *totalOffsetStr = [BinaryDataHelper stringWithHexBytesFromData:offsetData];
BOOL switchTwoBytes = YES;
if ([[totalOffsetStr substringFromIndex:2] isEqualToString:@"0000"]) {
offsetData = [sectionData subdataWithRange:NSMakeRange(16+96, 2)];
switchTwoBytes = NO;
}
NSData *stringsOffset = [BinaryDataHelper switchDataToLittleEndian:offsetData twoBytes:switchTwoBytes];
NSString *offSetStr = [BinaryDataHelper stringWithHexBytesFromData:stringsOffset];
return [BinaryDataHelper hexIntValueForString:offSetStr];
}
+ (NSString*) stringWithHexBytesFromData:(NSData*)data {
NSMutableString *stringBuffer = [NSMutableString stringWithCapacity:([data length] * 2)];
const unsigned char *dataBuffer = [data bytes];
int i;
for (i = 0; i < [data length]; ++i) {
[stringBuffer appendFormat:@"%02X", (unsigned long)dataBuffer[i]];
}
return [[stringBuffer copy] autorelease];
}
+ (unsigned int)hexIntValueForString:(NSString*)string
{
NSScanner *scanner;
unsigned int result;
scanner = [NSScanner scannerWithString: string];
[scanner scanHexInt: &result];
//NSLog(@"%u", result);
return result;
}
+ (NSData*)switchDataToLittleEndian:(NSData*)bigData twoBytes:(BOOL)shouldSwapTwo
{
//NSData *bigEndianOffset = [programData subdataWithRange:NSMakeRange(kOffsetPointer, 2)];
NSMutableData *switchEndianess = [[[NSMutableData alloc] initWithLength:0] autorelease];
if (shouldSwapTwo) {
[switchEndianess appendData:[bigData subdataWithRange:NSMakeRange(3, 1)]];
[switchEndianess appendData:[bigData subdataWithRange:NSMakeRange(2, 1)]];
[switchEndianess appendData:[bigData subdataWithRange:NSMakeRange(1, 1)]];
[switchEndianess appendData:[bigData subdataWithRange:NSMakeRange(0, 1)]];
} else {
[switchEndianess appendData:[bigData subdataWithRange:NSMakeRange(1, 1)]];
[switchEndianess appendData:[bigData subdataWithRange:NSMakeRange(0, 1)]];
}
return switchEndianess;
}
char hexCharToNibble(char nibble)
{
// 0 - 9
if (nibble >= '0' && nibble <= '9')
return (nibble - '0') & 0x0F;
// A - F
else if (nibble >= 'A' && nibble <= 'F')
return (nibble - 'A' + 10) & 0x0F;
// a - f
else if (nibble >= 'a' && nibble <= 'f')
return (nibble - 'a' + 10) & 0x0F;
// Not a hex digit
else
[NSException raise:NSInvalidArgumentException format:@"Character %c not a hex digit.", nibble];
return 0; // keep compiler happy
}
char hexCharsToByte(char highNibble, char lowNibble)
{
return (hexCharToNibble(highNibble) << 4) | hexCharToNibble(lowNibble);
}
+ (NSString*)hexToAscii:(NSString*)hexStr
{
// Get the ASCII data out of the string - hexadecimal numbers are expressed in pure ASCII
NSData *asciiData = [hexStr dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
const char *chars = (char *)[asciiData bytes]; // chars is NOT NULL- terminated!
if (([asciiData length] % 2) != 0)
{
// There were an odd number of hex characters in the source string.
return nil;
}
// Set up data storage for the raw bytes we interpret
NSMutableData *dataInEncoding = [NSMutableData dataWithLength: [asciiData length] / 2];
char *dataChars = [dataInEncoding mutableBytes];
// Loop over the ASCII numbers
for (NSUInteger i = 0; i < [asciiData length]; i += 2)
{
// Interpret each pair of hexadecimal characters into a byte.
*dataChars++ = hexCharsToByte(chars[i], chars[i + 1]);
}
// Create an NSString from the interpreted bytes, using the passed encoding.
// NSString will return nil (or throw an exception) if the bytes we parsed can't be
// represented in the given encoding.
return [[[NSString alloc] initWithData:dataInEncoding encoding:NSUTF8StringEncoding] autorelease];
}
@end