しばらくの間、私のブログをご覧になっていると思いますが、2012 年に Energy Mac G3 (Blueと白)。 これは、Forth プログラミング言語のリラックスできる入門書でした。 何が起こっているのかを示すために、Apple のファームウェア置換スクリプトのほとんどをリバース エンジニアリングする必要がありました。彼の iMac でもほぼ同じ起動音のカスタマイズができれば。 この説明では、iMac は「iMac (Slot Loading)」であり、PowerMac2,1 のモデル識別子を持っているため、正式に識別されます。 間違いなくタイトルからも推測できるように、PC pc タイプのトレイローディングパワーを備えた通常の iMac とは異なり、スロットローディング CD-ROM パワーを備えています。 ちなみにAidanのiMacは通常のG3の代わりにPowerPC G4プロセッサをロジックボードにハンダ付けしているので特殊です
彼は、このモデルの Apple の最終ファームウェア交換を送ってくれました: iMac ファームウェア アップデート 4.1.9。 Energy Mac G3で行ったのと同じプロットで、チャイムを変更するための工夫も判断できるかどうかを確認するために、交換内容を見て仕事に行きました. 私は、すべての人々を急いで盗み、音を変えるために何が生きていたかを正確に命令することは、おそらくリラックスできると思います. そして当然のことながら、この投稿は、新しいチャイムをファームウェア置換ファイルに挿入するために作成したユーティリティのコードを追加で共有することなしには完全ではありません.
調達を開始する前に、私の Energy Mac G3 の起動音のカスタマイズに関する 2012 年の作業の背景データを提供したいと思います。その一部は iMac にも関連していたからです。 G3 の ROM をダンプした後、生ファイルとして Audacity にインポートしました。 形式として、符号付き 16 ビット PCM、サイジング エンディアン、44,100 Hz を選択しました。 次に、あなたの完全な 1 MB ROM をかなり大きな音で再生しました。 それは主にスクラッチな混乱を賞賛するように聞こえましたが、明らかに起動時のサウンドデータを含む 2 つの領域がありました。 それは非常に静的に聞こえ、プロットが速すぎましたが、明らかに起動時のチャイムでした. ヘッドフォン/イヤフォン ユーザーは注意してください。
下げることでより正確な寸法と音程に近づけることもできますサンプル価格ですが、静かでチクチクしました。 以下に示す約 2.75 秒から 3.5 秒程度の断片を見て、Audacity で賞賛されたと見なされるものの例を確認してください。
当時、私は 他の Mac ROM のサウンドフォーマットをかなり掘り下げていました。調査中なので、全体的な音声圧縮アルゴリズムのペアは、私の頭の中ですでに新鮮でした。 ROM 内に IMA ADPCM ステップ テーブルのペアをすぐに見つけました。 Apple が間違いなく弱い 彼らの QuickTime IMA ADPCM 形式 を吸収し、提案をグループ化することは、標準的な感覚です。 34 バイトのパケットに変換されます。 そのデータにより、サウンドデータの保存開始と終了がROM内で正確に特定され、解読できました
それで、Aidan が iMac のサウンドを変更する様子も見られるかどうかを尋ねたとき、私は 10 年前にたまたま私の Energy Mac の ROM で圧縮されたサウンド データを取得し、同じものを探しました。 iMac のファームウェア置換ファイル内の知識の塊。 特に十分なサウンドは、すべてのバイトに至るまでのすべての工夫が整った、適切な種類の同じ圧縮サウンドでした。 このリプレイスファイルには、起動音の再現が一番手っ取り早いものがあります。 ここにあります:


繰り返しになりますが、ファームウェア置換ファイルに適切な種類の同じパッチを正直に行うほど簡単ではありませんでした。 iMac のファームウェア置換ファイルは、Energy Mac G3 を称賛する Forth スクリプトですが、別の方法で配置されています。 それを参考にして、Forth のチュートリアルをいくつか引っ張り出し、コードを理解することでプロットを偽装しました。 以下は、ファームウェア置換ファイルと、サウンドを変更するために採用したプロセスの分析です。
Forth コードは、一連の構造を定義することから始まります。 これは、起動ビープ音と対応する測定値を参照しているため、シャープです:
それについては後で詳しく説明します。 コード内のさらに下には、いくつかのフラグメント関連の構造があります。 全体のヘッダーと 6 つのフラグメント ヘッダー (sbb、srec、sboot、ssys、stst、および snv) 用のスペースを作成します。 各フラグメントにはチェックサムがあります。 この置換スクリプトは非常に貴重です。 置換ファイル内のさまざまな提案を意味することを教えてくれます.


私は、これらの構造を真に利用し、すべてのピースをモデル化する Forth コードによって戦うつもりはもうありません。おおまかに長く、一部には、それが行うすべての部分を完全にマークしていないためです. 重要な部分は、スクリプトの先端 (キャリッジ リターンによって採用された doit) の後に、生の非 ASCII データの束がまっすぐ続くことです。 この知識の主要部分は、上記の>h および>s 構造体の絶叫素材のように見えます。

構造体定義を使用すると、間違いなくすべての上記の強調表示されたデータ (少なくとも Mac では、PowerPC が
- かなり大きいと想像してください-エンディアン):
- ヘッダー:

- file-measurement=0x000E11C0=922048 (ファームウェア ファイルの正しい種類の測定値は次のとおりです)
- モデル=0xFFFF
- 吸収バイト=0xFF
- チェックサム=0x43B8671B
- srec:
- kind=0x01
フラグ=0x81
- 予約済み=0x0000
- kind=0x01
- 測定値=0x00078000
- exact=0x00063DA0
- チェックサム=0xF05F6B03
- sboot:
kind=0x02 - フラグ=0x81
- 予約済み=0x0000
- contrivance=0x0006E07C (srec データの直後)
オフセット=0x00080000
- 測定値=0x00080000
- exact=0x00072280
- ここで終了しますが、間違いなく置換セクションをデコードすることもできます。
- header-measurement=0x00A4 (ヘッダーが終了するため) 0x68DC で)
- include-model=0x000419F1=4.1.9f1

num-sections=6 sbb:
kind=0x00 フラグ=0x81
予約済み=0x000 0 工夫=0x000068DC (ヘッダー直後)
オフセット=0x00000000 測定値=0x00003F00
exact=0x00003A00
- オフセット=0x00008000
絶叫素材をもっと見つめて決めたこれらの構造体のうち contr ivance は提案の開始スペースです。ファームウェア置換ファイル内のそのフラグメントの場合、offset もしかしたら保存するかもしれませんsave フラッシュチップ内に保存されます、測定 は、フラッシュ内のフラグメント用に予約された測定値です。チップ、および exact は、ファームウェアの置き換え内のそのフラグメントに統合された知識の正確な量です。
上記で、起動音の候補はファイル内の 0xD1E2C から 0xE02DF にあると判断しました。 これにより、sboot フラグメントの合法的な内部、ほぼ先端に配置されます。 sboot フラグメントはファイル内の 0x6E07C から 0xE02FC まで実行されます。その構造まで。 20 個の 32 ビット フレーズを吸収して、合計 0x50 バイトになる可能性があります。 以下のコマンド内で知識が強調表示されます:
上記の構造体定義を使ってデコードすると、入手:
- inst0=0x48000080
- inst1=0x000419F1
- filler0=0x20010914
filler1=0x00100000
- HWINIT=0x00000000
HWINIT 測定=0x00006BF8
NUB-測定=0x00000000
- OF=0x00006C01 OF-測定=0x0005D195


このデータは正しいようです! 0xE4C4 は、サウンドの安価な測定値です。 保存の上の画像で音声データを示しましたが、抽出した知識のサイズが 0xE4B4 であることがわかりました。これは 16 バイト小さいものです。 サウンドのオフセット 0x63DA0 も妥当です。 それに伴い、0x6E07C という sboot の仕掛けに合わせて、たまたま見つけた音声データよりもファイル内で 16 バイト前にある 0xD1E1C を取得します。 そのため、サウンドには 16 バイトのヘッダーが追加されているように見えます:

私はもはや、このヘッダーのすべての悲鳴の素材が何であるか正確には確信が持てません. 0x00000010 の原則的な 32 ビット値は、おそらくヘッダーのサイズを示している可能性があります。 0x0000002C=44 は、レジャー サウンドのサンプル価格が 44.1 kHz であることをトレースするはずです。 証明された真実にもかかわらず、私はそれについて間違いを犯す可能性もあります. 0x0001AE80 はサンプルの選択です。 サウンド データの長さは 0xE4B4 バイトで、IMA データの各ブロックの長さは 34 バイトです。 これは、0xE4B4 / 34=1,722 ブロックがあることを意味します。 各ブロックは 64 サンプルを表すので、サウンド内には 64 1,722=110,208=0x1AE80 サンプルがあります
とにかく、これは、ROM 内の起動サウンドのスペースに積極的にチャンスがあることを確認するのに役立ちました。 . これで音を長くしたり短くしたりするための十分なデータが得られると思いますが、おそらくもう 1 人、もっと大胆に感じている人がそれを試すことができます!
したがって、このレベルでは、プロセスは真新しいチャイムを注入するのは、これを賞賛する時計を持っていました:
- まったく同じ測定値の音で起動します通常のサウンドのサンプル価格: 44.1 kHz で 110,208 サンプル=正直なところ 2.5 秒以下。
- Apple の IMA を使用して音声を圧縮するADPCM フォーマット
- ファームウェア内のサウンド データを新しいサウンド データに置き換えます。圧縮して計測しているため正常です。
このリストに欠けているのは更新ですチェックサムを食べます。 計画では、残りの 32 ビット値のため、すべてのフラグメント ヘッダーがチェックサムを含むと結論付けます。 Forth コードを最初に見て、置換ファイルを支配していると、それが Adler-32 チェックサム.


フラグメントのフラグが存在するチェックサム フラグを表しているかどうかをチェックしているように見えます。そうであれば、Adler-32 チェックサムを計算します。完全なフラグメント測定値から 4 バイトを引いたものです。 余暇の 4 バイトは、フラッシュ チップ内にチェックサムを格納するために予約されている可能性が高いため、これは素晴らしいことです
私は時計を盗むためにこれをかなりいじりました。 at で、通常のファームウェア置換の既存のチェックサムを再計算します。 私の最初のいくつかは、フラグメントの「正確な」測定が惨めに失敗した正直なチェックサムを試みます。 「測定」測定が重要なものであると判断したため、コードに近づいて時計を持っていた必要があります。 一般的なヘッダー構造体には、吸収バイト メンバー (0xFF) も含まれているため、フラグメントにその値を平和的に埋め込む必要があることはわかっていました。 正しいチェックサムを計算するために、ファイル内のそのフラグメントのバイト (「正確な」バイト) から始めて、完全なフラグメントの測定値が正確に「測定 – 4」でない限り、0xFF を追加しました。 これにより、最終的にチェックサム計算が正常に完全に一致するようになりました。スクリプト内。 さらに、スクリプトはそれ自体のチェックサムをチェックして、完全なファームウェア置換ファイルが安全に変更されていないことを確認します。

構文を見つけるのに大掛かりな時間を費やすことなく、この Forth コードを最も正確にマークしようとすると、完全なファームウェア置換ファイルのチェックサムからマイナスを引いたものであると判断できます。最後の 4 バイト (予想されるチェックサムを吸収する) を計算し、計算されたチェックサムを予想されるチェックサムと比較します

既存のチェックサムを複製するこの試みは、原則として成功しました。 わーい! このエビの実験の後、チェックサムの悲鳴について非常に合法だと感じました。 両方のチェックサムを計算するための正しいプロットを知っていました。 私の提案で最も残念だったのは、どこかに音を訴えるチェックサムがもう1つある可能性があるということでした.
この完全なプロセスを真の C++ プログラムにバンドルして、置換チャイム データが正しい測定値であることを保証し、IMA ADPCM で圧縮し、貼り付けます。正しいスペース内のファームウェア置換ファイルに挿入し、チェックサムを再計算します。 これは、G3 の起動音を変更するために作成した同じファームウェア パッチ ユーティリティを完全に修正したモデルです。入力として、時計を盗むためのパッチが適用されたファームウェア置換ファイルが装備されていました。 このパッチ適用プロセスをホーム ウィンドウで実行しました。 リソースフォーク
および サンバ。 ファイルのサジェスチョン フォークを変更するために、ホーム ウィンドウで Samba を使用して入力することができます。また、Mac で netatalk を使用してアクセスすると、リソース フォーク データが保留されます。 リソース フォークは、netatalk によって .AppleDouble フォルダのようなものに保存されます。
Aidan がこのパッチを適用したファームウェアを Open Firmware を起動し、議論を進めています が、実際のところ、私は OF を試すのに十分な居心地の良さを感じていませんでした。 そのため、業界の次の悲鳴は、Apple のファームウェア アップデーター プログラムを変更して、ファームウェアが既に更新されている場合にパッチを適用するための工夫を決定することでした.

私はまた、このプロセスを長い間行っていました私のG3のファームウェアアップデーターには、交換できるファームウェアバージョンの許可リストがありました。 これは、パッチを適用するのが簡単であると想定していました。 最新のファームウェア モデルを調査するために、許可リスト内のすべてのエントリの 1 つを正直に変更しました
iMac アップデータ内にそのようなリストは存在しませんでした。 私は提案フォークとリソースフォークを隅々まで見ましたが、何もありませんでした。 これはまれに 1 つのことを想定していました: 起動する時間でした ギドラ!
できる最低限、Intel と ARM のアセンブリ言語を大まかに読んでいますが、PowerPC は常に私にとって脅威でした。 幸いなことに、Ghidra には逆コンパイラが含まれているので、かなりなじみのあるものを見ることができます。 important() の廃止は次のとおりです:

Ghidra は機能名をロボットで確立することができたので、私の仕事の負荷がより単純になりました。 上に表示されたコードの多くは、置換が確実に許可されていることを確認するために、一種のサニティ チェックを行っています。 X. ALRT リソース 138 の見栄えは次のとおりです ResEdit:
私は、CompareWithCurrentVersion() はパッチを適用する合法的な機能である可能性が高いと判断しました。 5 が返された場合、ALRT リソース 131 が表示されます。これは、前述のメッセージ

ここに賢い人がいますCompareWithCurrentVersion() で監視します。 手動でワールド変数にタイトルを付けました firmwareVersion 何が起こっているのかをより明確にするために:

このオプションは、important() のより早い逆コンパイル内の (0x419f1 で) 渡されたパラメーターを比較します。 ) をワールド変数に変換し、次の 3 つの値のいずれかを返します。ファームウェア モデルが一致する場合は 6、最新のファームウェアが更新されるほど十分に使用されている場合は 7、ファームウェアが更新するには新しすぎる場合は 5 です。 さらに、セーブにマークを付けない場合もあります。セーブ内で「d」を待機させ、「f」を 0x419f1 にして、比較する前に true を「9」に変えることで、両方のバージョンを変更します。バージョンですが、それは問題ではありません.
私はミューズ内で、「39 80 00 05」を「 39 80 00 07」ですが、エイダンはそれが機能しなかったと報告しました. 古い段落を注意深く読んでいる間、あなたは間違いなく不思議に思っているでしょう。 ファームウェアのモデルが一致しています。」 明日、自分の間違いに気づきました。セーブが 5 ではなく 6 を返すように、ケースを編集していたに違いありません。 私の混乱は、important() の逆アセンブルから生じました。5 の戻り値を保存すると、ALRT 131 が表示されるようになりました。 ALRT 131 が表示されていることは知っていたので、それが望ましいパッチだと思いました。 CompareWithCurrentVersion() が 6 を返すときに知られている FirmwareIsUpdated() が、さらに ALRT 131 を示す可能性があるようです。

どうでもいいけど、まあ この機能で何が起こっているかについて、あなたは奇妙です。 こちらはファームウェアのフラッシュトライ以来の本命ブートなのかはかなり意識しており、そうであればALRT141を代替として提示しており、効率よくリプレースを入れたとのことです
ファームウェア アップデーターのパッチを要約すると、単にスワップしたかっただけです。 CompareWithCurrentVersion() の「39 80 00 06」を「39 80 00 07」に変更します。 これにより、ホット ファームウェア モデルが交換モデルと一致していても、ファームウェアを更新できるように変更されます。 これは、次の起動時に、ファームウェアが正確に置き換えられなかったという誤ったメッセージがポップアップ表示されることを意味しますが、それは正直なところ小さな問題です.
ファームウェア アップデータ プログラム内には、実際には 2 つの「39 80 00 06」16 進シーケンスがあることに注意してください。 2番目はパッチを当てたい人です. ディスク イメージ ファイルのリソース フォークを差し控えるために、ファイルを true にバンドルして Disk Reproduction ディスク イメージにし、MacBinary としてエンコードして、Aidan に送りました。 これは彼のビデオで、ファームウェアの置き換えのインストールと次の起動を示しています.
リラックスできるエビの些細な真実として、スタンリー・ジョーダン .
iMac のロジック ボードにハンダ付けされたカスタマイズされた G4 との互換性についてはかなり不安でしたが、正直なところ美的には機能しました。 Aidan は、それがすでにストック ファームウェアで動作していると指摘したので、後から考えると、私は惨めなことは何もありませんでした。 私は、G3 Blue and White ファームウェアが実例として、 Apple が意図的にパッチを適用G4 との互換性を奪うために 、G4 を再度有効にするにはカスタマイズされたファームウェア パッチが必要でした。 担当者として、パッチ適用プロセスですべての工夫を間違えた場合に備えて、彼の珍しい G4 iMac を破壊しようとしているわけではないので、最初にある種の iMac でもテストしてくれるかどうか彼に尋ねました。 そのテストも成功しました。 誰かが熱心にこれを試みている場合に備えて、パッチャーを GitHub にアップロードしました。 さらに、Energy Mac G3 (Blue and White) 用に作成したパッチャーを統合しました。 これを達成している間は、パッチを適用する際に、置換ファイルとアップデータ ユーティリティの両方のリソース フォークを差し控えるようにしてください。 前に認めた愛、ここで実行する 1 つの計画は、Linux または NetBSD サーバーで netatalk を利用して動作させることです。担当します! これが、私が iMac の起動音にパッチを当てるために採用したプロセスです (Slot Loading)。 サポートを見た後、間違いなくそれほど簡単ではありませんでした. Forth コードは間違いなく銀の大皿で答えを提供してくれました。 sboot フラグメントには十分な空き容量があり、理論的には約 4.5 秒程度の長さのチャイムを挿入することもできますが、ファームウェアの置き換えファイルにパッチを適用するのは簡単ではない可能性があります。 sboot 後にフラグメント構造内の位置をシフトします。 あと1名の方にお任せします 𝚆𝚊𝚝𝚌𝚑 𝙽𝙾𝚆 📺