Linux C++ ptrace Сопоставить все ячейки памяти дочерних процессов

У меня есть связанный список, подобный этому:

class MemoryCell
{
protected:
    unsigned char* _address; // the address offset (in another process)
    unsigned int _size;  // the size of this memory block
    unsigned char* _buffer; // the data

    MemoryCell* _next; // points to next memory cell to form linked list
};

Тогда у меня есть класс MemoryMapper, который будет держать голову. Я хочу получить все ячейки памяти в нем.

// void MemoryMapper::MapAllCells(unsigned int procId)//
unsigned int offset = 0x0;
while (true)
    {
        long memoryData = ptrace(PTRACE_PEEKDATA, procId, offset);
        if (memoryData == -1) break; // need to check for errno(3) too
       // add new MemoryCell w/ data to head of linked list
       // how to get next offset based on what was returned?

он сразу прерывается по адресу 0. Я думал, что для этого процесса он может начинаться с 0x0, но, думаю, мне нужно реальное смещение. Но как я могу получить и следующее смещение (в зависимости от размера предыдущего)?

Надеюсь, это было понятно, но я могу уточнить, если нужно. Спасибо.


person r00t_    schedule 14.04.2012    source источник


Ответы (1)


Вы не можете получить эту информацию от ptrace(); вы можете получить его от /proc/PID/maps для дочернего процесса. Обратите внимание, что адрес 0 обычно не отображается, чтобы поймать ссылки указателя NULL, и может не иметь смысла для PTRACE_PEEKDATA (отдельные I и D в наши дни обычно не используются, и в его отсутствие адрес 0 обычно является текстом, а не данными; мешает ли ядро ​​различать, навскидку не знаю).

person geekosaur    schedule 14.04.2012
comment
интересно. Можете ли вы помочь указать, как понять данные, содержащиеся в файле карт? std::‹map› загромождает поиск - person r00t_; 15.04.2012
comment
Я попытался проверить это на процессе. беззнаковое длинное длинное смещение = 0x7f64e21c3000; Но все равно ломается без чтения? - person r00t_; 15.04.2012
comment
Какая у вас ошибка? Процесс принадлежит вашему uid? Есть ли у вас другой доступ к нему (либо через PTRACE_ATTACH, либо через то, что он является дочерним и вызывает PTRACE_TRACEME)? - person geekosaur; 15.04.2012
comment
да, принадлежит моему uid... пробовал использовать PTRACE_ATTACH заранее, но все равно не работает. Недостаточно сообразителен со страницы руководства, как определить, какую ошибку я получаю. pastebin.com/yF2rfSRw - person r00t_; 15.04.2012
comment
хм, это тоже ошибка при подключении .. errno равно 1. тогда для чтения памяти errno равно 3 - person r00t_; 15.04.2012
comment
Вы должны проверить errno, как и любой другой системный вызов C, как с вызовом PTRACE_ATTACH, так и с вызовом PTRACE_PEEKDATA. Я думаю, что я бы использовал /proc/PID/mem вместо ptrace(), если память (в отличие от регистров или остановки/отслеживания программы) - это все, что вам нужно, между прочим; Кроме того, чтение памяти потенциально совершенно бессмысленно во время работы программы, я подозреваю, что она хочет, чтобы вы остановили процесс, чтобы получить значимый снимок своей памяти. - person geekosaur; 15.04.2012
comment
В конце концов мне нужно будет перезаписать значения, для чего мне, вероятно, понадобится ptrace? Кстати, когда я пытаюсь прочитать /proc/PID/mem с терминала, мне нужно сделать это как суперпользователь, а потом он ничего не выводит? r00t@:/proc/27589$ more mem mem: Отказано в доступе r00t@:/proc/27589$ sudo more mem [sudo] пароль для r00t: r00t@:/proc/27589$ - person r00t_; 15.04.2012
comment
Я думаю, если more mem имеет для вас смысл, то вы еще не до конца проработали то, что пытаетесь сделать. Вы также должны посмотреть, что означают конкретные значения errno. Однако отмечу, что эти неудачи взаимосвязаны. - person geekosaur; 15.04.2012
comment
редактирование памяти — традиционная сложность, с которой я играл только в macroquest2. Я тоже сделал file mem, и он сказал, что он пуст. Я имею в виду, что если это представляет реальную память, я думал, что в ней что-то есть, но я тоже не какой-то сертифицированный инженер RedHat. Также не знаю, что на самом деле означают коды ошибок. Это они? 1. [EIO] Указывает, что параметр запроса не имеет ни одного из перечисленных значений или недействителен для типа машины, на которой выполняется процесс. ..... 3. [EIO] Указывает, что используемый адрес либо выходит за пределы, либо неправильно выровнен. ? - person r00t_; 15.04.2012
comment
хорошо, я прочитал руководство (man 3 errno в Linux) для вас: 1 это EPERM (отказано в доступе). Ни file, ни du не сделают ничего разумного с mem, потому что это не настоящий файл, это адресное пространство процесса, а адрес 0 не отображается (см. начало этого обсуждения); программы, которые ожидают файлы, не знают, что с этим делать. - person geekosaur; 15.04.2012
comment
чувак, это отстой, зачем ему отрицать, что он принадлежит r00t, и я запускаю эту программу как r00t. когда я запускал его как root, я мог прикрепить, но не читать. примечание: добавил вас в твиттер кстати - person r00t_; 15.04.2012
comment
Обычно это связано с безопасностью. Я не знаю конкретных деталей, но вы не должны получать это от /proc/PID/mem, если у вас действительно тот же uid (попробуйте ls -l) и быстрый тест, кажется, работает в системах Linux, которые у меня есть. - person geekosaur; 15.04.2012
comment
-rw------- 1 r00t r00t 0 14.04.2012 18:50 мэм.... так что да, принадлежит мне... не знаю, почему мне нужен настоящий root, чтобы действовать на нем. Кстати, я еще посмотрю ./mem в C++, но можете ли вы сказать мне, могу ли я редактировать в нем значения? Если бы не ptrace, сводящий меня с ума. - person r00t_; 15.04.2012
comment
write() работает (см. man 4 proc); опять же, вам, вероятно, нужно остановить процесс перед записью в его память, если вы хотите что-то вроде согласованности. - person geekosaur; 15.04.2012
comment
чувак, я даже не знаю, я действительно беспокоюсь, потому что я так легко написал раздел Windows этого кода, и теперь я не могу заставить его работать на Linux. собираюсь изучить write() памяти .. btw r00t@:/proc/6741$ man 4 proc Нет ручного ввода для proc в разделе 4.... в любом случае спасибо за помощь заслужил выбранный ответ, который я дал, потому что никто другой не знает что за бред - person r00t_; 15.04.2012