PageRenderTime 88ms CodeModel.GetById 10ms app.highlight 69ms RepoModel.GetById 1ms app.codeStats 1ms

/parsembdb.m

http://github.com/petewarden/iPhoneTracker
Objective C | 206 lines | 142 code | 32 blank | 32 comment | 15 complexity | 79ac20e613eef3f0f6903ddd5abe7896 MD5 | raw file
  1//
  2//  iPhoneTracking
  3//
  4//  Created by Pete Warden on 4/15/11.
  5//
  6
  7/***********************************************************************************
  8*
  9* All code (C) Pete Warden, 2011
 10*
 11*    This program is free software: you can redistribute it and/or modify
 12*    it under the terms of the GNU General Public License as published by
 13*    the Free Software Foundation, either version 3 of the License, or
 14*    (at your option) any later version.
 15*
 16*    This program is distributed in the hope that it will be useful,
 17*    but WITHOUT ANY WARRANTY; without even the implied warranty of
 18*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 19*
 20*    GNU General Public License for more details.
 21*
 22*    You should have received a copy of the GNU General Public License
 23*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 24*
 25************************************************************************************/
 26
 27#import <Cocoa/Cocoa.h>
 28
 29#import "parsembdb.h"
 30
 31static NSNumber* getint(uint8_t* data, size_t* offset, size_t intsize);
 32static NSString* getstring(uint8_t* data, size_t* offset);
 33static NSDictionary* process_mbdb_file(NSString* filename);
 34static NSDictionary* process_mbdx_file(NSString* filename);
 35
 36@implementation ParseMBDB
 37
 38+ (NSDictionary*) getFileListForPath:(NSString*)path
 39{
 40  NSDictionary* mbdb = process_mbdb_file([path stringByAppendingPathComponent:@"Manifest.mbdb"]);
 41  NSDictionary* mbdx = process_mbdx_file([path stringByAppendingPathComponent:@"Manifest.mbdx"]);
 42
 43  if ((mbdb==nil)||(mbdx==nil)) {
 44    return nil;
 45  }
 46
 47  for (NSNumber* offset in mbdb) {
 48    NSMutableDictionary* fileinfo = [mbdb objectForKey:offset];
 49    NSString* fileID = [mbdx objectForKey:offset];
 50    if (fileID==nil) {
 51      fileID = @"<nofileID>";
 52    }
 53    [fileinfo setObject: fileID forKey:@"fileID"];
 54  }
 55  
 56  return mbdb;
 57}
 58
 59@end
 60
 61// Adapted from Python at
 62// http://stackoverflow.com/questions/3085153/how-to-parse-the-manifest-mbdb-file-in-an-ios-4-0-itunes-backup
 63
 64NSNumber* getint(uint8_t* data, size_t* offset, size_t intsize){
 65  // Retrieve an integer (big-endian) and new offset from the current offset
 66  int value = 0;
 67  while (intsize > 0) {
 68    value = (value<<8) + data[*offset];
 69    *offset = *offset + 1;
 70    intsize = intsize - 1;
 71  }
 72  
 73  return [NSNumber numberWithInteger: value];
 74}
 75
 76NSString* getstring(uint8_t* data, size_t* offset) {
 77  // Retrieve a string and new offset from the current offset into the data
 78  if ((data[*offset]==0xFF) && (data[*offset+1]==0xFF)) {
 79    // Blank string
 80    char* value = malloc(2);
 81    strcpy(value, "");
 82    *offset += 2;
 83    NSString* result = [[NSString alloc] initWithUTF8String:value];
 84//    NSLog(@"result=<blank>", result);
 85    return result;
 86  }
 87
 88  int length = [getint(data, offset, 2) integerValue];
 89  size_t start = *offset;
 90  char* value = malloc(length+1);
 91  strncpy(value, (data+start), length);
 92  value[length] = 0;
 93  
 94  *offset += length;
 95  
 96  NSString* result = [[NSString alloc] initWithUTF8String:value];
 97  if (result==nil) {
 98    result = @"<null>";
 99  }
100//  NSLog(@"result=%@", result);
101  return result;
102}
103
104NSDictionary* process_mbdb_file(NSString* filename) {
105  NSMutableDictionary* mbdb = [NSMutableDictionary dictionary]; // Map offset of info in this file => file info
106  NSData* fileData = [NSData dataWithContentsOfFile: filename];
107  size_t dataLength = [fileData length];
108  uint8_t* data = (uint8_t*)[fileData bytes];
109
110  if (data==NULL) {
111    NSLog(@"No MBDB file found at '%@'", filename);
112    return nil;
113  }
114
115  if ((data[0]!='m')||
116    (data[1]!='b')||
117    (data[2]!='d')||
118    (data[3]!='b')) {
119    fprintf(stderr, "Bad header found for mbdb file");
120    return mbdb;
121  }
122  size_t offset = 4;
123  offset = offset + 2; // value x05 x00, not sure what this is
124  while (offset < dataLength) {
125    NSMutableDictionary* fileinfo = [NSMutableDictionary dictionary];
126    [fileinfo setObject: [NSNumber numberWithInteger: offset] forKey:@"start_offset"];
127    [fileinfo setObject:getstring(data, &offset) forKey:@"domain"]; 
128    [fileinfo setObject:getstring(data, &offset) forKey:@"filename"];
129    [fileinfo setObject:getstring(data, &offset) forKey:@"linktarget"];
130    [fileinfo setObject:getstring(data, &offset) forKey:@"datahash"];
131    [fileinfo setObject:getstring(data, &offset) forKey:@"unknown1"]; 
132    [fileinfo setObject:getint(data, &offset, 2) forKey:@"mode"];
133    [fileinfo setObject:getint(data, &offset, 4) forKey:@"unknown2"];
134    [fileinfo setObject:getint(data, &offset, 4) forKey:@"unknown3"];
135    [fileinfo setObject:getint(data, &offset, 4) forKey:@"userid"];
136    [fileinfo setObject:getint(data, &offset, 4) forKey:@"groupid"];
137    [fileinfo setObject:getint(data, &offset, 4) forKey:@"mtime"];
138    [fileinfo setObject:getint(data, &offset, 4) forKey:@"atime"];
139    [fileinfo setObject:getint(data, &offset, 4) forKey:@"ctime"];
140    [fileinfo setObject:getint(data, &offset, 8) forKey:@"filelen"];
141    [fileinfo setObject:getint(data, &offset, 1) forKey:@"flag"];
142    [fileinfo setObject:getint(data, &offset, 1) forKey:@"numprops"];
143
144    NSMutableDictionary* properties = [NSMutableDictionary dictionary];
145    const int numProps = [[fileinfo objectForKey:@"numprops"] integerValue];
146    for (int ii=0; ii<numProps; ii++) {
147      NSString* propname = getstring(data, &offset);
148      NSString* propval = getstring(data, &offset);
149      [properties setObject: propval forKey:propname];
150    }
151    [fileinfo setObject:properties forKey:@"properties"];
152
153    [mbdb setObject: fileinfo forKey:[fileinfo objectForKey:@"start_offset"]];
154  }
155  
156  return mbdb;
157}
158
159NSDictionary* process_mbdx_file(NSString* filename) {
160
161  NSMutableDictionary* mbdx = [NSMutableDictionary dictionary]; // Map offset of info in the MBDB file => fileID string
162  NSData* fileData = [NSData dataWithContentsOfFile: filename];
163  size_t dataLength = [fileData length];
164  uint8_t* data = (uint8_t*)[fileData bytes];
165
166  if (data==NULL) {
167    NSLog(@"No MBDX file found at '%@'", filename);
168    return nil;
169  }
170
171  if ((data[0]!='m')||
172    (data[1]!='b')||
173    (data[2]!='d')||
174    (data[3]!='x')) {
175    fprintf(stderr, "Bad header found for mbdx file");
176    return mbdx;
177  }
178  size_t offset = 4;
179  offset = offset + 2; // value 0x02 0x00, not sure what this is
180
181  char* hexArray = "0123456789abcdef";
182  
183  NSNumber* filecount = getint(data, &offset, 4); // 4-byte count of records 
184  while (offset < dataLength) {
185    // 26 byte record, made up of ...
186    char* fileID_string = malloc(41);
187    for (int i=0; i<20; i+=1) {
188      uint8_t v = data[offset+i];
189      uint8_t l = (v&0x0f);
190      uint8_t h = (v&0xf0)>>4;
191      fileID_string[(i*2)+0] = hexArray[h];
192      fileID_string[(i*2)+1] = hexArray[l];
193    }
194    fileID_string[40] = 0;
195    
196    NSString* fileID_nsString = [[NSString alloc] initWithUTF8String:fileID_string];
197    
198    offset = offset + 20;
199    NSNumber* mbdb_offset = getint(data, &offset, 4); // 4-byte offset field
200    mbdb_offset = [NSNumber numberWithInteger: ([mbdb_offset integerValue] + 6)]; // Add 6 to get past prolog
201    NSNumber* mode = getint(data, &offset, 2); // 2-byte mode field
202    [mbdx setObject:fileID_nsString forKey: mbdb_offset];
203  }
204  
205  return mbdx;
206}