|
|
2012/9/21(Fri) 22:29:49|NO.49471
他プロセスにマッピングされてるdllの
ベースアドレスを取得するにはどうすればよいでしょうか?
マッピングされてあるdllネームなどは取得できましたが、
ベースアドレスの取得方法がわかりません。ベースアドレスはexeでいう0x00410000とかです
ご教授お願いいたします。
|
|
2012/9/21(Fri) 23:37:33|NO.49472
ファイル名の取得に GetModuleFileNameEx
を使ってますか?
ファイル名取得時に指定しているモジュールのハンドルの値を
参照して下さい。
|
|
2012/9/21(Fri) 23:56:18|NO.49474
HIMさん>
たとえばuser32.dll の Messageboxの開始アドレスを取得じゃなくて
user32.dll自体の開始アドレスを取得です・・
|
|
2012/9/22(Sat) 00:38:19|NO.49476
説明がわかりにくかったので修正します。
#uselib "kernel32.dll"
#cfunc GetModuleHandle "GetModuleHandleA" sptr
dll = "user32"
adr = GetModuleHandle (dll)
mes "このプロセスの"+dll+"の開始アドレス= "+strf("%#x", adr)
このスクリプトであれば
自身のプロセスにマッピングされたdllのベースアドレスを取得出来るのですが
●自プロセスから→他プロセスのuser32.dllの開始アドレスを調べる
ということを行いたいです。
|
|
2012/9/22(Sat) 10:44:18|NO.49483
上に提示した方法でできますよ。
他プロセスを例としてHSP2012コンテストの「応募作品(一般1)」のページにある
オーバーテイクトランスミッションという作品を起動してモジュールを取得します。
得られた結果は以下のようになります。
OVERTAKETRANSMISSION_VER_1_54.exe - 0x00400000
ntdll.dll - 0x7c940000
kernel32.dll - 0x7c800000
COMCTL32.dll - 0x77160000
msvcrt.dll - 0x77bc0000
ADVAPI32.dll - 0x77d80000
RPCRT4.dll - 0x77e30000
Secur32.dll - 0x77fa0000
GDI32.dll - 0x77ed0000
USER32.dll - 0x77cf0000
SHLWAPI.dll - 0x77f20000
MSIMG32.dll - 0x762d0000
comdlg32.dll - 0x76300000
SHELL32.dll - 0x7d5b0000
ole32.dll - 0x76970000
OLEAUT32.dll - 0x770d0000
WINMM.dll - 0x76af0000
IMM32.DLL - 0x762e0000
LPK.DLL - 0x60740000
USP10.dll - 0x73f80000
MSCTF.dll - 0x74660000
Atl.dll - 0x76ad0000
dsoundex.hpi - 0x10000000
DSOUND.dll - 0x73e50000
VERSION.dll - 0x77bb0000
MSACM32.dll - 0x77b90000
msctfime.ime - 0x73620000
GIMEJA.IME - 0x06000000
dbghelp.dll - 0x67930000
PSAPI.DLL - 0x76ba0000
UxTheme.dll - 0x58730000
WINTRUST.dll - 0x76be0000
CRYPT32.dll - 0x765c0000
MSASN1.dll - 0x77c40000
IMAGEHLP.dll - 0x76c40000
wdmaud.drv - 0x72c70000
msacm32.drv - 0x72c60000
midimap.dll - 0x77b80000
KsUser.dll - 0x73e20000
| |
|
2012/9/24(Mon) 01:17:11|NO.49518
Himさん>
恥ずかしながらGetModuleFileNameExの使い方がむずかしくついていけません・・
対象プロセスのPIDとプロセスハンドルを取得まではなんとかできたのですが
そこから指定したモジュールの列挙→アドレス取得がわかりません。
|
|
2012/9/24(Mon) 03:26:29|NO.49521
(1)プロセスハンドルを取得
(2)プロセスハンドルからモジュールの個数とモジュールハンドル(=ベースアドレス)を取得
EnumProcessModules
http://msdn.microsoft.com/ja-jp/library/cc429387.aspx
(3)モジュールハンドルからモジュール名を取得
GetModuleFileNameEx
http://msdn.microsoft.com/ja-jp/library/cc429403.aspx
という流れです。
#uselib "psapi.dll"
#func EnumProcessModules "EnumProcessModules" int, sptr, int, sptr
#func GetModuleFileNameEx "GetModuleFileNameExA" int, int, sptr, int
EnumProcessModules hProcess, varptr(lphModule), cb, varptr(lpcbNeeded)
GetModuleFileNameEx hProcess, lphModule(i), varptr(lpFilename), $100
もし lpcbNeeded = 124
であればモジュールの個数は31なので、これらのモジュール名とアドレスを列挙する場合は
sdim buf
repeat 31
GetModuleFileNameEx hProcess, lphModule(cnt), varptr(lpFilename), $100
buf + getpath (lpFilename, 8) + strf(" - 0x%08x\n", lphModule(cnt))
loop
dialog buf
といった具合です。
|
|
2012/9/24(Mon) 23:01:32|NO.49542
#uselib "kernel32.dll"
#cfunc OpenProcess "OpenProcess" int, int, int
#uselib "psapi.dll"
#func EnumProcessModules "EnumProcessModules" int, sptr, int, sptr
#func GetModuleFileNameEx "GetModuleFileNameExA" int, int, sptr, int
pid = 5356;調べたいプロセスのPID
hProcess = OpenProcess(0x400 | 0x0010 | 0x0001, 0,pid)
mes "プロセスハンドル"+hProcess
EnumProcessModules hProcess, varptr(lphModule), cb, varptr(lpcbNeeded)
mes "lpcbNeeded = "+lpcbNeeded+" 個"
sdim buf
repeat 31
GetModuleFileNameEx hProcess, lphModule(cnt), varptr(lpFilename), $100
buf + getpath (lpFilename, 8) + strf(" - 0x%08x\n", lphModule(cnt))
loop
dialog buf
Himさんのスクリプトを分解して調べてるところですが、LINE-19からエラーが出てしまいます
うううう・・
|
|
2012/9/25(Tue) 23:06:40|NO.49571
#uselib "kernel32.dll"
#cfunc OpenProcess "OpenProcess" int, int, int
#uselib "psapi.dll"
#func EnumProcessModules "EnumProcessModules" int, sptr, int, sptr
#func GetModuleFileNameEx "GetModuleFileNameExA" int, int, sptr, int
//使用する変数の型を把握するために定義する癖をつける
dim pid// プロセスID
dim hProcess// プロセスのハンドル
dim lphModule// モジュールハンドルを受け取る配列
dim cb// 配列のサイズ
dim lpcbNeeded// 必要なバイト数
sdim lpFilename, $100// パスを受け取るバッファ
sdim buf// 列挙したモジュール一覧用
pid = 5356//調べたいプロセスのPID
hProcess = OpenProcess(0x400 | 0x0010 | 0x0001, 0,pid)
mes "プロセスハンドル"+hProcess
//モジュールの配列に必要なバイト数を得るためここでは一旦cbは4バイトとする
cb = 4
EnumProcessModules hProcess, varptr(lphModule), cb, varptr(lpcbNeeded)
//モジュールを全て列挙するためには「配列のサイズ = 必要なバイト数」
cb = lpcbNeeded
//配列のサイズが決定したのでlphModuleを再定義する
//配列の個数(モジュールの個数) = 配列のサイズ / 4
dim lphModule, cb / 4
//EnumProcessModules 関数をもう一度呼び出してモジュールハンドルを全て取得
EnumProcessModules hProcess, varptr(lphModule), cb, varptr(lpcbNeeded)
//モジュールの数だけ繰り返して全てのモジュールを列挙する
repeat length (lphModule)
GetModuleFileNameEx hProcess, lphModule(cnt), varptr(lpFilename), $100
buf + getpath (lpFilename, 8) + strf(" - 0x%08x\n", lphModule(cnt))
loop
dialog buf
| |
|
2012/9/25(Tue) 23:58:19|NO.49574
Himさん>
非常にわかりやすい説明ありがとうございます。
「使用する変数の型を把握するために定義する癖をつける」
など、今までなんでいちいちdim定義してたんだろうーっていう疑問も解決して
さらにスッキリしました。
また、質問の回答者様が、Himさんでよかったです本当にありがとうございました!
|
|