1

我正在尝试检查从互联网下载的应用程序是否已完全启动。我正在尝试使用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 选择语句并从表中获取全部内容LSQuarantineEvent~/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2 中的表中获取全部内容,然后使用 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 中的这个值/行似乎永远不会改变。

我已经阅读了这篇文章这篇文章,但我没有看到任何方法来完成我想要做的事情。

4

2 回答 2

2

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

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

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

计算器

Swift 中的示例检查:

let flags = 0x1e3

let checked =  (flags & 0b01000000) != 0 // true
let launched = (flags & 0b00100000) != 0 // true
于 2020-01-30T07:19:07.750 回答
1

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

10.11:
隔离:0002未隔离:0062

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

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

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

于 2020-01-30T01:53:41.987 回答