2006/01/24(Tue)DLL Injection

はてブ数 2006/01/24 12:56 計算機な日記::ソフト作り つーさ

MG遊んでるうちにはちらっと書いたけど、
やっぱりこのディスプレイに320x240はちょっときついなと思って。
掲示板を見て何を思い立ったか、どうにかして画面を大きくできないかと考えた。
が、結局さじなげた。以下はその軌跡。失敗談なので悪しからず。

追記: コメント欄で協力してくださったhoshu氏のおかげで実現しました。

制作者側で調整して貰っちゃうことは簡単なのだけど、お勉強も兼ねて。
(お勉強も兼ねてと言えば何しても許されると思ってるヤツ一名

基本的には redraw 1 の直前タイミングで320x240の別Bufferにgcopyして、
元のウィンドウにgzoomして戻すだけでいいはずだ。
というわけでそういう手段をとってみよう。それにはどうするか。。

……一般的なところで、gdi32.dllをラップするDLLを作りそうなもんだけど、
いい加減なんかのためにその手のDLLを作るのが嫌だったので、
DLL Injectionとか、あれこれ調べながらやってみた。
他のプロセスにLoadLibrary「させる」手法。

とりあえずDLLを書いて、DLLを注入するプログラムを書いて……。

アタッチ→FindWindowしてMoveWindow(ウィンドウサイズを変更)
普通のプログラムで行けば、WM_PAINTが飛んできたところで再描画だから、
その時呼ばれるのはBeginPaintとEndPaintか。
インポートテーブルを書き換えて、この2つのAPIをフック。
アタッチ時に320x240のビットマップを持ったHDCを作っておいて、
BeginPaint時は内部でそのダミーのHDCを返却。
EndPaintが呼ばれたタイミングで、やっとBeginPaintしダミーのHDCからStretchBlt!
うまく行くかに思われたが、全然機能しなかった。

あれ、なんで動かないの?ω
実際、BeginPaint EndPaintは、画面が隠れた時ぐらいにしか呼ばれていないorz
WM_PAINTも飛んでない。というか、メッセージなんも飛んでない……。
HSPは画面更新時をWM_PAINTに頼ってないんだろう。(←ソースコード持ってない
え、じゃあ、どうやって画面描画してるんだ?
InvalidateRectも呼ばれてないっぽいし……。
内部でタイマーをイベントで持ってて、
インポートテーブル使わないでGetProcAddressからポインタを得てAPI呼んでる……?
なんで普通そんな回りくどいことしないだろうに……
でも、他に画面更新の仕方を知らない自分は頭に「?」を浮かべるしかない。

ためしに、GetDCとかも張ってみたが……

HDC WINAPI Hook_GetDC(HWND hWnd){return OriginalGetDC(hWnd);}

↑落ちる。え、なんで落ちんのorz
OriginalGetDCはWINAPIで宣言した関数ポインタ型にGetProcAddress。
特に問題ないような気がする。
落ちるんだから気がするだけなんだろうけど、うーん……。
ちなみに、似たようにReleaseDCも落ちる。謎ぃ。

ここで初めてHSPDXFIX.dllの存在に気づく。
名前からしてDirectXプラグインだなぁ。こん中?

HSPのプラグインはスクリプトの中で明示的ロードされるので、
インポートテーブル書き換えたところで……動くのかな?
その時は動かないような気がして、ラップDLLを作ってしまった。
HSP2のプラグインは引数4個て決まってるから正規表現であっさり作れる。

enum { ……, num_es_ini, …… };
typedef int (WINAPI *F)(int,int,int,int);
F g_pfn[100];

……
HSPDXFIX_API int WINAPI es_ini(int p1, int p2, int p3, int p4){
    return g_pfn[num_es_ini](p1,p2,p3,p4); }
……

で、es_syncに対して似たようなのを仕込んでビルドして……実行。

落ちる! それも g_pfn[num_es_ini]の中で、
0x0000100のメモリがreadになれませんでしたとか言ってくる。
えええー、なんで落ちんのorz

さっきといい今といい、なんかラップの仕方間違ってんだろうか?
この辺でさじ投げたっす。自分、解析は向いてないっすねorz

そして、他の人が一切使えなそうな情報しか書かないのも、物書きも向いてないω

参考にした → DLL Injection

(……なにそれ

やね先生の美咲本買ってみようかな。