Подтвердить что ты не робот

Чтение памяти другого процесса в OS X?

Я пытался понять, как читать память других процессов в Mac OS X, но мне не очень повезло. Я видел много примеров в Интернете, используя ptrace с PEEKDATA и т.д., Однако он не имеет этой опции в BSD [man ptrace].

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

Как можно читать и записывать в память другого процесса в Mac OS X?

4b9b3361

Ответ 1

Используйте task_for_pid() или другие методы для получения целевого порта целевых процессов. После этого вы можете напрямую манипулировать адресным пространством процессов с помощью vm_read(), vm_write() и других.

Ответ 2

У Matasano Chargen была хорошая публикация после переноса некоторого кода отладки в OS X, который включал изучение того, как читать и писать память в другом процессе (между прочим).

Он должен работать, иначе GDB не будет:

Оказывается, Apple, в своей бесконечной мудрости, потрошена ptrace(). На странице руководства OS X перечислены следующие коды запросов:

  • PT_ATTACH - выбрать процесс для отладки
  • PT_DENY_ATTACH - поэтому процессы могут перестать отлаживаться

    [...]

Не упоминается чтение или запись памяти или регистров. Это было бы обескураживающим, если бы страница руководства не упоминала PT_GETREGS, PT_SETREGS, PT_GETFPREGS и PT_SETFPREGS в разделе кодов ошибок. Итак, я проверил ptrace.h. Там я нашел:

  • PT_READ_I - читать слова инструкции
  • PT_READ_D - читать слова данных
  • PT_READ_U - читать данные области U, если вы достаточно стары, чтобы помнить, что такое область U [...]

Проблема решена. Я могу читать и писать память для контрольных точек. Но я все еще не могу получить доступ к регистрам, и мне нужно иметь возможность взаимодействовать с EIP.

Ответ 3

Вы хотите, чтобы иметь возможность обмениваться кусками памяти между процессами, вы должны проверить shm_open (2) и mmap (2). Очень легко выделить кусок памяти в одном процессе и передать путь (для shm_open) другому, и оба могут сходить вместе с ума. Это намного безопаснее, чем прокручивать в другом адресном пространстве процесса, как упоминает Крис Хэнсон. Конечно, если у вас нет контроля над обоими процессами, это не принесет вам много пользы.

(Помните, что максимальная длина пути для 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()

Ответ 4

Я знаю, что этой теме исполнилось 100 лет, но для людей, приезжающих сюда из поисковой системы:

xnumem делает именно то, что вы ищете, манипулируете и читаете память между процессами.

// Create new xnu_proc instance
xnu_proc *Process = new xnu_proc();

// Attach to pid (or process name)
Process->Attach(getpid());

// Manipulate memory
int i = 1337, i2 = 0;
i2 = process->memory().Read<int>((uintptr_t)&i);

// Detach from process
Process->Detach();

Ответ 5

Я определенно нашел краткую реализацию того, что вам нужно (только один исходный файл (main.c)). Он специально разработан для XNU.

В первой десятке результатов поиска Google находятся следующие ключевые слова "dump process memory os x"

Исходный код здесь

но из строгой точки виртуального адресного пространства точки вы должны быть более заинтересованы в этом вопросе: OS X: Генерировать дамп ядра без снижения процесса? (смотрите также this)

Когда вы смотрите на исходный код gcore, это довольно сложно сделать, поскольку вам нужно иметь дело с протектором и их состоянием...

В большинстве дистрибутивов Linux программа gcore теперь входит в пакет GDB. Я думаю, что версия OSX установлена ​​с помощью xcode/инструментов разработки.

UPDATE: wxHexEditor - это редактор, который может редактировать устройства. IT CAN также может редактировать память процесса так же, как и для обычных файлов. Он работает на всех машинах UNIX.

Ответ 6

В общем, я бы рекомендовал вам использовать обычный open(), чтобы открыть временный файл. Как только он откроется в обоих процессах, вы можете отключить() его от файловой системы, и вы будете настроены так, как если бы вы использовали shm_open. Эта процедура очень похожа на процедуру, определенную Скоттом Марси для shm_open.

Недостатком такого подхода является то, что если процесс, который будет выполнять сбой unlink(), вы получите неиспользуемый файл, и никакой процесс не несет ответственности за его очистку. Этот недостаток делится с shm_open, потому что если ничто не shm_unlinks заданное имя, имя остается в пространстве общей памяти, доступное для shm_opened в будущих процессах.

Ответ 7

Вы хотите выполнить Inter-Process-Communication с использованием метода общей памяти. Сводка другого метода commons см. В здесь

Мне не потребовалось много времени, чтобы найти то, что вам нужно в этом book, который содержит все API, которые являются общими для всех UNIX сегодня (что намного больше, чем я думал). Вы должны купить его в будущем. Эта книга представляет собой набор (несколько сотен) печатных страниц, которые редко устанавливаются на современных машинах. На каждой странице пользователя отображается функция C.

Мне не потребовалось много времени, чтобы найти shmat() shmctl(); shmdt() и shmget(). Я не искал экстенсивно, может быть, там больше.

Это выглядело немного устаревшим, но: ДА, базовый API-интерфейс пользовательского пространства современной ОС UNIX вернулся к старым 80-х.

Обновление: большинство функций, описанных в книге, являются частью заголовков POSIX C, вам не нужно ничего устанавливать. Есть несколько исключений, например, с "проклятиями", исходной библиотекой.

Ответ 8

Манипуляция памятью процесса за его спиной - это плохая вещь и чревата опасностью. Именно поэтому Mac OS X (как и любая система Unix) имеет защищенную память и изолирует процессы друг от друга.

Конечно, это можно сделать: есть средства для обмена памятью между процессами, которые явно сотрудничают. Существуют также способы манипулирования адресными пространствами других процессов, пока процесс, выполняющий это, имеет явное право на это (предоставленное инфраструктурой безопасности). Но это для людей, которые пишут инструменты для отладки. Это не то, что должно быть нормальным или даже редким явлением для подавляющего большинства разработок в Mac OS X.