如何读取 macOS iMessage 数据库中的“attributedBody”列?

ste*_*sas 4 macos objective-c imessage macos-ventura

Apple 在最新的 macOS Ventura 更新中更改了消息数据库架构,并且发送的消息似乎不再将其正文/内容存储在列中text。该attributedBody列包含内容,但它存储为编码的 blob。

有没有人有幸从中得到明文?

ste*_*sas 5

attributedBody列是NSMutableAttributedString使用NSArchiver. 它可以使用解包和读取,NSUnarchiver但必须首先从 Messages sqlite 数据库中提取,而不会丢失任何不可打印的字符。

\n

要在执行查询时保留列的内容,可以使用 sqlite3 的HEX()函数。然后,可以通过迭代生成的字节并构建新的NSString.

\n
\n

在下面的示例中,NSData使用两个辅助方法进行了扩展,以处理读取具有十六进制编码数据的文件。使用dataWithContentsOfHexEncodedFile,可以将消息记录attributedBody传递给NSUnarchiver,它将处理对序列化的 进行解码NSAttributedStringNSString然后可以通过访问该属性将其转换为正常值string

\n
#import <Foundation/Foundation.h>\n\n@implementation NSData (NSDataExtended)\n+ (NSData *)dataWithContentsOfHexEncodedString:(NSString *) string {\n    const char * chars = [string UTF8String];\n    int i = 0;\n    \n    NSMutableData *data = [NSMutableData dataWithCapacity: string.length / 2];\n    char byteChars[3] = {\'\\0\', \'\\0\', \'\\0\'};\n    unsigned long wholeByte;\n    \n    while (i < string.length) {\n        byteChars[0] = chars[i++];\n        byteChars[1] = chars[i++];\n        wholeByte = strtoul(byteChars, NULL, 16);\n        [data appendBytes:&wholeByte length:1];\n    }\n    \n    return data;\n}\n\n+ (NSData *)dataWithContentsOfHexEncodedFile:(NSString *) filePath {\n    return [self dataWithContentsOfHexEncodedString:[NSString\n                                    stringWithContentsOfFile:filePath\n                                    encoding:NSUTF8StringEncoding\n                                    error:nil]];\n}\n@end\n\nint main(int argc, const char * argv[]) {\n    system([[[NSString alloc] initWithFormat:@"%s %s > %s",\n             "/usr/bin/sqlite3 ~/Library/Messages/chat.db",\n             "\'SELECT HEX(attributedBody) FROM message ORDER BY ROWID DESC LIMIT 1\'",\n             "/private/tmp/msgbody"] UTF8String]);\n    \n#pragma clang diagnostic ignored "-Wdeprecated-declarations"\n    NSMutableAttributedString *msg = [[[NSUnarchiver alloc]\n                                       initForReadingWithData:[NSData dataWithContentsOfHexEncodedFile:@"/private/tmp/msgbody"]\n                                      ] decodeTopLevelObjectAndReturnError:nil];\n    \n    NSLog(@"%@", [msg string]);\n    \n    return 0;\n}\n\n\n
Run Code Online (Sandbox Code Playgroud)\n