3

したがって、私がやりたいのは、別のプロセスの仮想メモリ内の既知のメモリアドレスからいくつかの値を読み取るRubyプログラムを作成することだけです。メモリ内で実行中のプロセスのx86アセンブリを16進数で編集するという私の調査と基本的な知識を通じて、必要なメモリ内の値のベースアドレスとオフセットを見つけました。私はそれらを変更したくありません。読みたいだけです。私は、メモリエディタの開発者に、この言語の要約にアプローチし、Windowsプラットフォームを想定する方法を尋ねました。彼は、OpenProcess、CreateProcess、ReadProcessMemory、およびWriteProcessMemoryのWin32API呼び出しが、CまたはC++のいずれかを使用する方法であると私に言いました。Win32APIクラスを使用し、その2つのインスタンスをマッピングするだけでよいと思います。ユーザーがすでにプロセスを実行しているかどうかに応じて、OpenProcessまたはCreateProcessのいずれかに1つ。別のインスタンスがReadProcessMemoryにマップされます。実行中のプロセスのリストを取得するための関数を見つける必要があるので、すでに実行中の場合、どの実行中のプロセスが必要かがわかります。

これをすべてまとめるには多少の作業が必要ですが、コーディングするのにそれほど悪くはないと思います。私は高水準言語(とにかくCよりも高水準)からこの低水準で作業したことがないので、これは私にとってプログラミングの新しい領域にすぎません。私はこれにアプローチする方法を考えています。たくさんのWin32API呼び出しを使用することもできますが、それは、システムに依存する一連の文字列と配列のパックとアンパックを処理する必要があることを意味します。私が読んでいるプロセスは複数のプラットフォームビルドを持つ実行可能ファイル(メモリアドレスがシステムごとに変わることはわかっています。Rubyプログラムが現在のプラットフォーム環境を一致するメモリマッピングに一致させることができるように、すべてのメモリマッピングを含むフラットファイルを作成するというアイデアです。

私が知っている限りでは、私が見つけていないこれらすべてを処理するRubygemがすでに存在している可能性があります。また、ビルドごとに実行可能ファイルを編集して、読み取りたいメモリ値がプロセスによって書き込まれるたびに、新しい値のコピーを共有メモリ内のスペースに書き込むようにすることもできます。 Rubyは、その共有メモリアドレスへの内部ポインタであるクラスのインスタンスを作成し、値が更新されて再ロードする必要があることをRubyプログラムに何らかの形で通知します。基本的には割り込みベースのシステムがいいのですが、これらの値を読み取る目的は中央サーバーからブロードキャストされたスコアボードに送信することだけなので、一定の時間間隔で更新を送信するポーリングベースのシステムに固執することができます。また、Rubyを完全に放棄して、CまたはC ++に移行することもできますが、それらについてはほとんどわかりません。私は実際にはC++よりも多くのx86を知っており、システムに依存しないANSI CまではCしか知らず、これまで共有システムライブラリを扱ったことがありません。

それで、すでにこれを行っている宝石またはあまり知られていないモジュールが利用可能ですか?そうでない場合は、これを実現する方法に関する追加情報があれば便利です。簡単に言えば、これをすべて行うにはどうすればよいでしょうか。

よろしくお願いします、Grg

PS:また、これらのWin32API呼び出しがkernel32.dllライブラリを対象とする必要があることを確認するとよいでしょう。

4

2 に答える 2

2

Ruby-FFIを使用します。

CとWin32APIを知っている場合は、Ruby-FFIgemを使用する方が簡単な場合があります。 Ruby-FFIC関数を透過的にラップし、任意のWin32関数を使用できるようにします。

名前付き共有メモリの場合、Win32はとを提供CreateFileMapping( )MapViewOfFile( )ます。

これらにはヘッダーがあります

# WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,DWORD,DWORD,LPCSTR);
# WINBASEAPI PVOID WINAPI MapViewOfFile(HANDLE,DWORD,DWORD,DWORD,DWORD);

に無効なファイルハンドルを渡すことで、ファイルの処理0xFFFFFFFFCreateFileMappingまったく回避し、配列とポインタを使用して共有メモリを定義するだけで済みます。

以下は、共有メモリから読み取る簡単な例です。(本番品質バージョンでは、リーダーとライターのセマフォと循環バッファーを使用して、リーダーがバッファーの読み取りを終了するまでライターがバッファーを上書きしないようにしながら、両方のプロセスを非同期で続行できるようにします。)

簡略化されたRubyの例:

require 'ffi'

module Win32
   extend FFI::Library
   ffi_lib 'kernel32'  # see winbase.h
   attach_function :CreateFileMapping, 
            :CreateFileMappingA,[ :uint, :pointer, :long, :long, :long, :pointer ], :pointer   
            # suffix A indicates the ASCII version
   attach_function :MapViewOfFile, 
            :MapViewOfFile,[ :pointer, :long, :long, :long, :long ], :pointer  
end

memoryName = "Share Memory Name"
sz_buf = 1000  # bytes  (250 ints, 4 bytes each)
num_ints = sz_buf / 4

# Windows constants
PAGE_READWRITE = 0x0004
FILE_MAP_WRITE = 2

# Get handle to shared memory
hMemory = Win32.CreateFileMapping(0xFFFFFFFF, nil, PAGE_READWRITE, 0, sz_buf, memoryName)

# Create pointer into shared memory in the reader's memory space 
pMemory = FFI::MemoryPointer.new(:int, num_ints )
pMemory = Win32.MapViewOfFile(hMemory, FILE_MAP_WRITE, 0, 0, sz_buf)

# Read from shared memory buffer
puts pMemory.read_array_of_int(sz_buf).join(" ")  

いくつかの有用な情報:

于 2013-01-20T17:45:06.733 に答える
2

win32utilsを見てください。私はそれが少なくともあなたを立ち上がらせるべきだと思っています、そして宝石自体があなたのために機能しない場合にAPI自体を掘り下げる方法の例をあなたに与えるでしょう。弾丸を噛んでCでモジュールを書く必要があるかもしれません。

于 2010-05-15T01:16:37.870 に答える