检查 macOS 应用程序是否已被隔离并完全启动

Checking if macOS App Has Ever Been Un-Quarantined and Fully Launched

我正在尝试检查从 Internet 下载的应用程序是否已完全启动。我正尝试为此使用 xattr -p com.apple.quarantine,但此命令的 return 值似乎不一致。

在一个 Mac 上,我在 return 中获得了这两个 Gatekeeper Score 值:0183 如果应用程序从未完全启动,01c3 如果应用程序已启动并且用户在 GateKeeper "Do you really want to open this app" 对话框中单击了打开。在另一个 Mac 上,我得到完全不同的值:0003 & 0063.

我猜这些是 4 位十六进制数字,我可以这样转换它们:

NSString *gateKeeperScore = [outputItems firstObject];
NSScanner *scanner = [NSScanner scannerWithString:gateKeeperScore];
unsigned int number = 0;
if ([scanner scanHexInt:&number]) {
    NSLog(@"Gatekeeper Score is %u", number);
}

但是是否存在阈值,一旦分数超过该阈值,我就可以安全地假设该应用程序已完全启动并且不再被隔离?

我尝试了 运行 SQL select 语句并从 table LSQuarantineEvent 中获取了 ~/Library/Preferences/com 中的全部内容。 apple.LaunchServices.QuarantineEventsV2,然后使用 grep 查找相关行,但我没有看到该行有任何变化 before/after 应用程序完全启动。

有什么方法可以确定应用程序是否可以完全启动并且没有被隔离?我正在尝试使用 Objective-C 来完成此操作。没有沙盒。提前致谢!

这是我正在做的一些示例代码:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    NSString *output1 = [self runTask: [NSArray arrayWithObjects:@"-c", @"xattr -p com.apple.quarantine '/path/to/app'", nil]];

    NSArray *outputItems = [output1 componentsSeparatedByString:@";"];
    NSString *UUID = [outputItems lastObject];
    UUID = [UUID stringByReplacingOccurrencesOfString:@"[\r\n]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, UUID.length)];

    NSString *output2 = [self runTask: [NSArray arrayWithObjects:@"-c", [NSString stringWithFormat:@"sqlite3 ~/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2 \"SELECT * FROM LSQuarantineEvent WHERE LSQuarantineEventIdentifier == '%@'\"", UUID], nil]];
}

- (NSString *) runTask : (NSArray *) args
{
    NSTask *task = [[NSTask alloc] init];
    [task setLaunchPath: @"/bin/bash"];

    [task setArguments:args];

    NSPipe * taskOutput = [NSPipe pipe];
    [task setStandardOutput:taskOutput];

    [task launch];
    [task waitUntilExit];

    NSFileHandle * read = [taskOutput fileHandleForReading];
    NSData * dataRead = [read readDataToEndOfFile];
    NSString * taskOutputString = [[NSString alloc] initWithData:dataRead encoding:NSUTF8StringEncoding];

    return taskOutputString;
}

output1 的值如下所示:

01c3;5e31c850;Safari;92CB3715-7A0F-4582-9FF3-9B0CBE2A23BB

只有前 4 个字符发生变化 before/after 应用已完全启动。

output2 的值如下所示:

92CB3715-7A0F-4582-9FF3-9B0CBE2A23BB|602013648.990506|com.apple.Safari|Safari|https://url/of/files/origin|||0|||

SQL 数据库中的这个 value/row 似乎永远不会改变。

我已经通读了 and this one,但我没有找到任何方法来完成我想做的事情。

我想我将继续以下内容。经过进一步测试,在 macOS 10.11 → 10.15 中,我始终看到这些值,所以我希望它们是准确的:

10.11:
已隔离:0002 未隔离:0062

10.12 → 10.14:
已隔离:0183 未隔离:01e3

10.15:
已隔离:0183 未隔离:01c3

我的应用已使用开发者 ID 进行代码签名并经过公证。

您错过了所链接文章中的一个关键点。不要将数字视为神奇数字。这些是标志,您应该检查各个位以检查特定属性。

文章指出(您自己的回答多少证实了)第 6 位是“App 已打开”标志,第 7 位是“已通过 Gatekeeper 验证”。

您可以在计算器应用程序中检查您的示例中这两位的变化:

示例签入 Swift:

let flags = 0x1e3

let checked =  (flags & 0b01000000) != 0 // true
let launched = (flags & 0b00100000) != 0 // true