タイトルそのままですが、メモリ内の指定のアドレスの値を読むには
どのようにしたらいいのでしょうか?
一応、読む方法を自分で調べてみたのですが、コーディング仕方がわかりません・・・
まず、FindWindowでそのメモリを扱っているウインドウハンドルを調べ、
CreateFileMappingで、ファイルマッピングオブジェクトを作成する。
MapViewOfFileで、作成したファイルマッピングオブジェクトをメモリ上にマップし、読み書きを行う。
UnmapViewOfFile、CloseHandleで、共有メモリを開放する。
そもそも、この方法で合ってるのでしょうか?
だいたいあっていますが、FindWindowする必要はないと思います。
別々のプロセスでも、同じマッピングオブジェクトの名前を指定すればよいので。
http://forum.nifty.com/fdelphi/samples/index.htm
こちらに、共有メモリのサンプルがありました。
Halbow です。
質問を読んだ限りでは、違うプロセスの保持しているなんらかのメモリの内容を
読み込みたいのですよね? 同じプロセスだったら、ただ Move() するだけです
から簡単です。
仮想メモリ空間はプロセスごとに定義されているので、違うプロセスから直接
アドレスのメモリの内容を読み込むことはできません。ですから、ファイル
マッピングオブジェクトのような、どちらからも読み書きできるようなものを
使わなければなりません。そこで疑問なんですが、読み込むほうはプログラム
可能だとして、読み込まれるほうはプログラム可能なんでしょうか。つまり、
なんらかのメッセージなりを受け取って、自主的にファイルマッピングオブ
ジェクトに書き込みことができますか、ということです。これができないと、
NT/2000/XP では ファイルマッピングオブジェクトは使えません。
にしのさん、Hallbowさん、お早い返答ありがとうございます。
>だいたいあっていますが、FindWindowする必要はないと思います。
まさにその通りですね。
MapViewOfFileで使用するハンドルを、ウインドウのハンドルと勘違いしていました。
このハンドルは、ファイルマッピングオブジェクトのハンドルですね^^;
>そこで疑問なんですが、読み込むほうはプログラム可能だとして、
>読み込まれるほうはプログラム可能なんでしょうか。
読み込まれるほうは、全く別の人が作ったプログラムです。
やはり、この方法では無理でしょうか・・・?
プロセスメモリエディタのようなものでしょうか。
たぶん、
CreateToolhelp32Snapshotでプロセス一覧を取得。
Process32First, Process32Nextなどでプロセスを選択。
CreateToolhelp32Snapshotで特定のプロセスのヒープ一覧を取得。
Heap32First, Heap32Nextなどでヒープのハンドルを選択
・・・という感じになるかと思います。
# 未確認です
Halbow です。
> 読み込まれるほうは、全く別の人が作ったプログラムです。
いや、だれがつくったかが重要なのではなくて、そのプログラムでは、わたされた
ハンドルがファイルマッピングオブジェクトであることをしっていて、そして
そちら側でも MapViewOfFile を実行するかどうかが重要です。NT/2000/XP では
アドレスを渡しても無意味であり、ちゃんと読み込まれる方が自主的に
MapViewOfFile を実行して書き込むことが必要です。いっぽう、9X系では、
アドレスだけを渡しても書き込むことができます。
> やはり、この方法では無理でしょうか・・・?
何をなさりたいのか具体的に分からないので答えようがありませんです。
にしのさん、Hallbowさん、どうもありがとうございます。
>プロセスメモリエディタのようなものでしょうか。
まさにそれです。名前がわかりませんでした。
>CreateToolhelp32Snapshotでプロセス一覧を取得。
>Process32First, Process32Nextなどでプロセスを選択。
>CreateToolhelp32Snapshotで特定のプロセスのヒープ一覧を取得。
>Heap32First, Heap32Nextなどでヒープのハンドルを選択
この方法で試してみます。
あと、ファイルマッピングオブジェクトを利用する方法では、
Hallbowさんがおっしゃる通り無理ですね・・・
>何をなさりたいのか具体的に分からないので答えようがありませんです。
自分でもしたい事がよく判っていないのに、他人に教えてくれと言っても無理ですね。
失礼しました。
やろうとしていることは、プロセスメモリエディタのような物ですが、
汎用性は無く、特定のプロセスの特定のアドレスのみ変更する
というものです。(表現が変かもしれません)
Halbow です。
> やろうとしていることは、プロセスメモリエディタのような物ですが、
> 汎用性は無く、特定のプロセスの特定のアドレスのみ変更する
> というものです。(表現が変かもしれません)
「プロセスメモリエディタ」ってどのようなものか知りませんが、その
「特定のプロセスの特定のアドレス」をどうやって知ることができるのか
教えていただけないでしょうか。強力なウィルスを作れそうです。(笑)
おおよそのところだけでも・・・・。よろしくお願い致します。
調べてみました。
まだコーディングは全く行っていないので、これで動作するか確認してみます。
CreateProcessで起動時に対象プロセスのプロセスIDを取得するか、
CreateToolhelp32Snapshot、Process32First、Process32Nextを利用して、
対象プロセスのプロセスIDを取得。
プロセスIDを元に、OpenProcessにPROCESS_ALL_ACCESSを渡してプロセスハンドルを取得。
ReadProcessMemoryでメモリの読み込み、WriteProcessMemoryでメモリの書き込む。
終了時に、プロセスハンドルを開放する。
ネット上で見つけたのもの組み合わせなので、間違いがあるかもしれません。
これで組んでみようと思いますが、完成はいつになるのやら・・・
>強力なウィルスを作れそうです。(笑)
重要なシステムプロセスは、外部からの書き換えが出来ないようになってるんじゃないでしょうか?
タスクマネージャでも終了できませんし。
試してないのでわかりませんが^^;
Halbow です。
回答、ありがとうございます。
> 対象プロセスのプロセスIDを取得。
GetWindowThreadProcessId() でウィンドウハンドルから簡単に得られます。
> ReadProcessMemoryでメモリの読み込み、WriteProcessMemoryでメモリの書き込む。
ReadProcessMemory はわたしも使ったことがあります。
http://130.158.124.192/~takeuchi/delphi/browse.cgi?index=066648
何かの参考になるかも知れません。
書き込みのサンプルです。
http://www.overs.jp/software/download/delphi/EditGroup.lzh
ちゃちゃっと作ったので問題ありかもしれません。何となく、PCの調子が悪くなった気もしますし^^;
# DelphiやらVBやらブラウザやらを立ち上げすぎというのが原因かもしれませんが
Test.exeと、EditTest.exeを起動して、念のためTest.exeのButton2を押して書き換える文字列のアドレスを確認します。
Button1を押し、表示される文字列を確認してから、以下の通り実行してみてください。
EditTest.exeのProcess Listボタンでプロセス一覧を取得し、書き換えボタンを押した後、再度Test.exeのButton1を押します。
変わりましたでしょうか。
WindowsXP Proの環境でテストしました。
プロセス一覧は、EnumProcessesというものがありました。
ProcessIdのみであれば、こっちの方が簡単です^^;
Halbowさん、にしのさん、どうもありがとうございます。
>GetWindowThreadProcessId() でウィンドウハンドルから簡単に得られます。
こんなAPIもあったんですね。
私のAPIの無知さが良く感じられます。。。
もっと勉強しないといけないですね^^;
>書き込みのサンプルです。
w2k proでも、文字列が変わりました。
Halbowさん、にしのさん、
お忙しい中、何度も適切なアドバイスしていただき、どうも有難うございました。
サンプルのソースも頂けましたので、参考にしてみます。
ツイート | ![]() |