レス数が1スレッドの最大レス数(1000件)を超えています。残念ながら投稿することができません。
技術情報交換スレ
RTXのみならずROや支援ツール全般に関する技術的な情報を交換するスレです。
コーディングに詰まった作者が他力本願的に知恵を増やす目的で設立されましたが、
それだけでなく広く情報交換に使っていただけることを願っています。
管理人の手持ちの情報は少ないですが、RTX/RoTimerの内部動作に関する
御質問などでしたら、できるだけお答えしたいと思います。
規約云々や解析手法の是非などは別スレ/別BBSへ誘導のこと。
水面下に落ちるまではsage縛りで。
とりあえず >>1 からネタ振り
21f→21g/h で発生した「特定の環境でタイマーがガクブル問題」ですが、とりあえず
原因となる箇所は判明しました。
DX乗っ取りで実際に書き込みを行うタイミングを変更したのが原因だったようです。
○21f
2D書き込み:
窓モードでは DirectDrawSurface->Blt() 、フルスクでは Flip() のタイミングで
GetDC() してGDIでプライマリサーフェスに直接描画、あるいは自前サーフェスからBlt()
3D書き込み:
Direct3DDevice->EndScene() のタイミングで DrawPrimitive() などを投下
○21g/h
3D書き込み:
EndScene() で (21fと同じ)
2D書き込み:
EndScene() で 3D書き込みを行った後に保存しておいたプライマリサーフェスの
ポインタを使って GetDC() して以下略
というわけで 2D書き込みのタイミングを3Dのそれと一本化したのがまずかったようで。
これがどうしてまずいのかは不明です。
>>2
> ○21g/h
> 2D書き込み:
> EndScene() で 3D書き込みを行った後に保存しておいたプライマリサーフェスの
> ポインタを使って GetDC() して以下略
EndSceneが非同期で動いてると、その後GDI処理するためにレンダリング終了
まで待つ必要があってRO本体の足を引っ張ってるってことはないでしょうか?
EndSceneでプライマリサーフェイスに書き込んでもFlipかBltでなかったことにな
りませんっけ?バックバッファーに書き込んでるのでしたら、サーフェイスが
VRAM上にあった場合には、GetDCやGDIでほげほげするときにシステムメモリと
VRAM間で転送しまくってて遅い可能性も。
DirectX5〜7ぐらいの期間しかDirectXさわってなかったので、記憶違いだっ
たらすみません。それに、プロファイルとったわけでもないので全部予想に
過ぎません。
>>3
21g/h ではこんなふうに書いてたわけですが
// フックした Direct3DDevice->EndScene() 関数
HRESULT WINAPI Nisemono_EndScene(LPDIRECT3DDEVICE7 *lpD3DDevice)
{
HRESULT hRes1, hRes2;
hDC hDC;
/*
// 色々と3Dなお絵かき
lpD3DDevice->SetRenderState();
lpD3DDevice->SetTexture();
lpD3DDevice->DrawPrimitive();
*/
// 本物を呼び出し (ここで3D命令がグラボに飛ぶの?)
hRes1 = Honmono_EndScene(lpD3DDevice);
// プライマリサーフェス (LPDIRECTDRAWSURFACE7 lpPrimarySurface) は
// 別箇所 (CreateSurface()のフック関数) で取得・保持しています
if (lpPrimarySurface)
{
hRes2 = lpPrimarySurface->lpVtbl->GetDC(lpPrimarySurface, &hDC);
if (hRes2 == S_OK)
{
/*
// 色々と2Dなお絵かき
TextOut();
Ellipse();
*/
lpPrimarySurface->lpVtbl->ReleaseDC(lpPrimarySurface, hDC);
}
}
return hRes1;
}
*lpD3DDevice自体はプライマリサーフェイスから生成されてますから、Honmono_Endscene() を
呼ぶ前に2D描画を試みてもGetDC()自体が成功しません。でこんな順序に。
でもこれだとガクブルするということで
21fでは if (lpPrimarySurface) { ... } のブロックがそっくり 偽Blt() の中にありまして、
Nisemono_EndScene() はRTXの3D描画を終えた後すみやかに
return Honmono_EndScene(lpD3DDevice);
してますた。これだとガクブルしない、と
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpdx8_c/hh/directx8_c/_dx_d3dcaps8_graphics.asp
を見ると
一般的には、BeginScene と EndScene のペアの外側で 2D 処理を実行する
ことを推奨する。2D 処理がBeginScene と EndScene のペアの間で実行される
場合は、D3DCAPS2_NO2DDURING3DSCENE 能力をチェックする必要がある。この
能力が設定されている場合、アプリケーションでは、BeginScene と EndScene
の間にある 2D 処理は破棄されると考えなければならない。
とあるので、GetDCが成功しないのはそういうことなんじゃないのでしょうか?
ところで、ゲームの一般的な処理って
入力読んだりネットワーク通信したりいろいろ情報更新
BeginScene
DrawXXXなんかで描画
EndScene←ここでバックバッファーに画面が作られる
Flip/Blt←ここでバックバッファーからプライマリサーフェイスに転送
適当にSleep
の繰り返しですよね。だとするとEndSceneの直後にプライマリサーフェイスに
いろいろお絵かきしても無駄じゃありませんか?
##なんか私がどっか勘違いしてる気がしてきた。
当方、コンシューマー機畑の人間、オマケにヒッキーなので
DirectX(というよりGefのドライバ)がどうなっているのかは知らないのですが、
調べてみた限りでは、>>3 の説が濃厚な気がします。
つまり、EndScene直後ではまれなタイミングでしかGetDCに成功せず、
ほとんどのRTXの2D描画が廃棄されガクブル。
しかし、Blt重あてをしていて、Flip/Bltまでドライバに時間が与えられていれば
GetDCに成功し、概ね描画可能になっている、のだと思います。
問題の発生しない環境だと、VGAにぶちこむディスプレイリストの再構築の間、
プライマリは好きにしてもいいよ、な実装になっていて、直後でもS_OKがもらえるんじゃないでしょうか。
>>6
私の言いたかったのは、GetDCが成功したり失敗したりってそういうことでは
ないです。単純に呼び出しが失敗しているのなら作者さん気がつくでしょうし。
IDirect3DDevice9::EndSceneのドキュメントに
When this method succeeds, the scene has been queued up for rendering
by the driver. This is not a synchronous method, so the scene is not
guaranteed to have completed rendering when this method returns.
って記述がありました。(手元にはDXSDK9しかなく、DirectX 7のドキュメント
はだいぶ前に処分したので実際どうなのかはわからないです。)
また、GetDCするときに内部的にはサーフェイスをLockしているようです。
しかし、Lock後に整合性を保つにはLockの前にレンダリング済ませる必要が
あるはずです。
それらのことから、もしROがEndSceneがすぐ戻ってくることを前提に書かれて
いてEndScene→Flipの間に非同期に何かやろうとしてることがあったとすれば
それを同期的にしか処理できないことでフレームレートが落ちる可能性がある
んじゃなかろうかっていう推測です。
とりあえず、もう寝ます。
2だと管理人さんじゃん。3と5と7でした。
GetDCの動作を理解していませんでした。
EndSceneについては自分で調べた通りで、だから6のような妄想をしてしまったわけですが、
なるほどROクライアント本体で何か、という推測は成り立ちますね。
ガクブルの実際の動作がどうなっているのか気になります。
1.ROクラは普通に動作/RTXの3D描画も普通に動作/RTXの2D描画のみがガクブル
2.ROクラは普通に動作/RTXの3D/2D描画ともにガクブル
3.ROクラからRTXから全部ガクブル
外野から想像できるのはこんなところでしょうか。
うちも21gでガクブル(((;゚Д゚))) してましたけど、文字列(2D表示)がちらついてない
ので、GetDC() 自体は成功してるんじゃないかなと思います。
おそらく EndScene() から返ってからその3D描画が実現するまでのレイテンシが、
直後に 2D描画を突っ込むことでロスされる、というのが真実かと。
(2D描画をBlt()部に分離した試作版いただきましたが、正常動作しました)
関係ありませんがここってパケの話とかはOKですか?
ウンバラで最初取引チャイム出なかったのはやっぱ新パケなのかなと
>>10
それでビンゴのようです。
とりあえず再びBlt()/Flip()のところに文字列描画を引き離すことで事なきを得ましたが、
最終的には面倒くさがらず2D描画もDIB→動的Texture変更など使ってGDI撲滅の方向へ
いかなければなりませんでしょうか……
今は毎フレームプライマリサーフェイスにTextOut()する、という信じられないようなことをしている
のですが、タイマーって少なくとも1秒ごとに文字列が変わるわけで、画面上に20本のタイマーが
出ていたら、文字列不変をスキップしても、1秒ごとに20個のテクスチャをロックする必要があるわけ
ですよね。今は毎フレームサーフェイスロック1回のみなわけで。
やっぱこれでも3Dに統合した方がパフォーマンス出るのかなぁ
>パケの話
全く問題ありません。
とりあえず、ウンバラの取引要請でしたっけ?
// 取引要請(受)
R 00E5 → R 01F4 <trader's name>.24B <trade id?>.L <LV>.w
// 取引要請(攻)
R 00E7 → R 01F5 <success>.B <trade id?>.L <LV>.w
以降のシークエンスはいままでと同じです。
<trade id>.L は取引中保持され続ける固有値ですが、同じ相手と
再び取引しても同じ値だったり。生成方法は不明。
先ほどfpatchに置かれた20040619RagexeHC_jp.rgzですが、
どうやら何らかの方法で圧縮かかっているようです。
800KBと、半分以下になっていますし、逆アセンブラも通りません。
>>12
ASProtectで圧縮されてる。
>>12
Thanks! 解凍できました。
unpack済みのexeとメモリ内で展開されたexeでアドレス違ったりしないんだろうか。
展開の方法にもよるんだろうけど。
>>15
私が使ったUnpackツールは途中まで走らせたやつを吸い上げるみたいだから、
たぶん大丈夫…だと思いたい
ASPack/Protect圧縮部の自動解析機能は準備できました。
ただ、ログインシークエンス自体が変わっている (0x200系OP) ようで、
もしかすると新たな暗号化の可能性もあります。
したがって現行開発版が次パッチで動作可能かどうかは不明です。
ログイン部分やスキル使用など、kSakrayのパケログをお持ちの方が
いらっしゃったら、ぜひ送っていただきたいです。
それはそうと、RTXでは手法が異なるので影響を受けていないのですが、
インポートテーブルを参照した標準的なAPIフックがうまくいかないという話を、
他ツールの方々からお聞きしました。
これについても、役に立つ情報などありましたらお寄せください。
> インポートテーブルを参照した標準的なAPIフックがうまくいかない
ragexeのPEヘッダに書かれてるインポートテーブルはASProtect
展開ルーチン用のインポートテーブルを指してるせいではないでしょうか。
(覗いてみると、明らかにインポートされてる関数が少ない)
ragexe用のインポートテーブルを探してそちらを書き換える必要があるかと。
IATはさっくりと出るのですが、
INTが無いですね...
例のexeでダミーWS2_32.dllかませて最初の送信パケだけを眺める
unpackしてみたもの
send> 04 02 b0 2f b3 a4 00 e9 c8 30 9d 52 c1 a8 9e e9 6f d6
send> db 01
オリジナルそのまま
send> 04 02 ff 66 ac 95 5e 9d f8 62 d6 cd 8b 90 c5 73 0d f7
send> db 01
OPの後に16バイトの時点で察した通り、ragexe.exeのMD5送ってますね
だからどーしたと言われたらそれまでですが…
>>18-19
オリジナルのIATは容易に出せますし、これだけでフックも可能ですが、
複数ツール間でフックが競合することを念頭におくと、どうしてもINTが欲しい。
でもみつからない∧||∧
また、フックするにしても .adata+.data の正規セクション(.text/.rdata/.data)
への展開が完了したタイミングを検知してからフックしないと成功しないようで、
これがまた大変なようです。
>>20
サクライでは少し前から S 0204 仕様のようです。
S 0204 <ragexe/sakexe md5>.16B
これと S 0064 を対にして send しないと認証が成功しません
本鯖でのログインシークエンスは、さしずめ
S 0204 + S 01db
R 01dc
S 01dd
R 0069
S 020b + S 0065
R 006b
(以下略)
といったところでしょうか。
exeのmd5送信は、クライアントの改竄防止としては有効期間が短すぎます。
むしろ、昔のバグありクライアントを継続使用、といった弱い形での不正利用を
やんわりと抑止するのが目的ではないでしょうか。
今回はASProtect導入と併せてダブルチェックを狙っているものと思われます。
もっとも、どのみちメモリ上でパッチ当て+ S 0204 自前送信、で回避されて
しまうわけで、不慮のトラブルでパッチを当て損ねた人への誤爆だけが増えた、
などということにならないよう祈っています。
重力の斜め上開発能力を考えると、クライアントの改竄防止を
無理を承知でやってみた気配。
もしかすると、本気かもしれませんががが
boterが喜ぶだけの解析はやめてもらいたいもんだ
これだけ改変嫌がってるんだから開発止めてもいいと思う。
開発(改良?)したunpack技術を公開しないのに何故Botterが喜ぶかは不明
Mystleさんの作品を逆汗して技術だけ盗めるようなスキルのBotterはもう既にunpack技術の開発に乗り出してるはずです
それとココは技術情報交換所なので23さんの意見はスレ違いなので
http://jbbs.shitaraba.com/bbs/read.cgi/computer/6346/1085343913/l100
ここの議論スレにて発言するとよいでしょう
開発も何もASProtectは既存の技術で複合も検索すればツールが見つかるし。
まぁ、この板で話してる程度のことじゃBotterにもそのBOTの開発者にも
何の影響も及ぼさんよ。特に役に立つようなことはかかれてないし。
とはいえ、堂々とパケやらを載せるのはどうかというのは他所でも出てる意見。
その辺はまぁ、管理者のモラルによるもんだろ。
>>23-25
っ[議論スレ
お前らがやってることはBOTerと同じってことですよ、恥を知れ
文句いってる奴らはとりあえず
消えろ
うざい
邪魔だ
つ[http://jbbs.shitaraba.com/bbs/read.cgi/computer/6346/1085343913/l100
マターリしましょうねー
ああ、おかげさんでASProtectだって事だけ参考にさせてもらいますた。
zone動くまでにキー要求パケをMD5送信パケに置き換える作業出来て多謝w
今は改造クラをフックなどとめんどくさいのでragexeのMD5算出コード潰すor
別ファイルのMD5取って来るように改造ちゅ。
鳩スレなんかに降臨したりする低級紙でもありませんのでご安心。
>>30
超頑張ってくださいorz
スマートフォン版
掲示板管理者へ連絡
無料レンタル掲示板