制作日記

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

トップ

トップ
※申し訳ないですが、メールでの返信は出来ません。

DEP回避して任意コード実行
_reimu_ver191.ico

DTCリターンアドレス改竄テストキャラ(ver0.7xとは別物です)
_reimu_ver181.ico

MUGEN用プロセスメモリリーダ、memRead 最終更新 2013/11/17
memRead.ico
CUIアプリです、普通にアイコンをダブルクリックでも起動できます

リンクを右クリックして、「対象をファイルに保存」からダウンロード
ファイルの拡張子をrarに変えてから解凍してください

MUGENステコン入力支援マクロ
入力補完、短縮表記機能有り版(取説)
stateControl_2.js
入力補完、短縮表記機能なし版
stateControl_1.js
使い方とかはjsの先頭に書いてあるので、メモ帳で開くなりして読んでください

バグ報告等々コメントして頂けると助かります
公開物とそれらに関する情報の利用は、内容に依らず自由にして頂いて問題ないです

過去verは続きへ追いやられました

続きを読む

アセンブラ書く人が増えて

嬉しいんやなって

textの文字列直接実行はステコンまとめる必要性を感じなくて、そういう発想自体なかった
16進からDTCのステコン吐くプログラム自前で書いてるから、それで事足りるし

真っ当?なキャラ製作者の観点も大切やねんなって思った
どこから真っ当と言っていいのかは甚だ疑問だけども

あと新でも出来そうなのは利点かね
新の方は幅指定できないから、馬鹿正直に1024byte埋めないとだめだけど


そんなこんなで久しぶりにMUGEN起動して全然関係ないことしてた
一部、拡張子でファイル種別判別してんのな
だから、spriteで指定するファイルはsffとかpcxにせんとあかんのか
sffぐらい自動判別して頂戴よ

ここね、xmなんてのもあるんやな
00418250  /$ 55             PUSH EBP
00418251 |. 8B6C24 08 MOV EBP,DWORD PTR SS:[ESP+8]
00418255 |. 56 PUSH ESI
00418256 |. 57 PUSH EDI
00418257 |. 8BFD MOV EDI,EBP
00418259 |. 83C9 FF OR ECX,FFFFFFFF
0041825C |. 33C0 XOR EAX,EAX
0041825E |. F2:AE REPNE SCAS BYTE PTR ES:[EDI]
00418260 |. F7D1 NOT ECX
00418262 |. 49 DEC ECX
00418263 |. 8BF1 MOV ESI,ECX
00418265 |. 83FE 04 CMP ESI,4
00418268 |. 0F8E 02010000 JLE winmugen.00418370
0041826E |. 807C2E FC 2E CMP BYTE PTR DS:[ESI+EBP-4],2E
00418273 |. 0F85 F7000000 JNZ winmugen.00418370
00418279 |. 8D7C2E FD LEA EDI,DWORD PTR DS:[ESI+EBP-3]
0041827D |. 68 68424A00 PUSH winmugen.004A4268 ; ASCII "pcx"
00418282 |. 57 PUSH EDI
00418283 |. E8 085D0800 CALL winmugen.0049DF90
00418288 |. 83C4 08 ADD ESP,8
0041828B |. 85C0 TEST EAX,EAX
0041828D |. 75 09 JNZ SHORT winmugen.00418298
0041828F |. 5F POP EDI
00418290 |. 5E POP ESI
00418291 |. B8 01000000 MOV EAX,1
00418296 |. 5D POP EBP
00418297 |. C3 RETN
00418298 |> 68 6C424A00 PUSH winmugen.004A426C ; ASCII "sff"
0041829D |. 57 PUSH EDI
0041829E |. E8 ED5C0800 CALL winmugen.0049DF90
004182A3 |. 83C4 08 ADD ESP,8
004182A6 |. 85C0 TEST EAX,EAX
004182A8 |. 75 09 JNZ SHORT winmugen.004182B3
004182AA |. 5F POP EDI
004182AB |. 5E POP ESI
004182AC |. B8 02000000 MOV EAX,2
004182B1 |. 5D POP EBP
004182B2 |. C3 RETN
004182B3 |> 68 70424A00 PUSH winmugen.004A4270 ; ASCII "wav"
004182B8 |. 57 PUSH EDI
004182B9 |. E8 D25C0800 CALL winmugen.0049DF90
004182BE |. 83C4 08 ADD ESP,8
004182C1 |. 85C0 TEST EAX,EAX
004182C3 |. 75 09 JNZ SHORT winmugen.004182CE
004182C5 |. 5F POP EDI
004182C6 |. 5E POP ESI
004182C7 |. B8 03000000 MOV EAX,3
004182CC |. 5D POP EBP
004182CD |. C3 RETN
004182CE |> 68 74424A00 PUSH winmugen.004A4274 ; ASCII "snd"
004182D3 |. 57 PUSH EDI
004182D4 |. E8 B75C0800 CALL winmugen.0049DF90
004182D9 |. 83C4 08 ADD ESP,8
004182DC |. 85C0 TEST EAX,EAX
004182DE |. 75 09 JNZ SHORT winmugen.004182E9
004182E0 |. 5F POP EDI
004182E1 |. 5E POP ESI
004182E2 |. B8 04000000 MOV EAX,4
004182E7 |. 5D POP EBP
004182E8 |. C3 RETN
004182E9 |> 68 78424A00 PUSH winmugen.004A4278 ; ASCII "mp3"
004182EE |. 57 PUSH EDI
004182EF |. E8 9C5C0800 CALL winmugen.0049DF90
004182F4 |. 83C4 08 ADD ESP,8
004182F7 |. 85C0 TEST EAX,EAX
004182F9 |. 75 09 JNZ SHORT winmugen.00418304
004182FB |. 5F POP EDI
004182FC |. 5E POP ESI
004182FD |. B8 05000000 MOV EAX,5
00418302 |. 5D POP EBP
00418303 |. C3 RETN
00418304 |> 68 7C424A00 PUSH winmugen.004A427C ; ASCII "mid"
00418309 |. 57 PUSH EDI
0041830A |. E8 815C0800 CALL winmugen.0049DF90
0041830F |. 83C4 08 ADD ESP,8
00418312 |. 85C0 TEST EAX,EAX
00418314 |. 75 09 JNZ SHORT winmugen.0041831F
00418316 |. 5F POP EDI
00418317 |. 5E POP ESI
00418318 |. B8 06000000 MOV EAX,6
0041831D |. 5D POP EBP
0041831E |. C3 RETN
0041831F |> 68 80424A00 PUSH winmugen.004A4280 ; ASCII "mod"
00418324 |. 57 PUSH EDI
00418325 |. E8 665C0800 CALL winmugen.0049DF90
0041832A |. 83C4 08 ADD ESP,8
0041832D |. 85C0 TEST EAX,EAX
0041832F |. 75 09 JNZ SHORT winmugen.0041833A
00418331 |. 5F POP EDI
00418332 |. 5E POP ESI
00418333 |. B8 07000000 MOV EAX,7
00418338 |. 5D POP EBP
00418339 |. C3 RETN
0041833A |> 68 84424A00 PUSH winmugen.004A4284 ; ASCII "s3m"
0041833F |. 57 PUSH EDI
00418340 |. E8 4B5C0800 CALL winmugen.0049DF90
00418345 |. 83C4 08 ADD ESP,8
00418348 |. 85C0 TEST EAX,EAX
0041834A |. 75 09 JNZ SHORT winmugen.00418355
0041834C |. 5F POP EDI
0041834D |. 5E POP ESI
0041834E |. B8 07000000 MOV EAX,7
00418353 |. 5D POP EBP
00418354 |. C3 RETN
00418355 |> 68 88424A00 PUSH winmugen.004A4288 ; ASCII "zip"
0041835A |. 57 PUSH EDI
0041835B |. E8 305C0800 CALL winmugen.0049DF90
00418360 |. 83C4 08 ADD ESP,8
00418363 |. 85C0 TEST EAX,EAX
00418365 |. 75 09 JNZ SHORT winmugen.00418370
00418367 |. 5F POP EDI
00418368 |. 5E POP ESI
00418369 |. B8 09000000 MOV EAX,9
0041836E |. 5D POP EBP
0041836F |. C3 RETN
00418370 |> 83FE 03 CMP ESI,3
00418373 |. 7E 41 JLE SHORT winmugen.004183B6
00418375 |. 807C2E FD 2E CMP BYTE PTR DS:[ESI+EBP-3],2E
0041837A |. 75 3A JNZ SHORT winmugen.004183B6
0041837C |. 8D742E FE LEA ESI,DWORD PTR DS:[ESI+EBP-2]
00418380 |. 68 8C424A00 PUSH winmugen.004A428C ; ASCII "xm"
00418385 |. 56 PUSH ESI
00418386 |. E8 055C0800 CALL winmugen.0049DF90
0041838B |. 83C4 08 ADD ESP,8
0041838E |. 85C0 TEST EAX,EAX
00418390 |. 75 09 JNZ SHORT winmugen.0041839B
00418392 |. 5F POP EDI
00418393 |. 5E POP ESI
00418394 |. B8 07000000 MOV EAX,7
00418399 |. 5D POP EBP
0041839A |. C3 RETN
0041839B |> 68 90424A00 PUSH winmugen.004A4290 ; ASCII "da"
004183A0 |. 56 PUSH ESI
004183A1 |. E8 EA5B0800 CALL winmugen.0049DF90
004183A6 |. 83C4 08 ADD ESP,8
004183A9 |. 85C0 TEST EAX,EAX
004183AB |. 75 09 JNZ SHORT winmugen.004183B6
004183AD |. 5F POP EDI
004183AE |. 5E POP ESI
004183AF |. B8 08000000 MOV EAX,8
004183B4 |. 5D POP EBP
004183B5 |. C3 RETN
004183B6 |> 5F POP EDI
004183B7 |. 5E POP ESI
004183B8 |. 33C0 XOR EAX,EAX
004183BA |. 5D POP EBP
004183BB \. C3 RETN

varrandomでのmugen落ちとか

http://oki6761.blog23.fc2.com/blog-entry-2464.html

あと、mugen落ちの原因説明のための細かい仕様解説とか

まず、mugenが内部で使用している乱数について
http://drabs.blog40.fc2.com/blog-entry-215.html
要は0~7FFFhの乱数になっている

で本題その1、varrandomの仕様補足
・rangeの最小値、最大値指定は逆にしても大丈夫、勝手に内部で入れ替える
・最小値~最大値の乱数を生成するという仕様は嘘
 生成範囲は概ね最小値~min(最小値+7FFFh、最大値)、例外あり
 生成アルゴリズムは次の通り
 1.元ネタ乱数生成(上述の通り、0~7FFFh)
 2.乱数の生成幅を算出(最大値 - 最小値 + 1)
 3.1の乱数を生成幅で割った余りを算出(乱数 mod 生成幅)
 4.3の剰余に乱数生成範囲の最小値を加算

次、本題2、生成範囲にある値を指定した場合に落ちる原因
 3.1の乱数を生成幅で割った余りを算出(乱数 mod 生成幅)
これで0除算してる
以下、アセンブラ見ながら解説
0046F0DB  |> E8 573E0200    CALL winmugen.00492F37
# 元ネタ乱数生成(eaxに入る)
0046F0E0 |. 2BF7 SUB ESI,EDI
# 最大値(esi) - 最小値(edi)を計算、ここでオーバーフローして結果(esi)が-1になる
0046F0E2 |. 99 CDQ
# eaxを64bit(edx:eax)に拡張する、割り算の前準備
0046F0E3 |. 46 INC ESI
# さっきの計算結果(esi)に1加算、0になる
0046F0E4 |. F7FE IDIV ESI
# esiで乱数(edx:eax)を割る、ここで0除算
# edx=剰余、eax=商
0046F0E6 |. 03D7 ADD EDX,EDI
#剰余に最小値を加算、これがvarrandomで代入される値



ついでにvarrandom全体コードと懇切丁寧な解説をどうぞ
ちなみに、実際にそういう順序で解析したわけではない
0046F08F  |> 8B9C24 A010000>MOV EBX,DWORD PTR SS:[ESP+10A0]          ;  Case 6 of switch 0046E830
0046F096 |. 8D4E 24 LEA ECX,DWORD PTR DS:[ESI+24]
0046F099 |. 6A 01 PUSH 1
0046F09B |. 51 PUSH ECX
0046F09C |. 53 PUSH EBX
0046F09D |. E8 3E85F9FF CALL winmugen.004075E0
0046F0A2 |. 8BE8 MOV EBP,EAX
0046F0A4 |. 83C4 0C ADD ESP,0C
0046F0A7 |. 85ED TEST EBP,EBP
0046F0A9 |. 7C 51 JL SHORT winmugen.0046F0FC
0046F0AB |. 83FD 3B CMP EBP,3B
0046F0AE |. 7F 4C JG SHORT winmugen.0046F0FC
0046F0B0 |. 8D56 18 LEA EDX,DWORD PTR DS:[ESI+18]
0046F0B3 |. 6A 01 PUSH 1
0046F0B5 |. 52 PUSH EDX
0046F0B6 |. 53 PUSH EBX
0046F0B7 |. E8 2485F9FF CALL winmugen.004075E0
0046F0BC |. 83C6 30 ADD ESI,30
0046F0BF |. 6A 01 PUSH 1
0046F0C1 |. 56 PUSH ESI
0046F0C2 |. 53 PUSH EBX
0046F0C3 |. 8BF8 MOV EDI,EAX
0046F0C5 |. E8 1685F9FF CALL winmugen.004075E0
0046F0CA |. 8BF0 MOV ESI,EAX
0046F0CC |. 83C4 18 ADD ESP,18
0046F0CF |. 3BF7 CMP ESI,EDI
0046F0D1 |. 7D 08 JGE SHORT winmugen.0046F0DB
0046F0D3 |. 8BF7 MOV ESI,EDI
0046F0D5 |. 894424 18 MOV DWORD PTR SS:[ESP+18],EAX
0046F0D9 |. 8BF8 MOV EDI,EAX
0046F0DB |> E8 573E0200 CALL winmugen.00492F37
0046F0E0 |. 2BF7 SUB ESI,EDI
0046F0E2 |. 99 CDQ
0046F0E3 |. 46 INC ESI
0046F0E4 |. F7FE IDIV ESI
0046F0E6 |. 03D7 ADD EDX,EDI
0046F0E8 |. 33C0 XOR EAX,EAX
0046F0EA |. 8994AB 400E000>MOV DWORD PTR DS:[EBX+EBP*4+E40],EDX
0046F0F1 |. 5F POP EDI
0046F0F2 |. 5E POP ESI
0046F0F3 |. 5D POP EBP
0046F0F4 |. 5B POP EBX
0046F0F5 |. 81C4 8C100000 ADD ESP,108C
0046F0FB |. C3 RETN
0046F0FC |> 55 PUSH EBP
0046F0FD |. 68 88C04A00 PUSH winmugen.004AC088 ; ASCII "randomized var out of range (%i)"
0046F102 |. 53 PUSH EBX
0046F103 |. E8 2865FAFF CALL winmugen.00415630
0046F108 |. 83C4 0C ADD ESP,0C
0046F10B |. 33C0 XOR EAX,EAX
0046F10D |. 5F POP EDI
0046F10E |. 5E POP ESI
0046F10F |. 5D POP EBP
0046F110 |. 5B POP EBX
0046F111 |. 81C4 8C100000 ADD ESP,108C
0046F117 |. C3 RETN


これ見てすぐにわかるのは、↓は警告表示してRETしてる
つまりエラーハンドリング、ここに飛ぶのは全部エラー、エラー内容は警告のフォーマットで察する
0046F0FC  |> 55             PUSH EBP
0046F0FD |. 68 88C04A00 PUSH winmugen.004AC088 ; ASCII "randomized var out of range (%i)"
0046F102 |. 53 PUSH EBX
0046F103 |. E8 2865FAFF CALL winmugen.00415630
0046F108 |. 83C4 0C ADD ESP,0C
0046F10B |. 33C0 XOR EAX,EAX
0046F10D |. 5F POP EDI
0046F10E |. 5E POP ESI
0046F10F |. 5D POP EBP
0046F110 |. 5B POP EBX
0046F111 |. 81C4 8C100000 ADD ESP,108C
0046F117 |. C3 RETN


この関数呼び出しは、他所の類似箇所とかも見ればわかるけど
printfみたいな可変長引数で、関数の右側から引数を積んでる
よって、警告文内の"%i"に入る値は、直前にpushしているebp直後にpushしているebx
0046F0FC  |> 55             PUSH EBP
0046F0FD |. 68 88C04A00 PUSH winmugen.004AC088 ; ASCII "randomized var out of range (%i)"
0046F102 |. 53 PUSH EBX
0046F103 |. E8 2865FAFF CALL winmugen.00415630


実際に、↑に飛ぶ箇所を見てみる
0046F0A7  |. 85ED           TEST EBP,EBP
0046F0A9 |. 7C 51 JL SHORT winmugen.0046F0FC
0046F0AB |. 83FD 3B CMP EBP,3B
0046F0AE |. 7F 4C JG SHORT winmugen.0046F0FC

testの後にjlは負数かどうかの確認
直後は3Bh(=59)以下かの確認
さっきの警告文で明白だけど、こっちの確認内容からも察しやすい
これはvarの範囲チェック、よってebpはvarの番号

ところで、ここを処理してるときのESIの中身をデバッガで確認すると、ステコン情報のアドレスが入っている
中身はこんな感じ、dataの内容はステコン種別によっていろいろ
概ね、4byte*3が1組になってオプション1つを表す
varrandomはオプション3つ(rangeは2つ指定するから、1オプションで2つ分)が入っていると予想できる
    void *trigger;
int enable;
int persist;
int ignore;
int Id;
int data[20];


それを踏まえて、ebp=varの番号(オプション"v"の値)を取得する箇所はというと
0046F0A2  |. 8BE8           MOV EBP,EAX

ここでeaxから代入されていて
eaxは関数の戻り値に使われるんだから、このeaxは直前で呼び出してる↓の戻り値のはず
0046F09D  |. E8 3E85F9FF    CALL winmugen.004075E0

0046F096  |. 8D4E 24        LEA ECX,DWORD PTR DS:[ESI+24]
0046F099 |. 6A 01 PUSH 1
0046F09B |. 51 PUSH ECX
0046F09C |. 53 PUSH EBX
0046F09D |. E8 3E85F9FF CALL winmugen.004075E0


引数の内容もそれっぽい、ebxは確認してみるとキャラの先頭アドレス
ecx=esi+24hでesiは上述の通りステコンの先頭アドレス
これに24h足すとdata部分を指す、キャラの先頭アドレス渡してる辺り、それっぽい
push 1はわからん、無視

計算式の先頭アドレスとキャラのアドレス渡せば整数値系の計算はできるのかな?
小数計算はどこに投げるのか、そこらへんの解析すればmugen用デバッガも作れそうだけど
ここでは関係ないから詳細は放置、とりあえず整数値のオプション取得用関数っぽい

それを踏まえて後続の処理を見ると
↓のオプション2つ取得はrangeの値を取得で間違いなさそうで、それぞれediとesiに結果を入れている
0046F0B0 8D5618              	lea	edx, [esi+18h]
0046F0B3 6A01 push 01h
0046F0B5 52 push edx
0046F0B6 53 push ebx
0046F0B7 E82485F9FF call 004075E0h
0046F0BC 83C630 add esi, 30h
0046F0BF 6A01 push 01h
0046F0C1 56 push esi
0046F0C2 53 push ebx
0046F0C3 8BF8 mov edi, eax
0046F0C5 E81685F9FF call 004075E0h0046F0CA 8BF0 mov esi, eax


ということは、直後の↓の処理はesi > ediになるように
どちらのほうが小さいかをチェックして必要に応じて入れ替えていると
0046F0CF 3BF7                	cmp	esi, edi
0046F0D1 7D08 jge 0046F0DBh
0046F0D3 8BF7 mov esi, edi
0046F0D5 89442418 mov [esp+18h], eax
0046F0D9 8BF8 mov edi, eax


ここまで理解できれば、命令の意味を調べながらだけど
最初に0除算の原因解説した部分もすらすらっと読み解ける

ね、簡単でしょう?

講談社漫画単行本のビニール包装の開け方

最近ってほどではないけど、あの開けにくいとか言われてる全包装の奴
慣れると下手な包装より楽なんじゃないかと気づいた

あれは裏表紙側に縦方向の切り取り線が入っているから
ポケットティッシュみたいに親指2本で左右に引っ張って開けるんやで

ただ、真ん中付近でやるとビニールが伸びて開けにくい
せやから、真ん中で引っ張るより、切り取り線の端の方
つまり、上下どっちかで左右に引っ張ったほうが良い

おすすめは下
切り取り線は、上は表表紙ギリギリ、下は熱溶着されてるとこまで伸びてるから
下のほうが切り取り線の端が近いし、溶着のおかげでビニールが伸びにくい

もうちょっと切り取り線を切れやすくすれば、漫画単行本の包装としては最高
他社も見習うべき

なんか調べようと思った

generanaiを2体対戦させつつ、EIPレジスタダンプを100msec毎に100回実施したら
このあたりが良く引っかかった
00457098  |> 8A16           |/MOV DL,BYTE PTR DS:[ESI]
0045709A |. 84D2 ||TEST DL,DL
0045709C |. 74 16 ||JE SHORT winmugen.004570B4
0045709E |. 8B6C24 5C ||MOV EBP,DWORD PTR SS:[ESP+5C]
004570A2 |. 81E2 FF000000 ||AND EDX,0FF
004570A8 |. 66:8B5455 5C ||MOV DX,WORD PTR SS:[EBP+EDX*2+5C]
004570AD |. 8B6C24 14 ||MOV EBP,DWORD PTR SS:[ESP+14]
004570B1 |. 66:8910 ||MOV WORD PTR DS:[EAX],DX
004570B4 |> 8B5424 30 ||MOV EDX,DWORD PTR SS:[ESP+30]
004570B8 |. 83C0 02 ||ADD EAX,2
004570BB |. 03CA ||ADD ECX,EDX
004570BD |. 8BD1 ||MOV EDX,ECX
004570BF |. 81E1 FFFF0000 ||AND ECX,0FFFF
004570C5 |. C1EA 10 ||SHR EDX,10
004570C8 |. 2BF2 ||SUB ESI,EDX
004570CA |. 4F ||DEC EDI
004570CB |.^75 CB |\JNZ SHORT winmugen.00457098



perfというか重い箇所を調べてみようと思って、ついでにmemRead作り直そうしてた
で、ipレジスタのモニターだけサクッと作ってやってみた

https://github.com/drab-l/memRead
Makefileは完全自分用、ビルドしたければlinuxにmingw64入れてどうぞ

ipダンプする以外の機能ないけど、使い方は
memRead [-p プロセスID | -c 実行ファイル名(部分一致)]
で実行、メインスレッドに対して100msecごとにipレジスタをダンプ
実行ファイル名指定時は検索して最初に見つかったやつ

次は指定箇所の処理時間計測やろうかなと思ったけど、どういう方式にすべきか

RISCとか固定長命令のアーキテクチャなら指定箇所を逆アセンブラして計測開始終了箇所時に自前のコードに飛ぶようにしてってので良いかもだけど
可変長命令のx86でそれは面倒くせー、もうBP張る方法で良いかな
という状態で、GW終わってから絶賛放置中
プロフィール

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

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