148 lines
4.4 KiB
Python
Executable File

# Volatility
# Copyright (C) 2007 Volatile Systems
#
# Original Source:
# Copyright (C) 2004,2005,2006 4tphi Research
# Author: {npetroni,awalters}@4tphi.net (Nick Petroni and AAron Walters)
#
# This program 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.
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
@author: AAron Walters
@license: GNU General Public License 2.0 or later
@contact: awalters@volatilesystems.com
@organization: Volatile Systems
Alias for all address spaces
"""
# pylint: disable=missing-docstring
import os
import struct
class FileAddressSpace:
def __init__(self, fname, mode='rb', fast=False):
self.fname = fname
self.name = fname
self.fhandle = open(fname, mode)
self.fsize = os.path.getsize(fname)
if fast:
self.fast_fhandle = open(fname, mode)
def fread(self, len):
return self.fast_fhandle.read(len)
def read(self, addr, len):
self.fhandle.seek(addr)
return self.fhandle.read(len)
def read_long(self, addr):
string = self.read(addr, 4)
(longval,) = struct.unpack('L', string)
return longval
def get_address_range(self):
return [0, self.fsize - 1]
def get_available_addresses(self):
return [self.get_address_range()]
def is_valid_address(self, addr):
return addr < self.fsize - 1
def close(self):
self.fhandle.close()
# Code below written by Brendan Dolan-Gavitt
BLOCK_SIZE = 0x1000
class HiveFileAddressSpace:
def __init__(self, fname):
self.fname = fname
self.base = FileAddressSpace(fname)
def vtop(self, vaddr):
return vaddr + BLOCK_SIZE + 4
def read(self, vaddr, length, zero=False):
first_block = BLOCK_SIZE - vaddr % BLOCK_SIZE
full_blocks = ((length + (vaddr % BLOCK_SIZE)) // BLOCK_SIZE) - 1
left_over = (length + vaddr) % BLOCK_SIZE
paddr = self.vtop(vaddr)
if paddr is None and zero:
if length < first_block:
return "\0" * length
else:
stuff_read = "\0" * first_block
elif paddr is None:
return None
else:
if length < first_block:
stuff_read = self.base.read(paddr, length)
if not stuff_read and zero:
return "\0" * length
else:
return stuff_read
stuff_read = self.base.read(paddr, first_block)
if not stuff_read and zero:
stuff_read = "\0" * first_block
new_vaddr = vaddr + first_block
for __ in range(0, full_blocks):
paddr = self.vtop(new_vaddr)
if paddr is None and zero:
stuff_read = stuff_read + "\0" * BLOCK_SIZE
elif paddr is None:
return None
else:
new_stuff = self.base.read(paddr, BLOCK_SIZE)
if not new_stuff and zero:
new_stuff = "\0" * BLOCK_SIZE
elif not new_stuff:
return None
else:
stuff_read = stuff_read + new_stuff
new_vaddr = new_vaddr + BLOCK_SIZE
if left_over > 0:
paddr = self.vtop(new_vaddr)
if paddr is None and zero:
stuff_read = stuff_read + "\0" * left_over
elif paddr is None:
return None
else:
stuff_read = stuff_read + self.base.read(paddr, left_over)
return stuff_read
def read_long_phys(self, addr):
string = self.base.read(addr, 4)
(longval,) = struct.unpack('L', string)
return longval
def is_valid_address(self, vaddr):
paddr = self.vtop(vaddr)
if not paddr:
return False
return self.base.is_valid_address(paddr)