【问题标题】:Checking if macOS App Has Ever Been Un-Quarantined and Fully Launched检查 macOS 应用程序是否已被隔离并完全启动
【发布时间】:2020-01-29 19:34:51
【问题描述】:

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

在一台 Mac 上,我在返回中得到这两个 Gatekeeper Score 值:0183 如果应用程序从未完全启动,01c3 如果应用程序已经启动并且用户在 GateKeeper 中单击了“你真的想要打开这个应用程序”对话框。在另一台 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 选择语句并从 ~/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2 中的表 LSQuarantineEvent 中获取全部内容,然后使用 grep 查找相关行,但我在应用程序完全启动之前/之后,在行中没有看到任何变化。

有什么方法可以确定应用程序是否可以完全启动并且没有被隔离?我正在尝试使用 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 个字符在应用完全启动之前/之后发生变化。

output2 的值是这样的:

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

SQL DB 中的这个值/行似乎永远不会改变。

我已经阅读了this postthis one,但我没有看到任何方法可以完成我想做的事情。

【问题讨论】:

    标签: objective-c cocoa osx-gatekeeper xattr


    【解决方案1】:

    您在链接的文章中遗漏了一个关键点。不要将数字视为魔术数字。这些是标志,您应该检查各个位以检查某个属性。

    文章指出(您自己的回答在一定程度上证实了)第 6 位是“应用已打开”标志,第 7 位是“由 Gatekeeper 验证”。

    您可以在计算器应用程序中检查您的示例中这两个位是否发生了变化:

    Swift 中的示例检查:

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

    【讨论】:

    • 感谢您抽出宝贵时间回复。然而,对于我的目的来说,这整个问题似乎没有意义。 1. 我发现一个帖子说你不能再依赖这个位来确定莫哈韦的隔离状态。我已经通过了 URL,但它包含一个表情符号并且不起作用。我已经尝试了 5 次以使其在此评论中起作用。 2. 看起来我可以使用 NSTask 剥离 com.apple.quarantine 属性来运行 xattr -r -d com.apple.quarantine /path/to/app。再次感谢!
    【解决方案2】:

    我想我将只使用以下内容。经过进一步测试,跨 macOS 10.11 → 10.15,我看到这些值一致,所以我希望它们是准确的:

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

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

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

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

    【讨论】:

    • 哦,哇,隔离与未隔离在不同版本的 macOS 之间发生了变化?这令人沮丧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-25
    相关资源
    最近更新 更多