2012年2月アーカイブ

GetProcAddressの罠 (2)

| コメント(0) | トラックバック(0)
その後Windows 7 x64環境で確認したところ、x86バイナリ・x64バイナリ共に再現せず。OSの違いなのか何なのか、と謎が深まってしまいました。

Visual Studioのデバッガにモジュールの一覧表示があったのに気付き、Vista x86で表示させたところ、shimeng.dllのアドレス範囲となっていました。Windows互換性テクノロジの中の人だそうな。

色々試した結果、slnファイルをUAC昇格して開くための自作ツールが原因だと判明しました。といっても、requireAdministratorなmanifestを持たせ、ShellExecuteExするだけの小さな小さなものなのですが。Vista環境でのみ、Send Toに入れて使っていたのです。

ファイル名に"launch"を含んでいると、問答無用で互換性テクノロジの餌食となるようです。互換性レイヤーを示す環境変数__COMPAT_LAYER=ElevateCreateProcessとありましたが、GetProcAddressに介入するのはWRPDllRegisterとかいうものだけではないのでしょうか。

インストーラー検出のinstall,setup,update,etc.とは異なり(他にpatchも)、今のところファイル名にlaunchを含むx86バイナリのみですが、Vista/7共にOSはx86/x64両方で再現しています。

asInvokerの中ILでも互換性レイヤーが入り込み、GetProcAddressをshimeng.dllに取られます。requestedPrivilegesがあってもダメということは、Vista以降用として作っても回避できない、ということです。

こんなテストコードを作りました。実行ファイル名を変えるとアドレスが変わることがあるのがわかります。
GetProcAddress.zip

昇格ランチャーのファイル名変更で回避できたのですが、真正面から行く場合、GetModuleInformationでkernel32.dllの範囲を取得し、その中にあるかどうかを確認して、外れていればLdrGetProcedureAddressする、という方法になるでしょうか。

余談ですがANSI_STRINGのMaximumLengthはLength+1になるようなので、RtlInitAnsiString/RtlFreeAnsiStringを使わずとも、構造体の決め打ち初期化で大丈夫でした。

ANSI_STRING str = {14,15,"GetProcAddress"};

上のサンプルもこのコードになっています。実はRtlFreeAnsiStringがx64でヒープエラーになったせいで、こう逃げたという側面もあったり。

GetProcAddressの罠

| コメント(0) | トラックバック(0)
GetProcAddressはGetProcAddress自身のアドレスを正しく取得できないことがあるようです。どうもUACで高ILにしたデバッガー下だと違うアドレスが返っています。

どうしてCreateRemoteThreadがロジックボムになるのかと思ったら、なんという罠でしょうか。

環境はVista x86、Visual Studio 2008 SP1。

関係あるのかないのか、ntdll.dllのUndocumentedなLdrGetProcedureAddressだと正しく取得できるという情報があり、試してみるとその通りでした。

単独で実行させる限り大丈夫なら、UndocumentedなAPIに手を出すこともありませんが、常時正しく動いてほしいのが本音です。

C文字列ではなくANSI_STRING構造体でAPI名を渡すので、RtlInitAnsiString/RtlFreeAnsiStringも使う必要があります。モジュールハンドルはLdrLoadDLLではなくLoadLibraryのもので大丈夫のようです。

ダミーウィンドウを作らせるだけですから、GetModuleHandleでuser32.dllの存在を確認した上で、DllMainから作ってしまうのが楽ではあります。

しかし「のどか」にて、これは共用メモリの話ですが、Adobe Readerという全くのGUIアプリでエラーが発生したことを考えると、ロードされていてもDllMainからuser32.dllのAPIを呼ぶのは危険かもしれません。

Windows Vista延命

| コメント(0) | トラックバック(0)
Windows Vistaおよび7のHome系製品が延長サポート対象になったようです。

Windows Vistaサポートライフサイクル
Windows 7サポートライフサイクル

Vistaの残り2ヶ月足らずで突然の方針転換。粘っていた人は嬉しいでしょうが、既に更新した人は恨むでしょう。今やPCはただの道具であって、維持費はかけたくないのです。

そういえばXPのサポート切れをカウントダウンするガジェットなんてものが昨年4月にリリースされましたが、ガジェットというカジュアルな手段(しかもXP非対応)に訴えるなら、Vistaの方が先ではないかと思ったものです。

この延命はいつ頃から確定路線だったのか、と勘ぐってしまいます。

私の仕事PC(MacBook MB062J/B)はVista Ultimateなので救済されましたが、Visual Studio 2010には非力なので、できれば本体ごと新しくしてほしいなあ...。

aacをm4aに

| コメント(1) | トラックバック(0)
AMFMラジオ録音さんのlame MP3で、再生ピッチが一定しないような感じがしたので(細かい音飛び?)、試しにaac Pipeに切り替えたのです。まあ、録音時のハードウェアの問題でしょうが。

ところがこれは生AACなので、iTunesやiPhoneで再生できないのですね。

そこでMP4Boxでm4aに変換したところ、QuickTime Playerで「不正なサンプル記述」というエラーが出てしまいました。Windows Media Playerは通りますがiPhoneではやはり再生できません。

iOSは中にQuickTimeと同じものが入っているので、QuickTime Playerはテスト環境として有用です。どうやらMPEG-2扱いされたのが問題だったようで、MPEG-4に強制することで回避できました。

mp4box -add <input.aac>:mpeg4 <output.m4a>

faacにオプション-wを追加して直接出力させたm4aは、QuickTime Playerでも再生できたので、録音時に使うならこちらでしょうか。

しかしいずれも音飛びは悪化してしまいました。そういえばHandBrakeの時にも音飛びしていました。faacは音質以前に音飛びが問題です。

Windows NT 4.0

| コメント(0) | トラックバック(0)
DeltaEndに元々のVJE-Delta 4.0対応機能を組み込み直しているのですが、そういえばNT 4.0ってどんなだったっけ、と気になったので仮想PCに入れました。
nt4.png
Windows 95相当のUIで、実はPnP非対応、Windows Updateも無し。ブリーフケースや受信トレイが懐かしいですが、常用した時期は短いです。

無断でWindows 2000 β3にして仕事をするというアホなことをしていたためですが、幸運なことに不具合には遭遇しませんでした。

で、NT 4.0です。Service Pack 6aの配布がもう終了しているのですね。sp6full_i386.exeというファイル名で探してきたものを入れて何とか対応。これがないとVMWare Toolsが入りません。幸いInternet Explorer 6はまだ普通に手に入りました。

MacBook Proのファンが回り始めて何事かと思ったら、当時は省電力機能がなかったのを思い出しました。ですので割り当てたコア数が100%貼り付きっぱなしになります。今となっては引退させないと電気の無駄でしょう。

ImmDisableIMEってWin98/2000以降だったのね、とDeltaEndのコードfixはもうちょっと先の話です。

VMWare Player 4.0.2のVMWare Tools (2)

| コメント(0) | トラックバック(0)
なかなか更新されないので、Workstationからもらうことにしました。

まずはVMware Workstation 8.0.2をダウンロードして解凍します。

VMware-workstation-full-8.0.2-591240.exe /e <解凍先フォルダ>

"tools-"で始まるファイルがVMWare Toolsです。例えばWindows 2000以降用ならtools-windows-8.8.2.exeを実行すれば、無事にVMWare Playerのフォルダの中が更新されます。
OpenProcessしてEnumProcessModulesしてDLLのハンドルを取得し、CreateRemoteThread経由でFreeLibraryに渡すという手がありました。

が、次にウィンドウが生成された時に、同じDLLがWH_CALLWNDPROCRETフックに指定されていると(つまりフックを使用するそのアプリがもう一度起動されていると)、アクセス違反で落ちました。

呼び出し履歴によるとCreateWindowから最終的にDispatchHookWで落ちており、名前からすると何事もなくフックを呼ぼうとしているのでしょう。DLLは開放できてもフックの状態は解除できなかったと推測されます。

となると何とかしてウィンドウプロシージャを呼ばせる、つまりCreateRemoteThreadからCreateWindowするしかありません。どんどんイケナイ道に踏み出している気がします。

LoadLibraryさせたDLLで、隠しダミーウィンドウを一瞬生成(WM_CREATEでDestroyWindow)すると開放できました。最初は論理試作としてDllMainでやったりしましたが、もちろん危険なのでエクスポート関数に実装しなければなりません。

コード注入だけで行なうのは無理そうです。CREATESTRUCTのlpCreateParams経由で受け取ったアドレスを、保存しておく場所がないためです。静的な変数が一切使えず、それがなくてはDefWindowProcすら呼べないのでは、ウィンドウプロシージャの実装は無理でしょう。

ウィンドウを生成するためにはRegisterClassする必要がありますが、クラス登録は相手プロセスの中ですから、同名クラスが既にあれば重複エラーとなります。時刻等を組み合わせてリトライする方向になるでしょうか。

USB 3.0 LANアダプタ

| コメント(0) | トラックバック(0)
台湾ASIX社からUSB 3.0対応GbEコントローラが発表されていました。1月3日のことです。
ASIX Releases the World's First Single-Chip USB 3.0 to Gigabit Ethernet Controller

現在サンプル、第一四半期の終わりに量産開始だそうなので、早ければ今年半ばぐらいに周辺機器として出回り始めるでしょうか。

PCI-Expressが1つしか使えず、しかも100BASEしかない廉価スリムPCで使い途があるでしょう。私の会社デスクトップPCがそれで、現在GbEで埋まっています。

GbEを維持しつつ高速な外付けHDDを接続するとしたら、USB 3.0経由しかないだろうと妄想していたところでした。

USB 2.0はともかく100BASEしかないスリムPCは今も販売されていたりします。ようやく救世主が現れました。
1

アーカイブ

ウェブページ

Powered by Movable Type 5.2.13

ホームページ