0

別のプロセスが所有する Win32 ListView のデータを読み込もうとしています。残念ながら、私の WriteProcessMemory() 呼び出しは、「この関数はこのシステムではサポートされていません」というエラーで失敗します。VirtualAlloc() 呼び出しでベース アドレスに「NULL」を指定した場合。ただし、その VirtualAlloc() アドレスを、幸運にもフラストレーションの瞬間にランダムに選択した「魔法の」値でオフセットすると、呼び出しはシステムで機能しますが、他のシステムでは失敗します。(以下のコードを参照)

この魔法のオフセットが私のために何をしているのか、誰か提案できますか? 試行錯誤により、特定のシステムで機能する値を見つけることができますが、この問題の一般的な解決策は見つかりません。

ありがとう、ポールH

#define MAGIC_OFFSET (DWORD)0x01020000

LVHITTESTINFO hti   = { 0 };
hti.pt              = clientPoint;

LPVOID lpBuffer = ::VirtualAlloc( NULL, 1, MEM_RESERVE, PAGE_READWRITE );
::VirtualFree( lpBuffer, 0, MEM_RELEASE );

lpBuffer = ::VirtualAlloc( (LPVOID)((DWORD)lpBuffer + MAGIC_OFFSET), sizeof( hti ), MEM_RESERVER, PAGE_READWRITE );
DWORD dwBuffer = (DWORD)lpBuffer + MAGIC_OFFSET - sizeof( hti );

if( !::WriteProcessMemory( hProcess, (LPVOID)dwBuffer, (LPVOID)&hti, sizeof( hti ), NULL ) )
    return 0;

if( ListView_HitTest( hWndListView, (LPVOID)dwBuffer ) < 0 )
    return 0;

if( !::ReadProcessMemory( hProcess, (LPVOID)dwBuffer, (LPVOID)&hti, sizeof( hti ), NULL ) )
    return 0;

::VirtualFree( lpBuffer, 0, MEM_RELEASE );

明確化 (Cd-MaN によって追加): これは Windows Mobile プラットフォーム上にあり、おそらく非 x86 アーキテクチャです。したがって、状況は異なる可能性があります (ARM プロセッサには個別のアドレス空間がありますか?)。

4

3 に答える 3

3

別のプロセスにメモリを割り当てようとする代わりに、代わりに名前付き共有メモリを使用してみませんか。この記事では、共有メモリの基本的なセットアップについて説明します。これらの機能がWindows Mobile 5でサポートされていることを簡単に確認しました。

于 2008-11-11T18:53:42.493 に答える
2

VirtualAlloc は、あなたのアドレス空間にメモリを割り当てます。別のプロセスのメモリ空間を書き込むときにそのアドレスを使用することは絶対に無効です。代わりに VirtualAllocEx を使用し、 hProcessを渡す必要があります。

それが機能するとき、あなたはただ運が良くて、ランダムな記憶の一部を走り書きしているだけです.

VirtualAllocEx の最初のパラメーターに NULL を指定して、別のプロセスをクエリするときにサポートされていない場合 (それがサポートされているかどうかはわかりません) ... VirtualQueryExを使用して、他のプロセスのアドレス空間をマップし、 VirtualAlloc に渡す有効な空き領域を見つけます。

空の場所を探している間に他のプロセスのアドレス空間の状態が変化する可能性があるため、これを再試行ループに入れなければならない可能性があります。

于 2008-11-11T15:06:48.720 に答える
0

プログラムの仮想アドレス空間に書き込んでいることを覚えておく必要があります。Windows では、多くの場合、マジック ナンバーのようなアドレスから始まります。

プログラムをデバッグしたことがありますか? アドレスはどのように見えますか?

私のシステムでは、実行可能ファイルは通常 00400000 または 01000000 あたりにロードされます。これは実行可能ファイルから実行可能ファイルに変わります。Windows には、同じ実行可能ファイルを連続して実行した場合でも、このアドレスを変更する機能があると思います。

さらに、実行可能ファイルには、独自の (そして比較的小さい) オフセットを持つセクションがあります。たとえば、コード セクションは通常 +1000 前後で、次にデータ、ゼロ化されたデータ セクションなどが続きます。

つまり、実行可能ファイルのベースが 00400000 で、そのデータ セクションのオフセットが +2000 の場合、データの最初のバイトは 00402000 になります。このバイトを読み書きするには、次のように指定する必要があります。ベース アドレスは 00402000 であり、2000 ではなく、0 でもありません。

ポインターの値を出力してみてください。指しているオブジェクトの有効期間が静的である場合、おそらくデータ セクションに存在し、00402000 のようなアドレスを取得します。次に、WriteProcessMemory をそのアドレスに書き込むと、オブジェクトが変更されたことになります。

さまざまな Win32 実行可能形式にはすべて、この「0040000」ベース アドレスとさまざまなセクションのオフセットが含まれていますが、別のプロセスのメモリを読み取るこのようなハックは、おそらく特定の実行可能ファイルの特定のバージョンを対象としているため、より良いかもしれません。マジックナンバーをそのままにしておきます。

于 2008-11-11T15:23:46.377 に答える