#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

#############################################################################
##                                                                         ##
## mdosx.py -- Memory Dump for OS X                                        ##
##             See https://security-labs.org/fred                          ##
##             for more informations                                       ##
##                                                                         ##
## Copyright (C) 2008 Fred Raynal  <fred@security-labs.org>                ##
##                                                                         ##
## This program is free software; you can redistribute it and/or modify it ##
## under the terms of the GNU General Public License version 2 as          ##
## published by the Free Software Foundation; version 2.                   ##
##                                                                         ##
## This program is distributed in the hope that it will be useful, but     ##
## WITHOUT ANY WARRANTY; without even the implied warranty of              ##
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       ##
## General Public License for more details.                                ##
##                                                                         ##
#############################################################################

#
# VERSION : 0.1
# DATE : Mon Jun 23 11:13:51 CEST 2008
#

#
# TODO 
#
# - Add an option to start a program within the script
# - Handle those f*****g programs with PTRACE_DENY
#
#


import os
import sys
import re

if len(sys.argv) < 3:
    print "Usage: %s PID patterns*" % sys.argv[0]
    print "  patterns are the name of the regions to dump in the process"
    print
    print "Example: "
    print "  To dump all memory from stack and heaps: \"%s PID stack malloc\"" % sys.argv[0]
    exit(0)
    
pid = sys.argv[1]
reg = sys.argv[2:]

print reg

print "Dumping PID "+pid

f = os.popen("vmmap -w "+pid)
lines = f.readlines()
f.close()

#
# Output format of vmmap -w PID:
# [region] [addr]-[addr] ...
#

gdb = open("dump.gdb", "w")
gdb.write("attach %s\n" % pid)

# Add a simple "anti-anti-ptrace() tip"
# gdb.write("break ptrace\ncommands 1\n  return\n  continue\nend\n\n")

for l in lines:
    #print "[%s]" % l
    for p in reg:
        prg = re.compile(p, flags=re.IGNORECASE)
        res = prg.match(l)
        if res:
            print "found match: "+l
            l = l[len(p):].strip()
            prg = re.compile("[\d,a,b,c,d,e,f]+-[\d,a,b,c,d,e,f]+", flags=re.IGNORECASE)
            res = prg.search(l)
            if not res: 
                continue
            b, e = res.span()
            mem = l[b:e]
            start, end =  mem.split('-')
            f = "%s-%s-%s.raw" % (pid, p.lower(), mem)
            cmd = "dump mem %s 0x%s 0x%s" % (f, start, end)
            gdb.write(cmd+"\n")

gdb.write("quit\n")
gdb.close()

ret = os.system("gdb -q -x dump.gdb")
print "done ! (%d)" % ret


