制作日記

こういうの作った方が、逃げにくいじゃない

elemフリーズ

http://d.hatena.ne.jp/xboxaruhuraito/20130729/1375066369
x86用のsyntaxhighlighterを使おうと思ったけど、見難かったのでcpp用で
こっちの方がまだマシ

今回は割とややこしい上に、結構端折ってるので注意
正確な発生条件書くのは、非常に面倒なので、割愛

まず、前提知識
elemに直値を指定しても発生する
1もしくは最大値を指定した場合は発生しない

これをmugenが読み込むと、
[Begin Action 1]
8901, 0, 1, 2, -1
8901, 4, 5, 6, -1
8901, 8, 9, 10, -1
8901, 16, 17,18, -1
8901, 32, 33,34, -1
8901, 64, 65,66, -1

メモリ上ではこうなる、アドレスは毎回変わる

0B35C3A0 00 00 00 00 FF FF FF FF C5 22 00 00 00 00 00 00
0B35C3B0 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00
0B35C3C0 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0B35C3D0 FF FF FF FF FF FF FF FF C5 22 00 00 04 00 00 00
0B35C3E0 05 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00
0B35C3F0 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0B35C400 FE FF FF FF FF FF FF FF C5 22 00 00 08 00 00 00
0B35C410 09 00 00 00 0A 00 00 00 00 00 00 00 00 00 00 00
0B35C420 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0B35C430 FD FF FF FF FF FF FF FF C5 22 00 00 10 00 00 00
0B35C440 11 00 00 00 12 00 00 00 00 00 00 00 00 00 00 00
0B35C450 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0B35C460 FC FF FF FF FF FF FF FF C5 22 00 00 20 00 00 00
0B35C470 21 00 00 00 22 00 00 00 00 00 00 00 00 00 00 00
0B35C480 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0B35C490 FB FF FF FF FF FF FF FF C5 22 00 00 40 00 00 00
0B35C4A0 41 00 00 00 42 00 00 00 00 00 00 00 00 00 00 00
0B35C4B0 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00



つまり、これが、
8901, 0, 1, 2, -1

これになる

0B0EC3A0 00 00 00 00 FF FF FF FF C5 22 00 00 00 00 00 00
0B0EC3B0 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00
0B0EC3C0 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00


で、0B0EC3A0から4byteずつ、x枚目以前のtimeの合計(1枚目なので0)、
x枚目のtime(-1)、スプライトの番号(0x22C5=8901)


やっと、changeanimの処理を見ていく

まず、★1から★2のループで、何枚目でelemの総timeが0より大きくなるか調べる
ループごとに■1でxを[ESI+14]に突っ込んでるので、調査結果はそこに保存される
1を指定した場合は、elemを調べる必要がないので、この処理自体を通らない
該当するelemが見つからなかった場合、調べた枚数は最大値となる
よって、changeanimeのelemに最大値を指定した場合は、最後の2命令で引っかかって以降の処理を飛ばすから無限ループしない


0040318B |> 8B5D 00 /MOV EBX,DWORD PTR SS:[EBP] <<<<< ★1
0040318E |. 85FF |TEST EDI,EDI
00403190 |. 7C 05 |JL SHORT winmugen.00403197
00403192 |. 3B7B 0C |CMP EDI,DWORD PTR DS:[EBX+C]
00403195 |. 7C 2C |JL SHORT winmugen.004031C3
~省略 エラー処理~
004031C3 |> 8B43 04 |MOV EAX,DWORD PTR DS:[EBX+4]
004031C6 |. 8B4B 14 |MOV ECX,DWORD PTR DS:[EBX+14]
004031C9 |. 0FAFC7 |IMUL EAX,EDI
004031CC |. 8B56 1C |MOV EDX,DWORD PTR DS:[ESI+1C]
004031CF |. 03C1 |ADD EAX,ECX
004031D1 |. 8B08 |MOV ECX,DWORD PTR DS:[EAX]
004031D3 |. 3BCA |CMP ECX,EDX <<<<< ▲1 x枚目の総timeが0(EDXの値)より大きいかどうか判定
004031D5 |. 7F 0E |JG SHORT winmugen.004031E5 <<<<< 大きければ、ループから抜ける
004031D7 |. 8946 10 |MOV DWORD PTR DS:[ESI+10],EAX
004031DA |. 897E 14 |MOV DWORD PTR DS:[ESI+14],EDI <<<<< ■1 xを保存
004031DD |. 8B45 04 |MOV EAX,DWORD PTR SS:[EBP+4]
004031E0 |. 47 |INC EDI <<<<< xを1増やす
004031E1 |. 3BF8 |CMP EDI,EAX <<<<< 調べた枚数がelemの最大数より小さいかどうか判定
004031E3 |.^7C A6 \JL SHORT winmugen.0040318B <<<<< ★2 小さいなら、まだ調べられるのでループ
004031E5 |> 8B7C24 20 MOV EDI,DWORD PTR SS:[ESP+20]
004031E9 |. 8B46 14 MOV EAX,DWORD PTR DS:[ESI+14]
004031EC |. 3BC7 CMP EAX,EDI <<<<< 調べた枚数とchangeanimeで指定したelemの判定
004031EE |. 74 12 JE SHORT winmugen.00403202 <<<<< 一致した場合は以降の処理は必要ないので、飛ばす



次、無限ループしてるとこ

CALL winmugen.00402850で、timeがxの時、何枚目のelemを表示するのか調べて、[ESI+14]に突っ込む
CMP DWORD PTR DS:[ESI+14],EDIで、changanimeで指定したelemと比較
一致しなければ、JNZ SHORT winmugen.004031F0でループ、一致すればループから抜ける
これが一致しないから、無限ループ


004031F0 |> 56 /PUSH ESI
004031F1 |. E8 5AF6FFFF |CALL winmugen.00402850
004031F6 |. 83C4 04 |ADD ESP,4
004031F9 |. 85C0 |TEST EAX,EAX
004031FB |. 75 1D |JNZ SHORT winmugen.0040321A
004031FD |. 397E 14 |CMP DWORD PTR DS:[ESI+14],EDI <<<<< ●1 ここの判定が原因で無限ループ
00403200 |.^75 EE \JNZ SHORT winmugen.004031F0




次、winmugen.00402850の中身

★3から★4までのループは、微妙に変数名(レジスタ)は違うけど、★1から★2までと同一処理
ただし、▲1と▲2の変数(レジスタ)の値が異なる
▲1は上述の通り
▲2の左オペランドは0枚目からではなくて、★1から★2の調査結果の枚数から調べ始める
右オペランドは初期値0で、00402850が呼び出される毎に1増える

で、★1から★2と同様に、調査結果のelem([ESI+14])の値も更新される
当然、以降の▲2の左オペランドの値も、更新された値に沿った数値になる


00402850 /$ 83EC 08 SUB ESP,8
~省略 エラー処理~
0040295D |> 8B7E 14 MOV EDI,DWORD PTR DS:[ESI+14]
00402960 |. 8B43 04 MOV EAX,DWORD PTR DS:[EBX+4]
00402963 |. 3BF8 CMP EDI,EAX
00402965 |. 7D 5D JGE SHORT winmugen.004029C4
00402967 |> 8B2B /MOV EBP,DWORD PTR DS:[EBX] <<<<< ★3 ★4までの処理で、xフレーム目は何枚目のelemを表示するか調べている
00402969 |. 85FF |TEST EDI,EDI
0040296B |. 7C 05 |JL SHORT winmugen.00402972
0040296D |. 3B7D 0C |CMP EDI,DWORD PTR SS:[EBP+C]
00402970 |. 7C 2C |JL SHORT winmugen.0040299E
~省略 エラー処理~
0040299E |> 8B45 04 |MOV EAX,DWORD PTR SS:[EBP+4]
004029A1 |. 8B55 14 |MOV EDX,DWORD PTR SS:[EBP+14]
004029A4 |. 0FAFC7 |IMUL EAX,EDI
004029A7 |. 8B4E 1C |MOV ECX,DWORD PTR DS:[ESI+1C]
004029AA |. 03C2 |ADD EAX,EDX
004029AC |. 8B10 |MOV EDX,DWORD PTR DS:[EAX]
004029AE |. 3BD1 |CMP EDX,ECX <<<<< ▲2
004029B0 |. 7F 0E |JG SHORT winmugen.004029C0
004029B2 |. 8946 10 |MOV DWORD PTR DS:[ESI+10],EAX
004029B5 |. 897E 14 |MOV DWORD PTR DS:[ESI+14],EDI
004029B8 |. 8B43 04 |MOV EAX,DWORD PTR DS:[EBX+4]
004029BB |. 47 |INC EDI
004029BC |. 3BF8 |CMP EDI,EAX
004029BE |.^7C A7 \JL SHORT winmugen.00402967 <<<<< ★4
004029C0 |> 8B6C24 14 MOV EBP,DWORD PTR SS:[ESP+14]
004029C4 |> 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
004029C7 |. 8B4E 1C MOV ECX,DWORD PTR DS:[ESI+1C]
004029CA |. 3BC8 CMP ECX,EAX <<<<< ■2 ECXは▲2と同値、EAXはデバッグ情報に表示される総time
004029CC |. 0F8C 7B010000 JL winmugen.00402B4D
004029D2 |. 83F8 FF CMP EAX,-1 <<<<< ■3 EAXはデバッグ情報に表示される総time
004029D5 |. 0F84 72010000 JE winmugen.00402B4D
~省略 エラー処理~
00402B4D |> 8B46 10 MOV EAX,DWORD PTR DS:[ESI+10]
00402B50 |. 8B4E 04 MOV ECX,DWORD PTR DS:[ESI+4]
00402B53 |. 8B50 0C MOV EDX,DWORD PTR DS:[EAX+C]
00402B56 |. 8B40 08 MOV EAX,DWORD PTR DS:[EAX+8]
00402B59 |. 52 PUSH EDX
00402B5A |. 50 PUSH EAX
00402B5B |. 51 PUSH ECX
00402B5C |. E8 0FC30400 CALL winmugen.0044EE70
00402B61 |. 8B4E 18 MOV ECX,DWORD PTR DS:[ESI+18]
00402B64 |. 8946 2C MOV DWORD PTR DS:[ESI+2C],EAX
00402B67 |. 8B46 1C MOV EAX,DWORD PTR DS:[ESI+1C]
00402B6A |. 83C4 0C ADD ESP,0C
00402B6D |. 41 INC ECX
00402B6E |. 40 INC EAX
00402B6F |. 894E 18 MOV DWORD PTR DS:[ESI+18],ECX
00402B72 |. 8946 1C MOV DWORD PTR DS:[ESI+1C],EAX
00402B75 |. 8B4424 1C MOV EAX,DWORD PTR SS:[ESP+1C]
00402B79 |. 5F POP EDI
00402B7A |. 5E POP ESI
00402B7B |. 5D POP EBP
00402B7C |. 5B POP EBX
00402B7D |. 83C4 08 ADD ESP,8
00402B80 \. C3 RETN



というわけで例えば、最初に例示したようなtimeの合計が常に0以下の場合、
★1~★2のループのせいで、▲2で調べるelemは常に最後のelemになってしまう
最後のelemということは、★4で絶対に★3~★4のループから抜けることになる

▲2でEDXの方が大きくなったとしても、その下の命令でループから抜けるだけで状況に変化はない

よって、[ESI+14]の値も変化しないため、●1の判定は絶対に抜けられない

コメントの投稿

非公開コメント

プロフィール

Author:drab
霊夢改変キャラ
「12 3 ! {V} [_]」
公開中
L霊夢でもl_reimuでも好きなように読んでください

最新記事
最新コメント
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク