Для программы восстановления данных мне нужно иметь возможность извлекать значения + типы из файлов, написанных NSArchiver, без доступа к фреймворкам CF/NS от Apple.Проверка файлов типа «NeXT/Apple typedstream» версии 4 (NSArchiver)
Доклады команд OS X file
такие файлы как:
NeXT/Apple typedstream data, little endian, version 4, system 1000
Есть ли документация о том, как эти файлы кодируются, или кто-нибудь придумать код, который может разобрать их?
Вот пример таких данных (также: downloadable):
04 0B 73 74 72 65 61 6D 74 79 70 65 64 81 E8 03 ..streamtyped...
84 01 40 84 84 84 12 4E 53 41 74 74 72 69 62 75 [email protected]
74 65 64 53 74 72 69 6E 67 00 84 84 08 4E 53 4F tedString....NSO
62 6A 65 63 74 00 85 92 84 84 84 08 4E 53 53 74 bject.......NSSt
72 69 6E 67 01 94 84 01 2B 06 46 65 73 6B 65 72 ring....+.Fesker
86 84 02 69 49 01 06 92 84 84 84 0C 4E 53 44 69 ...iI.......NSDi
63 74 69 6F 6E 61 72 79 00 94 84 01 69 01 92 84 ctionary....i...
96 96 1D 5F 5F 6B 49 4D 4D 65 73 73 61 67 65 50 ...__kIMMessageP
61 72 74 41 74 74 72 69 62 75 74 65 4E 61 6D 65 artAttributeName
86 92 84 84 84 08 4E 53 4E 75 6D 62 65 72 00 84 ......NSNumber..
84 07 4E 53 56 61 6C 75 65 00 94 84 01 2A 84 99 ..NSValue....*..
99 00 86 86 86 .....
Это содержит NSAttributedString. У меня есть аналогичные примеры, которые содержат NSMutableAttributedStrings и т. Д., Но все они в конечном итоге разрешают NSAttributedStrings, для которых мне нравится получать текст. Я не забочусь обо всем остальном, но мне нужно знать, действительно ли это.
Мое настоящее решение - использовать NSUnarchiver и, полагая, что я всегда должен найти NSAttributedString там, получить его первый элемент и прочитать его текст, а затем воссоздать из него архив и посмотреть, совпадает ли он с исходными данными , Если я получаю исключение или другой архив назад, я полагаю, что архив поврежден или недействителен:
NSData *data = [[NSData alloc] initWithBytesNoCopy:dataPtr length:dataLen freeWhenDone:false];
NSUnarchiver *a = NULL;
// The algorithm simply assumes that the data contains a NSAttributedString, retrieves it,
// and then recreates the NSArchived version from it in order to tell its size.
@try {
a = [[NSUnarchiver alloc] initForReadingWithData:data];
NSAttributedString *s = [a decodeObject];
// re-encode the string item so we can tell its length
NSData *d = [NSArchiver archivedDataWithRootObject:s];
if ([d isEqualTo:[data subdataWithRange:NSMakeRange(0,d.length)]]) {
lenOut = (int) d.length;
okay = true; // -> lenOut is valid, though textOut might still fail, see @catch below
textOut = [s.string cStringUsingEncoding:NSUTF8StringEncoding];
} else {
// oops, we don't get back what we had as input, so let's better not consider this valid
}
} @catch (NSException *e) {
// data is invalid
}
Однако есть несколько проблем с выше кодом:
- Это не х-платформа , Мне тоже нужно работать в Windows.
- Некоторые примеры поврежденных данных вызывают нежелательную ошибку msg, записанную в stderr или syslog (не уверены, какой), например:
*** mmap(size=18446744071608111104) failed (error code=12) *** error: can't allocate region *** set a breakpoint in malloc_error_break to debug
(я печатал отчет об ошибке, который был закрыт как «не исправить», к сожалению). - Ничто не гарантирует, что код NSUnarchiver 100% защищен от кражи. Для этого примером является ошибка malloc. Я мог бы также получить ошибку шины в некоторых ситуациях, и это было бы фатальным. Если у меня есть пользовательский код для синтаксического анализа, я сам позабочусь об этом (и исправлю любые сбои, с которыми я сталкиваюсь). (Обновление: я только что нашел некоторые недопустимые данные, которые действительно приводят к сбою NSUnarchiver с помощью SIGSEGV.)
Поэтому мне нужен специальный код для декодирования этих типов архивов. Я посмотрел на несколько, но не могу понять коды, которые он использует. По-видимому, существуют поля длины и поля типа, причем типы находятся в диапазоне от 0x81 до 0x86. Кроме того, первый 16-байтовый заголовок, включая системный код (0x03E8 = 1000) со смещением 14-15.
Я также задаюсь вопросом, доступен ли исходный код в некоторых старых источниках NeXT или в версии Windows, которая когда-то существовала, но где бы я ее нашел? (Примечание. Я был направлен в источник GNUstep («core.20131003.tar.bz2»), в котором я нашел его источник NSUnarchiver, но этот код, по-видимому, с 1998 года, использует свою собственную кодировку, которая не понимает этого «потоковое» кодирование.)
К сожалению, этот формат использует другой формат, как и GNUstep :( –
Поскольку эти два класса устарели, возможно, вы смотрите на 'NSKeyed * rchiver'? –
Нет, это старая неблокированная версия. Фактически, когда я передаю данные NSKeyedUnarchiver, он прерывается с ошибкой. –