GNU/Linux >> Belajar Linux >  >> Linux

Membaca memori proses langsung tanpa mengganggunya

Sejak versi 3.2 dari kernel. Anda dapat menggunakan panggilan sistem process_vm_readv untuk membaca memori proses tanpa gangguan.

ssize_t process_vm_readv(pid_t pid,
                                const struct iovec *local_iov,
                                unsigned long liovcnt,
                                const struct iovec *remote_iov,
                                unsigned long riovcnt,
                                unsigned long flags);

Panggilan sistem ini mentransfer data antara ruang alamat dari proses pemanggilan ("proses lokal") dan proses yang diidentifikasi oleh pid ("proses jarak jauh"). Data bergerak langsung antara ruang alamat dari dua proses, tanpa melewati ruang kernel.


Untuk proses 1234 Anda bisa mendapatkan peta memorinya dengan membaca /proc/1234/maps secara berurutan (file pseudo-tekstual) dan membaca memori virtual dengan mis. baca(2)-ing atau mmap(2)-ing segmen yang sesuai dari /proc/1234/mem file pseudo-sparse.

Namun, saya yakin Anda tidak dapat menghindari semacam sinkronisasi (mungkin dengan ptrace(2), seperti gdb tidak), karena proses 1234 dapat (dan memang) mengubah ruang alamatnya kapan saja (dengan mmap &syscall terkait).

Situasinya berbeda jika proses yang dipantau 1234 tidak sewenang-wenang, tetapi jika Anda dapat memperbaikinya untuk berkomunikasi entah bagaimana dengan proses pemantauan.

Saya tidak yakin untuk mengerti mengapa Anda menanyakan hal ini. Dan gdb dapat watch beberapa lokasi tanpa menghentikan proses.


Jika Anda memiliki akses root dan menggunakan sistem linux, Anda dapat menggunakan skrip linux berikut (diadaptasi dari jawaban unix.stackexchange.com yang sangat baik dari Gilles dan jawaban awalnya diberikan dalam pertanyaan di atas tetapi termasuk SyntaxErrors dan bukan pythonic):

#!/usr/bin/env python

import re
import sys

def print_memory_of_pid(pid, only_writable=True):
    """ 
    Run as root, take an integer PID and return the contents of memory to STDOUT
    """
    memory_permissions = 'rw' if only_writable else 'r-'
    sys.stderr.write("PID = %d" % pid)
    with open("/proc/%d/maps" % pid, 'r') as maps_file:
        with open("/proc/%d/mem" % pid, 'r', 0) as mem_file:
            for line in maps_file.readlines():  # for each mapped region
                m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r][-w])', line)
                if m.group(3) == memory_permissions: 
                    sys.stderr.write("\nOK : \n" + line+"\n")
                    start = int(m.group(1), 16)
                    if start > 0xFFFFFFFFFFFF:
                        continue
                    end = int(m.group(2), 16)
                    sys.stderr.write( "start = " + str(start) + "\n")
                    mem_file.seek(start)  # seek to region start
                    chunk = mem_file.read(end - start)  # read region contents
                    print chunk,  # dump contents to standard output
                else:
                    sys.stderr.write("\nPASS : \n" + line+"\n")

if __name__ == '__main__': # Execute this code when run from the commandline.
    try:
        assert len(sys.argv) == 2, "Provide exactly 1 PID (process ID)"
        pid = int(sys.argv[1])
        print_memory_of_pid(pid)
    except (AssertionError, ValueError) as e:
        print "Please provide 1 PID as a commandline argument."
        print "You entered: %s" % ' '.join(sys.argv)
        raise e

Jika Anda menyimpan ini sebagai write_mem.py, Anda dapat menjalankan ini (dengan python2.6 atau 2.7) atau di awal python2.5 (jika Anda menambahkan from __future__ import with_statement ) sebagai:

sudo python write_mem.py 1234 > pid1234_memory_dump

untuk membuang memori pid1234 ke file pid1234_memory_dump.


Linux
  1. Membangun wadah dengan tangan:Ruang nama PID

  2. Linux – Batasi Penggunaan Memori Untuk Proses Linux Tunggal?

  3. Tidak Dapat Membunuh Proses Gedit Dari Pidnya?

  1. Linux – Mendapatkan Informasi Tentang Penggunaan Memori Proses Dari /proc/pid/smaps?

  2. Proses Yang Memiliki Pid 0?

  3. Bagaimana Mengidentifikasi Proses Yang Tidak Memiliki Pid?

  1. Mendefinisikan variabel dengan atau tanpa ekspor

  2. Penggunaan memori dari proses saat ini di C

  3. -bash:fork:Tidak dapat mengalokasikan memori