Post

Replies

Boosts

Views

Activity

Reply to XPC service and mac application do not connect to each other
For Mac versions that do not have the kext endpoint security framework, that is, catalina and later, the system extension is loaded, while for the lower versions, kext is loaded. The program I am trying to make works as follows. Don't pay too much attention to the arrows, the program will generally work like this. When we open an application, it connects to the service and monitors and controls the transactions. kext and system extension do the same thing but kext uses kauth from old sdk. But the reason here is not related to kext I have already made NSXPCConnection as you wrote. Below I will write the code of the places causing the problem. XPCConnection.swift func connectToDaemon(bundle: Bundle, delegate: ClientXPCProtocol, handler: @escaping (Bool) -> Void) { guard connection == nil else { Logger(.Info, "Client already connected.") handler(true) return } guard getMachServiceName(from: bundle) == ClientBundle else { handler(false) return } let newConnection = NSXPCConnection(machServiceName: DaemonBundle) newConnection.exportedObject = delegate newConnection.exportedInterface = NSXPCInterface(with: ClientXPCProtocol.self) newConnection.remoteObjectInterface = NSXPCInterface(with: DaemonXPCProtocol.self) newConnection.invalidationHandler = { self.connection = nil Logger(.Info, "Daemon disconnected.") handler(false) } newConnection.interruptionHandler = { self.connection = nil Logger(.Error, "Daemon interrupted.") handler(false) } connection = newConnection newConnection.resume() let proxy = newConnection.remoteObjectProxyWithErrorHandler { error in Logger(.Error, "Failed to connect with error [\(error)]") self.connection?.invalidate() self.connection = nil handler(false) } as? DaemonXPCProtocol proxy!.connectResponse(handler) handler(true) } XPCServer.swift class XPCServer: NSObject { static let shared = XPCServer() var fusionlog = FusionLog() var listener: NSXPCListener? var connection: NSXPCConnection? private func getMachServiceName(from bundle: Bundle) -> String { let clientKeys = bundle.object(forInfoDictionaryKey: ClientName) as? [String: Any] let machServiceName = clientKeys?[MachServiceKey] as? String return machServiceName ?? "" } func connectToSext(bundle: Bundle, delegate: ManagerXPCProtocol, handler: @escaping (Bool) -> Void) { guard connection == nil else { Logger(.Info, "Manager already connected.") handler(true) return } guard getMachServiceName(from: bundle) == ClientBundle else { handler(false) return } let newConnection = NSXPCConnection(machServiceName: SextBundle) newConnection.exportedObject = delegate newConnection.exportedInterface = NSXPCInterface(with: ManagerXPCProtocol.self) newConnection.remoteObjectInterface = NSXPCInterface(with: SextXPCProtocol.self) newConnection.invalidationHandler = { self.connection = nil Logger(.Info, "System Extensions disconnected.") handler(false) } newConnection.interruptionHandler = { self.connection = nil Logger(.Error, "System Extensions interrupted.") handler(false) } connection = newConnection newConnection.resume() let proxy = newConnection.remoteObjectProxyWithErrorHandler { error in Logger(.Error, "Failed to connect with error [\(error)]") self.connection?.invalidate() self.connection = nil handler(false) } as? SextXPCProtocol proxy?.connectResponse(handler) handler(true) } } FusionCommon.swift func getSignInfoFromPath(_ path: String) -> [String] { let fileUrl = URL(fileURLWithPath: path) var secCode: SecStaticCode? var status = SecStaticCodeCreateWithPath(fileUrl as CFURL, SecCSFlags(rawValue: 0), &secCode) if status != errSecSuccess || secCode == nil { Logger(.Warning, "Failed to create static signed code for [\(path)] with error [\(status)].") return [] } var secDict: CFDictionary? status = SecCodeCopySigningInformation(secCode!, SecCSFlags(rawValue: kSecCSSigningInformation), &secDict) if status != errSecSuccess || secDict == nil { Logger(.Warning, "Failed to copy signed info for [\(path)] with error [\(status)].") return [] } let signedDict = secDict! as NSDictionary guard let certChain = signedDict[kSecCodeInfoCertificates as NSString] as? NSArray else { return [] } var signInfo = [String]() for cert in certChain { var name: CFString? status = SecCertificateCopyCommonName(cert as! SecCertificate, &name) if status != errSecSuccess || name == nil { continue } signInfo.append((name! as String)) } return signInfo }
Nov ’23
Reply to XPC service and mac application do not connect to each other
Hello Quinn, I apologize for the delay in my response. I'm a high school student currently in exam week. Thank you for your feedback. To clarify, I'm actually working on a delegate but it looks like there might be some confusion in the terminology. Let me explain: I created a normal mac app project in xcode and this application is launched with launchd The xpc service is not as you say, I created a new app with a new target and made it run completely in the background. This background becomes my service and it loads the endpoint security system extension and kext. I created the endpoint security plugin using the Endpoint Security framework According to your last question, launchd starts the program's service and loads the kext and system extension in the service. Thank you for your help and reading this message. Kind regards, Bugra
Oct ’23