第31話 フォークボム
図書塔の壁を突き破って、それは現れた。
人型だった。だが人間ではない。全身がコードの文字列で構成されている。半透明の体の内部で、赤黒いコードが脈動するように流れている。顔に相当する部分には、三つのドットが並んでいるだけだ。
...
省略記号。未定義の顔。
「端末プログラム」メモリが呟いた。「ヴァイラスの——分身のような存在です」
端末のステータスが展開された。
NAME: VIRUS_TERMINAL #??
CLASS: Fork Process
HP: 1,200/1,200
ATK: 95
DEF: 40
SKILL: Self-Replication (Fork) / Code Injection
WARNING: Entity can duplicate itself
自己複製——フォーク。
Unix系OSの基本機能だ。プロセスが自分自身のコピーを生成する。正常に使えば並列処理の基盤になるが、悪用されれば——
「フォークボムか」
俺は呟いた。
フォークボム。プロセスが無限に自己複製を繰り返し、システムリソースを食い尽くす攻撃手法。シンプルだが凶悪だ。
端末が動いた。速い。
ガルドが前に出た。
「来い!」
拳がうなった。スタックオーバーフローの予備動作——限界突破のバフをかけた全力の一撃が、端末の胸部を貫いた。
端末が砕けた。
コードの欠片が飛び散る。
——そして、欠片の一つ一つが、膨張を始めた。
「増えてる!」ガルドが叫んだ。
砕けた断片から、新しい端末が再生していく。一体が二体に。二体が四体に。
[WARNING] Fork process detected
VIRUS_TERMINAL count: 1 → 2 → 4 → 8
Process multiplication rate: exponential
「倒すな! 壊すと分裂する!」
俺が叫んだが、遅かった。ガルドの一撃で砕けた端末が、既に八体に増殖していた。
八体の端末が、同時に動いた。
図書塔の中を縦横に駆け回り、壁面のコードを——記録石を——手当たり次第に破壊していく。データベースを直接物理破壊する攻撃だ。
「アリア!」
「分かっています!」
アリアの条件分岐剣法が走った。端末の動きをパターン分析し、最適な迎撃角度を割り出す。
剣が閃く。端末の腕を切断した。
——腕が再生した。しかも切断面から、もう一本の腕が生えた。
「切っても増えます!」
「分かってる——壊さずに止める方法を考えろ!」
アリアが端末の動きを読みながら、破壊ではなく「押し戻し」に切り替えた。斬撃の代わりに、剣の腹で打ち返す。
だが八体を一人で相手にするのは無理がある。
ガルドが再び前に出た。
「壊すなって言ったな? じゃあ——押さえつける!」
ガルドが端末を掴んだ。力任せに床に押しつける。端末が暴れるが、ガルドの腕力が上回っている。
「一体押さえたぞ! あと七体!」
七体。
いや——目の前で、また分裂が起きた。押さえていない端末同士が接触し、そこから新しい個体が生まれた。
VIRUS_TERMINAL count: 8 → 12 → 16
十六体。
「キリがない——」
俺はデバッガーズ・アイで端末のコードを分析していた。
自己複製のメカニズム。端末が分裂する際、新しい「プロセスID」が割り当てられる。プロセスIDは世界の源コードが管理する識別番号だ。
各端末のIDを読んでいく。
PID: 77801 → fork → PID: 77802, 77803
PID: 77802 → fork → PID: 77804, 77805
PID: 77803 → fork → PID: 77806, 77807
...
連番で増えている。プロセスIDの割り当ては、源コードの「プロセス管理テーブル」が自動で行っている。
「プロセスIDが有限……」
俺は呟いた。
プロセスIDの上限。どんなシステムでも、IDには上限がある。32ビットなら約21億。この世界のプロセスIDは——
デバッガーズ・アイでプロセス管理テーブルを読んだ。
PROCESS_ID_TABLE:
type: uint32
current_max: 77,807
absolute_max: 99,999
allocation_rule: sequential_increment
最大値99,999。現在値77,807。残り約22,000のIDが割り当て可能だ。
フォークボムの古典的な対策は、プロセスIDの枯渇を待つことだ。IDが尽きれば、新しいプロセスを作れなくなる。
だが——22,000体もの端末を相手にするのは非現実的だ。
「逆だ」
俺は閃いた。
「IDの枯渇を待つんじゃない。IDの割り当てルールを——変える」
俺はデバッガーズ・アイでプロセス管理テーブルにアクセスした。Lv2の権限で——ぎりぎり、アプリケーション層のプロセス管理に手が届く。
「メモリ! プロセス管理テーブルの書き込み権限は俺にあるか!」
「ぎりぎりです! アプリケーション層の管理テーブルは、Lv2の上限範囲です!」
「やる」
俺は源コードに手を入れた。
端末の自己複製——フォーク処理——には、新しいプロセスIDの発行が必要だ。IDがなければ、新しいプロセスは生まれない。
俺が書き換えたのは、割り当てルールだ。
// BEFORE:
allocation_rule: sequential_increment
// New PID = current_max + 1
// AFTER:
allocation_rule: frozen
// New PID allocation: DENIED
// Reason: Administrative lock by Debugger's Eye Lv2
新規プロセスIDの発行を——凍結した。
効果は即座に現れた。
分裂しようとした端末が、途中で止まった。コードが実行されるが、新しいIDを取得できず、フォーク処理がエラーを返す。
[ERROR] Fork failed: Unable to allocate new PID
Reason: PID allocation frozen by admin lock
Process stuck in fork() call
「止まった——!」メモリが叫んだ。
分裂が止まった端末は、フォーク処理の無限ループに陥る。複製しようとして、失敗して、また複製しようとして、また失敗する。CPUリソースをフォーク試行に消費し続け、攻撃行動が停止した。
「今だ! ガルド! アリア!」
ガルドとアリアが同時に動いた。
フォークに失敗し、動きが鈍った端末を——ガルドが拳で叩き、アリアが剣で斬る。分裂能力を失った端末は、通常のモンスターと同じだ。壊してもコピーが生まれない。
一体、二体、三体——次々と撃破していく。
ガルドのスタックオーバーフローが唸りを上げ、アリアの条件分岐剣法が残りを仕留めた。
最後の一体が崩壊した。
静寂が戻った。
図書塔のあちこちに、端末の残骸が散らばっている。コードの断片が光を失い、塵のように消えていく。
シェルが即座に残骸のコードを回収した。分析用だ。
「端末のコードを保存しました。後で詳細に解析します」
「頼む」
俺はプロセス管理テーブルの凍結を解除した。通常のID割り当てに戻す。これを放置すると、世界全体のプロセス管理に影響が出る。
そこで——ガルドのことが気になった。
スタックオーバーフローを何度も使っていた。戦闘中、少なくとも四回は限界突破を発動した。
俺はデバッガーズ・アイを——ガルドに向けた。
自動的にステータスが展開される。
NAME: ガルド・スタック
HP: 891/1,480
MP: 120/680
SKILL: Stack Overflow Lv.5
→ Accumulated strain: [ERROR: VALUE OVERFLOW]
→ Life force index: ...
蓄積負荷の値が——エラーを返している。数値が大きすぎてオーバーフロー。そして寿命指数が……「...」。表示されていない。
見てはいけない数字を見た気がして、俺は視線を逸らした。
「ガルド」
「おう」
ガルドは壁に背をもたせかけていた。汗まみれだが、笑っていた。
「無理してないか?」
「問題ない」
即答だった。
「お前こそ顔が青いぞ」
ガルドが笑って、話題を変えた。
俺は——それ以上、踏み込まなかった。
踏み込めなかった。
シェルが端末の残骸コードの解析結果を報告した。
「端末のメモリ空間に、座標情報が残っていました。ヴァイラスの次のターゲットに関する情報です」
「次のターゲット?」
シェルが手帳を開いた。
「ビジュアル帝国。芸術の国が——次の標的です」
俺は窓の外を見た。南の方角。遥か遠くに、ビジュアル帝国があるはずだ。
「移動する前に、ここの復旧を済ませよう。それから——」
俺はメモリを見た。
メモリが頷いた。「はい。やるべきことがあります」
「ああ。大公にも協力を仰ぐ。それから——備えよう」
次の戦いは、もっと大規模になる。
そう確信していた。
次回、第32話「データ・リカバリ」——復旧作業の中で、蓮とシェルの間に生まれる信頼。そしてシェルの決断。




