2004年10月25日

11月1日よりいくつかのパーツを販売停止します。(mingol.net mgo site)


…結局パッチは当てる気なしですか
 
ショップにパーツを置いただけで価格の表示内容がおかしくなり、しかもパーツ追加自体は正常に完了していること、新配布に伴って同数の旧パーツが販売停止になったこと、その相関関係に特筆すべき点が見当たらないことから考察するに、おそらくショップのデータは以下のような構造体になっているのではないだろうか。(フィールド名は適当、PS2のアーキテクチャは判らんのであくまでVisual C++相当)
unsigned char id; // ショップ内での識別ID
unsigned int partsid; // パーツの識別ID
unsigned long price; // 価格 (購入可能フラグを兼ねる)
で、これとは別に、価格>0である場合に、partsidをキーに商品名、商品種別ID(ソートに使用する)、アイコンを引っ張ってくるようなプログラムになっているのではないだろうか。
 
ショップ内での識別IDがunsigned char(0〜255)であることがミソである。
私は全種をまだ並べられていないので正確な数字はわからない(神、以上の段位である方、ご協力いただけたら幸いである)のだが、おそらく現在ショップに並んでいるパーツ数が255個か、それに近い値なのではないだろうか?
プログラムというのは冷淡なもので、メモリ上のデータエリアをここからここまで、と指定したところで、それが正確に行使されるかどうかはプログラム次第なのである(なので、プログラム中からプログラムを書き換えるという荒業も使えた。これを悪用したのがいわゆるバッファオーバーラン脆弱性)。
当然データエリア上においても同じことが発生するわけで、データの格納に必要なメモリ量を超えてしまって別な部分を上書きしてしまっても、それをプログラムで回避しない限りプログラムは破壊されたデータを正常なデータと認識して使うしかないのである。
川奈パッチの時、川奈を回ったときのラウンド結果に妙な値が表示されたことを覚えていらっしゃる方もおられるだろう。
要はあれと似たような状況になっているのである。
脱線した。おそらくショップにパーツを並べる機構というのは、パーツにショップ用の一意なIDを振り、そのパーツのパーツIDと価格を設定したデータをショップ用のデータエリアに追加することで新しく商品として認識されるようになっているものと思われる(新商品が並ぶ時にパッチがないことを考慮せよ)が、256個めを追加しようとしたためにunsigned charで確保された8ビットの領域(0〜255)を飛び越し、価格データを上書きしてしまったのだろう。
256は16進数で0x100、これをunsigned charに格納すると00の部分だけが格納されて、1は直前にある「価格」フィールドを上書きしてしまう。これにより、データエリアを初期化したデータとたまたま同じ値のパーツIDを持つパーツ(壁紙セット)が、異常な価格で表示されてしまう、という事態が発生したのではないか。
 
実際のプログラム内容がどうなっているかはわからないが、おそらく不具合内容としてはこんなもんか、これにかなり近いと思われる。

Post: @ 2004.10.25 15:48
to /fblog/mgo
この記事のコメントとトラックバック: 0 件


・同じカテゴリの新着記事一覧へ
・全体の新着記事一覧へ