概要
CMDOFとは、Command Buffer OverFlowの略称であり、トリガーのCommand名が64Byteを超えることで発生するBuffer Overflowの一種である。
DBOFなどと同様に、キャラ読み込み時にコードを実行することができる。基本的な使い方はDBOFと同じだが、DBOFと異なりティア・ディフェンス(TD)の影響を受けないという利点を持つ。
しかしその一方で、後述するが、工夫をしなければ復帰処理に成功しても「Undefined command label」のエラーが発生しmugenが落ちてしまうという欠点もある。
しかしその一方で、後述するが、工夫をしなければ復帰処理に成功しても「Undefined command label」のエラーが発生しmugenが落ちてしまうという欠点もある。
利用方法
DBOF同様、一旦コマンド名の先頭にジャンプさせ、そこからcommandトリガーの下に記述したコードへとジャンプする手法が多く採用されている。以下ではこの手法について解説する。
コマンド名の先頭のアドレスはBuffer Overflowによって上書きするリターンアドレスの次の4Byteに格納されているため、Buffer Overflowによって飛んだ先では単にRET命令を実行するだけでよく、その候補はDBOFと比較しても非常に多い。典型的な例としては"]EE"を用いて0x45455Dへジャンプする例がある。
コマンド名の先頭ではJMP命令を用いてコマンド名の次の行の先頭へジャンプさせるのが基本的な形となる。改行コードにCRLF方式を利用している場合には、コマンド名の先頭をJMP 0x43に対応する機械語、0xEB43としておくことでちょうど次の行の先頭へジャンプさせることができる。
復帰処理
概要で述べた通り、単にレジスタやスタックなどの状態を元通りにし正常なコード処理へ復帰させても、「Undefined command label」のエラーによりmugen落ちしてしまうため、対策する必要がある。
方法は大きく下記の三種類に分けられる。
- あらかじめ64Byteの長さのCommand名を登録しておき、エラーを出さないようにする。
- CMDOFで実行するコードの中でファイルやコマンド名を書き換えた上でもう一度判定させる。
- 元の処理位置ではない別の場所へ戻すようにし、エラーを出さないようにする。
1番目の方法は最も簡単だが、コマンドラベル数を圧迫する点や不格好なコマンドを登録しなければならないという欠点を持つ。
2番目の方法は最も複雑だが、最も欠点の少ない手法である。
3番目の方法は比較的簡単であり、1番の方法に見られた欠点もないが、同じステート内の以降の処理を飛ばしてしまう欠点を持つ。
2番目の方法は最も複雑だが、最も欠点の少ない手法である。
3番目の方法は比較的簡単であり、1番の方法に見られた欠点もないが、同じステート内の以降の処理を飛ばしてしまう欠点を持つ。
ここではX番の方法について解説する。
(要追記)
コード例
[State ] type = Null trigger1 = command="��34567890123456789012345678901234567890123456789012345678901234]EE" ��`ヌ @K @@@@a�$fヌ " �h{姆 テ
※Command名先頭の"��"は0xEB43を示す文字列である。
上記で実行しているコードは下記の通りである。
- SUB ESP,0x4
- PUSHAD
- MOV DWORD PTR [0x4B4000],0x40404040
- POPAD
- MOV EAX,DWORD PTR [ESP]
- MOV WORD [EAX],0x22
- MOV DWORD [ESI],EAX
- PUSH 0x479B7B
- RET