Seaside Laboratory

Post

Proxomitron を多重起動可能にする

用途毎に Proxomitron のコピーを作成して起動しようとしたら、多重起動チェックにひっかかってしまったので、起動できるようにパッチを当ててみた。使ったバイナリは Naoko 4.5 に 日本語パッチ 1.0a を当てたもの。

多重起動を検出するときは Win32API の 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 を引くと、EXE 上のアドレス (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 つ起動してテストする。


問題なく起動。

通信もポート別に独立して動作しているので問題なさそう。ただ、動作保障外なので使う時には注意。