gpt4 book ai didi

Swift 特权助手(XPC 监听器)因非法指令错误而崩溃

转载 作者:行者123 更新时间:2023-11-28 08:02:56 27 4
gpt4 key购买 nike

我创建了一个 Swift macOS 应用程序,它使用 SMJobBless 创建一个具有升级权限的助手。这工作正常 - 帮助程序安装到 /Library/Privileged Helper Tools 并在 /Library/LaunchDaemons 中创建一个伴随的 LaunchDaemon。但是,助手无法成功启动。相反,它会崩溃并显示“非法指令:4”消息。

我已经准备好助手通过实现 NSXPCListenerDelegate 协议(protocol)来响应 XML 连接。这是我的助手 main.swift 代码:

import Foundation

class HelperDelegate: NSObject, NSXPCListenerDelegate {
func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
newConnection.exportedInterface = NSXPCInterface(with: HelperToolProtocol.self)
newConnection.exportedObject = HelperTool()
newConnection.resume()
return true
}
}

let delegate = HelperDelegate()
let listener = NSXPCListener.service()
listener.delegate = delegate
listener.resume()

崩溃发生在最后一行,listener.resume()

我尝试从命令行手动启动助手应用程序(这与 LaunchDaemon 所做的相同),但它再次崩溃,并将上述错误消息打印到标准输出。关于如何测试这个问题的根本原因,我没有更多的想法。在 Apple’s guidlines for implementing XM services 之后,我的实现不仅仅是简陋的.此外,SO 上关于 XML 服务的各种帖子并没有帮助我解决这个问题。你们中有人尝试过在 Swift 中成功创建特权助手吗?顺便说一句,该应用没有沙盒化。

为了完整起见,下面是我上面的 HelperDelegate 类中引用的 HelperTool 类的代码:

import Foundation

class HelperTool: NSObject, HelperToolProtocol {
func getVersion(withReply reply: (NSData?) -> ()) {
let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString" as String) as? String ?? "<unknown version>"
let build = Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String) as? String ?? "<unknown build>"
if let d = "v\(version) (\(build))".data(using: .utf8, allowLossyConversion: false) {
reply(d as NSData)
}
}
}

最后是 HelperToolProtocol:

import Foundation

@objc(HelperToolProtocol) protocol HelperToolProtocol {
func getVersion(withReply: (NSData?) -> ())
}

感谢您的帮助!

最佳答案

经过几天的测试,我终于找到了一个解决方案,可以让我的 XPC 助手正确启动并响应任何消息。问题出在当前读取的 main.swift 模块的最后三行

let listener = NSXPCListener.service()
listener.delegate = delegate
listener.resume()

正如问题中所提出的那样,它使助手在最后一行立即崩溃。

我直接从 Apple’s Creating XPC Services documentation 中获取了这些行.以下是 NSXPCListener resume() 函数的文档:

If called on the service() object, this method never returns. Therefore, you should call it as the last step inside the XPC service's main function after setting up any desired initial state and configuring the listener itself.

解决方案是不调用NSXPCListener.service()单例对象而是使用实例化一个新的NSXPCListener对象init(machServiceName:) 初始化程序传递与主应用程序的 XPC 连接上使用的相同的 Mach 服务名称。由于 resume() 在这种情况下会立即恢复——从而终止 helper——你必须将它放在当前运行循环中以使其不确定地运行。这是新的工作代码:

let listener = NSXPCListener(machServiceName: "Privilege-Escalation-Sample.Helper")
listener.delegate = delegate
listener.resume()
RunLoop.current.run()

关于Swift 特权助手(XPC 监听器)因非法指令错误而崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46096085/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com