Проверка того, было ли приложение macOS когда-либо снято с карантина и полностью запущено

Я пытаюсь проверить, было ли полностью запущено приложение, загруженное из Интернета. Я пытаюсь использовать для этого 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 никогда не меняется.

Я прочитал этот пост и этот, но я не вижу ни одного способ выполнить то, что я хочу сделать.


person William Gustafson    schedule 29.01.2020    source источник


Ответы (2)


Вы упустили один важный момент в статье, на которую ссылаетесь. Не относитесь к числам как к магическим числам. Это флаги, и вы должны проверять отдельные биты, чтобы проверить определенный атрибут.

В статье говорится (и ваш собственный ответ несколько подтверждает), что 6-й бит — это флаг «Приложение было открыто», а 7-й бит — «Проверено гейткипером».

Вы можете проверить в приложении «Калькулятор», что эти два бита меняются в ваших примерах:

калькулятор

Пример проверки в Swift:

let flags = 0x1e3

let checked =  (flags & 0b01000000) != 0 // true
let launched = (flags & 0b00100000) != 0 // true
person pointum    schedule 30.01.2020
comment
Спасибо что нашли время ответить. Однако кажется, что весь этот вопрос может быть спорным для моих целей. 1. Я нашел сообщение, в котором говорится, что вы больше не можете полагаться на этот бит для определения состояния карантина по состоянию на Мохаве. Я бы пропустил URL-адрес, но он содержит смайлик и не работает. Я пытался 5 раз заставить его работать в этом комментарии. 2. Похоже, я могу просто удалить атрибут com.apple.quarantine, используя NSTask, чтобы запустить xattr -r -d com.apple.quarantine /path/to/app. Еще раз спасибо несмотря ни на что! - person William Gustafson; 30.01.2020

Я полагаю, что я собираюсь просто пойти со следующим. После дальнейшего тестирования в macOS 10.11 → 10.15 я постоянно вижу эти значения, поэтому надеюсь, что они точны:

10.11:
На карантине: 0002 Не на карантине: 0062

10.12 → 10.14:
На карантине: 0183 Не на карантине: 01e3

10.15:
На карантине: 0183 Не на карантине: 01c3

Мое приложение подписано кодом с идентификатором разработчика и нотариально заверено.

person William Gustafson    schedule 30.01.2020
comment
Ух ты, значит, карантин и не карантин меняются в разных версиях macOS? Это расстраивает. - person Stan James; 25.05.2020