制作日記

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

トップ

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

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は続きへ追いやられました

続きを読む

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終わってから絶賛放置中

allegro

mugenで使ってるallegroのライブラリalleg40.dllはmugen-hiに同梱されてるの使ってるけど
試しにallegro公式サイトからソース持ってきて自前でビルドしてみた
ビルド環境はcygwin+mingw(i686-w64-mingw32)
古すぎてビルド通すのも一苦労
特に何か効果があったわけではないけど、patch公開しとく

allegro_patch.ico

手順
$ wget http://download.gna.org/allegro/allegro/4.0.3/allegro-4.0.3.tar.gz
$ wget http://blog-imgs-104.fc2.com/d/r/a/drabs/allegro_patch.ico
$ rm -rf allegro-4.0.3 && tar xf allegro-4.0.3.tar.gz
$ cd allegro-4.0.3
$ ./fix.sh mingw32
$ patch -p0 < ../allegro_patch.ico
$ make
makeはdemo.exeのビルドでこけるけど、この時点でalleg40.dllはビルド終わってるから問題なし

以下、ビルド通るまでの紆余曲折
サイト:http://liballeg.org/
Older vbersionから4.0.3持ってくる
4.0.0でもいいけどpatch当たらない
はじめは4.0.0でビルド通してpatch作って、その後4.0.3用にpatch作り直したから
4.0.3と同じように修正すればビルドは通る

適当なとこに解凍して
allegro-4.0.x\docs\build\mingw32.txt
の Setting up Cygwin to build Allegro
に従って設定していく

dx70_mgw.zip持ってくるのは飛ばした、VC入れてるし無視
入れようと思ったけど止めた、誰か頑張れ
http://download.gna.org/allegro/files/dx70_mgw.zip

makefileでtoolchainをgccとか直で叩いてるから、適当にmingwに書き換え
あとは、ビルドオプションとか諸々をその場しのぎで修正
ソースも一部こけるから修正
それでもこけるとこを、色々試しつつ無難かつお手軽な方法で修正

で、とりあえずビルド通ってmugen起動するとget_dx_verないって怒られる
munge-hiに同梱されてるalleg40.dllはget_dx_verをエクスポートしてるっぽい?
というわけで、lib/mingw32/allegro.defにget_dx_ver追加してmugenとリンクできるようにエクスポートしてやる
これでリンクは成功するけど、次はDXのversionで怒られて起動できない
面倒だから固定値で0x800を返すように変更
プロフィール

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

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