2018年04月09日

F12進展?(追記あり)

制作日記 F12

バッファオバフロでコード実行してるのは予想してた通り
ただどこで実行されてるのか不明だったからもうちょい調査した

前回調べた時はどうやらパソコンの調子が悪かったらしくブルスクが出たのも外的要因かな

結論
4177B5のRETNで任意コード実行でした
実行されるのはファイル保存後だったので、ファイルの中身や名前は弄れそうにないですね

でも最終処理でのコード実行にはうまく使えそうな感じ

実行方法は
4A41F0に出力ファイル名があるからそこを書きかえ
4A41FCにfopenのフラグであるrbが書いてあるけど、これはファイルの存在確認にしか使われてないので関数が失敗しても何の問題もない
で、4A4200~4A4203がリターンアドレスになるからそこにリターン先を書き込む
注意点は、文字列の中にヌル文字が入ってるとそこで読み込みが終了してバッファオバフロができなくなること
だから必ず4A41F0~4A4203には0以外の数値を入れる(終端は実行先によって違うけど)
コード実行先では、結果的に421708にRETNできればOK
レジスタの修復はお忘れなく…

drab氏の記事を補足すると、4B54E4にはmugen%i.pcxの部分の引数が入ってる
だから数値を大きくしても落ちはしないんじゃないかな
追記
%iの引数の桁が7桁以上になると同様にバッファオーバーフローしてしまうので、4B54E4の値が大きすぎるとコード実行が発生してしまいます。
drab氏、解説ありがとうございました。

情報が増えたらまた追記します
posted by めろんピエロ at 09:28| Comment(0) | MUGEN | このブログの読者になる | 更新情報をチェックする

2018年04月05日

F12キーによるスクショ生成処理の怪

F12キーを押すとその時点でのスクリーンショットがmugen(数字).pcxという名前でwinmugen直下フォルダに生成されます

この名前が保存されているメモリを弄ればwinmugen以下の任意の階層に画像を保存できるのではないかと思ったので調べました

予想通りあるアドレス(出先なので数値は忘れた)に"mugen%i.pcx"が書き込まれており、そこを弄ると任意の名前で画像出力が可能でした
(うさみみハリケーンのメモリ検索でANSIにした上で先程の名前を検索すれば出てくると思います)
%iの部分は%.0sに書き換えれば何も出力されなくなるので気にしなくて大丈夫です

此方の調査では"font\mugen%.0s.txt"のようにすればきちんと出力されることが判明
しかし、長いパスに書き換えたところファイル出力自体はできたものののその直後にフリーズしてしまいました

その原因を調査すると、とんでもないことが・・・
なぜか書き込んだ数値に対応するアドレスへの任意コード実行が行われていました
しかもパスによって実行されたりされなかったり、変な値を書くとブルスクがでたりとなんだかよくわからない仕様ばかりだったので一旦保留にしてブログでの公開ということに


時間ができたら再調査する予定ですが、任意コードを実行する手段が増えたという意味では進歩なのか…?

(任意コード実行のタイミングはファイル生成よりも前なので、コード実行可能なファイルパスを事前に書き込み、任意コードで本来出力させたいパスに修正すれば使えそう)


時間ができたらアドレス周辺など追記します
posted by めろんピエロ at 17:09| Comment(0) | MUGEN | このブログの読者になる | 更新情報をチェックする

2018年03月14日

負数ステートへの移動

通常、selfstateやhitdefのp2stateno、hitoverrideのstatenoで負数ステートへ移動することはできません
selfstateとchangestateはvalueが負数の場合警告文を吐き、hitdef-p2stateno等では-1未満だと警告文を吐きます
しかしエラー判定が行われるのはステコン実行時であるので、hitdefやhitoverrideではステコン実行後に何らかの方法(ステコンオバフロ,%n,コードなど)でパラメータを弄ることで負数ステートへ移動可能になることがわかりました
statedefは負数でも個別ステートとして移動できれば通常通り読み込むので、移動方法さえ知っていれば利用できます
移動可能なステコンと弄る箇所は以下の通り
hitdefのp1stateno(char+0x11E8)
hitdefのp2stateno(char+0x11E4)
hitoverrideのstateno(char+0x10B0+slot*0x14)
検証してないですがreversaldefのp1stateno,p2statenoも移動できると思います

注意点としては負数ステートではdefオプションが反映されないこと
persistentは動きます

汎用化できそうな条件にならなかったのでブログで公開しました
適当に書いたので今度追記するかもです
posted by めろんピエロ at 20:34| Comment(0) | MUGEN | このブログの読者になる | 更新情報をチェックする

2018年01月29日

proj反射 進捗

進捗ダメです

コード書けば書くほどこれ無理や…ってなる
処理候補としては
・被弾感知してprojcontacttimeで反射
利点:記述が楽
欠点:Proj1個しか反射できない、同じIDのProjだと処理を増やす必要あり

・Projの座標と速度を見て近傍なら反射
利点:比較的記述が楽、複数Proj反射可能
欠点:誤感知が増える

・被弾処理を別スレッドから監視してパラメータ変動感知でレジスタを読みProjを特定する
利点:誤感知が少なく複数Proj反射可能
欠点:記述量が半端じゃなく多い、レジスタを読むのに一々スレッドを停止しなきゃいけないので重い

全体的な欠点
装飾Proj(攻撃用Projと同時に射出される演出用のProj)の区別ができないため反射ができない
これを反射しようとすると誤感知が増える

てな訳で結構詰んでるわけです
記述が比較的楽で条件次第では誤感知を減らせそうな座標型が第1候補
上の候補のいいところを組み合わせたやつが作れれば良いのだがなかなかきびちい

うまく自動判別できるコードは書けないものかねぇ
posted by めろんピエロ at 09:36| Comment(0) | MUGEN | このブログの読者になる | 更新情報をチェックする

2018年01月13日

欠陥ありました

前の記事で
記述例1([[char+345C]]は書き換え済)
[state ]
type=displaytoclipboard
trigger1=1||var(0):=敵charアドレス+3620(aliveのアドレス)
text="%c%c%c"
params=0,0,0
ignorehitpause=1
ってあったと思うんですけど、これ動きませんわ

理由は、[[[char+345C]]]にスタックの文字列をコピーする際に「ヌル文字までの文字列をコピーしている」から

上のtextだと1バイト目にヌル文字が用いられ、スタック上では2個目以降の%cも処理されるのですが、コピーする時に1文字目を文字列終端と誤認するためそれ以降の文字列がコピーされません

ってことで、text中に%c(引数0)があるとそれ以降の代入処理を行えません

4バイト丸ごと0にしたいときは%nを使えば良いのですが、そうでないときはこの方法ではどうしようもありません

ステコンを分ければ別ですが、それならば%nもしくは%hnでいい感じがします


この手法はダメみたいですね…悲しいなぁ
posted by めろんピエロ at 22:41| Comment(0) | MUGEN | このブログの読者になる | 更新情報をチェックする

2018年01月12日

%nより軽い任意代入

この記事は%nの処理やアドレスの概念をわかっている人向けのものです。

displaytoclipboard(以後DTC)の処理は、
@textパラメータをスタックにコピー
Aそのtextを頭から読んでいき、%なんちゃらの部分を処理する
Bスタック上の処理済みのtextを[[[[char+345C]]]]にコピー
のようになってます

ここで、[[[char+345C]]]を任意のアドレスに書き換えるとtext内の文章がそのアドレスに代入されることになります(Bの処理を利用している)

[[[char+345C]]]を0x4B5BA0にして
text="%c%c%c%c"
params=1,2,3,4
のDTCを実行すると
DWORD [0x4B5BA0]は0x04030201になりますが、BYTE [0x4B5BA4]が0になってしまいます(これは文字列終端のため)

上位1バイトが0の数値を代入するときは最後の%cを省略することで後ろ巻き込みなしの4バイト代入が可能です

ただし、ここで重大な問題点があります
それはこの手法では書き込み先アドレスを毎回[[[char+345C]]]を弄って指定する必要があるということです
というわけでそれを指定しやすい手段に変更したいと思います

[char+345C]にはいくつかの分岐先が存在します
[[char+345C]]:アドレス値
[[char+345C]+4]:アドレス値
[[char+345C]+8]:0x4D
[[char+345C]+C]:0x3(出力行数)

さらに、[[char+345C]]に関しても複数の分岐があります
[[[char+345C]]]:DTC出力1行目へのアドレス値
[[[char+345C]]+4]:DTC出力2行目のアドレス値
[[[char+345C]]+8]:DTC出力3行目のアドレス値

先ほどの手法ではこの「DTC出力1行目へのアドレス値」を書き換えることによって任意代入を実現していました
ここで[[char+345C]]を自分の変数領域のアドレスにし、該当する変数に代入先アドレスを指定すれば任意の箇所への数値の代入がとても簡単になります

[[char+345C]]をchar+E40(var(0)へのアドレス)に書き換えると、先ほどのアドレス表は以下のようになります
[[char+345C]]:char+E40
[[char+345C]+4]:アドレス値
[[char+345C]+8]:0x4D
[[char+345C]+C]:0x3(出力行数)

[char+E40]:DTC出力1行目へのアドレス値(var(0))
[char+E40+4]:DTC出力2行目のアドレス値(var(1))
[char+E40+8]:DTC出力3行目のアドレス値(var(2))

これでは変数を3つ消費するため、[[char+345C]+C]の出力行数を3から1に書き換えます
DTC出力n行目のアドレス値のアドレスは[[char+345C]+C]に依存しているため、ここを1に書き換えると必要なアドレスは[char+E40]の1つのみとなります

結果、var(0)に書き込み先アドレスを指定すればDTCで任意代入ができるようになります

記述例1([[char+345C]]は書き換え済)
[state ]
type=displaytoclipboard
trigger1=1||var(0):=敵charアドレス+3620(aliveのアドレス)
text="%c%c%c"
params=0,0,0
ignorehitpause=1

これは敵に直死を実行しています
(正直、この程度の代入処理ならば%nでやってしまった方が楽)

この手法が真価を発揮するのは複数箇所への代入や複数byteを書き換えるときです

記述例2([[char+345C]]は書き換え済)
[state ]
type=displaytoclipboard
trigger1=1||var(0):=charアドレス+5012(残像参照先アドレス)
text="%c%c%c%c"
params=(char+340)の1byte目,(char+340)の2byte目,(char+340)の3byte目,(char+340)の4byte目,
ignorehitpause=1
これはafterimageの参照先をchar+0x154に書き換えています
ここで、afterimagetimeを用いてpower参照先を任意値にするとpowersetによる4バイト代入やpower参照が行えます

これを%nでやろうとするとステコンが4つ必要な上に、文字数を稼ぐ必要があるため重くなります
そのため、この手法は利用価値が高いと思われます

巻き込み範囲や軽さの点では%nより有能と言えるでしょう(事前準備は必要だが)
もちろん自己のアドレスを取得しておく必要はありますが、そもそも%nを使う時点で自己アドレスは取得していることが多いと思うのでまあ問題ないと思います

デメリットは通常のDTCのデバッグ表示に影響が及ぶかもしれないということぐらいですかね
ここは検証してみないとわからないところなので今後も検証していこうと思います

参考記事としてここも見ておくと良いかもしれません

posted by めろんピエロ at 10:46| Comment(0) | MUGEN | このブログの読者になる | 更新情報をチェックする

2018年01月11日

%fコードの問題点の続き

ちょっと進展したので

前の記事で「常時監視と個別ステートでのコード開始地点が16byteズレている」という文言があったと思います。
その後何人かの製作者様に協力していただき、16byteのズレが安定したものであるかを調査しました。

結果、Windows7とWindows10の環境下では常時監視での%fコード開始地点は個別ステートで実行するのに比べて16byte手前になるということが判明しました。
よって常時監視で%f準備を行い、個別ステで処理を行いたい場合は常時監視で使う全てのコードの先頭に「瑞瑞瑞瑞瑞瑞瑞瑞」を加えれば動くようになると思われます。

これで安定してくれればいいな…!
posted by めろんピエロ at 23:05| Comment(0) | MUGEN | このブログの読者になる | 更新情報をチェックする

2018年01月04日

新年の挨拶とか

あけましておめでとうございます。
今年もよろしくお願いいたします。
2017年は神の捏造補助界隈や隔離界隈が結構賑わった年だったかなと思います。
これからも程々に頑張ります

さて、話題は変わりまして
%fコードでの問題点(環境差?)が出てきたので少し取り上げたいと思います

これを利用するにあたって、必要なステコン数は2つ
・4B48E8にコード開始地点を代入する(事前準備)
・4B48E8に496651を代入する(修復)

ここでdef-2で事前準備を実行し、個別ステで任意コード実行と修復を行った時にMUGENが落ちるといった報告が見受けられます
本来、これらの準備や修復のステコンは任意コード実行の直前後にやるべきなのではありますが、ステコン数を減らすためにこのような処理を行いたい場合があると思います

MUGEN落ちする原因は「コード開始地点のズレ」です
%fを利用する場合は[esp]を4B48E8に代入するのが主流なのですが、espつまりスタックポインタは動的に変化します
任意コード実行の直前後に準備や修復を行う場合は一意のアドレスを指す場合が多いのでMUGEN落ちの可能性は低いです
しかし、def-2で準備を行うと-2での[esp]と個別ステでのコード開始地点にズレが生じ、結果的にMUGEN落ちが起こります
私の環境では16byteのズレを観測できましたが、これも起動するごとにズレたりズレなかったりするのであまり当てにならないという状況です

対策として考えられるのは
・コードの先頭をnop(何もしない命令)で埋める
・4B48E8に代入するアドレスを安定したものに変える
といったものです
前者は、ズレが発生した場合でもnopがある場所からコードを開始できさえすれば目的のコードにたどり着くことができます(この手法はクラッキング技術の「NOPスライド」とほぼ同一で、その界隈では時々利用されます)
これの欠点はnop領域でカバーしきれない範囲にコード開始地点が生成されてしまった場合で、こればかりは解決不可能です
後者は、そもそも不安定な[esp]代入を利用しない方法です
%fコード開発当初はdisplaytoclipboardの出力が保存される[[char+345C]+4]を代入していました
これで%fコードを使う際はステコンが2つ(コード部分と%f)が必要となるため、後に発見された[esp]の方法に取って代わられました
上記の[[char+345C]+4]のアドレスはコードの文字数によって変化したため、今ではより安定した[[[char+345C]]]を利用すれば%fコード自体の安定化は図れると思います(ステコン数増加の弊害はあり)

というわけで、%fコードの安定化は
・ステコン数を増やしたくない人は前者
・安定させたいなら後者
に転換することをお勧めします
もちろん、任意コードの直前後に準備と修復を置く場合は上記手法は関係ありません

私ももう少し調査してうまく解決することができればなー、と思います




posted by めろんピエロ at 17:35| Comment(0) | MUGEN | このブログの読者になる | 更新情報をチェックする

2017年11月14日

最近

リアルが忙しくて何もできてない

winmugenのパッチとか、十徳ナイフ補助ツールの構想を練ってたんだけど、まだexe作成には詳しくないからあんまり進まない

最近はydccdy氏がbaiduでちょくちょく話してるdefファイル内でヒープオバフロ起こす攻撃について調べてる
これもあんまり芳しくないけど…

時間あったらまた調べてみるかな
posted by めろんピエロ at 11:21| Comment(0) | MUGEN | このブログの読者になる | 更新情報をチェックする

2017年10月03日

SAM氏のとこのコメント&drab氏の記事


別に新しいことはしてない
ブログにもあるようにL霊夢の1.90はDEP回避してloadlibrary呼び出してる

以前からやりたいとは思ってたんだけど、DLL作成に難儀してたのが解決したから記事にした

プロセス系にはまだ詳しくないからなんとも言えないけど、
loadlibraryの実行先が0x49F12CにあったようにVirtualProtectのアドレスもないか探してみたけど、無さそうな感じ

今のところDLL使わずにアセンブラで十分な気がする

もっと複雑なことやるなら別だけどね
posted by めろんピエロ at 01:01| Comment(0) | MUGEN | このブログの読者になる | 更新情報をチェックする