25

Mac OS X で他のプロセスのメモリを読み取る方法を理解しようとしてきましたが、うまくいきません。ptracewithなどを使用してオンラインで多くの例を見てきましたが、BSD [ ]PEEKDATAにはそのオプションがありません。man ptrace

int pid = fork();
if (pid > 0) {
    // mess around with child-process's memory
}

Mac OS X で別のプロセスのメモリを読み書きするにはどうすればよいですか?

4

8 に答える 8

16

または他の方法を使用task_for_pid()して、ターゲットプロセスのタスクポートを取得します。vm_read()その後、、、などを使用してプロセスのアドレス空間を直接操作できますvm_write()

于 2008-09-15T13:48:35.297 に答える
12

Matasano Chargen は、デバッグ コードを OS X に移植することについてしばらく前に良い投稿をしました。これには、別のプロセスでメモリを読み書きする方法の学習が含まれていました。

動作する必要があります。そうしないと、GDB は動作しません:

Apple は、その無限の叡智でptrace(). OS X のマニュアル ページには、次のリクエスト コードがリストされています。

  • PT_ATTACH— デバッグするプロセスを選択する
  • PT_DENY_ATTACH— そのため、プロセスは自分自身のデバッグを停止できます
    [...]

メモリまたはレジスタの読み取りまたは書き込みについては言及されていません。マニュアル ページのエラー コード セクションにPT_GETREGSPT_SETREGSPT_GETFPREGS、およびも記載されていなかったら、これはがっかりしたでしょう。PT_SETFPREGSということで、調べてみptrace.hました。そこで私は見つけました:

  • PT_READ_I— 命令語を読む
  • PT_READ_D— データワードを読み取る
  • PT_READ_U— U 領域が何であるかを覚えるのに十分な年齢であれば、U 領域のデータを読み取る
    [...]

解決した問題が 1 つあります。ブレークポイントのメモリを読み書きできます。しかし、私はまだレジスタにアクセスできず、EIP をいじる必要があります。

于 2008-08-14T04:46:37.850 に答える
6

プロセス間でメモリのチャンクを共有できるようにしたい場合は、shm_open(2) と mmap(2) を調べてください。あるプロセスにメモリのチャンクを割り当てて、(shm_open の) パスを別のプロセスに渡すのは非常に簡単です。これは、Chris Hanson が言及しているように、別のプロセスのアドレス空間をいじるよりもはるかに安全です。もちろん、両方のプロセスを制御できない場合、これはあまり役に立ちません。

(これはどこにも文書化されていないようですが、shm_open の最大パス長は 26 バイトのように見えることに注意してください。)

// Create shared memory block
void* sharedMemory = NULL;
size_t shmemSize = 123456;
const char* shmName = "mySharedMemPath";        
int shFD = shm_open(shmName, (O_CREAT | O_EXCL | O_RDWR), 0600);
if (shFD >= 0) {
    if (ftruncate(shFD, shmemSize) == 0) {
        sharedMemory = mmap(NULL, shmemSize, (PROT_READ | PROT_WRITE), MAP_SHARED, shFD, 0);
        if (sharedMemory != MAP_FAILED) {
            // Initialize shared memory if needed
            // Send 'shmemSize' & 'shmemSize' to other process(es)
        } else handle error
    } else handle error
    close(shFD);        // Note: sharedMemory still valid until munmap() called
} else handle error

...
Do stuff with shared memory
...

// Tear down shared memory
if (sharedMemory != NULL) munmap(sharedMemory, shmemSize);
if (shFD >= 0) shm_unlink(shmName);





// Get the shared memory block from another process
void* sharedMemory = NULL;
size_t shmemSize = 123456;              // Or fetched via some other form of IPC
const char* shmName = "mySharedMemPath";// Or fetched via some other form of IPC
int shFD = shm_open(shmName, (O_RDONLY), 0600); // Can be R/W if you want
if (shFD >= 0) {
    data = mmap(NULL, shmemSize, PROT_READ, MAP_SHARED, shFD, 0);
    if (data != MAP_FAILED) {
        // Check shared memory for validity
    } else handle error
    close(shFD);        // Note: sharedMemory still valid until munmap() called
} else handle error


...
Do stuff with shared memory
...

// Tear down shared memory
if (sharedMemory != NULL) munmap(sharedMemory, shmemSize);
// Only the creator should shm_unlink()
于 2008-09-15T16:08:25.320 に答える
1

プロセスのメモリを背後で操作することは悪いことであり、危険をはらんでいます。そのため、Mac OS X (他の Unix システムと同様) はメモリを保護し、プロセスを互いに隔離しています。

もちろん、それは可能です。明示的に連携するプロセス間でメモリを共有するための機能があります。他のプロセスのアドレス空間を操作する方法もあります (セキュリティ フレームワークによって許可されているように)。しかし、それは、使用するデバッグ ツールを作成している人々のためにあります。これは、Mac OS X での開発の大部分において、通常の、またはまれに発生するものではありません。

于 2008-08-14T09:19:08.283 に答える
1

一般に、通常の open() を使用して一時ファイルを開くことをお勧めします。両方のプロセスで開いたら、ファイルシステムから unlink() できます。これにより、shm_open を使用した場合と同じようにセットアップできます。この手順は、Scott Marcy が shm_open に対して指定した手順と非常によく似ています。

このアプローチの欠点は、unlink() を実行するプロセスがクラッシュした場合、未使用のファイルが残り、それをクリーンアップする責任を負うプロセスがないことです。この欠点は、shm_open と共有されます。これは、指定された名前を shm_unlink するものがない場合、その名前は共有メモリ空間に残り、将来のプロセスで shm_open できるようになるためです。

于 2010-01-19T16:36:48.617 に答える