33

ここで以前に尋ねられた質問に対する答えが見つからなかったため、別のアプローチを試みています。

2 つのプロセス間でメモリを共有する方法はありますか?

2 番目のプロセスは、インジェクションから情報を取得します。これは、サポートされなくなったレガシー プログラムであるためです。

私の考えは、そこにいくつかのコードを挿入することです。挿入されたプログラムに渡す構造体に、実行する必要があるデータが配置されている共有メモリにアドレス (または何でも) を渡します。データを取得したら、注入されたスレッド内に独自の変数を入力します。

これは可能ですか?どのように?

コードは大歓迎です。

編集:

わかりにくいと思いますので補足します。注射の仕方は知っています。私はすでにそれをやっています。ここでの問題は、動的データをインジェクションに渡すことです。

4

7 に答える 7

28

WindowsはファイルマッピングAPIを介して共有メモリをサポートしていますが、 MapViewOfFileExはプロセス引数を受け取らないため、共有メモリマッピングを別のプロセスに直接簡単に挿入することはできません。

ただし、 VirtualAllocExWriteProcessMemoryを使用して別のプロセスにメモリを割り当てることにより、一部のデータを挿入できます。DuplicateHandleを使用してハンドルをコピーし、MapViewOfFileExを呼び出すスタブを挿入する場合は、別のプロセスで共有メモリマッピングを確立できます。とにかくコードを挿入するように聞こえるので、これはうまくいくはずです。

要約すると、次のことを行う必要があります。

  • hFileの場合はINVALID_HANDLE_VALUE、lpNameの場合はNULLを指定してCreateFileMappingを呼び出し、匿名の共有メモリセグメントハンドルを作成します。
  • DuplicateHandleを使用して、このハンドルをターゲットプロセスにコピーします
  • flAllocationType = MEM_COMMIT |を使用して、 VirtualAllocExを使用してコードにメモリを割り当てます。MEM_RESERVEおよびflProtect=PAGE_EXECUTE_READWRITE
  • WriteProcessMemoryを使用して、このメモリにスタブコードを書き込みます。このスタブは、おそらくアセンブラで記述する必要があります。ここのどこかにHANDLEを書き込んで、DuplicateHandleからHANDLEを渡します。
  • CreateRemoteThreadを使用してスタブを実行します。次に、スタブは、取得したHANDLEを使用してMapViewOfFileExを呼び出す必要があります。プロセスには、共通の共有メモリセグメントがあります。

スタブが外部ライブラリをロードする場合、つまり、LoadLibraryを呼び出して(LoadLibraryのアドレスを見つけることは読者の練習問題として残されています)、ライブラリのdllmainエントリポイントから作業を行うと、少し簡単になる場合があります。この場合、名前付き共有メモリの使用は、DuplicateHandleをいじくり回すよりも簡単である可能性があります。詳細については、 CreateFileMappingに関するMSDNの記事を参照してください。ただし、基本的に、hFileにはINVALID_HANDLE_VALUEを渡し、lpNameには名前を渡します。

編集:問題はデータの受け渡しであり、実際のコードインジェクションではないため、ここにいくつかのオプションがあります。

  1. 可変サイズの共有メモリを使用します。スタブは、サイズと、共有メモリの名前またはハンドルのいずれかを取得します。これは、データを1回だけ交換する必要がある場合に適しています。共有メモリセグメントのサイズは、作成後に簡単に変更できないことに注意してください。
  2. 名前付きパイプを使用します。スタブは、パイプの名前またはハンドルを取得します。次に、適切なプロトコルを使用して、可変サイズのブロックを交換できます。たとえば、長さのsize_tを記述し、その後に実際のメッセージを記述します。または、PIPE_TYPE_MESSAGEおよびPIPE_READMODE_MESSAGEを使用し、ERROR_MORE_DATAを監視して、メッセージが終了する場所を判別します。これは、データを複数回交換する必要がある場合に適しています。

編集2:スタブにハンドルまたはポインターストレージを実装する方法のスケッチを次に示します。

.db B8            ;; mov eax, imm32
.dl handle_value  ;; fill this in (located at the start of the image + one byte)
;; handle value is now in eax, do with it as you will
;; more code follows...

固定名を使用することもできますが、これはおそらくもっと簡単です。

于 2009-07-29T15:14:28.557 に答える
16

メモリ マップト ファイルを試すことができます。

これにより、もう少し段階的な詳細が得られます。

于 2009-07-29T15:13:17.810 に答える
4

共有メモリを使用できます

于 2009-07-29T15:16:14.327 に答える
1

パイプ (メモリ用) またはシリアライゼーション (オブジェクト用) を使用しようとしましたか? ファイルを使用して、プロセス間のメモリを管理できます。ソケットは、プロセス間の通信にも適しています。

于 2010-09-01T15:40:54.027 に答える
1

メモリ マッピングはその方法です。永続的なメモリ空間を作成する必要さえありません。共有しているすべてのプロセスがシャットダウンされると、メモリ セクタは範囲外になります。他の方法もあります。ある C アプリから別の C アプリにデータを渡す手っ取り早い方法は、OS を使用することです。コマンド ラインでapp1 | app2. これにより、app2 が app1 の出力先になるか、app1 からの printf コマンドが app2 に送信されます (これをパイピングと呼びます)。

于 2011-09-12T13:11:30.650 に答える
0

Boost.Interprocessを使用して、2つのプロセス間で通信を試みることができます。ただし、サポートされていない既存のソフトウェアにコードを挿入するには、おそらくWriteProcessMemoryを使用した@bdonlanの方法を使用する必要があります

于 2009-07-29T15:30:32.393 に答える
0

Windows について話している場合、主な障害は、各プロセスが独自の仮想アドレス空間に存在することです。残念ながら、プロセス間で通常のメモリ アドレスを渡し、期待する結果を得ることはできません。(一方、スレッドはすべて同じアドレス空間に存在するため、スレッドは同じ方法でメモリを参照できます。)

ただし、Windows には共有メモリ領域があり、正しく管理するには細心の注意を払う必要があります。共有メモリ空間にスペースを割り当てるプロセスは、そのメモリを明示的に解放する責任があります。これは、プロセスが停止すると多かれ少なかれ消えるローカル メモリとは対照的です。

共有メモリ スペースを使用して世界を支配する方法については、この MSDN のサンプル記事を参照してください。ええと、レガシーソフトウェアとのインターフェース。または何でも:)あなたが何をするにしても頑張ってください!

于 2009-07-29T15:21:25.860 に答える