[FR] DUMP MEMORY PROCESSUS WITH PYTHON

Il y a quelques mois de cela, j'ai eu besoin de récupérer des informations d'un processus (sauf que ce con s'était supprimé une fois lancé, vous savez certainement de quoi je parle ^^). Bref seule méthode, récupérer tout ça depuis la mémoire. Il existe plusieurs scripts sur le net, certains fonctionnent et d'autres non. Du coup je vous partage la chose ! :)

Le PID du processus que vous ciblez sera à mettre en argument (si vous mettez rien, ça retournera une erreur au pire). Cela va ensuite générer un fichier ${pid}.dump dans le répertoire courant. Par contre attention, d'une part le fichier ne sera pas trop lisible et d'autre part le fichier peut être volumineux (ça c'est en fonction de votre process). Pour le lire ce sera une autre histoire mais vous aurez déjà pas mal de piste pour continuer vos recherches.

Le script (repris sur le net avec 2/3 modifications pour l'enregistrement du fichier), tourne avec Python 2.x :

#!/usr/bin/env python
 
import ctypes, re, sys
 
c_ptrace = ctypes.CDLL("libc.so.6").ptrace
c_pid_t = ctypes.c_int32
c_ptrace.argtypes = [ctypes.c_int, c_pid_t, ctypes.c_void_p, ctypes.c_void_p]
 
def ptrace(attach, pid):
    op = ctypes.c_int(16 if attach else 17)
    c_pid = c_pid_t(pid)
    null = ctypes.c_void_p()
    err = c_ptrace(op, c_pid, null, null)
    if err != 0: raise Exception, 'ptrace', err
 
if (len(sys.argv) < 2):
    print "%s <pid>" % sys.argv[0]
    sys.exit(-1)
 
pid = sys.argv[1]
ptrace(True, int(pid))

dump_file = open("./%s.dump" % pid, 'w')
maps_file = open("/proc/%s/maps" % pid, 'r')
mem_file = open("/proc/%s/mem" % pid, 'r', 0)

for line in maps_file.readlines():
    m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line)
    if m.group(3) == 'r':
        try:
            start = int(m.group(1), 16)
            end = int(m.group(2), 16)
            mem_file.seek(start)
            chunk = mem_file.read(end - start)
            dump_file.write(chunk)
        except:
            pass
            
maps_file.close()
mem_file.close()
dump_file.close()
ptrace(False, int(pid))

Il fonctionne sous Linux et testé du kernel 2.6 au kernel 3.10. Gardez-le dans un coin, ça peut toujours être utile. 😇

Enjoy!
XorHak