# Volatility # # This file is part of Volatility. # # Volatility is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # Volatility 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. # # You should have received a copy of the GNU General Public License # along with Volatility. If not, see . # import os, sys, shutil import subprocess def run_cmd(args, output_file = None): """Run a command through subprocess. @param args: a list of arguments @param output_file: the process's stdout should be redirected here """ print "Running command: {0}".format(" ".join(args)) if output_file: stdout_handle = open(output_file, "w") else: stdout_handle = subprocess.PIPE p = subprocess.Popen(args, stdout = stdout_handle, stderr = subprocess.STDOUT) p.wait() if output_file: stdout_handle.close() print " Retcode: {0}".format(p.returncode) def generate_profile(temp_dir, volatility_dir, profile_dir, profile): """Generate a profile. @param temp_dir: temporary working directory @param volatility_dir: path to volatility installation @param profile_dir: where to put finished zip profiles @param profile: tuple of information for building the profile """ (full_path, arch, osx_name, version, build) = profile # This lets us mount the DMG without a GUI license Y/N prompt args = ["/usr/bin/hdiutil", "convert", "-quiet", full_path, "-format", "UDTO", "-o", os.path.join(temp_dir, "test")] run_cmd(args) args = ["/usr/bin/hdiutil", "attach", "-quiet", "-nobrowse", "-noverify", "-noautoopen", "-mountpoint", "/Volumes/KernelDebugKit", os.path.join(temp_dir, "test.cdr")] run_cmd(args) dwarf_info = os.path.join(temp_dir, "dwarf.txt") # handle the change in filenames in 10.10 if os.path.isfile("/Volumes/KernelDebugKit/kernel.dSYM"): kernel = "/Volumes/KernelDebugKit/kernel.dSYM" else: kernel = "/Volumes/KernelDebugKit/mach_kernel.dSYM" args = ["/usr/bin/dwarfdump", "-arch", arch, "-i", kernel] run_cmd(args, output_file = dwarf_info) convert_py = os.path.join(volatility_dir, "tools/mac/convert.py") new_dwarf = dwarf_info + ".conv" args = ["/usr/bin/python", convert_py, dwarf_info, new_dwarf] run_cmd(args) vtypes_file = new_dwarf + ".vtypes" args = ["/usr/bin/python", convert_py, new_dwarf] run_cmd(args, output_file = vtypes_file) symbol_file = dwarf_info + ".symbol.dsymutil" # handle the change in filenames in 10.10 if os.path.isfile("/Volumes/KernelDebugKit/mach_kernel"): kernel = "/Volumes/KernelDebugKit/mach_kernel" else: kernel = "/Volumes/KernelDebugKit/kernel" args = ["/usr/bin/dsymutil", "-s", "-arch", arch, kernel] run_cmd(args, output_file = symbol_file) profile_name = osx_name + "_" + version if arch == "i386": profile_name += "_Intel" else: profile_name += "_AMD" profile_name += ".zip" zip_file = os.path.join(profile_dir, profile_name) args = ["/usr/bin/zip", zip_file, symbol_file, vtypes_file] run_cmd(args) args = ["/usr/bin/hdiutil", "detach", "/Volumes/KernelDebugKit"] run_cmd(args) shutil.rmtree(temp_dir) os.mkdir(temp_dir) def main(): if len(sys.argv) != 5: print "Usage: {0} ".format(sys.argv[0]) return profile_runs = [] for kit in os.listdir(sys.argv[1]): try: full_path = os.path.join(sys.argv[1], kit) file_part = os.path.splitext(kit[len("kernel_debug_kit_"):])[0] (version, build) = file_part.split("_") except ValueError: continue if version.startswith("10.5"): osx_name = "Leopard" profile_runs.append((full_path, "i386", osx_name, version, build)) elif version.startswith("10.6"): osx_name = "SnowLeopard" profile_runs.append((full_path, "i386", osx_name, version, build)) profile_runs.append((full_path, "x86_64", osx_name, version, build)) elif version.startswith("10.7"): osx_name = "Lion" profile_runs.append((full_path, "i386", osx_name, version, build)) profile_runs.append((full_path, "x86_64", osx_name, version, build)) elif version.startswith("10.8"): osx_name = "MountainLion" profile_runs.append((full_path, "x86_64", osx_name, version, build)) elif version.startswith("10.9"): osx_name = "Mavericks" profile_runs.append((full_path, "x86_64", osx_name, version, build)) elif version.startswith("10.10"): osx_name = "Yosemite" profile_runs.append((full_path, "x86_64", osx_name, version, build)) for profile in profile_runs: generate_profile(temp_dir = sys.argv[2], volatility_dir = sys.argv[3], profile_dir = sys.argv[4], profile = profile) if __name__ == "__main__": main()