WindowsはファイルマッピングAPIを介して共有メモリをサポートしていますが、 MapViewOfFileExはプロセス引数を受け取らないため、共有メモリマッピングを別のプロセスに直接簡単に挿入することはできません。
ただし、 VirtualAllocExとWriteProcessMemoryを使用して別のプロセスにメモリを割り当てることにより、一部のデータを挿入できます。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回だけ交換する必要がある場合に適しています。共有メモリセグメントのサイズは、作成後に簡単に変更できないことに注意してください。
- 名前付きパイプを使用します。スタブは、パイプの名前またはハンドルを取得します。次に、適切なプロトコルを使用して、可変サイズのブロックを交換できます。たとえば、長さの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...
固定名を使用することもできますが、これはおそらくもっと簡単です。