2016/06/16(Thr)LoadLibraryに渡されたDLLのパスをデバッガで見る x86

はてブ数 2016/06/16 1:05 プログラミング::C++ つーさ

ロードされるDLLの一覧がほしいだけなら Dependency Walker 上で、プロファイリングすれば十分なのだけど。

Kernel32.dll は、すべてのプロセスで同じアドレス空間にロードされているため、
あるプログラムで、Kernel32.dll の API に対してGetProcAddress して得た関数アドレスは、実は他のプロセスでも有効。
これを利用して、LoadLibrary に渡される文字列をデバッガから調べてみることにする。

まずは、適当なプログラム(x86)で、LoadLibraryA と LoadLibraryW を GetProcAddress して、アドレスを調べておく。
調べた結果、それぞれ 0x7639A840 と 0x763A4BF0 だった。

デバッグ対象のEXEをVisual Studioでソリューションとして開き、「デバッグ→ステップイン」でプロセスを開始する。
EXEのエントリポイントで止まるので、この状態で「デバッグ→ウィンドウ→逆アセンブル」を開き、
アドレスに先ほど得た 0x7639A840 を、アドレスとして入力しLoadLibrary の先頭にブレークポイントを仕掛ける。
同様に 0x764A5BF0 にもブレークポイントを仕掛ける。

F5で実行を再開。
ブレークしたときLoadLibraryの先頭にいる。
x86の関数呼び出し規約によれば LoadLibrary の第1引数は、ESPレジスタの指しているアドレス+4の位置に格納されている。
LoadLibraryの第1引数はロードしたいDLLへのパスを格納している文字列へのポインタなので、
これを得るための式をウォッチウィンドウに追加することで、何を引数に関数が呼ばれたかがわかる。

  (char**)(@esp+4) ← LoadLibraryAが呼ばれたとき
  (wchar_t**)(@esp+4) ← LoadLibraryWが呼ばれたとき

結果。*1

debugloadlibrary.png

というようなことをやっていた。
↑のDSPプラグインを他のアプリから使いたかったんだけど、うまく動かないやつがあってどうしてだろうと思って。

ちなみに、ESPレジスタで思い出したけど、
上記のように関数が呼び出されたとき、ESPレジスタの指す先にはリターンアドレスが入っているので、
これを使うことで、関数の呼び出し元のアドレスを得て メモリリークの追跡もできたりした。
過去形なのは最近x64が台頭しつつあるから。*2

void *my_alloc(void *pCaller, size_t size) { ... }

#define NAKED __declspec(naked)
#define WITH_CALLER(...) { void *CALLER; { __asm mov eax, [esp] __asm push ebp __asm mov ebp, esp __asm mov CALLER, eax } __VA_ARGS__;  { __asm pop ebp __asm ret } }

NAKED void * operator new(size_t size) WITH_CALLER(my_alloc(CALLER, size));
// WITH_CALLER の 展開後イメージ
__declspec(naked) void* operator new(size_t size)
{
	void* pCALLER; 
	__asm mov eax, [esp];    // 関数が呼び出された瞬間、ESPの指す先にあるリターンアドレスをEAXにメモ。
	__asm push ebp;            // VC++ がローカル変数へのアクセスをEBPを元に行うコードを生成するので、
	__asm mov ebp, esp;        // それと互換するようにEBPを準備する。
	__asm mov pCALLER, eax;      // メモったリターンアドレスをローカル変数へ移して
	my_alloc(pCALLER, size);     // それを使って本命の関数呼び出し。
	__asm mov esp, ebp;        // 使ったものは
	__asm pop ebp;             // 戻しておこう
	__asm ret;               // my_alloc の戻り値がEAXに入ってるはずなので、それがそのまま戻る。
}

my_alloc は呼び出し元のアドレスをつけて呼び出されるので、線形リストなどに時刻・サイズ等とともにメモっておけばよい。
ビルド時 .map ファイルや、逆アセンブルを出力しておけば、__FILE__などなくとも関数を特定できるのでこれで十分。

*1 : ついでにスタックのメモリも覗いてみる。

*2 : x64ではVC++はx64ではインラインアセンブラが書けないので別のやり方が必要

2016/05/14(Sat)YAMAHA XGの音源コントローラを結局作り直した。

XGTGCTL2 開発やめた の続きになる。

あれから10年近く経っても、自分のDTM環境が、MU2000 EXから脱却できていないので、
ドラムやEQを自由にいじりやすくするために結局作っていた。
前のバージョンはHSPで作ってて、ソースコードがスパゲティ状態で、拡張なんてとても無理だったのでC#で書き直している。
gitの使い方の勉強もかねて、GitHub上で公開してみる。

リリース: https://github.com/ttsuki/XGMidiControllerForMU2000EX/releases

これを使って作った曲: Another Wing -Deep White- と、そのソースコード
スクリーンショット:

MIDIファイルからの読み込み機能はあんまり使わないので省いて、
音源とSysExでSEND/DUMPするほか、サクラMMLスクリプトではき出すようにしたりした。

もはやXGという規格がレトロ化してきている昨今。
MOXFを買おうかとか、でもソフトで何でもできる時代だしーと思うと躊躇してしまう今日この頃。

2016/04/03(Sun)RAMDISKドライバを作る

RAMDISKドライバを作る

ほんとは、これがやりたくてオレオレ認証局とか作ってたんだけど、
調べたところによると、Windowsで使えるドライバ用のコード証明書のCAは決まってて
そればかりか、Windows 10のカーネルモードのドライバのコード署名はEV証明書でないといけないみたいで、
結局、この記事でやってるようにドライバ署名の検証をスルーしないと動かせなかった。
趣味レベルでカーネルモードドライバをちゃんと作ってリリースする道はもはや絶望的だなー……。

この記事では、

Visual Studioでのドライバの開発に必要なものをインストールして、
サンプルドライバをビルド・インストールしてみてから、
RAMDISKの容量が1GBになるよう、ソースコードを改造してみます。

制限

この記事の範疇ではFAT16なので、2GB(一説では4GB?)よりも大きいドライブは作れないはず。
FAT32への対応はすぐできるんだと思うけど、あんまり調べてない。

上記の通りドライバにコード署名できないので、ドライブを使うには、
毎回ドライバ署名の検証をスルーできる状態でWindowsを起動する必要がある。

続きを読む

2015/12/28(Mon)WINAMPにStereo ToolというDSPプラグインを入れたら、音楽を聴くのが楽しくなる。

はてブ数 2015/12/28 2:50 計算機な日記::ボクと計算機 つーさ

作業用BGMを自分好みにEQかけて聴きたい。
マスタリングエンジニアの人には失礼な話だと思いながら。
(2016.01.18 ちょっと更新した)

いれたもの

Winamp → いつものプレーヤー。
in_!mpg123 → MP3デコーダプラグイン。32bit int PCM/64bit float PCMとかが出る。今回は32bit intで出す。
Stereo Tool → WINAMPのDSPプラグイン。マルチプレッサ他いろいろついてる。
Yet Another (WA)SAPI Output Plugin for Winamp (YASAPI) → WASAPIで、カーネルミキサーを通さず音が出せる。

Stereo Toolの設定ファイル(いじった)

テンション上がる感じのStereo Tool用の設定ファイル ※ダウンロードにならない場合は右クリックして保存
Stereo Toolの設定画面で、LOAD → ALL AUDIO SETTINGS → tu3.sts を読み込むと反映します。

個人の再生環境とか、むしろ好き嫌いがかなり大きい世界なので万人向けではないけど、
かなりドンシャリでプリエンファシスなテンションあがる感じにはなったかな。
プリセットの Bojcha - Enlightened をベースに、低音と中音と高音をいじった。(?)
あんまりコンプレッサーとかよくわかってないけど。

画は設定いじってる途中


本文

今までは普通に、MU2000のA/D Inputを、ただのPC用イコライザーとして使ってたのですが、
ノートPCにさすがにMU2000つないであっちこっち行くのはめんどくさくて、
WMPのイコライザーをオンにしてたんですが、PREAMPがないので、
上げる方向にだけ調整すると音が歪んじゃうんですよね。

んじゃ、PREAMPついてるEQついてるプレーヤー使えばいいじゃないと、
ノートPCにもWINAMPを入れたわけですが、WMPのEQに耳が慣れてしまうと、
なんかWINAMPのEQは音籠ったみたいになっちゃうんですよね。なんでかな。

で、そこはWINAMPなんで、プラグインとかきっとあるよなーと思って検索してたら、
Stereo Toolというのを見つけた。一部有料だけど、ほとんどの機能が無料でつかえる! 

続きを読む

OK キャンセル 確認 その他