# Volatility # Copyright (C) 2007-2013 Volatility Foundation # # 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 . # """ @author: Andrew Case @license: GNU General Public License 2.0 @contact: atcuno@gmail.com @organization: """ import struct import volatility.obj as obj import volatility.debug as debug import volatility.addrspace as addrspace import volatility.plugins.mac.common as mac_common import volatility.plugins.mac.pstasks as mac_tasks bash_vtypes = { 'bash32_hist_entry': [ 0xc, { 'line': [0x0, ['pointer', ['String', dict(length = 1024)]]], 'timestamp': [0x4, ['pointer', ['String', dict(length = 1024)]]], 'data': [0x8, ['pointer', ['void']]], }], 'bash64_hist_entry': [ 24, { 'line': [0, ['pointer', ['String', dict(length = 1024)]]], 'timestamp': [8, ['pointer', ['String', dict(length = 1024)]]], 'data': [16, ['pointer', ['void']]], }], } class _mac_hist_entry(obj.CType): """A class for history entries""" def is_valid(self): line_addr = self.line_ptr() time_addr = self.time_ptr() if (not obj.CType.is_valid(self) or not self.obj_vm.is_valid_address(line_addr) or not self.obj_vm.is_valid_address(time_addr)): return False ts = self.obj_vm.read(time_addr, 256) if not ts: return False idx = ts.find("\x00") if idx != -1: ts = ts[:idx] # At this point in time, the epoc integer size will # never be less than 10 characters, and the stamp is # always preceded by a pound/hash character. if len(ts) < 10 or str(ts)[0] != "#": return False # The final check is to make sure the entire string # is composed of numbers. Try to convert to an int. try: int(str(ts)[1:]) except ValueError: return False return True def line(self): line_addr = self.line_ptr() buf = self.obj_vm.read(line_addr, 256) if buf: idx = buf.find("\x00") if idx != -1: buf = buf[:idx] return buf @property def time_as_integer(self): # Get the string and remove the leading "#" from the timestamp time_addr = self.time_ptr() ts = self.obj_vm.read(time_addr, 256) ts = ts[1:] idx = ts.find("\x00") if idx != -1: ts = ts[:idx] # Convert the string into an integer (number of seconds) return int(ts) def time_object(self): nsecs = self.time_as_integer # Build a timestamp object from the integer time_val = struct.pack("