MAC kernel panic分析(2)

admin 2023年5月16日08:08:48评论95 views字数 7630阅读25分26秒阅读模式


0x01 前言

接上文继续对kernel panic进行更进一步的分析.

0x02 分析

前文中使用的IDA分析的二进制文件是没有更详细的符号信息的,因此我们可以使用其他的工具来帮助我们更好的分析.

前期准备

众所周知苹果的MAC OS 内核是开源的,而上层运行库及图形界面是私有的.

下载对应内核版本的kernel源代码。

可以使用uname -a 查看内核版本。

可以看到这里我们使用的版本是xnu-7195.121.3~9。

而后在github上查看对应版本的源代码并下载。

https://github.com/apple/darwin-xnu/tags

如下图。

除此之外还需要安装对应版本的mac 的 kernel debug kit 。

在苹果官网下载https://developer.apple.com/download/more/?q=Kernel%20Debug%20Kit

系统版本可以在关于本机查看。

开始分析

使用lldb 来进行加载kernel。

lldb (lldb) settings set target.load-script-from-symbol-file true

根据panic report调整kernel slide。

(lldb) target modules load --file kernel --slide 0x000000000bc00000

查看panic report 中发生异常的代码位置。

(lldbimage lookup -a 0xffffff800926997d      Address:kernel[0xffffff800025997d] (kernel.__TEXT.__text + 231805)      Summary:kernel`ipc_kmsg_get_from_kernel + 45 at ipc_kmsg.c:2103:29打开源码包中的对应文件找到对应行数。

通过观察汇编代码能确定问题发生在。

IP_PREALLOC(dest_port)

IP_PREALLOC和IP_VALID的定义为。

#define IP_PREALLOC(port)      ((port)->ip_object.io_bits & IP_BIT_PREALLOC)#define IP_VALID(port)         IPC_PORT_VALID(port)#define IPC_PORT_VALID(port)   ipc_port_valid(port)ipc_port_valid(ipc_port_t port){         return port != IPC_PORT_DEAD&& port;}

dest_port为 ipc_port_t类型数据。

ipc_port_t dest_port;typedef struct ipc_port *ipc_port_t;

ipc_port结构体如下:

struct ipc_port {         /*          * Initial sub-structure in common withipc_pset          * First element is an ipc_object second is a          * message queue          */         struct ipc_object ip_object;         struct ipc_mqueueip_messages;         union {                 struct ipc_space *receiver;                 struct ipc_port *destination;                  ipc_port_timestamp_t timestamp;         } data;          /* updatehost_request_notification if this union is changed */         union {                 ipc_kobject_tXNU_PTRAUTH_SIGNED_PTR("ipc_port.kobject") kobject;                 ipc_kobject_label_t XNU_PTRAUTH_SIGNED_PTR("ipc_port.kolabel")kolabel;                 ipc_importance_task_timp_task;                 ipc_port_tsync_inheritor_port;                 struct knote*sync_inheritor_knote;                 struct turnstile*sync_inheritor_ts;         } kdata;         struct ipc_port*ip_nsrequest;         struct ipc_port*ip_pdrequest;         struct ipc_port_request*ip_requests;         union {                 struct ipc_kmsg*XNU_PTRAUTH_SIGNED_PTR("ipc_port.premsg") premsg;                 struct turnstile*send_turnstile;                 ipc_port_tXNU_PTRAUTH_SIGNED_PTR("ipc_port.alt_port") alt_port;         } kdata2;         mach_vm_address_tip_context;         natural_tip_sprequests:1,      /* send-possiblerequests outstanding */             ip_spimportant:1,           /* ... at least one is importancedonating */             ip_impdonation:1,           /* port supports importance donation*/             ip_tempowner:1,             /* dont give donations to currentreceiver */             ip_guarded:1,               /* port guarded (use contextvalue as guard) */             ip_strict_guard:1,          /* Strict guarding; Prevents usermanipulation of context values directly */             ip_specialreply:1,          /* port is a special reply port */             ip_sync_link_state:3,       /* link the port to destination port/Workloop */             ip_sync_bootstrap_checkin:1,/* port part ofsync bootstrap checkin, push on thread doing the checkin */             ip_immovable_receive:1,     /* the receive right cannot be moved outof a space, until it is destroyed */             ip_no_grant:1,              /* Port wont accept complexmessages containing (ool) port descriptors */             ip_immovable_send:1,        /* No send(once) rights to this portcan be moved out of a space */             ip_tg_block_tracking:1,     /* Track blocking relationship betweenthread groups during sync IPC */             ip_pinned: 1,               /* Can't deallocate the lastsend right from a space while the bit is set */             ip_impcount:16;             /* number of importance donationsin nested queue */         mach_port_mscount_tip_mscount;         mach_port_rights_tip_srights;         mach_port_rights_tip_sorights;#if     MACH_ASSERT#define IP_NSPARES              4#define IP_CALLSTACK_MAX        16/*       queue_chain_t     ip_port_links;*//* all allocated ports */         thread_t        ip_thread;      /* who made me?  thread context */         unsigned long   ip_timetrack;   /* give an idea of "when" created*/         uintptr_t       ip_callstack[IP_CALLSTACK_MAX]; /* stacktrace */         unsigned long   ip_spares[IP_NSPARES]; /* for debugging */#endif  /* MACH_ASSERT */#if DEVELOPMENT || DEBUG         uint8_t         ip_srp_lost_link:1,     /* special reply port turnstile link chainbroken */             ip_srp_msg_sent:1;                  /* special reply port msgsent */#endif};

发生崩溃的数据来源于ipc_kmsg_get_from_kernel函数传入的msg参数赋值。

dest_port = msg->msgh_remote_port;

根据panic的调用栈分析,调用ipc_kmsg_get_from_kernel的上层函数为mach_msg_send_from_kernel_proper

往上是ipc_notify_port_destroyed-->ipc_port_destroy-->ipc_port_dealloc_special-->ipc_thread_terminate-->thread_deallocate_complete-->_mpsc_daemon_queue_drain-->_mpsc_queue_thread_continue-->call_continuation。

call_continuation用于继续线程

_mpsc_queue_thread_continue用于mpsc 线程队列的继续

_mpsc_daemon_queue_drain排队,排空和取消

thread_deallocate_complete完成线程释放

ipc_thread_terminateipc线程的终止

ipc_port_dealloc_special释放端口,消除引用

ipc_port_destroy销毁ipc 端口

ipc_notify_port_destroyed(ipc_port 1006) 发送端口销毁通知

ipc_kmsg_get_from_kernel查看端口是否为内核客户端分配了 kmsg

整个过程大概是 在进行ipc线程终止的时,释放端口的过程发生了内存访问错误。

具体原因通过观察panic进行分析。

可以从其中获得Fault CR2 以及Error code 信息来进行发生问题的具体分析。通过翻看源代码可以知道Error code是来自regs->isf.err

在源码中定位到这么一段

找到相关错误代码的定义表

#define T_PF_PROT              0x1             /* protectionviolation */#define T_PF_WRITE             0x2             /* write access */#define T_PF_USER              0x4             /* from user state*/#define T_PF_RSVD              0x8             /* reserved bitset to 1 */#define T_PF_EXECUTE           0x10            /* instructionfetch when NX */

至此有个问题那就是错误代码0x0在哪呢?

仔细观察,定义上面错误代码的源文件是osfmki386trap.h

发现在osfmkarmtrap.h也做了定义如下

#define T_PF_PROT              0x1             /* protectionviolation */
#define T_PF_WRITE 0x2 /* write access */
#define T_PF_USER              0x4             /* from user state*/

因此只能大概的知道是内存访问的问题。

但是不清楚当时的内存是什么布局什么情况,panic要是有类似vmmap那样显示内存布局就好了.

0x03 分析过程的坑

LLDB使用过程中的问题

python 版本问题

loading kernel debugging from /Library/Developer/KDKs/KDK_11.4_20F71.kdk/System/Library/Kernels/kernel.dSYM/Contents/Resources/Python/kernel.py
LLDB version lldb-1205.0.28.2
Apple Swift version 5.4.2 (swiftlang-1205.0.28.2 clang-1205.0.19.57)
settings set target.process.python-os-plugin-path"/Library/Developer/KDKs/KDK_11.4_20F71.kdk/System/Library/Kernels/kernel.dSYM/Contents/Resources/Python/lldbmacros/core/operating_system.py"
settings set target.trap-handler-names hndl_allintrs hndl_alltrapstrap_from_kernel hndl_double_fault hndl_machine_check _fleh_prefabt_ExceptionVectorsBase _ExceptionVectorsTable _fleh_undef _fleh_dataabt_fleh_irq _fleh_decirq _fleh_fiq_generic _fleh_dec
command script import"/Library/Developer/KDKs/KDK_11.4_20F71.kdk/System/Library/Kernels/kernel.dSYM/Contents/Resources/Python/lldbmacros/xnu.py"
error: module importing failed: Traceback (most recent call last):
File "<string>",line 1, in <module>
File"/Library/Developer/KDKs/KDK_11.4_20F71.kdk/System/Library/Kernels/kernel.dSYM/Contents/Resources/Python/lldbmacros/xnu.py",line 123
print "Executioninterrupted by user"
          ^SyntaxError: Missing parentheses in call to 'print'. Did you meanprint("Execution interrupted by user")?
settings set target.process.optimization-warnings false

解决方法在命令行输入

defaults write com.apple.dt.lldb DefaultPythonVersion 2

0x04 小结

本文对kernel更进一步的分析,由于对mac的kernel并没有足够的研究积累。因此还有很多疑问,欢迎大家一起探讨。后续如果能找到能稳定复现的方法可能会出下一章,涉及到内核调试,以及内核漏洞利用的内容。

 

原文始发于微信公众号(BeFun安全实验室):MAC kernel panic分析(2)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年5月16日08:08:48
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   MAC kernel panic分析(2)https://cn-sec.com/archives/1066057.html

发表评论

匿名网友 填写信息