检查 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
我正在尝试检查从 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 似乎永远不会改变。
我已经通读了
我想我将继续以下内容。经过进一步测试,在 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