Posts
Proxomitron を多重起動可能にする
用途毎に Proxomitron のコピーを作成して起動しようとしたら、多重起動チェックにひっかかってしまったので、起動できるようにパッチを当ててみた。使ったバイナリは Naoko 4.5 に 日本語パッチ 1.0a を当てたもの。
多重起動を検出するときは Win32 API の FindWindow を呼び出して、自分と同じウィンドウが既に作られていないかチェックするのが一般的。
HWND FindWindow ( LPCTSTR lpClassName, // クラス名 LPCTSTR lpWindowName // ウィンドウ名 );
Proxomitron でも同じ方法が使われているだろうという推測を元に、OllyDbg を使って FindWindow を呼び出しているところにブレークポイントを仕掛ける。実行して見つかったのが以下のコード。
; lpWindowName に NULL をセット 00413940 33DB XOR EBX,EBX 00413942 53 PUSH EBX ; lpClassName にウィンドウ名をセット 00413943 C740 70 0A000000 MOV DWORD PTR DS:[EAX+70],0A 0041394A 8B0D 44A14200 MOV ECX,DWORD PTR DS:[42A144] 00413950 51 PUSH ECX ; FindWindow を呼び出す 00413951 FF15 34624200 CALL DWORD PTR DS:[<&USER32.FindWindowA>] 00413957 8BF0 MOV ESI,EAX ; 戻り値が NULL だったらジャンプ 00413959 3BF3 CMP ESI,EBX 0041395B 74 31 JE SHORT Proxomit.0041398E
FindWindow は条件に一致するウィンドウがなかったら NULL を返すので、チェック成功時にジャンプしていることがわかる。結果に関係なくジャンプさせてやれば通常起動処理に遷移できるので、条件付きジャンプ (JE) を無条件ジャンプ (JMP) に書き換える。
いざ書き換えようとしたらオペコードがわからないことに気付き、手元にある「はじめて読む 8086」を参照してみたが詳細な解説がない。仕方なく Intel が公開している IA-32 のリファレンスを探すことにした。
オペコード | 命令 | 説明 |
---|---|---|
74 cb | JE rel8 | 等しい (ZF=1) 場合 short ジャンプする。 |
E9 cb | JMP rel8 | 次の命令との相対分量分だけ相対 short ジャンプする。 |
メモリ上のアドレス (0041395B) から 400C00 を引くと、実行ファイル上のアドレス (00012D5B) を求めることができるので、Proxomitron をバイナリエディタに放り込み、
ADDRESS 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00012D50 51 FF 15 34 62 42 00 8B F0 3B F3 74 31 56 FF 15
アドレス 00012D5B にある 74 を E9 に変更する。JE も JMP もオペコードは 2 バイトで構成されるが、ジャンプ先の変更はしないので、実質 1 バイトの書き換えで済む。
準備が整ったので、書き換えた Proxomitron を 2 つ起動してテストする。
![](/files/posts/2012/1119/tasktray.png)
通信もポート別に独立して動作しているので問題なさそう。ただ、動作保障外なので使うときには注意。