如何在macOS上使用Mach内核设置主机异常端口?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在macOS上使用Mach内核设置主机异常端口?相关的知识,希望对你有一定的参考价值。
我想使用Mach Exception Ports来处理在macOS上运行的所有任务(进程)的异常。我的理解是在这种情况下使用host_set_exception_ports
。然而,即使我用host_set_exception_ports
执行我的程序,KERN_NO_ACCESS
也会返回error code 8(sudo
)。我的实验代码用于处理使用task_set_exception_ports
的单个任务的异常。
我已经看过Mach kernel code的host_set_exception_ports
了。有a single line of code,其中KERN_NO_ACCESS
从函数返回。我有点难以理解那里发生了什么。似乎内核代码检查我传递给host_set_exception_ports
的异常掩码。我测试了不同的异常掩码,但我总是得到相同的负面结果。
我的问题:这是否意味着在用户空间应用程序中使用host_set_exception_ports
存在一般限制?如果没有,我如何设置主机异常端口以在我的应用程序中接收系统范围的异常?
以下程序是显示行为的最小示例,否则没有太多用处。使用gcc example.c
编译程序和sudo ./a.out
来执行它。
#include <mach/mach.h>
#include <stdio.h>
#include <stdlib.h>
void catchMachExceptions() {
mach_port_t exception_port;
kern_return_t rc;
rc = mach_port_allocate(mach_task_self(),
MACH_PORT_RIGHT_RECEIVE,
&exception_port);
if (rc != KERN_SUCCESS) {
fprintf(stderr, "Unable to allocate exception port: %d
", rc);
exit(-1);
}
rc = mach_port_insert_right(mach_task_self(),
exception_port,
exception_port,
MACH_MSG_TYPE_MAKE_SEND);
if (rc != KERN_SUCCESS) {
fprintf(stderr, "Unable to insert right: %d
", rc);
exit(-1);
}
rc = host_set_exception_ports(mach_host_self(),
EXC_MASK_ALL,
exception_port,
EXCEPTION_STATE_IDENTITY,
MACHINE_THREAD_STATE);
if (rc != KERN_SUCCESS) {
fprintf(stderr, "Unable to set exception: %d
", rc);
exit(-1);
}
}
int main(int argc, char **argv) {
catchMachExceptions();
}
正如你所注意到的那样,host_set_exception_ports
正在调查mac_task_check_set_host_exception_ports
。
深入研究,你可以发现mac_task_check_set_host_exception_ports
正在根据任务检索凭据,然后调用MAC_CHECK(proc_check_set_host_exception_port, cred, exception)
。
这是security/mac_internals.h
中定义的宏。见the xnu code here。阅读,这将遍历策略模块列表,检查策略模块是允许还是拒绝请求。
根据代码,所有策略模块必须同意,不发布错误。所以看起来你需要拥有正确的权限。 GNU Mach项目中有一些文档表明发送到特权主机端口的权限被授予第一个任务,并且只能从那里传递。见GNU Mach definition of host_ports, etc。
将它们拼凑在一起,不仅不能作为用户proc进行更改,还需要从引导时间通过链特别继承权限。
以上是关于如何在macOS上使用Mach内核设置主机异常端口?的主要内容,如果未能解决你的问题,请参考以下文章