逆向修改 macOS Alt+Tab 行为 && 编写沙箱注入器
文章目录
众所周知 macOS 默认的 Alt/Command+Tab 行为十分智障,已经被吐槽好些年了,有些 APP 没有打开窗口,依然会显示在切换列表中,切换过去的时候什么也不会发生。
我预期的行为是 Alt/Command+Tab 列表中应该只显示有窗口存在的 APP,并且每个工作区应该仅持有当前工作区 APP 的列表,我不喜欢 Alt/Command+Tab 切换 APP 会切换到其它工作区以及 “无事发生” 的行为。
系统版本: macOS 26.1 (25B78)
这篇文章记录修改过程。
主要是两个功能:
-
从切换列表中剔除所有没有可见窗口的 App。
-
各工作区独立管理自己的 App 切换列表,不会再跳到其他工作区。
先上最终效果图
1. 旧

2. 新

修改 Dock.app
别的先不管,先给头文件 dump 出来看看
|
|
随便搜索一下关键词 switch 发现 ASAppSwitcher 接口,定义如下
|
|
还有一个 show 方法
|
|
每次按下 Alt/Command+Tab 的时候都会调用 show,然后展示 NSMutableArray *_processes; 储存的 APP 列表
也就是说,只要 hook ASAppSwitcher show 然后修改 _processes 就行了
|
|
但说起来容易,实际上并不知道 _processes 里面到底是个什么东西,要实现我的需求,首先要能获取 _processes 中的具体信息
这时我发现有两个方法 imageChanged progressChanged,看签名可能和 _processes 有关系,也许 _processes 携带了 CPSProcessSerNum
如果能拿到 CPSProcessSerNum 我们就可以通过 GetProcessPID(const ProcessSerialNumber *psn, pid_t *pid) 获取到进程 ID
|
|
我决定先模糊测试一下是否可以找到 PSN,结果我发现
|
|
PSN 就在 _processes 中每个元素偏移 16 的位置,这下好办了
先遍历获取进程 ID
|
|
获取当前屏幕上的所有窗口
|
|
如果窗口 pid 存在于 _processes 中,并且 layer 为 0,就表示它是实际有效的窗口,因此 _processes 里只需要保留 layer == 0 的项即可。
|
|
沙箱注入器
实际上 Dock.app 作为系统核心应用,并没有开启沙箱,但我还是编写了一个沙箱注入器,用于处理开启了沙箱的其它 APP
主流远程线程注入都是这个过程
- 获取目标进程的控制权(task port)
- 在目标进程中分配内存
- 写入执行代码(shellcode)
- 创建远程线程执行 shellcode
- shellcode 调用 dlopen 加载我们的 dylib
但是 macOS 有沙箱机制的存在,调用 dlopen 加载我们的 dylib 通常会找不到路径。
所以需要在加载我们的 dylib 之前开通沙箱权限,一般有三种方式
-
直接重签名权限移除沙箱、添加文件路径、修改二进制文件,这种方式非常粗暴,可能导致 APP 产生异常行为,尤其是和多进程相关的,非常不推荐
-
找到一个即便开启了沙箱也可以访问到的公用路径,限制大,可能有权限问题,不推荐
-
直接在 shellcode 中临时授权,这种方式不会破坏原有签名、不会修改二进制文件,即便出了问题也就是进程崩溃,只要重启一下进程就行了,比较安全
我这里使用方法 3
构造 loader.s
|
|
引入标签计算偏移
|
|
获取 Task Port
|
|
分配内存
|
|
签发沙箱 token
|
|
修补 shellcode
|
|
写入 shellcode
|
|
设置线程状态并执行
|
|
检查 x0 寄存器判断 shellcode 是否执行完成
|
|
享受
当然还有很多改进的点,例如 payload_path 和 token 可以直接传一个指针而不是限定长度,这样可以缩小 shellcode 大小;在沙箱授权之前可以检查进程是否已经开启了沙箱,更为严谨,虽然即便没有开启沙箱但是添加了沙箱授权也不会有什么问题就是
完整代码: 去我的 Github 中自己找吧,写这篇文章的时候还没有整合到单独仓库中 😁
感谢:
https://github.com/koekeishiya https://github.com/jslegendre
提供了无沙箱授权的基本注入器参考
从大佬的代码中第一次知道沙箱注入的操作
https://github.com/GRAVITYDIV10
对 C/ASM 方面的帮助
文章作者 kk
上次更新 2025-11-23