2ちゃんねる ■掲示板に戻る■ 全部 1- 最新50    

■ このスレッドは過去ログ倉庫に格納されています

BonDriver共有ツール総合 その2

1 :名無しさん@編集中:2015/04/07(火) 20:25:07.03 ID:n6IDd8Gi.net
BonDriver共有ツール総合

※前スレ
http://peace.2ch.net/test/read.cgi/avi/1366339738/

311 :名無しさん@編集中:2015/09/18(金) 00:34:44.21 ID:9PcEUns2.net
310 続き

DeviceIoControl以外にデバイスドライバの読書をする関数を知らないので、BのWindows上の他のシステム関数からだと厄介だ...。

@のDeviceIoControlの引数が違う点については、別の側面から疑っている。それは
>>296にも書いたが、pestudio.exeというツールでBonDriver_PX_W3U3_T0.dllを見た時にImported symbolsの中にDeviceIoControlが見当たらない。
kumaさんドライバにも同様にDeviceIoControlが見当たらない。対して上記のデバイスドライバをオープンして閉じるだけの短いプログラムにはkernel32.dllのDeviceIoControlを利用していることが表示される。
ということで、このプロセスからはデバイスドライバに対して直接アクセスしてないのではないかと考えている。

ということで>>296にも書いたが、デバイスドライバに対してDirctShowの仕組み、恐らく別プロセスのCOMサーバー上からデバイスドライバにに設定値を送り込んでいるのではないかと考えている。
フィルタグラフを構築する時に、チューニングスペースオブジェクトかMicrosoft DVBT Network Providerフィルタに設定値を送り込む機能があるのではないか、もしくはチューナーフィルタか
キャプチャフィルタにその機能があるのではないかとも考えている。

この推測に基づいてまずは、DirectShowのCOMサーバーの実体プロセスがあるものと考え、それがどれなのかを調べていくとことにする。

---------
別談だが、pestudio.exeでHDTV_PX_W3U3_BDA.sysを調べた時に嫌なImported symbolを見つけた。
srand(乱数)だ。1024byteのデータ、keyという変数が登場する何かの処理、ここから得られたデータをデバイスドライバに対して上記の方法でデバイスドライバに送るので、
これはもしかしたらこれがこちらから送ったkeyを元にどこかで乱数を加え、 MULTI2暗号化されているデータを更にPlex独自の暗号化をHDTV_PX_W3U3_BDA.sysで施し、
キャプチャフィルタから送出されるのではないかと考えている。
そうなると>>296でも書いた2つのデータテーブルの前の謎の1024Byteのデータテーブルが暗号解読に必要なキーではないかと合点がいく。あくまで推測なので定かではない。

312 :300:2015/09/18(金) 17:08:37.10 ID:molxTCMc.net
>309
RPC_E_CHANGED_MODEのEはErrorの意味なので、この場合はCoUnInitializeはいらないようです。

スレッドモデルについてですが、もちろん>308に記載の通りにCoInitialize自体を適切なタイミングで行うと仮定して、
まさにwww.kekyo.net/2013/07/22/382を読んでCOINIT_MULTITHREADEDでいいのではないかなと判断しました。
「スレッドで行われる操作が、ウインドウやウインドウメッセージに及ぶ可能性がある場合は、STAとして設定する。」
と書かれているので、単純に、BonDriverにはウインドウは関係ないからMTAでいいかな、と。

313 :300:2015/09/18(金) 17:29:01.95 ID:molxTCMc.net
ただ、それだと乱暴なのでもう少し考えてみると、BonDriverを呼び出すアプリケーションは
以下の2種類に大別されると思います。

1.アプリケーション側でCOMを使うのでBonDriverを呼び出すスレッドですでに初期化している。(TVTest)
2.そもそもCOMを使わないので初期化もしない。(EDCB)

1.の場合は、仮にBonDriver側でCOINIT_MULTITHREADEDで初期化しようとしても、RPC_E_CHANGED_MODEが
返ってくるだけで、なんの処理も行われないので影響はない。
2.の場合はそもそもアプリケーション側でCOMを呼び出すことがないのでBonDriver側でどのスレッドモデルで
初期化しようが関係ない。

また、アプリケーション側は、BonDriver側がリアルタイムにメモリに溜め込んだTSデータを、アプリケーションの
都合のいい時にGetTsで読み出し、PurgeTsで消去処理を呼び出しているだけなので、特別な同期処理も必要ない
(GetTs, PurgeTsはCriticalsectionに入れているとして)。

というわけでCOINIT_MULTITHREADEDで問題ない様な気がしてます。

ただ、BonDriverProxyもCOINIT_APARTMENTTHREADEDなので、できたらこちらの作者のお話もお聞きしてみたいです。

314 :名無しさん@編集中:2015/09/18(金) 19:44:58.02 ID:bi0g4EkT.net
呼び出し元のスレッドをアパートメントが設定されてるスレッドに固定できるかどうか、って話なのでは?
呼ばれる側からは内部でCOM専用スレッドとか作らない限り固定出来ないでしょ。

COINIT_APARTMENTTHREADEDにしてるってのは呼び出し元は単一スレッドであることを前提に
メインスレッドから呼んでも大丈夫なようにしてるだけなのでは。

現状でCOM呼び出しがパフォーマンスのネックになってるかどうかも不明なのに
汎用のDLLをわざわざ危険側に倒す思想がよくわからない。

315 :名無しさん@編集中:2015/09/19(土) 13:14:21.14 ID:fMUe+7h+.net
>>292 でおしえて頂いた初期化処理についてですが、どうやらIKsPropertySet インターフェイスを
使っているようです。
>>311で考えた”DirectShowのCOMサーバーの実体プロセス”とやり取りをすると考えたのですが、
これは誤りで同一プロセス内のKsproxy.axフィルタを通してやり取りが行われるようです。
以下その解析記録です。

DirectShowのCOMについてこの項目を読んでいると「あっ」と思うキーワードを見つけた。
https://msdn.microsoft.com/ja-jp/library/cc354739.aspx
「Ksproxy」というキーワードである。
これは実はWinDBGで KERNELBASE!DeviceIoControlの辺りで一時停止させた時に何度も見たもので、
KERNELBASE!DeviceIoControlの呼び出し元となっていた。
説明に「TV チューナー、TV オーディオ、アナログ ビデオ クロスバー、および KsProxy の各フィルタは、
IKsPropertySet インターフェイスによってカスタム ドライバのプロパティをサポートする。」とある。
この時はcxレジスタに0x8d81という値は1度も来なかったので、てっきりKsproxyは他の何等かの他のデバイスドライバ
に対して読書しているのだろうと勝手に思い込んでしまった。
しかしこれは間違いで実はBonDriver_PX_W3U3_T0.dllは同一プロセス内に読み込まれているKsproxy経由で
デバイスドライバに対して初期設定を行っているという思いが強くなってきた。

では何故pestudio.exeでBonDriver_PX_W3U3_T0.dllを調べた時にImported symbolの中にDeviceIoControlが
見つからなかったのか。
pestudio.exeではBonDriver_PX_W3U3_T0.dllが直接アクセスする関数しか表示されない。
その証拠に”デバイスドライバをオープンして(”1度アセクスして”が前回の記述で抜けていた)閉じるだけの
短いプログラム”を作成した時に、直接呼び出しているkernel32.dllのDeviceIoControlの表示しかなかった。
kernel32.dllが更に読みだしているKERNELBASE.dll.DeviceIoControlの表示がなかったのである。
ということでKsproxy経由のDeviceIoControlは表示されることがなかったとなる。

316 :名無しさん@編集中:2015/09/19(土) 13:16:03.33 ID:fMUe+7h+.net
315 続き

もう一つ疑問がある。
WinDBGに bp KERNELBASE!DeviceIoControl+0xF "j cx==0x8d81'';'g'" とcxレジスタが0x8d81の時停止するように
入れた時になぜ停止することがなかったのか。Ksproxy経由でも停止するはずである。
きっとマイナーファンクションコード(IOCTLコード)0x8d81がLinux用のものと違うはずだ。

そもそもマイナーファンクションコードは、デバイスドライバのプログラムソースがC言語で書かれていると仮定して
ユーザー モードアプリケーションにはWinMainとLRESULT CALLBACKがあるように、デバイスドライバには
DriverEntryとディスパッチルーチンがある。
システムやアプリケーションからデバイスドライバが呼び出されるとDriverEntryで登録されたディスパッチルーチンが
呼び出される。
アプリケーションからDeviceIoControlを実行するとディスパッチルーチンが呼び出され、引数から
メジャーファンクションコードを取り出す処理が行われる。
DeviceIoControlを実行の場合のメジャーファンクションコードはIRP_MJ_DEVICE_CONTROLであり、これを元に
switch case で分岐処理が行われ_IoCtlHandlerを呼び出す。
呼び出された_IoCtlHandlerの引数の中にスタックロケーションの構造体の
xxxx->Parameters.DeviceIoControl.IoControlCodeがある。
この値がマイナーファンクションコード(IOCTLコード)であり
これはswitch case で分岐処理に利用される。
switch caseに設定される定数はプログラマーの設定した値でありなんでもありだ。
この分岐処理の定数に0x8d81が存在すると仮定して解析をやってきたが、今では違う値だと考えている。

KERNELBASE!DeviceIoControlの所の調査からやり直すことにした。
Ksproxy経由でKERNELBASE!DeviceIoControlに来た時のcxレジスタの値を調べてみた。
0x0003 0x0008 0x0007 0x0003 0x000f.........
これらのコマンドとデータを送り込めればチューナーが何か反応するのかも。

317 :名無しさん@編集中:2015/09/19(土) 13:17:09.02 ID:fMUe+7h+.net
316 続き

これらの解析からIKsPropertySetを使って何等かの初期設定を行ってチューナーに起動をかけていると考えていこう。
上記のMSDNに「アプリケーション ベンダーは、IKsPropertySet インターフェイスのメソッドを使って、
ドライバやフィルタが特定のプロパティ セットをサポートしているかどうかを調べ、それらの
プロパティを取得または設定できる。」とある。

PLEXの提供するCLSIDが必要らしい。
そんな資料ない...。先は随分長そうだ。

318 : ◆SALrG1ld3mTc :2015/09/19(土) 19:19:11.78 ID:92YkKb/m.net
>>313
BonDriverProxyの場合は単純に、読み込んだBonDriverがCOMを使っていた場合に、STA/MTAのどっちを想定しているのか
わからないので、安全側に倒すと言う意味でSTAにしています

また、現代のPCの性能ではMTAを使って目に見えてパフォーマンスを上げられるとすれば、まず使用するCOMオブジェクトの
ThreadingModelがFreeかBothであり、かつそのCOMオブジェクトのメソッドをフルスピードで回るループの中から
呼び出しているようなパターンくらいじゃないでしょうか?
BonDriverのAPIのような、昨今のCPUの速度を基準にみるとごく低頻度で呼び出されるだけと言える用途では、
それによる性能改善はほぼ無さそうな気がしますヽ(;´ー`)ノ

319 : ◆SALrG1ld3mTc :2015/09/19(土) 19:23:49.63 ID:92YkKb/m.net
そう言えば、COMを使うBonDriverの実装の形として、大体は取得したCOMオブジェクトのインタフェースをメンバ変数に
保持していて、API内部ではそのメンバ変数経由でCOMオブジェクトのメソッドを呼んでいます
この場合、例えばAPI1とAPI2で上記メンバ変数を使用していたとして、アプリがそれらを別スレッドから呼び出した場合、
特に目的のCOMオブジェクトのThreadingModelがSTAに属するものであった場合は、本来のCOMの仕組みから外れた
危ない使い方をしている事になってしまいます
ですが、正しい使い方(律儀に元のインタフェースをマーシャリング/アンマーシャリングして、別スレッドからの
呼び出しであった場合には取得したプロキシ経由でメソッドを呼び出す)をした場合に本来発生する筈の、
WindowメッセージによるCOMのマーシャリングをバイパスして直接メソッド呼び出しになるので、その分の
オーバヘッドは発生しなくなっています

つまり、本来重い(かもしれない)はずのアパートメントをまたいだCOMオブジェクトのメソッド呼び出しですが、
少なくともソースが存在しているBonDriverでの実情としては、上記の通りほぼ単なるメソッド呼び出しとなっているので、
そう言う意味でもSTA/MTAの違いは恐らく有って無いような物ではないでしょうか

またこのようなつくりになっている関係上、その手のBonDriverを利用する際には、OpenTuner()/CloseTuner()/
SetChannel()/GetSignalLevel()辺りの呼び出しはそれぞれ排他にしておいた方が無難なのでしょう
本来はxtne6fさんが行われたこの↓使い方が一番安全なんでしょうけどもヽ(;´ー`)ノ
http://peace.2ch.net/test/read.cgi/avi/1438432913/792n

320 : ◆SALrG1ld3mTc :2015/09/19(土) 19:38:24.01 ID:92YkKb/m.net
>>310-311,315-317
当方もさっきまたBonDriver_PX_W3PE_S0.dllを眺めてたんですが、確かにBonDriver_HDUSで言う所の、
CDShowMain::CreateAddTunerDevFilter()成功の後、m_pTunerDeviceにIKsPropertySetをQueryInterface()して、
それ経由でデータの取得や設定を行っているように見えますね
対象のguidPropSetは{9E1781E1-9CB1-4407-BBCE-5426C8D00A4B}、dwPropID==0x0cがlinuxドライバでの0x8d81相当、
0x0dが0x8d82相当、0x09(それが失敗したら0x14)が0x8d83相当かと思います

dwPropID==0x0dで得た16バイトの乱数とシードである
{0x61,0xd8,0x56,0x3d,0xc1,0x15,0x46,0x68,0xb2,0xec,0x6f,0xa9,0xed,0x45,0x33,0x81}
からGetKey()相当の処理を行って鍵を取得し、dwPropID==0x09でドライバにセットと言う流れのようですね
#なお、上記シードはdwPropID==0x09用で、0x14用はまた違う値です
この一連の処理は、>>305にも書いた通りBonDriver_PX_W3PE_S0.dllのロードアドレス+1040c辺りから始まっていますので、
デバッガで動き見るならその辺からで大丈夫だと思います

一応、このIKsPropertySetは他のdwPropIDでSetChannel()やらGetTsStream()の中からも使われているようですが、
その処理が実際に呼ばれるのかどうかはわかりません、と言うか、これ以上は実機での動作が見られないとツライ(;´Д`)

とりあえず上記初期化処理だけやってRun()してみる感じでどうでしょう?

総レス数 837
356 KB
新着レスの表示

掲示板に戻る 全部 前100 次100 最新50
read.cgi ver 2014.07.20.01.SC 2014/07/20 D ★