re-kernel について
カーネルの挙動や逆アセンブル結果の食い違いを調べるための、クロスプラットフォームのカーネルリバースエンジニアリングスキルです。ビルド、ロード、実行時の違いに着目し、症状別の調査手順と検証方法を示します。
主な機能
- 01多様な OS カーネルモデルに対応
- 02症状別の失敗要因の調査
- 03ディスク・実行時・ロード済みの版を照合
- 04シンボル・型情報・実行時検証を併用
活用シーン
- 01構造体オフセットやシンボル解決の調査
- 02ファイルと実行時の挙動の食い違いの分析
- 03モジュール欠落・ロード失敗・ドライバー IPC の調査
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ dslsdzc/ rev-skills --skill re-kernelインストール後、Claude Code で/re-kernelを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/android-kernel.mdfreebsd-kernel.mdgenode.mdhaiku.mdhelenos.mdhic.mdibmi.mdillumos-kernel.mdlinux-kernel.mdmacos-kernel.mdminix3.mdnetbsd-kernel.mdopenbsd-kernel.mdopenvms.mdplan9.mdredox.mdsel4-kernel.mdunikraft-mirageos.mdwindows-decision-tree.mdwindows-gotchas.mdwindows-kernel.mdzircon-kernel.mdzos.md詳細
内核逆向(跨平台)
**内核态分析的难点不是"用什么工具反编译",而是"观察与预期冲突时先怀疑什么"。** 各平台形态不同(PE / ET_REL / Mach-O / 模块集合),但共性是:**构建与加载模型决定你能看到什么**——版本、符号解析方式、结构随机化、签名、加载阶段、缓存集合,都会让"看起来一样"的两份东西实际不同。 所以顺序永远是:**先确认"我在看的这份是不是正在运行/被加载的那份",再谈逻辑。**平台差异(不是同义替换)
| 平台 | 单元形态 | 加载与签名模型 | 类型信息来源 | 主要观测面 |
|---|---|---|---|---|
| Windows | 先分驱动模型:WDM / KMDF / UMDF / minifilter / NDIS·miniport;再谈 .sys(PE) | SCM 注册 + 驱动签名(WHCP / 测试签名;2026-04 起 legacy cross-sign 默认不受信) | PDB(public≠private)、WDK / ntddk.h 类型 | WinDbg 内核调试、!drvobj/!process/!wdfkd.*、Volatility |
| Linux | .ko(ET_REL 可重定位目标) | insmod/modprobe + vermagic / symbol CRC / 签名尾 | BTF(含 split BTF 与 .BTF.base)、vmlinux、源码 | /proc/kallsyms、/sys/module/*/sections/、kprobe/ftrace、内存 cross-view |
| macOS | 三套模型:KEXT(内核态)/ DEXT·DriverKit(用户态)/ System Extension(框架) | AuxKC(启动时加载)+ UAKL + Reduced Security / System Extension 激活审批 | 符号、Mach-O、Info.plist(IOKitPersonalities) | IORegistry、kmutil、dSYM+KDK;dext 走用户态分析与调试 |
| Android | GKI module / vendor module | GKI 签名 + KMI 符号白名单 | BTF、KMI symbol list、Module.symvers | 模块所在分区、modules.load 计划 |
| seL4(微内核) | capability 系统:对象(TCB/Endpoint/CNode/Frame/Untyped/SC)+ cap 分布 | 无 capability 即无访问权;对象在构造期由 spec/loader 创建 | capDL spec(.cdl)、CAmkES ADL、ELF | capDL snapshot(seL4_DebugSnapshot)、seL4_DebugCapIdentify、QEMU 仿真 |
| Fuchsia/Zircon | handle 引用内核对象(数值进程本地)+ 用户态驱动 component(DFv2) | driver manager 维护 node 拓扑、driver index 按 bind rules 匹配、driver host 承载实例 | FIDL、组件清单、bind rules | driver manager/driver index 的匹配与拓扑、driver host 进程划分、handle+rights 关系图 |
| FreeBSD | .ko(KLD,ELF 可重定位) | linker sets + SYSINIT(SI_SUB_* + SI_ORDER_* 排序)+ 运行期 kernel linker | 符号、set_* 集合、源码 | __start_set_*/__stop_set_* 边界、加载路径(内建/预加载/kldload) |
| illumos/Solaris | .so 内核模块(DDI/DKI 驱动) | _init → mod_install(&modlinkage);_fini → mod_remove | modlinkage→modldrv→dev_ops→cb_ops 静态链 | 逐字段读 dev_ops/cb_ops(含 nulldev/nodev 占位语义) |
| OpenBSD | 与一般 Unix 同形,但内核每次 boot 重新随机链接(KARL)+ autoconf 运行时匹配 | link kit + rc 后台重链接;detach 可等待使用者退出 | 符号(KARL 后必须按符号而非字节比较) | link kit/rc 重链接痕迹、autoconf 表、pledge/unveil 状态 |
| NetBSD | .kmod(ELF,由内核 linker 解析) | 按需自动加载(含依赖递归)+ 自动卸载;模块与内核版本强约束 | 模块版本报告与内核版本 | 实际模块路径(布局随 KERNEL_DIR 变化)、.plist 属性 |
| Genode | 组件树:session + capability + quota | parent 中介的路由,名字逐层重映射 | 组件的 XML 配置与路由表 | capability 的 PD 局部命名、quota 捐赠链、ROM 更新 |
| MINIX 3 | 用户态服务 + RS 自愈重启 | RS 监控/重启;label 稳定、endpoint 会变 | 定长消息(56 字节)定义与 grants | 服务 label↔endpoint、grant 校验、live update 阶段 |
| Plan 9 / 9front | 每进程命名空间 + 用户态 file server | bind/mount/union;服务经 /srv 发布后挂载 | 9P 的 fid/qid/walk 与消息类型 | 命名空间绑定历史、9P 会话对齐 |
| HelenOS | 用户态 server + fibril(内核不知道) | 用户态 DDF;devman 按 match id 评分启动驱动 | DDF 结构(driver_ops_t) | kernel thread 与 user fibril 的区分 |
| Redox | scheme + 用户态 daemon | 内核把文件操作转成 SQE/CQE 消息 | SQE/CQE 字段、句柄映射 | scheme 名 → provider;客户端 fd 与 provider 描述符的映射 |
| Haiku | kernel module,但分 driver module / device module 两层 | Device Manager 的 device_node 树 + 按需发现 | 节点属性与总线类型规则 | /dev 路径 ↔ 节点 ↔ 驱动 |
| IBM z/OS | TCB 与 SRB 两类可调度单位 | cross-memory / PC / AR 模式 | 地址空间三元组(home/primary/secondary) | 当前 primary/secondary/home 与工作单位类型 |
| IBM i | 对象式(库即容器对象) | 单一存储层:内存与磁盘同一 64 位地址空间 | 对象限定名与全局指针 | 对象引用 vs 主存地址 |
| OpenVMS | 进程/线程 + AST 异步控制流 | $QIO + 事件标志 + AST | IOSB、AST 参数 | 完成流(IOSB → 标志 → AST) |
| Unikraft / MirageOS | 库操作系统 / unikernel:应用与 OS 库整链 | 构建目标决定一切(native vs binary;unix/hvt/xen…) | 构建配置与 shim | 调用进入"内核"的方式、设备接线来源 |
| HIC | 同特权级进程 + MMU 隔离(Privileged-1 与 Core-0 同物理特权级);驱动只映射被授权的 MMIO/共享内存 | 自描述模块(UUID/版本/端点/资源/依赖/签名)+ capability 记账;动态加载与滚动更新 | 模块元数据、capability 表 | domain / capability / mapping / device ownership / version / lifecycle 拓扑 |
失败模式决策表(本技能的主入口)
当反编译结果或运行观察与预期冲突时,按这张表先怀疑、再排除:
| 症状 | 優先して疑う点(順番) | 対処方針 |
|---|---|---|
| struct offset がすべて誤っている | ① BTF と対象が一致しているか ② kernel build が一致しているか ③ RANDSTRUCT(CONFIG_GCC_PLUGIN_RANDSTRUCT;この種のカーネルには taint T が付く) | 優先順位:対象の BTF > exact build のデバッグ情報 > exact seed+config > 動的検証 > offset の推測(最も望ましくない) |
| symbol resolution が不自然 | ① MODVERSIONS(CRC)② Android KMI ③ livepatch(.klp.rela/.klp.sym)④ split BTF | それぞれ該当する分岐に沿って確認し、「ファイル破損」と決めつけない |
| ファイルと実行時の挙動が一致しない | ① Linux の実行時 relocation/init-only セクションが消失している ② macOS AuxKC が古いバージョンのまま実行されている ③ Android では実際には別パーティションにある同名モジュールが読み込まれている | 「ディスク上のバージョン/実行中のバージョン/起動時刻」を記録し、ディスクだけを見ない |
| ディスク上のコードとメモリ上の命令が一致しない | まず正当な動的パッチ適用を除外する:alternatives、static keys/jump labels、ftrace、livepatch、paravirt、kprobe(Linux) | 「説明のつかない変更」がある場合にのみ rootkit の疑いを強める――「改ざんされたように見える」ものの多くはカーネルの仕組みです |
| メモリ内に特定の関数が見つからない | ① __init セクションが解放済み ② built-in(そもそも独立した .ko はない)③ stripped ④ split BTF | init 関数そのものではなく、「init がどのような状態変更を残したか」(callback/hook/変更されたポインター)を追う |
kallsyms がすべて 0/アドレスが vmlinux と一致しない | ① kernel.kptr_restrict ② KASLR(kernel text と module base の両方がランダム化される) | まずポリシーを確認して slide を復元し、「hook された」や「別の kernel だ」と判断しない |
| シンボル化した offset が常にずれる/文字列として解析される | ① __TEXT_EXEC.vmaddr を加算し忘れている(arm64e の KEXT panic の基底アドレスにはこれを加算する必要がある)② シンボルファイルと panic image の UUID/build が一致しない | まずセグメントに応じて基底アドレスを調整し、次に UUID+arch+exact build(KDK)を確認する。逆アセンブルを疑わない |
| kext の署名は有効なのに読み込めない | 署名だけではない:UAKL/ユーザーによる承認/Reduced Security/AuxKC の再構築+再起動;x86_64 kext では KMErrorDomain 71 にも該当(Rosetta は kext を変換しません) | architecture/signature/approval/UAKL/boot policy/AuxKC inclusion を分けて判断する |
UserClient に接続できない/kIOReturnBadArgument | ① activated/entitlement/Team ID/sandbox ② dispatch の count/size/completion が handler より前に拒否している | 「まず認可チェーン、次に ABI、最後に handler」の順に調べ、最初から selector のロジックを推測しない |
| モジュールが「消えた」 | ① built-in(そもそもモジュールファイルはない)② rootkit によるリストからの除去(module list unlink)③ macOS Kernel Collection ④ Android の別パーティションまたは別の boot stage | 複数のビューを相互比較し、単一のビューだけで結論を出さない |
| driver IPC が通らない | ① selector/ABI ② entitlement ③ sandbox ④ Team ID(macOS)⑤ service がそもそも activate されていない ⑥ dispatch の count/size/completion が handler より前に拒否している(Windows の kIOReturnBadArgument に相当するケースは macOS の分岐を参照) | selector を直接推測するのではなく、「接続できるか」から「接続後にどう呼び出すか」の順に調べる |
IRP handler が見つからない/MajorFunction が空 | まずドライバーモデルを判定する:KMDF(!drvobj が Wdf01000.sys を指すのは正常)、NDIS/miniport、minifilter、UMDF | 対応する callback の登録図(Evt* / Ndis* / FLT_* / WDF config dataflow)を探す。「I/O がない」とは判断しない |
IoCallDriver は返ったが処理が完了していない | completion edge:STATUS_PENDING は失敗ではなく、最終状態は IRP->IoStatus.Status と completion path にある(STATUS_MORE_PROCESSING_REQUIRED は処理を引き継ぐ) | CFG に completion edge を追加しないと、cleanup/copy-back/retry が「誰にも呼び出されていない」ように見える |
古い .sys が突然読み込めなくなった(署名に問題はなさそう) | ① 2026-04 以降、legacy cross-sign はデフォルトで信頼されない(WHCP のみ認められる;先行評価モード)② HVCI 下では Test Mode でも署名が必要 ③ Secure Boot が testsigning を阻止している | 「署名が破損した」「API が変わった」と判断せず、まずポリシー層を確認する([[windows-kernel]] §26–28 を参照) |
| 異常な ELF section が見える | ① 署名の末尾データ(ELF の末尾に追加されている)② livepatch .klp.rela ③ BTF/.BTF.base ④ ORC unwind ⑤ アーキテクチャ/ツールチェーンのメタデータ | まず分類してから対処する。「修復」のために truncate/strip しない |
| 同じ CPtr 値が同一のオブジェクトとして扱われている | CPtr は各 CSpace 内のローカルアドレスであり、グローバル ID ではない(seL4) | まず各 CSpace のマッピングを復元し、kernel object を基準に対応付ける |
| スレッド/サービスが「停止した」または「設定が破損した」ように見える | ① MCS:SC がバインドされていない/budget を使い果たした/passive server にはそもそも SC がない ② fault handler が fault を修復していない | MCS のセマンティクス(SC/budget/貸与チェーン)に沿って調べる。POSIX のデッドロックとして扱わない |
| IRQ が一度しか届かない | Ack がない(seL4:ack しないとカーネルは後続の割り込みを再送しない) | IRQ 処理ループ内の seL4_IRQHandler_Ack を確認する |
| 同じ handle 値が同一のオブジェクトとして扱われている | handle 値は現在のプロセス内でのみ有効であり、クローズ後に再利用される(Fuchsia/Zircon) | 各プロセスの handle テーブルを復元して kernel object を基準に対応付ける。関係図には object + handle + rights の 3 項目を記録する |
以前は保持していた handle が今は BAD_HANDLE を返す | channel_write で送られた(in-transit / transfer)、または書き込み失敗で破棄された | まず transfer のセマンティクス(ZX_RIGHT_TRANSFER が削除されているかも含む)を確認し、UAF と判断しない |
| 明らかにドライバー間 IPC があるのに syscall trace に channel 呼び出しがない | 2 つのドライバーが同じ driver host に常駐している → driver runtime のプロセス内チャネル | driver host で区分して検証する(同じ host に常駐する場合、node symbols はプロセス内を経由する)。「呼び出しが隠されている」と判断しない([[zircon-kernel]]) |
bus probe() でドライバーのバインド先が見つからない | DFv2 では node properties + bind rules が driver index を介して照合される | probe callback ではなく、node → bind rules → driver component → driver host のチェーンを復元する([[zircon-kernel]]) |
| init/登録関数に呼び出し元がまったくない | linker set 登録(FreeBSD SYSINIT;Zephyr は [[re-rtos/zephyr]] を参照) | 関数アドレスから登録用構造体と所属する set_* 集合をたどり、dead code と分類しない([[freebsd-kernel]]) |
連続した大量のポインター/オブジェクト、section 名が set_* | カーネル独自の linker set 集合 | jump table/難読化テーブルではなく、登録集合として解釈する |
| ドライバーの「対応機能」の判定に一貫性がない | nulldev(有効な no-op)と nodev(非対応で ENXIO を返す)が混同されている | dev_ops/cb_ops の各フィールドにあるプレースホルダーの意味を確認する([[illumos-kernel]]) |
| 同じバージョンのカーネルなのに起動ごとにレイアウトが異なる/2 つのバイナリがバイト単位で一致しない | KARL による再リンク(OpenBSD)――パッチ適用でもバージョン違いでもない | バイト単位ではなく、シンボル/セマンティクスで比較する([[openbsd-kernel]]) |
| モジュールが勝手に現れたり消えたりし、ロード元が見つからない | カーネルによるオンデマンドの自動ロードと自動アンロード(NetBSD) | トリガーとなったイベントと .plist の設定を照合し、プロセスではなくタイムラインを見る([[netbsd-kernel]]) |
| ファイルに問題がなさそうなのにモジュールのロードが失敗する | モジュールとカーネルのバージョン互換性(NetBSD) | まず exact kernel version/build を確認し、安易に強制ロードしない([[netbsd-kernel]]) |
| サービス名は同じなのに別のオブジェクトへ接続しているように見える/capability 値がグローバル ID として扱われている | 名前が有効なのはローカル階層内のみで、capability は PD のローカル名前空間に属する(Genode) | ルーティングテーブル+label チェーンに沿って、または session 単位で照合する([[genode]]) |
| ドライバープロセスが消えてまた現れる | RS による自動復旧再起動(MINIX 3)――永続化ではない | label(安定)と endpoint(変化する)を照合する([[minix3]]) |
| IPC 内の整数が buffer ポインターとして扱われている | grant ID の可能性がある(MINIX 3、メッセージ長は固定で 56 バイト) | (endpoint, grant ID, offset, rights) に沿って復元する。EPERM は grant が無効であることを示し、権限不足ではない |
| 同じパスなのに異なるオブジェクトへアクセスする | プロセスごとの名前空間(Plan 9) | bind/mount の履歴と 9P セッションを復元し、パスだけで同じリソースだと断定しない([[plan9]]) |
| 1 つの OS thread 内で大量の「スレッド切り替え」が発生する | fibril:ユーザー空間で協調スケジューリングされ、カーネルは認識しない(HelenOS) | カーネルスケジューリング内に証拠を探さない([[helenos]]) |
read/write の対象がファイルシステムではない | 意味は scheme が決定する(Redox) | scheme 名から provider を探す。クライアントの fd と provider の記述子は一致しない([[redox]]) |
| boot 時にドライバーがなく、後から現れる | オンデマンドで検出される(Haiku) | バスの種類に関するルールとオンデマンドフラグを確認し、ロード失敗と判断しない([[haiku]]) |
| 実行アドレスが別のアドレス空間に属している | cross-memory / PC 命令(z/OS) | home/primary/secondary と TCB/SRB を区別し、乗っ取りと判断しない([[zos]]) |
| ルーチンに呼び出し元がないのに挙動がある | AST による非同期制御フロー(OpenVMS) | AST のエッジを追加する。「戻った後に再び待機する」のは正常([[openvms]]) |
| オブジェクトアドレスが DRAM ポインターのように見えない | 単一ストレージ層(IBM i) | メモリとディスクは同じ 64 ビットアドレス空間を使う。POSIX のファイルモデルを当てはめない([[ibmi]]) |
| user → syscall → kernel の境界が見つからない | ライブラリ OS/unikernel | まずビルド対象を判定する。「システムコール」は単なる関数呼び出しかもしれない([[unikraft-mirageos]]) |
| モジュールに UUID/バージョン/エンドポイント/リソース/依存関係/署名の自己記述メタデータがある | まずメタデータをトリアージし、その後に逆アセンブルする | メタデータは第一層の証拠です([[hic]]) |
| 高速パスの IPC が「入口ページ → ビットマップ検査 → 失敗分岐 → 業務ページへのジャンプ」となり、ジャンプが fault を起こす可能性がある | 正常な IPC 境界(隔離モードでのページ切り替え/検証パス) | 難読化/CFI stub/不正な CFG と判断しない([[hic]]) |
| 同じ capability 構造でも、バージョンやドキュメントによってレイアウトが異なる | まず世代を識別する(per-core でグローバルロックなし ↔ 保護されたグローバルテーブル) | 最新のドキュメントに記載された構造をそのまま当てはめない([[hic]]) |
| 初期化時に「余計に見える」reset/状態検査が大量にある | sandbox の再起動/復旧パス(ドライバーの再構築 ≠ ハードウェアが clean boot 状態に戻ること) | boilerplate と見なして削除しない([[hic]]) |
操作步骤(跨平台通用主线)
- 确认身份:这是哪一份(磁盘 / 运行 / 加载集合中的版本)、什么构建(vermagic / CRC / KMI / 签名)、什么形态(PE / ET_REL / Mach-O / 用户态 dext)
- 类型与符号:优先官方类型来源(PDB / BTF / 符号表 / KMI list),其次精确构建信息,最后才是推断
- 功能骨架:从 imports/exports 与内核 API 调用关系切分功能——闭源或 stripped 时这一步尤其有效
- hook 与隐藏:枚举 hook 落点(表项 / inline text / 回调数组 / operation 结构)+ cross-view 交叉(用户态视图 vs 内核真实对象与内存)
- 验证与收尾:运行时核对(调试器 / kprobe / IORegistry / 内存侧),结论与证据按 [[re-analyze/analysis-contract]] 入档
平台分支(references)
- [[windows-kernel]] —— まずドライバモデルを特定(WDM/KMDF/UMDF/minifilter/NDIS・miniport);
GsDriverEntryは業務の入口ではありません;WDM のDRIVER_OBJECT割り当てグラフ;KMDF の Evt* callback とWDF_*_CONFIGdataflow(!drvobjが Wdf01000.sys を指すのは正常);miniport/NDIS の登録 callback;device stack と INF のスタック位置;minifilter の altitude と pre/post パイプライン;CTL_CODEとMETHOD_*のバッファーの意味(NEITHER はユーザーポインター);completion edge とSTATUS_PENDING;PAGEsection の IRQL の意味;Driver Verifier の障害注入と 0xC9;PE relocation;PDB の public/private と signature+age;!analyze -vはあくまで入口です;UMDF/Wudfhost と!wdfkd.wdfumdevstacks;2026 年のドライバー署名ポリシーと HVCI 互換要件;callback-registration graph - [[linux-kernel]] —— 3 つの禁止事項(.ko は通常の ELF ではない/ディスク上のコードは実行時の真実ではない/rootkit が疑われる場合は単一の列挙結果を信頼しない);artifact の識別(bzImage は圧縮された boot image);relocation を優先し
.modinfoを確認;.koの正当な形式すべて(署名末尾/圧縮/BTF と split BTF+.BTF.base/RANDSTRUCT/livepatch.klp.*/ORC unwind);正当な動的 patching の一覧(alternatives/static keys/ftrace/livepatch/paravirt/kprobe);__ex_tableの exception edge;ENDBR;callback-registration graph;__initの解放とロード段階の診断(CONFIG_MODULE_STATS);MODVERSIONS の 2 世代の形式;KASLR と kptr_restrict;rootkit の cross-view - [[macos-kernel]] —— 3 つのモデルの混同に注意(KEXT はカーネル空間/DEXT はユーザー空間/System Extension はフレームワーク);まず
Info.plistを確認し、IOKit class graph(OSMetaClass/vtable)を調べる;codeless kext;ディスク上のバージョンと AuxKC のバージョンおよびアンロードの見かけ上の現象;arm64e PAC ポインター;newUserClient→externalMethodと dispatch のcheck*フィールド(kIOReturnBadArgumentはフレームワークに拒否された可能性があります);認可チェーンのトラブルシューティング順序;dext はユーザー空間として分析・デバッグ;Kernel Collection;panic のシンボル化における__TEXT_EXECオフセットと UUID/KDK の照合;UAKL/Reduced Security/AuxKC と KIP;rootkit の時代による違い;KEXT は 2 台のマシンでデバッグ、DEXT は同一マシンでデバッグ - [[android-kernel]] —— GKI と vendor module、protected symbol と KMI 許可リスト、KMI ブランチは互換性がない、モジュールの配置場所とロード計画
- [[sel4-kernel]] —— capability システム:CPtr はローカルアドレスでありグローバル ID ではない、capDL/CAmkES の意味、badge と rights、CSpace guard/depth、エラーコードがそのまま診断になる、Untyped と device untyped、ユーザー空間ドライバーの IRQ と DMA のバイパス、fault IPC、MCS(SC/budget/passive server/reply object)、capDL snapshot cross-view
- [[zircon-kernel]] —— handle のローカル性(数値はプロセス内でのみ有効、クローズ後は再利用される、プロセス間での比較は無意味);in-transit と transfer(書き込み時点で送信側から削除され、失敗しても消費される、
ZX_RIGHT_TRANSFER、rights は縮小のみ可能;関係グラフには object + handle + rights を記録);DFv2(driver manager / driver host / driver index / driver runtime;bind rules によるマッチングでありbus probe()ではない);同居するドライバー間のローカルチャネル(IPC はあるが syscall はない);/dev/fooは FIDL channel であり Unix デバイスファイルではない - [[freebsd-kernel]] —— linker sets と
SYSINIT:登録項目は起動/終了用の集合に格納され、SI_SUB_*+SI_ORDER_*に従って順序付けされます(同じ sub と order の順序は未定義);現代の ELF では__start_set_*/__stop_set_*で範囲を定め、末尾に NULL は置かれません(古い構造に従ってスキャンすると範囲外アクセスになります);set_*集合の一般的な判定方法;KLD のSI_SUB_KLDによる統合タイミングと逆順の解体 - [[illumos-kernel]] —— DDI/DKI ドライバーの骨格:
_init/_fini/_info→modlinkage→modldrv→dev_ops→cb_ops;nulldev(正当な no-op)とnodev(未サポートでENXIOを返す)の違い;attachのDDI_ATTACH/DDI_RESUME(DDI_PM_RESUMEは廃止済み);インスタンスごとの初期化はattach()に属します;mod_removeが失敗した場合、_finiはリソースを解放してはいけません - [[openbsd-kernel]] —— KARL の再リンク(起動のたびに
.oをランダムに再リンクします。変わるのは内部レイアウトであり、ロードベースアドレスではありません。KASLR とは異なります。バイト単位の差異だけで patch と判断してはいけません);autoconf による実行時のマッチング/attach(foo_attachに caller がないのは正常で、detach は利用者を待機できます);pledge/unveil の一方向のラチェットと捕捉できない SIGABRT(「起動時にはアクセスできたのに、その後突然できなくなる」のは設計上のパターンであり、外部からの遮断が原因だと決めつけないでください) - [[netbsd-kernel]] —— 必要に応じたモジュールの自動ロード(modload がなくても出現し、依存関係の再帰的なロードも含む)と自動アンロード;モジュールとカーネルのバージョンには厳密な互換性要件があります(不一致の場合は失敗し、強制ロードには公式の警告があります);モジュールのパスは
KERNEL_DIRの新しいレイアウトに伴って変わります(/stand/...をハードコードするとサンプルを見落とします) - [[genode]] —— コンポーネントツリー + session + capability + quota:サービス名が有効なのはローカルな parent 階層内のみです(各階層で再マッピングでき、label は書き換えられる場合があります);capability は PD 内のローカルな名前です;quota の寄付分は経路に沿って各階層で差し引かれます(「システムにはまだメモリがある」と「その child が OOM になる」は矛盾しません);ROM session は更新に対応しています
- [[minix3]] —— RS による自己回復と再起動(ドライバーが消えて再び現れるのは正常です);label は安定していますが、endpoint は変わります;メッセージは固定長の 56 バイトで、大きなデータは grants を使用します(
EPERM= grant が無効、EFAULT= マッピングされていない);live update 中は旧インスタンスと新インスタンスが共存します(注入ではありません) - [[plan9]] —— プロセスごとの名前空間(同じ名前のパスでも異なるオブジェクトを指す場合があります);union は 1 層だけ重ねられます;
/srvはサービスレジストリーであり socket ではありません;9P の fid は session 内のハンドルです;open/read/writeはユーザー空間の RPC であることがよくあります - [[helenos]] —— fibril(ユーザー空間で協調スケジューリングされる実行単位で、カーネルはその存在を認識しません);ユーザー空間の DDF ドライバーフレームワーク(
driver_ops_tcallback、devman が match id を採点してマッチングと起動を行う);業務処理はカーネルの dispatch table にはありません - [[redox]] —— scheme モデル(
read()が必ずしもファイルシステムとは限らない;クライアントの fd と provider の記述子は一致しない;provider は null namespace に入ることが多い)+ 起動チェーン(ブートローダー → ごく小さな ELF ローダー bootstrap → initfs による 2 段階起動)+ relibc/補助ベクトル(安定した ABI はユーザー空間にあり、syscall ABI は意図的に不安定です)+ ドライバーはユーザー空間の daemon(initfs とメインシステムを2 回ビルド) - [[haiku]] —— ドライバー側:device_node ツリー + 必要に応じた検出 + driver module/device module の 2 層;システム側:team/thread/area/port/semaphore のカーネルオブジェクトモデル、KDL(スタックトレース/スレッド/メモリ/CPU 切り替え)とデバッグ API(BeOS とは互換性がありません)、BeOS R5 の一方向の互換性境界、ユーザー空間サービスの境界
- [[zos]] —— TCB と SRB、home/primary/secondary、AR モードの ALET;さらに load module / program object(PDS と PDSE)、AMODE/RMODE、XPLINK と非 XPLINK ではスタック動作が逆(方向、0x800 のオフセット、展開メカニズム)、SVC/PC テーブル、dump の種類と IPCS(XPLINK では制御ブロックが少なくなるため、LEDATA を確認)、EBCDIC とレコードモデル
- [[ibmi]] —— 階層(MI / TIMI / SLIC / PASE の境界)、プログラムモデル(OPM/EPM/ILE;
*MOD/*PGM/*SRVPGM;コピーによるバインドと参照によるバインド)、activation group(PSSA/PASA/ヒープとオーバーレイのスコープ)、2 種類のポインター(システムポインター/スペースポインター)と2 種類のストレージモデル(single-level と teraspace。job の境界と tagged ポインターの制限を含む)、実行可能な成果物の識別(DMPOBJ/コンパイル一覧/圧縮状態/タイムスタンプは必ず異なります) - [[openvms]] —— 2 つの制御フロー:AST(完了順序は IOSB を書き込む → イベントフラグをセットする → AST を起動する;実行中のシステムコールを中断しない;待機が中断された後に再実行する)と条件処理(ハンドラーチェーンの継続/再配送/巻き戻し、2 回目の例外では検索済みのフレームをスキップする、イメージ起動時のデフォルトの 3 点セット、言語間の違い);さらにイメージの活性化と共有イメージ(論理名によるリダイレクト、特権付き/実行専用イメージの制限)と呼び出し規約
- [[unikraft-mirageos]] —— ライブラリー OS/unikernel:単一アドレス空間、単一保護ドメイン;native(syscall が関数呼び出しになる)と binary-compatible(Linux ELF の syscall を捕捉する);デバイスの接続はビルド時の設定で決まるため、同じソースでもターゲットが異なれば動作はすべて変わります
- [[hic]] —— capability + 物理サンドボックス + マルチバージョンのドライバーシステム:同じ物理特権レベルのプロセス間は MMU で分離されます(
Ring 0 → カーネル全体をアドレス指定可能はここでは無効な前提です);逆アセンブルより先にモジュールのメタデータを確認;入口ページの IPC 形式は難読化ではありません;共有メモリーポインターにはドメインの意味があります{domain, cap, mapping, offset, length, rights};ドライバーのライフサイクルとハードウェアのライフサイクルは分けてモデル化(インスタンス/ドメイン/デバイスの所有権/DMA/IRQ ルーティング/バインド/バージョン/移行状態)。システム間の比較(Fuchsia / seL4-CAmkES / Xen / Genode / QNX / マイクロカーネル/MINIX)と該当・非該当の一覧を含みます(他の capability システムで誤検知しないため)
何时使用 / 何时不用
- 前置:拿不准目标属于哪一个系统(非 PE/ELF、OSABI 指向非主流系统、无标准容器)→ 先过 [[re-analyze/system-fingerprints]]
- 用:各平台内核态载荷与驱动(恶意驱动 / rootkit / 反作弊 / EDR 对抗 / 闭源驱动)的静态逆向与运行时验证
- 用:capability 系统(seL4 等微内核)的对象图 / capability 分布 / IPC 拓扑恢复,以及"行为为何与普通 OS 不同"的判定
- 用:Fuchsia/Zircon —— handle 与 rights 关系恢复、DFv2 驱动的 bind rules 匹配与 driver host 划分、同驻驱动通信的判定([[zircon-kernel]])
- 用:FreeBSD / illumos·Solaris —— linker set 注册的初始化(找不到调用者)与 KLD 生命周期([[freebsd-kernel]]);DDI/DKI 驱动骨架与
dev_ops/cb_ops能力判读([[illumos-kernel]]) - 用:需要判断"内存里/内核里这份代码是什么、从哪来、是否被改过"
- 不用:UEFI / 引导阶段(bootkit)→ [[re-uefi]];RTOS 内核对象 → [[re-rtos]];eBPF 程序(BPF-64 指令集、progs/maps)→ [[re-ebpf]];TEE / TrustZone → [[re-tee]];仅内核调试与崩溃定位 → [[re-windbg]] / [[re-lldb]]
- 不用:只需要采集内存里的载荷(不分析内核结构)→ [[re-sample-acquire]]
工具准备(按平台,细节见各分支)
- Windows:[[re-ghidra]] / [[re-ida]](导入 WDK 内核类型)、[[re-windbg]](双机 / KDNET 内核调试)、Microsoft 公共符号;测试签名仅在调试 VM 内开启(
bcdedit /set testsigning on,需关 Secure Boot) - Linux:
readelf/objdump -r(ET_REL 与 relocation)、modinfo(vermagic/依赖/签名/livepatch)、pahole/bpftool(BTF)、bpftrace/perf probe(kprobe)、ftrace - macOS:
otool/vmmap/ioreg/kmutil/codesign -d --entitlements/lldb([[re-lldb]]、[[re-format-macho]]) - Android:
modinfo/readelf+ 目标分支的 KMI symbol list 与Module.symvers比对
跨域联合
- [[re-windbg]] / [[re-lldb]] / [[re-gdb]]:各平台内核调试与运行时验证
- [[re-binary-core]]:静态初勘底座(PE/ELF/Mach-O 解析、导入导出)
- [[re-malware]]:rootkit / 驱动型恶意样本的深度分析环节引用本技能
- [[re-anti-analysis]]:驱动加壳与混淆对抗
- [[re-sandbox]]:驱动加载与调试环境隔离(VM + 快照,[[re-analyze/platform-tips]] 最高原则)
- [[re-emulation]]:摘出的关键函数可模拟执行验证
- [[re-mem-forensics]]:rootkit 取证对照(cross-view 的离线侧)
- [[re-sample-acquire]]:内核态载荷的现场采集(异常执行区与执行上下文归属)
- [[re-ebpf]]:eBPF 程序(非
.ko形态的内核代码)走那边 - [[re-rtos]] / [[re-uefi]] / [[re-tee]]:嵌入式内核、引导阶段与可信执行的分工
- 反编译工具选型:[[re-ghidra]] / [[re-ida]] / [[re-binaryninja]] 三选一
常见坑与陷阱(跨平台共性)
- 只看磁盘版本就下结论:Linux 的 init-only 段在运行时已消失、macOS 的 AuxKC 可能还在跑旧版本、Android 可能加载的是另一分区的同名模块——先对齐"磁盘 / 运行 / 加载集合"三份身份
- 把"看着像坏"的合法形态当损坏:Linux 的签名尾、livepatch 节、split BTF 都不是损坏(见 [[linux-kernel]] 的四类形态)
- 用同版本假设解释 offset 或符号错误:RANDSTRUCT、MODVERSIONS、KMI 分支都会让"同版本"实际不同
- 单一视图判定"没有 hook / 没有隐藏模块":
lsmod、syscall table、/sys/module任一为干净都不构成结论——必须 cross-view,且视图矛盾时优先信离线内存取证 - hook 手法只盯着老几样:现代落点包括 operation 结构、ftrace、kprobes、inline text——"syscall table 没被 hook"不等于内核干净
- 内核态操作没有隔离:加载/触发内核代码可能直接宕机(Windows 蓝屏);一切在调试 VM + 快照内做([[re-sandbox]] 最高原则)
- 各平台特有的坑见对应分支([[windows-kernel]] / [[linux-kernel]] / [[macos-kernel]] / [[android-kernel]])
コメント
Markdown 対応