问题标签 [xnu]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 关于从内核访问用户空间内存
我在 XNU 内核做 kext 开发,有一个叫做 copyin 的 KPI 函数和它的朋友,类似于 Linux 内核的 copy_from_user
所以我大部分时间都在使用copyin,它在内核空间而不是相对易变的用户空间处理数据更安全,但有时我需要从用户空间处理大量内存(例如2MB),我只需要读取,可以吗成为直接访问用户空间内存的借口?(这会导致意想不到的问题吗?)
来自用户空间的数据有条目,所以我至少每次都需要读取,此外我不需要从用户空间进程对此内存进行任何写入,我列出了三种我能想到的方法,希望有人能给我的建议,我真的很感激!
- 在内核空间分配足够大小的可分页内存(IOMallocPageable),并调用 copyin 从用户空间复制整个数据
- alloc 也分配可分页内存,大小足够一个条目,使用copyin读取和处理然后再次读取到同一个内存
- 使用stac disable smap,直接从用户空间读取
第一种方式,如果我不写,那可以映射到相同的物理地图,所以不需要浪费内存吗?哪种方式效率更高?
sockets - kext模块之间的IPC
我想知道是否可以使用域 PF_SYSTEM 下的套接字在 2 个 kext 模块之间实现双向通信通道。这种方法主要用于驱动程序和用户空间代理之间的通信。
在我的特殊情况下,我有一个基于 IOKit 的模块,另一个是具有启动和停止回调函数的简单内核模块,我想在它们之间传递一些小消息。
你认为这种方法适合我的需要还是有其他更好的方法(共享内存?马赫端口?)
编辑,在深入挖掘之后,也许可以选择通过如下修改客户端驱动程序 plist 文件将 API 从一个驱动程序导出到另一个驱动程序.. 可能吗?
然而,这不起作用,因为当我在服务器驱动程序已经加载(从 中可见kextstat
)之后尝试手动加载客户端驱动程序时,我得到了No kexts found for these libraries
错误。
macos - 在多个不同的内核模块(驱动程序)之间进行通信
为了实现更好的封装和模块化,我决定将我的内核驱动程序分成 2 个(可以更多)模块,每个模块负责不同的功能。
但是,我仍然想在这些模块之间共享一些数据+逻辑(即一个模块可以管理与用户空间的通信,而另一个模块将其用作中介),我想知道是否有任何简单的方法可以做到所以。
例如,我想将一些 API 从一个模块发布到另一个模块,这是绝对可行的,因为两个模块都在内核进程下运行,并且映射在同一地址空间中的不同范围内。
问题是每个内核模块都有自己的符号表,为了发布 API,需要某种加载器来修复寻址/指针/等。这就像在动态链接时从用户空间调用dlopen
和dlsym
库,但在内核空间中,并且每个库还拥有状态(由其所有内部堆/全局参数的当前快照定义的状态)。
我的问题是这种方法在 macOS 领域是否有效并被接受?
编辑,在下面的问题中,它解释了实现我目标的 linux 方式,也许你知道 macOS/XNU 中与symbol_get
和的等价物是什么symbol_put
?
llvm - 如何在编译时检测 XNU 内核二进制文件?
我想在编译时将我的代码块插入 XNU 内核中每个函数的序言。
为 IR 转换编写LLVM
pass 可能是它的最佳选择,但我找不到任何有关使用LLVM
pass 构建 XNU 内核的信息。
是否可以使用我自己的LLVM
pass 插件构建 XNU 内核?如果是这样,你能告诉我如何做到这一点或提供任何链接吗?
有没有其他方法可以在编译时使用我的代码块来检测 XNU 内核?
此链接描述了如何构建 XNU 内核。
谢谢。
c - SIDT 操作码返回地址到格式错误的 IDT 结构
我的目标是从 MacOS 内核模块访问 IDT。
我在 VMFusion 10.0.1 下运行 macOS 10.13.2,看起来sidt
汇编命令指向损坏的表结构。
此操作码应将地址返回到“中断描述符表”,该表保存每个中断的描述符。
每个中断都包含回调函数的指针,在调用特定中断时应该调用该回调函数。
例如,这里有 2 个中断描述符,它们指向以前旧版本中内核 __TEXT 部分的有效回调。
- int3 指向 idt64_int3
- int80 指向 idt64_unix_scall
ETC...
由于某种原因,从高 Sierra 10.13.2 开始,sidt
返回的内存范围不包含有效指针(都在内核__TEXT
部分的边界之外)。也许还有另一种获取表指针的方法?
这是我查找 idt 指针的源代码:
c++ - 通用内核扩展无法释放 OSObject 派生类
我有通用内核扩展,它在 C++ 示例中实现,用于开始和结束例程,而所有其他逻辑都存储在一个专用类中,继承自OSObject
.
它在模块启动例程时创建类,并在停止例程时释放它,如下面的代码所示:
但是,当尝试卸载服务时,它无法到达停止例程,因为该类仍在被引用(我假设它到达了我释放此类的停止例程)。这是确切的日志消息:
在参考检查之前我可以在停止例行程序之前释放我的课程吗?
谢谢
multithreading - 显示内核空间中远程线程的回溯
在内核空间调试时,我有时希望在一组线程中根据它的回溯帧搜索线程,就像特定任务上的所有线程一样。
例如,获取 kernel_task id
转储属于 kernel_task 的所有线程
现在我可以看到线程 id 和许多关于线程的其他信息,但是我如何观察线程的回溯?
c++ - IOKit 驱动程序已加载但未启动
我有 IOKit 基本驱动程序,它是非硬件触发的,源自 IOResources。它还提供给用户空间客户端类使用IOServiceOpen
,但我认为这与我的问题无关......主驱动程序具有 IOKit 依赖关系,如派生驱动程序 Info.plist 文件中所述:
另一个驱动程序(由 标识com.derived.driver
)作为通用内核扩展实现并存储在/Library/Extensions
.
当我加载基本驱动程序时,派生的会自动加载。由于派生驱动程序驻留在/Library/Extensions
其中,因此也可以在触发派生驱动程序之前加载kextcache
。
但是,当我将派生驱动程序从通用格式转换为 IOKit 格式时,它停止工作,因此现在两个驱动程序IOProviderClass
都是IOResources
.
似乎派生驱动程序只是拒绝启动它的基于 IOService 的类,在输出日志中没有任何错误迹象(我使用调试器并看到它实际上达到IOService::probeCandidates
但没有IOService::startCandidate
。由于内核编译时优化,我不能把我的手指放在确切的流量上)。
当我查看当前加载的驱动程序时kextstat
,似乎两个驱动程序都已加载,但根据ioreg
只有基本驱动程序具有活动实例(我期望两个驱动程序将共享同一个提供程序,即 IOResources)。
此外,过了一会儿,似乎更高的驱动程序简单地从加载的 kexts 中删除(可能是由于空闲)..
我的设计是否合法,或者我是否还必须将IOProviderClass
基驱动程序中的字段从IOResources
派生驱动程序 IOService 基于类更改。
编辑:我确实做到了,并且成功了(所有实例都已根据 ioreg 进行了初始化)。
但老实说,我不知道为什么,任何解释将不胜感激。
谢谢 !
c++ - 在 IOKit 代码中使用 `decltype`
在编译基于 IOKit 的内核扩展时,c++ 编译器无法识别关键字decltype
.
编译器在上面的代码上失败,原因是:Use of undeclared identifier 'decltype'
。auto
另一方面,关键字按预期工作。
但是,如果我在 C++ 用户模式应用程序中编译完全相同的代码,它工作正常。
知道为什么吗?
macos - 从 macOS 内核扩展挂载/卸载文件系统
hdiutil
可以将包含 HFS+ 分区的 DMG 文件附加和分离到选定的挂载点。但是,它使用DiskImages.framework
. 我的目标是让这个任务完全编程,所以我在内核驱动领域寻找替代方案。
在深入研究由我表示的 KPI 时,<sys/mount.h>
我发现根据匹配的 fsid 卸载文件系统的有用方法:
但是,我们对 mount 有相反的操作吗?