プログラミング
失われた配列の略奪者たち: オルファン化されたDrobo用macOSドライバーのvibeコーディング
Raiders of the Lost Array: vibe-coding a macOS driver for my orphaned Drobo (fetzu.ch)
要約
筆者は、Drobo 5DというRAIDストレージデバイスが、Drobo社の事業停止とmacOSのアップデートにより将来的に使用できなくなる問題に直面しました。この問題を解決するため、AIアシスタントClaudeの助けを借りて、macOSドライバーと管理ソフトウェアの再構築を試みる冒険の記録です。Claudeは、デバイスのプロトコルを解析し、CLIツールや最終的には完全なドライバーの作成を目指す5段階の計画を立案しました。
全文翻訳
免責事項: 私が行っていることが合法かどうかは分かりません。また、ハードウェアハッキングに関する深い知識も一切ありません。
免責事項2: 私はコーヒーメーカーを自動化するためにLLMを使用するほど愚かで怠惰ですが(おっと!)、時々コードを書くためにLLMを使用します。このテキストは完全に人間によって書かれ、LLMによる校正はほとんど受けていません。この免責事項は、このブログでの今後のすべての執筆に適用されます。
私は2021年にこのウェブサイトを開始しましたが、ブログに何かを書く時間がありませんでした。「遅れてもやらないよりはまし」だと思います。さて、何も始まりません…
今日、HNへの投稿「Claudeが私の時代遅れのHPプリンター用のmacOSドライバーを書く(Windows専用)」に触発され、私の信頼できるDrobo 5D、過去14年間、私のファイルを完璧に保存・提供してきたRAIDアレイ(約2019年の「電源アダプターが壊れた」インシデントを除く)について考えました。Droboは事業を停止し、次期macOS 27「Golden Gate」はRosetta 2をサポートする最後のリリースとなるため、ソフトウェアスイートの一部は将来のmacOSリリースとの互換性がなくなります。そして、私にとってあまりにも多くのQoL(Quality of Life)改善があるため、それをパスすることはできません。病気で家に閉じこもっていたので、「なぜClaudioにこの件を任せないのか」と思いました。そして、これがその冒険の記録です。
まず、プロンプトがありました ¶
会社「Drobo」は事業を停止しました(https://petapixel.com/2023/06/06/drobo-is-officially-done-as-the-company-moves-into-liquidation/ を参照)。私は「Drobo 5D」を所有しており、USB 3でMacに接続されています(Thunderbolt 2ポートは新しいMacモデルでは動作しません)。これは、macOS Ventura (13) を実行している私の2017 iMacではまだ動作します。Drobo本体とDrobo Dashboardソフトウェアの両方が機能します。新しいmacOSバージョンでは、Drobo Dashboardソフトウェアは互換性がなくなり、Droboは外部ドライブとしてのみマウントできます。エコロジーのために、私はこのデバイスをできるだけ長く使用するという目標を持っていますが、「macOS(またはMacハードウェア)のアップグレードから締め出される」ことは避けたいです。
今日のあなたのタスクは、現在のDrobo 5DファームウェアとDrobo Dashboardソフトウェアを分析し、なぜ新しいmacOSバージョンで動作しないのか、ハードウェアが新しいMacハードウェアで動作するのを妨げている可能性のあるものは何かを理解し、これを修正する方法を提案することです。単純な修正から、モダンなMac/macOS用のドライバーとDrobo Dashboardの完全な書き直しまで、すべてが検討対象です。
注: 私は、DroboドライバーとDrobo Dashboardの最新バージョンまでのいくつかのバージョンを/Users/fetzu/Dev/ReDrobo/ZZ_BUFFERフォルダに提供しました。これらを必要に応じて自由に使用してください。ただし、このMacにインストールすることは避けてください(できないと思います)。
このプロンプトの構造は非常にシンプルです。コンテキストを提供し(サイバーセキュリティ/リバースエンジニアリングでフラグが立てられないことを願っています。どれほどナイーブなことか)、タスクを述べ、Claudeにソフトウェアの両方の最後の5つのリリース(個別のPDFでリリースノートを含む)を提供します。
これをFable 5 on Highにドロップし(なぜそうしないのか?)、自動的にフラグが立てられてOpus 4.8に切り替えられます。そこで中断し、Opus 5 on Maxで新しいセッションを開くことにしました。そして、レースの始まりです。
次に、計画がありました ¶
ドライバー/Drobo Dashboardバイナリを少し考えたりいじったりした後、Claudeは5段階の計画を思いつきました。優秀なエンジニアなら誰でもそうするように、Claudeは0から数え始めます。
「まずデータを保護する」(当然)
「プロトコルを検証する」(ドライバー付きのデバイス、macOS 13を実行している2017 iMac、およびドライバーなしのMacBook Pro M5 Pro、macOS 26を実行しているデバイス間のデータ出力を比較することによって)
「レコードペイロードをデコードする」(プロトコル仕様を検証し、出力することを目的として)
「使いやすいCLIをリリースする」(Drobo Dashboardが通常行う情報を出力するため)
「ライブドライバー」(実際のDrobo Dashboardの代替)
計画は十分に健全に見えます。飛び込みましょう…
フェーズ1: DroboをMacBook Proに接続する ¶
これが機能することは分かっていました(ボリュームは正常にマウントされ、読み書き可能ですが、間違ったサイズを報告し、ユーザーにボリューム/アレイ/ドライブの現在の状態に関する情報を提供しません)。Claudeは、デバイスを接続した後にデバイスをプローブするためのdroboprobeという便利なCユーティリティを作成しました。Claudeは、Drobo Dashboardの現在のDrobo 5Dの状態のスクリーンショットを最初に撮るように私に依頼しました(親切なことに、私はタイピングがあまり好きではありません)。このフェーズで、デバイスが動作しているが、確かにボリュームサイズが間違って報告されていることを確認できました。
合計 使用済み 空き容量
Dashboard (iMac) 5.42 TB 4.25 TB 1.17 TB
macOS (こちら) 17.6 TB 4.7 TB 12.9 TB
しかし、「悪いニュース」もありました。悪いニュース、そして私はこれを間違えました ¶
SCSITaskUserClientはDroboでは動作しません。IOReturnUnsupportedを返すIOCreatePlugInInterfaceForService。このMacでは、SCSITaskDeviceCategoryを公開するサービスはゼロです。イニシエーターはすべてのSCSIヌブにマッチカテゴリを予約しますが、実際には開始しません。理由は、Apple自身のヘッダーの中にありました。SCSITaskLibは、「カーネル内ドライバーがないデバイス」と光学式バーナーを提供します。DroboはAppleのIOSCSIPeripheralDeviceType00によって主張されるため、何も取得されません。バックドアも排除しました。1つのUSBインターフェース、1つのLUN、両方とも主張されています。
幸いなことに、追加の朗報がありました。
しかし、プロトコルを取得するクリーンな方法があります ¶
kextはiMacにインストールされ、動作しており、そのユーザークライアントは通常のIOUserClientです。バイナリから完全なディスパッチテーブルを抽出しました。
セレクタ メソッド シェイプ
2 sGetESAModePage スカラー2つ入力、1308バイト構造体出力 — 読み取り
3 sSetESAModePage スカラー3つ+1308バイト構造体入力 — 書き込み
セレクタ0-3はシンボルテーブルおよびターゲットディスパッチビットマスクに対して確認されています。2つの安全プロパティが重要です。セレクタ2のみを呼び出し、IOKitはkextが何かを見る前に、そのテーブルに対して引数の数とサイズを検証するため、間違いは実行されるのではなく拒否されます。これは、Dashboardのデーモンが数秒ごとに実行しているのと同じ呼び出しです。これにより、Dashboardが横にある状態で、セキュリティ設定を変更せずに、権威あるペイロードバイトを取得できます。
フェーズ2: レコードペイロードのダンプとデコード ¶
Claudeは次に、iMacからESAレコードをダンプできる便利なユーティリティdroboesaを提供してくれました。2回の試行の後(launchctl listにsudoが必要であることが判明しました)、Claudeは完全な「Drobo 'ESA'管理プロトコル」を考案することができました。これは、本格的なドライバーへの道が開かれたことを意味します。
フェーズ3と4: ドライバー(とアプリ)の構築(とテスト) ¶
次のフェーズは、Claudeが「どう進めるか?」と尋ねてきたことから始まりました。Appleの開発者アカウントを取得してSCSIPeripheralsDriverKitエンタイトルメントを要求するか(偶然にも私はすでに持っていますが、おそらくMr. Nobody-from-the-Alpsが特許取得済みの可能性のある製品をリバースエンジニアリングする私には決して得られないでしょう)、またはSIPを(一時的に?)無効にして生のまま実行するかです。
LLMによって書かれたコードに無制限のカーネル拡張アクセスを許可する。私にはそれを検証する専門知識が全くない…何が起こりうるだろうか?
だから、当然、私は(非)賢明な人がすることをしたのです。Claudeの「DroboDext」とReDrobo.appを試すためにSIPを無効にしました。しかし、私は大胆不敵ではなく、ただ愚かなだけなので、macOS 27開発者ベータ版を実行しているスペアのMacMini M1でそうしました。Claudeがゴールポストを動かすことについてどう「感じる」か不思議です。
MacMiniを起動し、SIPを無効にして、アプリを起動します。すると、クラッシュ。エンタイトルメントに関する何か。次に、アプリバンドルで拡張機能が見つからないという問題。次に、dextバンドルのレイアウトに関する問題。次に、命名に関する別の問題。次に、dextがx86_64 arm64e(ポインタ認証付き)用にコンパイルされているのではなく、arm64用にコンパイルされているという問題。次に、コード署名に関する別の問題。
その後、ドライバーはついにインストールされ、デバイスとほぼ通信できるようになりました。次に、別のエンタイトルメントの問題がありました。次に、「ExtensionNotFound」の問題がありました。
その時点で、Claudeは私に諦めるように(そして「グラインドを続ける」ように)ほとんど頼みましたが、私はそれを許しませんでした。