Dateien vom Typ "NeXT / Apple typedstream" Version 4 (NSArchiver) prüfen

Für ein Datenwiederherstellungsprogramm muss es mir möglich sein, die Werte + Typen aus Dateien zu extrahieren, die von NSArchiver geschrieben wurden, ohne Zugriff auf die CF / NS-Frameworks von Apple zu haben.

Das OS Xfile Befehl meldet solche Dateien wie:

NeXT/Apple typedstream data, little endian, version 4, system 1000

Gibt es eine Dokumentation darüber, wie diese Dateien codiert werden, oder hat jemand einen Code gefunden, der sie analysieren kann?

Hier ist ein Beispiel für solche Daten (auch:herunterladbar):

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                                   .....

Dieser enthält einen NSAttributedString. Ich habe ähnliche Beispiele, die NSMutableAttributedStrings usw. enthalten, aber alle werden schließlich zu NSAttributedStrings aufgelöst, für die ich den Text erhalten möchte. Ich kümmere mich nicht um den Rest, aber ich muss wissen, ob es gültig ist.

Meine derzeitige Lösung besteht darin, den NSUnarchiver zu verwenden und, vorausgesetzt, ich sollte immer einen NSAttributedString darin finden, sein erstes Element abzurufen und seinen Text zu lesen, dann ein Archiv daraus zu erstellen und zu prüfen, ob er mit den Originaldaten identisch ist. Wenn ich eine Ausnahme oder ein anderes Archiv zurück bekomme, gehe ich davon aus, dass das Archiv beschädigt oder ungültig ist:

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
}

Es gibt jedoch mehrere Probleme mit dem obigen Code:

Es ist keine X-Plattform. Ich brauche das auch für Windows.Einige Beispiele für beschädigte Daten verursachen eine unerwünschte Fehlermeldung, die in stderr oder syslog geschrieben wird (nicht sicher, welche), wie zum Beispiel:*** mmap(size=18446744071608111104) failed (error code=12) *** error: can't allocate region *** set a breakpoint in malloc_error_break to debug (Ich habe einen Fehlerbericht darüber eingereicht, der geschlossen wurde, da er leider nicht behoben werden kann.)Nichts garantiert, dass der NSUnarchiver-Code 100% absturzsicher ist. Der Malloc-Fehler ist ein Beispiel dafür. In manchen Situationen könnte ich genauso gut einen Busfehler bekommen, und das wäre fatal. Wenn ich benutzerdefinierten Code zum Parsen hätte, kann ich mich selbst darum kümmern (und alle Abstürze beheben, auf die ich stoße). (Update: Ich habe gerade ungültige Daten gefunden, die NSUnarchiver mit einem SIGSEGV zum Absturz bringen.)

Daher benötige ich benutzerdefinierten Code, um diese Art von Archiven zu dekodieren. Ich habe ein paar angeschaut, kann aber keinen Sinn aus den verwendeten Codes machen. Anscheinend gibt es Längen- und Typfelder, wobei die Typen anscheinend im Bereich von 0x81 bis 0x86 liegen. Die ersten 16 Byte sind auch der Header, einschließlich des Systemcodes (0x03E8 = 1000) bei Offset 14-15.

Ich frage mich auch, ob der Quellcode in einigen alten NeXT-Quellen oder in der früheren Windows-Version verfügbar ist, aber wo finde ich den? (Hinweis: Ich wurde auf die GNUstep-Quelle ("core.20131003.tar.bz2") verwiesen, in der ich die NSUnarchiver-Quelle gefunden habe, aber dieser Code verwendet anscheinend von 1998 eine eigene Codierung, die diesen "streamtyped" nicht versteht "Kodierung.)

Antworten auf die Frage(6)

Ihre Antwort auf die Frage