├── volatility ├── contrib │ ├── __init__.py │ ├── plugins │ │ ├── __init__.py │ │ ├── README.md │ │ ├── aspaces │ │ │ └── README.md │ │ ├── malware │ │ │ └── README.md │ │ ├── disablewarnings.py │ │ └── example.py │ └── library_example │ │ ├── libapi.py │ │ └── pslist_json.py ├── volatility │ ├── __init__.py │ ├── win32 │ │ ├── __init__.py │ │ └── modules.py │ ├── plugins │ │ ├── gui │ │ │ ├── __init__.py │ │ │ ├── vtypes │ │ │ │ ├── __init__.py │ │ │ │ └── win2003.py │ │ │ ├── eventhooks.py │ │ │ └── gahti.py │ │ ├── linux │ │ │ ├── __init__.py │ │ │ ├── aslr_shift.py │ │ │ ├── getcwd.py │ │ │ ├── ld_env.py │ │ │ ├── proc_maps_rb.py │ │ │ ├── psenv.py │ │ │ ├── libc_env.py │ │ │ ├── banner.py │ │ │ ├── psaux.py │ │ │ ├── lime.py │ │ │ ├── pslist_cache.py │ │ │ ├── flags.py │ │ │ ├── enumerate_files.py │ │ │ ├── iomem.py │ │ │ ├── lsof.py │ │ │ ├── procdump.py │ │ │ ├── netstat.py │ │ │ ├── library_list.py │ │ │ ├── keyboard_notifiers.py │ │ │ ├── dentry_cache.py │ │ │ ├── ldrmodules.py │ │ │ ├── elfs.py │ │ │ ├── psscan.py │ │ │ ├── vma_cache.py │ │ │ ├── plthook.py │ │ │ ├── tty_check.py │ │ │ ├── sk_buff_cache.py │ │ │ ├── malfind.py │ │ │ ├── check_creds.py │ │ │ └── librarydump.py │ │ ├── mac │ │ │ ├── __init__.py │ │ │ ├── version.py │ │ │ ├── arp.py │ │ │ ├── find_aslr_shift.py │ │ │ ├── dead_procs.py │ │ │ ├── bash_env.py │ │ │ ├── pstasks.py │ │ │ ├── dead_vnodes.py │ │ │ ├── pid_hash_table.py │ │ │ ├── print_boot_cmdline.py │ │ │ ├── machine_info.py │ │ │ ├── pstree.py │ │ │ ├── pgrp_hash_table.py │ │ │ ├── gkextmap.py │ │ │ ├── dmesg.py │ │ │ ├── lsof.py │ │ │ ├── psenv.py │ │ │ ├── dump_files.py │ │ │ ├── mount.py │ │ │ ├── dlyd_maps.py │ │ │ ├── memdump.py │ │ │ ├── malfind.py │ │ │ ├── dead_sockets.py │ │ │ ├── ifconfig.py │ │ │ ├── psaux.py │ │ │ └── proc_maps.py │ │ ├── addrspaces │ │ │ ├── __init__.py │ │ │ └── osxpmemelf.py │ │ ├── malware │ │ │ └── __init__.py │ │ ├── overlays │ │ │ ├── __init__.py │ │ │ ├── linux │ │ │ │ └── __init__.py │ │ │ ├── mac │ │ │ │ └── __init__.py │ │ │ ├── windows │ │ │ │ ├── __init__.py │ │ │ │ ├── xp.py │ │ │ │ └── kpcr_vtypes.py │ │ │ └── native_types.py │ │ ├── registry │ │ │ └── __init__.py │ │ ├── patchguard.py │ │ ├── __init__.py │ │ ├── heaps.py │ │ ├── machoinfo.py │ │ ├── fileparam.py │ │ ├── win10cookie.py │ │ ├── hpakinfo.py │ │ ├── win10smglobals.py │ │ ├── vboxinfo.py │ │ ├── multiscan.py │ │ ├── cmdline.py │ │ └── bioskbd.py │ ├── renderers │ │ ├── basic.py │ │ ├── dot.py │ │ ├── xlsx.py │ │ └── html.py │ ├── constants.py │ ├── validity.py │ ├── exceptions.py │ └── debug.py ├── gifs │ └── Multiple1.gif ├── drivers │ ├── winpmem_32.sys │ ├── winpmem_64.sys │ ├── att_winpmem_32.sys │ ├── att_winpmem_64.sys │ └── README.txt ├── tools │ ├── doxygen │ │ ├── vol.png │ │ └── d3 │ │ │ └── createtree.py │ ├── linux │ │ ├── kcore │ │ │ ├── Makefile │ │ │ └── getkcore.h │ │ ├── Makefile.enterprise │ │ └── Makefile │ └── windows │ │ └── parsesummary.py ├── resources │ ├── volatility.ico │ └── memforensics.ico ├── Makefile ├── PKG-INFO ├── pyinstaller │ ├── hook-yara.py │ ├── hook-openpyxl.py │ ├── hook-service.py │ ├── hook-distorm3.py │ └── hook-volatility.py ├── MANIFEST.in ├── LEGAL.txt ├── AUTHORS.txt ├── pyinstaller.spec └── libapi.py ├── .gitattributes └── .gitignore /volatility/contrib/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /volatility/contrib/plugins/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /volatility/volatility/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /volatility/volatility/win32/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/gui/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.py text eol=lf 3 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/addrspaces/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/gui/vtypes/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/malware/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/overlays/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/registry/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/overlays/linux/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/overlays/mac/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/overlays/windows/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /volatility/gifs/Multiple1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gleeda/memtriage/HEAD/volatility/gifs/Multiple1.gif -------------------------------------------------------------------------------- /volatility/drivers/winpmem_32.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gleeda/memtriage/HEAD/volatility/drivers/winpmem_32.sys -------------------------------------------------------------------------------- /volatility/drivers/winpmem_64.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gleeda/memtriage/HEAD/volatility/drivers/winpmem_64.sys -------------------------------------------------------------------------------- /volatility/tools/doxygen/vol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gleeda/memtriage/HEAD/volatility/tools/doxygen/vol.png -------------------------------------------------------------------------------- /volatility/resources/volatility.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gleeda/memtriage/HEAD/volatility/resources/volatility.ico -------------------------------------------------------------------------------- /volatility/drivers/att_winpmem_32.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gleeda/memtriage/HEAD/volatility/drivers/att_winpmem_32.sys -------------------------------------------------------------------------------- /volatility/drivers/att_winpmem_64.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gleeda/memtriage/HEAD/volatility/drivers/att_winpmem_64.sys -------------------------------------------------------------------------------- /volatility/resources/memforensics.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gleeda/memtriage/HEAD/volatility/resources/memforensics.ico -------------------------------------------------------------------------------- /volatility/contrib/plugins/README.md: -------------------------------------------------------------------------------- 1 | Plugins in this directory have moved. Please see the github.com/volatilityfoundation/community repository. 2 | -------------------------------------------------------------------------------- /volatility/contrib/plugins/aspaces/README.md: -------------------------------------------------------------------------------- 1 | Plugins in this directory have moved. Please see the github.com/volatilityfoundation/community repository. 2 | -------------------------------------------------------------------------------- /volatility/contrib/plugins/malware/README.md: -------------------------------------------------------------------------------- 1 | Plugins in this directory have moved. Please see the github.com/volatilityfoundation/community repository. 2 | -------------------------------------------------------------------------------- /volatility/tools/linux/kcore/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | 3 | all: getkcore 4 | 5 | getkcore: getkcore.c 6 | gcc -o getkcore getkcore.c -Wall -Wextra 7 | 8 | clean: 9 | rm getkcore 10 | -------------------------------------------------------------------------------- /volatility/Makefile: -------------------------------------------------------------------------------- 1 | all: build 2 | 3 | build: 4 | python setup.py build 5 | 6 | install: 7 | python setup.py install 8 | 9 | dist: 10 | python setup.py sdist 11 | 12 | clean: 13 | rm -f `find . -name "*.pyc" -o -name "*~"` 14 | rm -rf dist build 15 | -------------------------------------------------------------------------------- /volatility/drivers/README.txt: -------------------------------------------------------------------------------- 1 | These drivers are part of the Pmem Memory Acquisition Suite: 2 | 3 | Version 2.0rc1 Copyright 2015 Google Inc. All rights reserved. 4 | 5 | Author: Michael Cohen 6 | 7 | https://github.com/Velocidex/c-aff4/tree/master/tools/pmem 8 | -------------------------------------------------------------------------------- /volatility/PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 1.0 2 | Name: Volatility 3 | Version: GC1 4 | Summary: Volatility -- Volatile memory framwork 5 | Home-page: http://www.volatilityfoundation.org 6 | Author: AAron Walters 7 | Author-email: awalters@4tphi.net 8 | License: GPL 9 | Description: UNKNOWN 10 | Platform: UNKNOWN 11 | -------------------------------------------------------------------------------- /volatility/tools/linux/kcore/getkcore.h: -------------------------------------------------------------------------------- 1 | #ifndef _GETKCORE_H 2 | #define _GETKCORE_H 3 | 4 | typedef struct { 5 | unsigned int magic; 6 | unsigned int version; 7 | unsigned long long s_addr; 8 | unsigned long long e_addr; 9 | unsigned char reserved[8]; 10 | } __attribute__ ((__packed__)) lime_range; 11 | 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /volatility/pyinstaller/hook-yara.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | datas = [] 5 | 6 | for path in sys.path: 7 | if os.path.exists(os.path.join(path, "yara.pyd")): 8 | datas.append((os.path.join(path, "yara.pyd"), ".")) 9 | if os.path.exists(os.path.join(path, "yara.so")): 10 | datas.append((os.path.join(path, "yara.so"), ".")) 11 | -------------------------------------------------------------------------------- /volatility/tools/linux/Makefile.enterprise: -------------------------------------------------------------------------------- 1 | obj-m += module.o 2 | KDIR ?= /lib/modules/3.5.0-23-generic/build 3 | 4 | -include version.mk 5 | 6 | all: dwarf 7 | 8 | dwarf: module.c 9 | $(MAKE) -C $(KDIR) CONFIG_DEBUG_INFO=y M="$(PWD)" modules 10 | dwarfdump -di module.ko > module.dwarf 11 | $(MAKE) -C $(KDIR) M="$(PWD)" clean 12 | 13 | clean: 14 | $(MAKE) -C $(KDIR) M="$(PWD)" clean 15 | rm -f module.dwarf 16 | -------------------------------------------------------------------------------- /volatility/MANIFEST.in: -------------------------------------------------------------------------------- 1 | include *.txt 2 | include *.win 3 | include MANIFEST.in 4 | include setup.py 5 | include resources/* 6 | include pyinstaller/*.py 7 | include volatility/*.py 8 | include contrib/plugins/*.py 9 | include contrib/plugins/aspaces/*.py 10 | include tools/*.py 11 | include tools/linux/* 12 | include tools/linux/pmem/* 13 | include tools/mac/*.py 14 | include vol.py 15 | include Makefile 16 | include pyinstaller.spec 17 | -------------------------------------------------------------------------------- /volatility/tools/linux/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += module.o 2 | KDIR ?= / 3 | KVER ?= $(shell uname -r) 4 | 5 | -include version.mk 6 | 7 | all: dwarf 8 | 9 | dwarf: module.c 10 | $(MAKE) -C $(KDIR)/lib/modules/$(KVER)/build CONFIG_DEBUG_INFO=y M="$(PWD)" modules 11 | dwarfdump -di module.ko > module.dwarf 12 | $(MAKE) -C $(KDIR)/lib/modules/$(KVER)/build M="$(PWD)" clean 13 | 14 | clean: 15 | $(MAKE) -C $(KDIR)/lib/modules/$(KVER)/build M="$(PWD)" clean 16 | rm -f module.dwarf 17 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/patchguard.py: -------------------------------------------------------------------------------- 1 | import struct 2 | 3 | def rol(value, count): 4 | """A rotate-left instruction in Python""" 5 | 6 | for y in range(count): 7 | value *= 2 8 | if (value > 0xFFFFFFFFFFFFFFFF): 9 | value -= 0x10000000000000000 10 | value += 1 11 | return value 12 | 13 | def bswap(value): 14 | """A byte-swap instruction in Python""" 15 | 16 | hi, lo = struct.unpack(">II", struct.pack(". 21 | -------------------------------------------------------------------------------- /volatility/pyinstaller/hook-distorm3.py: -------------------------------------------------------------------------------- 1 | # Distorm3 hook 2 | # 3 | # This currently contains the hardcoded location for the standard distorm3.dll install 4 | # It could be improved by carrying out a search, or using sys.path 5 | # 6 | # This also requires the distorm3 module to be modified with the following patch: 7 | 8 | # import sys 9 | # if hasattr(sys, '_MEIPASS'): 10 | # _distorm_path = sys._MEIPASS 11 | 12 | import os 13 | import sys 14 | 15 | datas = [] 16 | 17 | for path in sys.path: 18 | if os.path.exists(os.path.join(path, "distorm3", "distorm3.dll")): 19 | datas.append((os.path.join(path, "distorm3", "distorm3.dll"), ".")) 20 | if os.path.exists(os.path.join(path, "distorm3", "libdistorm3.so")): 21 | datas.append((os.path.join(path, "distorm3", "libdistorm3.so"), ".")) 22 | 23 | -------------------------------------------------------------------------------- /volatility/pyinstaller/hook-volatility.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | 4 | projpath = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 5 | 6 | modules = set(['volatility.plugins']) 7 | 8 | for dirpath, _dirnames, filenames in os.walk(os.path.join(projpath, 'volatility', 'plugins')): 9 | dirpath = dirpath[len(os.path.join(projpath, 'volatility', 'plugins')):] 10 | if dirpath and dirpath[0] == os.path.sep: 11 | dirpath = dirpath[1:] 12 | for filename in filenames: 13 | path = os.path.join(dirpath, os.path.splitext(filename)[0]) 14 | if "/." in path: 15 | continue 16 | if "__" in path: 17 | continue 18 | 19 | path = path.replace("-", "_") 20 | path = path.replace(os.path.sep, ".") 21 | 22 | modules.add("volatility.plugins." + path) 23 | 24 | hiddenimports = list(modules) 25 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/overlays/native_types.py: -------------------------------------------------------------------------------- 1 | import copy 2 | 3 | ## The following is a conversion of basic C99 types to python struct 4 | ## format strings. NOTE: since volatility is analysing images which 5 | ## are not necessarily the same bit size as the currently running 6 | ## platform you may not use platform specific format specifiers here 7 | ## like l or L - you must use i or I. 8 | x86_native_types = { 9 | 'int' : [4, 'H'], 19 | 'short' : [2, ' 42 | Volatile Systems LLC 43 | 44 | Brendan Dolan-Gavitt 45 | 46 | Volatools Basic authors: 47 | ------------ 48 | 49 | AAron Walters 50 | Komoku, Inc. 51 | 52 | Nick L. Petroni, Jr. 53 | Komoku, Inc. 54 | -------------------------------------------------------------------------------- /volatility/tools/doxygen/d3/createtree.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | 4 | ''' 5 | Author: Gleeda 6 | 7 | modified from: 8 | http://stackoverflow.com/questions/25226208/represent-directory-tree-as-json 9 | 10 | Quick and Dirty. Run from the Volatility root directory and redirect: 11 | 12 | python createtree.py > OUTPUT/d3/vol.json 13 | 14 | ''' 15 | 16 | link = "https://github.com/volatilityfoundation/volatility/blob/master/" 17 | ignore = [".git", "doxygen", ".gitignore", ".gitattributes"] 18 | 19 | def path_to_dict(path): 20 | if path == ".": 21 | d = {'name': os.path.basename("root")} 22 | else: 23 | d = {'name': os.path.basename(path)} 24 | d['link'] = str(link + path).replace("/.", "") 25 | if os.path.isdir(path): 26 | d['type'] = "directory" 27 | d['children'] = [path_to_dict(os.path.join(path, x)) for x in os.listdir(path) if x not in ignore] 28 | else: 29 | d['type'] = "file" 30 | return d 31 | 32 | print json.dumps(path_to_dict('.')) 33 | -------------------------------------------------------------------------------- /volatility/volatility/renderers/basic.py: -------------------------------------------------------------------------------- 1 | __author__ = 'mike' 2 | 3 | import volatility.utils as utils 4 | 5 | class Bytes(bytes): 6 | """String class to allow us to encode binary data""" 7 | def __new__(cls, data): 8 | if data == None: 9 | return str.__new__(cls, "-") 10 | return str.__new__(cls, data.encode("hex")) 11 | 12 | class Address(long): 13 | """Integer class to allow renderers to differentiate between addresses and numbers""" 14 | def __new__(cls, number): 15 | return long.__new__(cls, number) 16 | 17 | 18 | class Address64(long): 19 | """Integer class to allow renderers to differentiate between addresses and numbers""" 20 | 21 | def __new__(cls, number): 22 | return long.__new__(cls, number) 23 | 24 | 25 | class Hex(long): 26 | """Integer class to allow renderers to differentiate between addresses and numbers""" 27 | 28 | def __new__(cls, number): 29 | return long.__new__(cls, number) 30 | 31 | 32 | class Renderer(object): 33 | def render(self, outfd, grid): 34 | """Renders the content, ideally to outfd, but this is not strictly necessary""" 35 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/__init__.py: -------------------------------------------------------------------------------- 1 | import volatility.conf as conf 2 | import volatility.constants as constants 3 | import os 4 | import sys 5 | 6 | config = conf.ConfObject() 7 | 8 | help_prefix = "" 9 | plugin_separator = ":" 10 | # Make a platform-dependent decision on plugin path separators 11 | # The separator is now in keeping with the PATH environment variable 12 | if sys.platform.startswith('win'): 13 | help_prefix = "semi-" 14 | plugin_separator = ";" 15 | 16 | 17 | config.add_option("PLUGINS", default = "", 18 | cache_invalidator = False, 19 | help = "Additional plugin directories to use (" + help_prefix + "colon separated)") 20 | 21 | # Add the PLUGINPATH, in case we're frozen 22 | __path__ = [constants.PLUGINPATH] + [ e for e in __path__ if not constants.PLUGINPATH.startswith(e) ] 23 | 24 | # This causes the config.PLUGINS paths to be treated as extensions of the volatility.plugins package 25 | # Meaning that each directory is search for module when import volatility.plugins.module is requested 26 | 27 | if config.PLUGINS: 28 | plugin_paths = [ os.path.abspath(x) for x in config.PLUGINS.split(plugin_separator)] 29 | __path__.extend(plugin_paths) 30 | -------------------------------------------------------------------------------- /volatility/volatility/win32/modules.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: AAron Walters and Nick Petroni 22 | @license: GNU General Public License 2.0 23 | @contact: awalters@4tphi.net, npetroni@4tphi.net 24 | @organization: Volatility Foundation 25 | """ 26 | 27 | #pylint: disable-msg=C0111 28 | import volatility.win32.tasks as tasks 29 | 30 | def lsmod(addr_space): 31 | """ A Generator for modules """ 32 | 33 | for m in tasks.get_kdbg(addr_space).modules(): 34 | yield m 35 | -------------------------------------------------------------------------------- /volatility/volatility/constants.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2008-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | # Blocksize was chosen to make it aligned 21 | # on 8 bytes 22 | # Optimized by Michael Cohen 23 | 24 | import os, sys 25 | 26 | VERSION = "2.6" 27 | 28 | SCAN_BLOCKSIZE = 1024 * 1024 * 10 29 | 30 | PLUGINPATH = os.path.dirname(__file__) 31 | # If we're in a pyinstaller executable 32 | if hasattr(sys, "frozen"): 33 | try: 34 | PLUGINPATH = sys._MEIPASS #pylint: disable-msg=W0212,E1101 35 | except ImportError: 36 | pass 37 | PLUGINPATH = os.path.join(PLUGINPATH, 'plugins') 38 | -------------------------------------------------------------------------------- /volatility/contrib/plugins/disablewarnings.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # 3 | # Authors: 4 | # Mike Auty 5 | # 6 | # This file is part of Volatility. 7 | # 8 | # Volatility is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # Volatility is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Volatility. If not, see . 20 | # 21 | 22 | import volatility.conf as conf 23 | import logging 24 | 25 | config = conf.ConfObject() 26 | 27 | def disable_warnings(_option, _opt_str, _value, _parser): 28 | """Sets the location variable in the parser to the filename in question""" 29 | rootlogger = logging.getLogger('') 30 | rootlogger.setLevel(logging.WARNING + 1) 31 | 32 | config.add_option("WARNINGS", default = False, action = "callback", 33 | callback = disable_warnings, 34 | short_option = 'W', nargs = 0, 35 | help = "Disable warning messages") 36 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/heaps.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 2 of the License, or (at 6 | # your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program; if not, write to the Free Software 15 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 16 | 17 | import volatility.obj as obj 18 | 19 | #-------------------------------------------------------------------------------- 20 | # profile modifications 21 | #-------------------------------------------------------------------------------- 22 | 23 | class HeapModification(obj.ProfileModification): 24 | 25 | before = ["WindowsObjectClasses"] 26 | conditions = {'os': lambda x: x == 'windows'} 27 | 28 | def modification(self, profile): 29 | profile.merge_overlay({ 30 | '_PEB': [ None, { 31 | 'ProcessHeaps': [ None, ['pointer', ['array', lambda x : x.NumberOfHeaps, ['pointer', ['_HEAP']]]]], 32 | }], 33 | }) 34 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/version.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.mac.common as common 29 | 30 | class mac_version(common.AbstractMacCommand): 31 | """ Prints the Mac version """ 32 | 33 | def calculate(self): 34 | common.set_plugin_members(self) 35 | yield obj.Object("String", offset = self.addr_space.profile.get_symbol("_version"), vm = self.addr_space, length = 256) 36 | 37 | def render_text(self, outfd, data): 38 | for version in data: 39 | outfd.write("{0}\n".format(version)) 40 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/aslr_shift.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # 3 | # This file is part of Volatility. 4 | # 5 | # Volatility is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # Volatility is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with Volatility. If not, see . 17 | # 18 | 19 | """ 20 | @author: Andrew Case 21 | @license: GNU General Public License 2.0 22 | @contact: atcuno@gmail.com 23 | @organization: 24 | """ 25 | 26 | import volatility.utils as utils 27 | import volatility.plugins.linux.common as common 28 | 29 | class linux_aslr_shift(common.AbstractLinuxCommand): 30 | """Automatically detect the Linux ASLR shift""" 31 | 32 | def calculate(self): 33 | aspace = utils.load_as(self._config) 34 | 35 | yield aspace.profile.virtual_shift, aspace.profile.physical_shift 36 | 37 | def render_text(self, outfd, data): 38 | self.table_header(outfd, [("Virtual Shift Address", "[addrpad]"), ("Physical Shift Address", "[addrpad]")]) 39 | 40 | for v, p in data: 41 | self.table_row(outfd, v, p) 42 | 43 | 44 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/getcwd.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.linux.common as linux_common 29 | import volatility.plugins.linux.pslist as linux_pslist 30 | 31 | class linux_getcwd(linux_pslist.linux_pslist): 32 | """Lists current working directory of each process""" 33 | 34 | def render_text(self, outfd, data): 35 | 36 | self.table_header(outfd, [("Name", "17"), 37 | ("Pid", "8"), 38 | ("CWD", "")]) 39 | 40 | for task in data: 41 | self.table_row(outfd, str(task.comm), task.pid, task.getcwd()) 42 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/arp.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.mac.common as common 29 | import volatility.plugins.mac.route as route 30 | 31 | class mac_arp(route.mac_route): 32 | """ Prints the arp table """ 33 | 34 | def calculate(self): 35 | common.set_plugin_members(self) 36 | 37 | arp_addr = self.addr_space.profile.get_symbol("_llinfo_arp") 38 | ptr = obj.Object("Pointer", offset = arp_addr, vm = self.addr_space) 39 | ent = ptr.dereference_as("llinfo_arp") 40 | 41 | while ent: 42 | yield ent.la_rt 43 | ent = ent.la_le.le_next 44 | -------------------------------------------------------------------------------- /volatility/pyinstaller.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python -*- 2 | import sys 3 | projpath = os.path.dirname(os.path.abspath(SPEC)) 4 | 5 | def get_plugins(list): 6 | for item in list: 7 | if item[0].startswith('volatility.plugins') and not (item[0] == 'volatility.plugins' and '__init__.py' in item[1]): 8 | yield item 9 | 10 | exeext = ".exe" if sys.platform.startswith("win") else "" 11 | 12 | a = Analysis([os.path.join(projpath, 'memtriage.py')], 13 | pathex = [HOMEPATH], 14 | hookspath = [os.path.join(projpath, 'pyinstaller')]) 15 | 16 | for d in a.datas: 17 | if 'pyconfig' in d[0]: 18 | a.datas.remove(d) 19 | break 20 | 21 | excludes = [".DS_Store", "arm.py", "elfcoredump.py", "ieee1394.py", "hpak.py", "vmware.py", "macho.py", "lime.py", "osxpmemelf.py", "vmem.py", "vmware.py"] 22 | 23 | for d in a.binaries: 24 | for item in d[0]: 25 | if item in excludes: 26 | print ("removing {}".format(d[0])) 27 | a.binaries.remove(d) 28 | 29 | pyz = PYZ(a.pure) 30 | plugins = Tree(os.path.join(projpath, 'volatility', 'plugins'), 31 | os.path.join('plugins')) 32 | exe = EXE(pyz, 33 | a.scripts + [('u', '', 'OPTION')], 34 | a.binaries, 35 | a.zipfiles, 36 | a.datas, 37 | plugins, 38 | name = os.path.join(projpath, 'dist', 'pyinstaller', 'memtriage' + exeext), 39 | debug = False, 40 | strip = False, 41 | upx = True, 42 | icon = os.path.join(projpath, 'resources', 'memforensics.ico'), 43 | console = 1) 44 | 45 | -------------------------------------------------------------------------------- /volatility/contrib/library_example/libapi.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (c) 2015 Michael Ligh (michael.ligh@mnin.org) 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | import copy, StringIO, json 21 | import volatility.conf as conf 22 | import volatility.registry as registry 23 | import volatility.commands as commands 24 | import volatility.addrspace as addrspace 25 | 26 | registry.PluginImporter() 27 | 28 | def get_json(config, plugin_class): 29 | strio = StringIO.StringIO() 30 | plugin = plugin_class(copy.deepcopy(config)) 31 | plugin.render_json(strio, plugin.calculate()) 32 | return json.loads(strio.getvalue()) 33 | 34 | def get_config(profile, target_path): 35 | config = conf.ConfObject() 36 | registry.register_global_options(config, commands.Command) 37 | registry.register_global_options(config, addrspace.BaseAddressSpace) 38 | config.parse_options() 39 | config.PROFILE = profile 40 | config.LOCATION = "file://{0}".format(target_path) 41 | return config -------------------------------------------------------------------------------- /volatility/volatility/plugins/machoinfo.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2009-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | import volatility.plugins.crashinfo as crashinfo 21 | 22 | class MachOInfo(crashinfo.CrashInfo): 23 | """Dump Mach-O file format information""" 24 | 25 | target_as = ['MachOAddressSpace'] 26 | 27 | def render_text(self, outfd, data): 28 | 29 | header = data.get_header() 30 | 31 | outfd.write("Magic: {0:#x}\n".format(header.magic)) 32 | outfd.write("Architecture: {0}-bit\n".format(data.bits)) 33 | 34 | self.table_header(outfd, [("File Offset", "[addrpad]"), 35 | ("Memory Offset", "[addrpad]"), 36 | ("Size", "[addrpad]"), 37 | ("Name", "")]) 38 | 39 | for seg in data.segs: 40 | self.table_row(outfd, seg.fileoff, seg.vmaddr, seg.vmsize, seg.segname) 41 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/find_aslr_shift.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.plugins.mac.common as common 28 | import volatility.debug as debug 29 | 30 | class mac_find_aslr_shift(common.AbstractMacCommand): 31 | """ Find the ASLR shift value for 10.8+ images """ 32 | 33 | def calculate(self): 34 | common.set_plugin_members(self) 35 | 36 | yield self.profile.shift_address 37 | 38 | def render_text(self, outfd, data): 39 | self.table_header(outfd, [("Shift Value", "#018x")]) 40 | for shift_address in data: 41 | if shift_address == 0: 42 | debug.error("Shift addresses are only required on 10.8+ images") 43 | else: 44 | self.table_row(outfd, shift_address) 45 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/dead_procs.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.mac.common as common 29 | import volatility.plugins.mac.list_zones as list_zones 30 | import volatility.plugins.mac.pslist as pslist 31 | 32 | class mac_dead_procs(pslist.mac_pslist): 33 | """ Prints terminated/de-allocated processes """ 34 | 35 | def calculate(self): 36 | common.set_plugin_members(self) 37 | 38 | zones = list_zones.mac_list_zones(self._config).calculate() 39 | 40 | for zone in zones: 41 | name = str(zone.zone_name.dereference()) 42 | if name == "proc": 43 | procs = zone.get_free_elements("proc") 44 | for proc in procs: 45 | yield proc 46 | 47 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/ld_env.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License Version 2 as 8 | # published by the Free Software Foundation. You may not use, modify or 9 | # distribute this program under any other version of the GNU General 10 | # Public License. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | """ 22 | @author: Andrew Case 23 | @license: GNU General Public License 2.0 24 | @contact: atcuno@gmail.com 25 | @organization: 26 | """ 27 | 28 | import volatility.plugins.linux.pslist as linux_pslist 29 | 30 | class linux_dynamic_env(linux_pslist.linux_pslist): 31 | """Recover a process' dynamic environment variables""" 32 | 33 | def render_text(self, outfd, data): 34 | self.table_header(outfd, [("Pid", "8"), 35 | ("Name", "20"), 36 | ("Vars", "")]) 37 | 38 | for task in data: 39 | varstr = "" 40 | 41 | for (key, val) in task.bash_environment(): 42 | varstr = varstr + "%s=%s " % (key, val) 43 | 44 | self.table_row(outfd, task.pid, task.comm, varstr) 45 | 46 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/proc_maps_rb.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License Version 2 as 8 | # published by the Free Software Foundation. You may not use, modify or 9 | # distribute this program under any other version of the GNU General 10 | # Public License. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | """ 22 | @author: Andrew Case 23 | @license: GNU General Public License 2.0 24 | @contact: atcuno@gmail.com 25 | @organization: 26 | """ 27 | 28 | import volatility.obj as obj 29 | import volatility.plugins.linux.common as linux_common 30 | import volatility.plugins.linux.pslist as linux_pslist 31 | import volatility.plugins.linux.proc_maps as linux_proc_maps 32 | 33 | class linux_proc_maps_rb(linux_proc_maps.linux_proc_maps): 34 | """Gathers process maps for linux through the mappings red-black tree""" 35 | 36 | def calculate(self): 37 | linux_common.set_plugin_members(self) 38 | tasks = linux_pslist.linux_pslist.calculate(self) 39 | 40 | for task in tasks: 41 | if task.mm: 42 | for vma in task.get_proc_maps_rb(): 43 | yield task, vma 44 | 45 | -------------------------------------------------------------------------------- /volatility/volatility/validity.py: -------------------------------------------------------------------------------- 1 | """ 2 | Created on 4 May 2013 3 | 4 | @author: mike 5 | """ 6 | 7 | 8 | class ValidityRoutines(object): 9 | """Class to hold all validation routines, such as type checking""" 10 | 11 | def type_check(self, value, valid_type): 12 | """Checks that value is an instance of valid_type, and returns value if it is, or throws a TypeError otherwise 13 | 14 | :param value: The value of which to validate the type 15 | :type value: object 16 | :param valid_type: The type against which to validate 17 | :type valid_type: type 18 | """ 19 | assert isinstance(value, valid_type), self.__class__.__name__ + " expected " + \ 20 | valid_type.__name__ + ", not " + type(value).__name__ 21 | return value 22 | 23 | def class_check(self, klass, valid_class): 24 | """Checks that class is an instance of valid_class, and returns klass if it is, or throws a TypeError otherwise 25 | 26 | :param klass: Class to validate 27 | :type klass: class 28 | :param valid_class: Valid class against which to check class validity 29 | :type valid_class: class 30 | """ 31 | assert issubclass(klass, valid_class), self.__class__.__name__ + " expected " + \ 32 | valid_class.__name__ + ", not " + klass.__name__ 33 | 34 | def confirm(self, assertion, error): 35 | """Acts like an assertion, but will not be disabled when __debug__ is disabled""" 36 | if not assertion: 37 | if error is None: 38 | error = "An unspecified Assertion was not met in " + self.__class__.__name__ 39 | raise AssertionError(error) 40 | -------------------------------------------------------------------------------- /volatility/volatility/renderers/dot.py: -------------------------------------------------------------------------------- 1 | from volatility import debug 2 | from volatility.renderers.basic import Renderer 3 | 4 | __author__ = 'mike' 5 | 6 | class DotRenderer(Renderer): 7 | def __init__(self, renderers_func, config): 8 | self._config = config 9 | self._columns = None 10 | self._text_cell_renderers_func = renderers_func 11 | self._text_cell_renderers = None 12 | 13 | def description(self, node): 14 | output = [] 15 | for column in self._columns: 16 | text = self._text_cell_renderers[column.index].render(node.values[column.index]) 17 | output.append((column.name + ": " + text).replace("|", "_").replace("\"", "_")) 18 | return "|".join(output) 19 | 20 | def _add_node(self, node, data): 21 | outfd, accumulator = data 22 | accumulator[node] = max(accumulator.values()) + 1 23 | outfd.write(" Node" + str(accumulator[node]) + " [label=\"{" + self.description(node) + "}\"];\n") 24 | if accumulator[node.parent] != 0: 25 | outfd.write(" Node" + str(accumulator[node.parent]) + " -> Node" + str(accumulator[node]) + ";\n") 26 | return (outfd, accumulator) 27 | 28 | def render(self, outfd, grid): 29 | """Renders the TreeGrid in data out to the output file from the config options""" 30 | self._columns = grid.columns 31 | self._text_cell_renderers = self._text_cell_renderers_func(self._columns) 32 | 33 | if grid.max_depth() <= 1: 34 | debug.warning("Dot output will be unhelpful since the TreeGrid is a flat list") 35 | outfd.write("digraph output {\n node[shape = Mrecord];\n # rankdir=LR;\n") 36 | grid.visit(None, self._add_node, (outfd, {None: 0})) 37 | outfd.write("}\n") 38 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/bash_env.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License Version 2 as 8 | # published by the Free Software Foundation. You may not use, modify or 9 | # distribute this program under any other version of the GNU General 10 | # Public License. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | """ 22 | @author: Andrew Case 23 | @license: GNU General Public License 2.0 24 | @contact: atcuno@gmail.com 25 | @organization: 26 | """ 27 | 28 | import struct 29 | from operator import attrgetter 30 | import volatility.obj as obj 31 | import volatility.debug as debug 32 | import volatility.addrspace as addrspace 33 | import volatility.plugins.mac.common as mac_common 34 | import volatility.plugins.mac.pstasks as mac_tasks 35 | from volatility.renderers import TreeGrid 36 | 37 | class mac_bash_env(mac_tasks.mac_tasks): 38 | """Recover bash's environment variables""" 39 | 40 | def unified_output(self, data): 41 | debug.error("This plugin is deprecated. Please use mac_psenv.") 42 | 43 | def generator(self, data): 44 | debug.error("This plugin is deprecated. Please use mac_psenv.") 45 | 46 | def render_text(self, outfd, data): 47 | debug.error("This plugin is deprecated. Please use mac_psenv.") 48 | 49 | -------------------------------------------------------------------------------- /volatility/contrib/library_example/pslist_json.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (c) 2015 Michael Ligh (michael.ligh@mnin.org) 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | import sys 21 | import volatility.plugins.taskmods as taskmods 22 | import libapi 23 | 24 | def main(): 25 | 26 | ## sys.argv[1] = volatility profile 27 | ## sys.argv[2] = full path on disk to your memory sample 28 | 29 | config = libapi.get_config(sys.argv[1], sys.argv[2]) 30 | data = libapi.get_json(config, taskmods.PSList) 31 | 32 | ## `data` now contains json with two keys: `columns` and `rows`, where `columns` 33 | ## contains a list of column headings (matching the corresponding volatility 34 | ## plugin output) and `rows` contains a list of the values for each object found. 35 | 36 | ## you can either print/save all columns, or you can drill down to a particular 37 | ## column by getting the desired column's index as shown below and then accessing 38 | ## the index in each row. the following example prints each process' name. 39 | 40 | name_index = data['columns'].index('Name') 41 | 42 | for row in data['rows']: 43 | print row[name_index] 44 | 45 | if __name__ == "__main__": 46 | main() -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/pstasks.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | import volatility.obj as obj 27 | import volatility.plugins.mac.pslist as pslist 28 | import volatility.plugins.mac.common as common 29 | 30 | class mac_tasks(pslist.mac_pslist): 31 | """ List Active Tasks """ 32 | def __init__(self, config, *args, **kwargs): 33 | pslist.mac_pslist.__init__(self, config, *args, **kwargs) 34 | 35 | def allprocs(self): 36 | common.set_plugin_members(self) 37 | tasksaddr = self.addr_space.profile.get_symbol("_tasks") 38 | queue_entry = obj.Object("queue_entry", offset = tasksaddr, vm = self.addr_space) 39 | 40 | seen = [tasksaddr] 41 | 42 | for task in queue_entry.walk_list(list_head = tasksaddr): 43 | if (task.bsd_info and task.obj_offset not in seen): 44 | proc = task.bsd_info.dereference_as("proc") 45 | yield proc 46 | 47 | seen.append(task.obj_offset) 48 | 49 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/dead_vnodes.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.mac.common as common 29 | import volatility.plugins.mac.list_zones as list_zones 30 | import volatility.plugins.mac.pslist as pslist 31 | 32 | class mac_dead_vnodes(pslist.mac_pslist): 33 | """ Lists freed vnode structures """ 34 | 35 | def calculate(self): 36 | common.set_plugin_members(self) 37 | 38 | zones = list_zones.mac_list_zones(self._config).calculate() 39 | 40 | for zone in zones: 41 | name = str(zone.zone_name.dereference()) 42 | if name == "vnodes": 43 | vnodes = zone.get_free_elements("vnode") 44 | for vnode in vnodes: 45 | yield vnode 46 | 47 | def render_text(self, outfd, data): 48 | for vnode in data: 49 | path = vnode.full_path() 50 | if path: 51 | outfd.write("{0:s}\n".format(path)) 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/psenv.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License Version 2 as 8 | # published by the Free Software Foundation. You may not use, modify or 9 | # distribute this program under any other version of the GNU General 10 | # Public License. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | """ 22 | @author: Andrew Case 23 | @license: GNU General Public License 2.0 24 | @contact: atcuno@gmail.com 25 | @organization: 26 | """ 27 | 28 | import volatility.plugins.linux.pslist as linux_pslist 29 | from volatility.renderers import TreeGrid 30 | 31 | class linux_psenv(linux_pslist.linux_pslist): 32 | '''Gathers processes along with their static environment variables''' 33 | def unified_output(self, data): 34 | return TreeGrid([("Name", str), 35 | ("Pid", int), 36 | ("Environment", str)], 37 | self.generator(data)) 38 | 39 | def generator(self, data): 40 | for task in data: 41 | yield (0, [str(task.comm), int(task.pid), str(task.get_environment())]) 42 | 43 | def render_text(self, outfd, data): 44 | outfd.write("{0:6s} {1:6s} {2:12s}\n".format("Name", "Pid", "Environment")) 45 | for task in data: 46 | outfd.write("{0:17s} {1:6s} {2:s}\n".format(str(task.comm), str(task.pid), task.get_environment())) 47 | -------------------------------------------------------------------------------- /volatility/volatility/exceptions.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # 3 | # This file is part of Volatility. 4 | # 5 | # Volatility is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # Volatility is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with Volatility. If not, see . 17 | # 18 | 19 | class VolatilityException(Exception): 20 | """Generic Volatility Specific exception, to help differentiate from other exceptions""" 21 | def __init__(self, *args, **kwargs): 22 | Exception.__init__(self, *args, **kwargs) 23 | 24 | class AddrSpaceError(VolatilityException): 25 | """Address Space Exception, so we can catch and deal with it in the main program""" 26 | def __init__(self): 27 | self.reasons = [] 28 | VolatilityException.__init__(self, "No suitable address space mapping found") 29 | 30 | def append_reason(self, driver, reason): 31 | self.reasons.append((driver, reason)) 32 | 33 | def __str__(self): 34 | result = VolatilityException.__str__(self) + "\nTried to open image as:\n" #pylint: disable-msg=E1101 35 | for k, v in self.reasons: 36 | result += " {0}: {1}\n".format(k, v) 37 | 38 | return result 39 | 40 | class CacheRelativeURLException(VolatilityException): 41 | """Exception for gracefully not saving Relative URLs in the cache""" 42 | 43 | class SanityCheckException(VolatilityException): 44 | """Exception for failed sanity checks (which can potentially be disabled)""" 45 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/libc_env.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License Version 2 as 8 | # published by the Free Software Foundation. You may not use, modify or 9 | # distribute this program under any other version of the GNU General 10 | # Public License. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | """ 22 | @author: Andrew Case 23 | @license: GNU General Public License 2.0 24 | @contact: atcuno@gmail.com 25 | @organization: 26 | """ 27 | 28 | import struct 29 | from operator import attrgetter 30 | import volatility.obj as obj 31 | import volatility.debug as debug 32 | import volatility.addrspace as addrspace 33 | import volatility.plugins.linux.common as linux_common 34 | import volatility.plugins.linux.pslist as linux_pslist 35 | 36 | class linux_bash_env(linux_pslist.linux_pslist): 37 | """Recover a process' dynamic environment variables""" 38 | 39 | def render_text(self, outfd, data): 40 | self.table_header(outfd, [("Pid", "8"), 41 | ("Name", "20"), 42 | ("Vars", "")]) 43 | 44 | for task in data: 45 | varstr = "" 46 | 47 | for (key, val) in task.bash_environment(): 48 | varstr = varstr + "%s=%s " % (key, val) 49 | 50 | self.table_row(outfd, task.pid, task.comm, varstr) 51 | 52 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/banner.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.debug as debug 29 | import volatility.plugins.linux.flags as linux_flags 30 | import volatility.plugins.linux.common as linux_common 31 | import volatility.plugins.linux.pslist as linux_pslist 32 | 33 | class linux_banner(linux_common.AbstractLinuxCommand): 34 | """ Prints the Linux banner information """ 35 | 36 | def calculate(self): 37 | linux_common.set_plugin_members(self) 38 | 39 | banner_addr = self.addr_space.profile.get_symbol("linux_banner") 40 | 41 | if banner_addr: 42 | banner = obj.Object("String", offset = banner_addr, vm = self.addr_space, length = 256) 43 | else: 44 | debug.error("linux_banner symbol not found. Please report this as a bug on the issue tracker: https://code.google.com/p/volatility/issues/list") 45 | 46 | yield banner.strip() 47 | 48 | def render_text(self, outfd, data): 49 | for banner in data: 50 | outfd.write("{0:s}\n".format(banner)) 51 | 52 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/psaux.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.plugins.linux.pslist as linux_pslist 28 | from volatility.renderers import TreeGrid 29 | from volatility.renderers.basic import Address 30 | 31 | class linux_psaux(linux_pslist.linux_pslist): 32 | '''Gathers processes along with full command line and start time''' 33 | 34 | def unified_output(self, data): 35 | return TreeGrid([("Arguments", str), 36 | ("Pid", int), 37 | ("Uid", int), 38 | ("Gid", int)], 39 | self.generator(data)) 40 | 41 | def generator(self, data): 42 | for task in data: 43 | yield (0, [str(task.get_commandline()), int(task.pid), int(task.uid), int(task.gid)]) 44 | 45 | def render_text(self, outfd, data): 46 | outfd.write("{1:6s} {2:6s} {3:6s} {0:64s}\n".format("Arguments", "Pid", "Uid", "Gid")) 47 | 48 | for task in data: 49 | outfd.write("{1:6s} {2:6s} {3:6s} {0:64s}\n".format(task.get_commandline(), str(task.pid), str(task.uid), str(task.gid))) 50 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/fileparam.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # 3 | # Authors: 4 | # Mike Auty 5 | # 6 | # This file is part of Volatility. 7 | # 8 | # Volatility is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # Volatility is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Volatility. If not, see . 20 | # 21 | 22 | import volatility.conf as conf 23 | import urllib 24 | import sys 25 | import os 26 | ## This is required to ensure that LOCATION is defined here 27 | import volatility.debug as debug 28 | import volatility.addrspace as addrspace #pylint: disable-msg=W0611 29 | 30 | config = conf.ConfObject() 31 | 32 | def set_location(_option, _opt_str, value, parser): 33 | """Sets the location variable in the parser to the filename in question""" 34 | if not os.path.exists(os.path.abspath(value)): 35 | debug.error("The requested file doesn't exist") 36 | if parser.values.location == None: 37 | slashes = "//" 38 | # Windows pathname2url decides to convert C:\blah to ///C:/blah 39 | # So to keep the URLs correct, we only add file: rather than file:// 40 | if sys.platform.startswith('win'): 41 | slashes = "" 42 | parser.values.location = "file:" + slashes + urllib.pathname2url(os.path.abspath(value)) 43 | 44 | config.add_option("FILENAME", default = None, action = "callback", 45 | callback = set_location, type = 'str', 46 | short_option = 'f', nargs = 1, 47 | help = "Filename to use when opening an image") 48 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/pid_hash_table.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.plugins.mac.pslist as pslist 28 | import volatility.obj as obj 29 | import volatility.plugins.mac.common as common 30 | 31 | class mac_pid_hash_table(pslist.mac_pslist): 32 | """ Walks the pid hash table """ 33 | 34 | def calculate(self): 35 | common.set_plugin_members(self) 36 | 37 | pidhash_addr = self.addr_space.profile.get_symbol("_pidhash") 38 | pidhash = obj.Object("unsigned long", offset = pidhash_addr, vm = self.addr_space) 39 | 40 | pidhashtbl_addr = self.addr_space.profile.get_symbol("_pidhashtbl") 41 | pidhashtbl_ptr = obj.Object("Pointer", offset = pidhashtbl_addr, vm = self.addr_space) 42 | pidhash_array = obj.Object("Array", targetType = "pidhashhead", count = pidhash + 1, vm = self.addr_space, offset = pidhashtbl_ptr) 43 | 44 | for plist in pidhash_array: 45 | p = plist.lh_first.dereference() 46 | 47 | while p: 48 | yield p 49 | p = p.p_hash.le_next.dereference() 50 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/lime.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2009-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License Version 2 as 8 | # published by the Free Software Foundation. You may not use, modify or 9 | # distribute this program under any other version of the GNU General 10 | # Public License. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | import volatility.plugins.crashinfo as crashinfo 22 | import volatility.plugins.linux.common as linux_common 23 | 24 | class LiMEInfo(linux_common.AbstractLinuxCommand): 25 | """Dump Lime file format information""" 26 | 27 | target_as = ['LimeAddressSpace'] 28 | 29 | def calculate(self): 30 | """Determines the address space""" 31 | linux_common.set_plugin_members(self) 32 | 33 | result = None 34 | adrs = self.addr_space 35 | while adrs: 36 | if adrs.__class__.__name__ in self.target_as: 37 | result = adrs 38 | adrs = adrs.base 39 | 40 | if result is None: 41 | debug.error("Memory Image could not be identified as {0}".format(self.target_as)) 42 | 43 | return result 44 | 45 | def render_text(self, outfd, data): 46 | self.table_header(outfd, [("Memory Start", "[addrpad]"), 47 | ("Memory End", "[addrpad]"), 48 | ("Size", "[addrpad]")]) 49 | 50 | for seg in data.runs: 51 | self.table_row(outfd, seg[0], seg[0] + seg[2] - 1, seg[2]) 52 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/win10cookie.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2015 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | import volatility.plugins.common as common 21 | import volatility.utils as utils 22 | import volatility.obj as obj 23 | 24 | class Win10Cookie(common.AbstractWindowsCommand): 25 | """Find the ObHeaderCookie value for Windows 10""" 26 | 27 | def __init__(self, config, *args, **kwargs): 28 | common.AbstractWindowsCommand.__init__(self, config, *args, **kwargs) 29 | 30 | @staticmethod 31 | def register_options(config): 32 | config.add_option('COOKIE', default = None, type = 'int', 33 | help = "Specify the address of nt!ObHeaderCookie (valid for Windows 10 only)") 34 | 35 | @staticmethod 36 | def is_valid_profile(profile): 37 | 38 | meta = profile.metadata 39 | vers = (meta.get("major", 0), meta.get("minor", 0)) 40 | 41 | # this algorithm only applies to Windows 10 or greater 42 | return meta.get('os', '') == 'windows' and vers >= (6, 4) 43 | 44 | def calculate(self): 45 | address_space = utils.load_as(self._config) 46 | cookie = obj.VolMagic(address_space).ObHeaderCookie.v() 47 | yield cookie 48 | 49 | def render_text(self, outfd, data): 50 | for cookie in data: 51 | print cookie -------------------------------------------------------------------------------- /volatility/volatility/renderers/xlsx.py: -------------------------------------------------------------------------------- 1 | from volatility import debug 2 | from volatility.renderers.basic import Renderer 3 | 4 | __author__ = "gleeda" 5 | 6 | try: 7 | from openpyxl.workbook import Workbook 8 | from openpyxl.writer.excel import ExcelWriter 9 | from openpyxl.cell import get_column_letter 10 | from openpyxl.styles import Color, Fill, Style, PatternFill, Border, Side, Alignment, Protection, Font 11 | from openpyxl.cell import Cell 12 | from openpyxl import load_workbook 13 | has_openpyxl = True 14 | except ImportError: 15 | has_openpyxl = False 16 | 17 | class XLSXRenderer(Renderer): 18 | def __init__(self, renderers_func, config): 19 | if not has_openpyxl: 20 | debug.error("You must install OpenPyxl 2.1.2 for xlsx format:\n\thttps://pypi.python.org/pypi/openpyxl") 21 | self._config = config 22 | self._columns = None 23 | self._text_cell_renderers_func = renderers_func 24 | self._text_cell_renderers = None 25 | self._wb = Workbook(optimized_write = True) 26 | self._ws = self._wb.create_sheet() 27 | 28 | def description(self): 29 | output = [] 30 | for column in self._columns: 31 | output.append((column.name)) 32 | return output 33 | 34 | def _add_row(self, node, data): 35 | accumulator = data 36 | accumulator[node] = max(accumulator.values()) + 1 37 | self._ws.append(list(node.values)) 38 | return accumulator 39 | 40 | def render(self, outfd, grid): 41 | """Renders the TreeGrid in data out to the output file from the config options""" 42 | if not self._config.OUTPUT_FILE: 43 | debug.error("Please specify a valid output file using --output-file") 44 | self._columns = grid.columns 45 | self._text_cell_renderers = self._text_cell_renderers_func(self._columns) 46 | self._ws.append(self.description()) 47 | grid.visit(None, self._add_row, {None: 0}) 48 | self._wb.save(filename = self._config.OUTPUT_FILE) 49 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/pslist_cache.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # 3 | # This file is part of Volatility. 4 | # 5 | # Volatility is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # Volatility is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with Volatility. If not, see . 17 | # 18 | 19 | """ 20 | @author: Joe Sylve 21 | @license: GNU General Public License 2.0 22 | @contact: joe.sylve@gmail.com 23 | @organization: Digital Forensics Solutions 24 | """ 25 | 26 | import volatility.plugins.linux.common as linux_common 27 | from volatility.plugins.linux.slab_info import linux_slabinfo 28 | import volatility.plugins.linux.pslist as linux_pslist 29 | 30 | class linux_pslist_cache(linux_pslist.linux_pslist): 31 | """Gather tasks from the kmem_cache""" 32 | 33 | def __init__(self, config, *args, **kwargs): 34 | linux_pslist.linux_pslist.__init__(self, config, *args, **kwargs) 35 | self._config.add_option('UNALLOCATED', short_option = 'u', 36 | default = False, 37 | help = 'Show unallocated', 38 | action = 'store_true') 39 | 40 | def calculate(self): 41 | linux_common.set_plugin_members(self) 42 | pidlist = self._config.PID 43 | if pidlist: 44 | pidlist = [int(p) for p in self._config.PID.split(',')] 45 | 46 | cache = linux_slabinfo(self._config).get_kmem_cache("task_struct", self._config.UNALLOCATED) 47 | 48 | for task in cache: 49 | if not pidlist or task.pid in pidlist: 50 | yield task 51 | 52 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/print_boot_cmdline.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.mac.common as common 29 | from volatility.renderers import TreeGrid 30 | 31 | 32 | class mac_print_boot_cmdline(common.AbstractMacCommand): 33 | """ Prints kernel boot arguments """ 34 | 35 | def calculate(self): 36 | common.set_plugin_members(self) 37 | 38 | pe_state_addr = self.addr_space.profile.get_symbol("_PE_state") 39 | pe_state = obj.Object("PE_state", offset = pe_state_addr, vm = self.addr_space) 40 | bootargs = pe_state.bootArgs.dereference_as("boot_args") 41 | 42 | yield bootargs.CommandLine 43 | 44 | def unified_output(self, data): 45 | return TreeGrid([("Command Line", str), 46 | ], self.generator(data)) 47 | 48 | def generator(self, data): 49 | for cmdline in data: 50 | yield(0, [str(cmdline),]) 51 | 52 | def render_text(self, outfd, data): 53 | self.table_header(outfd, [("Command Line", "")]) 54 | for cmdline in data: 55 | self.table_row(outfd, cmdline) 56 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/machine_info.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.mac.common as common 29 | 30 | class mac_machine_info(common.AbstractMacCommand): 31 | """ Prints machine information about the sample """ 32 | 33 | def calculate(self): 34 | common.set_plugin_members(self) 35 | 36 | machine_info = obj.Object("machine_info", offset = self.addr_space.profile.get_symbol("_machine_info"), vm = self.addr_space) 37 | 38 | yield machine_info 39 | 40 | def render_text(self, outfd, data): 41 | for machine_info in data: 42 | 43 | info = (("Major Version:", machine_info.major_version), 44 | ("Minor Version:", machine_info.minor_version), 45 | ("Memory Size:", machine_info.max_mem), 46 | ("Max CPUs:", machine_info.max_cpus), 47 | ("Physical CPUs:", machine_info.physical_cpu), 48 | ("Logical CPUs:", machine_info.logical_cpu), 49 | ) 50 | 51 | for i in info: 52 | outfd.write("{0:15} {1}\n".format(i[0], i[1])) 53 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/pstree.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.plugins.mac.pstasks as pstasks 28 | 29 | class mac_pstree(pstasks.mac_tasks): 30 | """ Show parent/child relationship of processes """ 31 | 32 | def render_text(self, outfd, data): 33 | self.procs_hash = {} 34 | self.procs_seen = {} 35 | 36 | outfd.write("{0:20s} {1:15s} {2:15s}\n".format("Name", "Pid", "Uid")) 37 | 38 | for proc in data: 39 | self.procs_hash[proc.p_pid] = proc 40 | 41 | for pid in sorted(self.procs_hash.keys()): 42 | proc = self.procs_hash[pid] 43 | self._recurse_task(outfd, proc, 0) 44 | 45 | def _recurse_task(self, outfd, proc, level): 46 | if proc.p_pid in self.procs_seen: 47 | return 48 | 49 | proc_name = "." * level + proc.p_comm 50 | 51 | outfd.write("{0:20s} {1:15s} {2:15s}\n".format(proc_name, str(proc.p_pid), str(proc.p_uid))) 52 | 53 | self.procs_seen[proc.p_pid] = 1 54 | 55 | proc = proc.p_children.lh_first 56 | 57 | while proc.is_valid(): 58 | self._recurse_task(outfd, proc, level + 1) 59 | proc = proc.p_sibling.le_next 60 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/flags.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | # flags used throughout the plugins 28 | # these aren't going to change due to binary breakage if they would 29 | 30 | # Protocol strings should use volatility.protos 31 | 32 | tcp_states = ("", 33 | "ESTABLISHED", 34 | "SYN_SENT", 35 | "SYN_RECV", 36 | "FIN_WAIT1", 37 | "FIN_WAIT2", 38 | "TIME_WAIT", 39 | "CLOSE", 40 | "CLOSE_WAIT", 41 | "LAST_ACK", 42 | "LISTEN", 43 | "CLOSING") 44 | 45 | MNT_NOSUID = 0x01 46 | MNT_NODEV = 0x02 47 | MNT_NOEXEC = 0x04 48 | MNT_NOATIME = 0x08 49 | MNT_NODIRATIME = 0x10 50 | MNT_RELATIME = 0x20 51 | 52 | mnt_flags = { 53 | MNT_NOSUID: ",nosuid", 54 | MNT_NODEV: ",nodev", 55 | MNT_NOEXEC: ",noexec", 56 | MNT_NOATIME: ",noatime", 57 | MNT_NODIRATIME: ",nodiratime", 58 | MNT_RELATIME: ",relatime" 59 | } 60 | 61 | S_IFMT = 0170000 62 | S_IFSOCK = 0140000 63 | S_IFLNK = 0120000 64 | S_IFREG = 0100000 65 | S_IFBLK = 0060000 66 | S_IFDIR = 0040000 67 | S_IFCHR = 0020000 68 | S_IFIFO = 0010000 69 | S_ISUID = 0004000 70 | S_ISGID = 0002000 71 | 72 | 73 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/pgrp_hash_table.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.plugins.mac.pslist as pslist 28 | import volatility.obj as obj 29 | import volatility.plugins.mac.common as common 30 | 31 | class mac_pgrp_hash_table(pslist.mac_pslist): 32 | """ Walks the process group hash table """ 33 | 34 | def calculate(self): 35 | common.set_plugin_members(self) 36 | 37 | pgrphash_addr = self.addr_space.profile.get_symbol("_pgrphash") 38 | pgrphash = obj.Object("unsigned long", offset = pgrphash_addr, vm = self.addr_space) 39 | 40 | pgrphashtbl_addr = self.addr_space.profile.get_symbol("_pgrphashtbl") 41 | pgrphashtbl_ptr = obj.Object("Pointer", offset = pgrphashtbl_addr, vm = self.addr_space) 42 | pgrphash_array = obj.Object("Array", targetType = "pgrphashhead", count = pgrphash + 1, vm = self.addr_space, offset = pgrphashtbl_ptr) 43 | 44 | for plist in pgrphash_array: 45 | pgrp = plist.lh_first 46 | 47 | while pgrp: 48 | p = pgrp.pg_members.lh_first 49 | 50 | while p: 51 | yield p 52 | p = p.p_pglist.le_next 53 | 54 | pgrp = pgrp.pg_hash.le_next 55 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/gkextmap.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.mac.common as common 29 | import volatility.plugins.mac.lsmod as lsmod 30 | 31 | class mac_lsmod_kext_map(lsmod.mac_lsmod): 32 | """ Lists loaded kernel modules """ 33 | 34 | def calculate(self): 35 | common.set_plugin_members(self) 36 | 37 | p = self.addr_space.profile.get_symbol("_g_kext_map") 38 | mapaddr = obj.Object("Pointer", offset = p, vm = self.addr_space) 39 | kextmap = mapaddr.dereference_as("_vm_map") 40 | 41 | nentries = kextmap.hdr.nentries 42 | kext = kextmap.hdr 43 | 44 | for i in range(nentries): 45 | kext = kext.links.next 46 | 47 | if not kext: 48 | break 49 | 50 | macho = obj.Object("macho_header", offset = kext.start, vm = self.addr_space) 51 | 52 | if macho.is_valid(): 53 | kmod_start = macho.address_for_symbol("_kmod_info") 54 | 55 | if kmod_start: 56 | kmod = obj.Object("kmod_info", offset = kmod_start, vm = self.addr_space) 57 | if kmod.is_valid(): 58 | yield kmod 59 | 60 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/dmesg.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.mac.common as common 29 | 30 | class mac_dmesg(common.AbstractMacCommand): 31 | """ Prints the kernel debug buffer """ 32 | 33 | def calculate(self): 34 | common.set_plugin_members(self) 35 | 36 | msgbuf_ptr = obj.Object("Pointer", offset = self.addr_space.profile.get_symbol("_msgbufp"), vm = self.addr_space) 37 | msgbufp = msgbuf_ptr.dereference_as("msgbuf") 38 | 39 | bufx = msgbufp.msg_bufx 40 | size = msgbufp.msg_size 41 | bufc = self.addr_space.read(msgbufp.msg_bufc, size) 42 | 43 | if bufc[bufx] == 0 and bufc[0] != 0: 44 | ## FIXME: can we do this without get_string? 45 | buf = common.get_string(bufc, self.addr_space) 46 | else: 47 | if bufx > size: 48 | bufx = 0 49 | 50 | # older messages 51 | buf = bufc[bufx:bufx + size] 52 | buf = buf + bufc[0:bufx] 53 | 54 | # strip leading NULLs 55 | while ord(buf[0]) == 0x00: 56 | buf = buf[1:] 57 | 58 | yield buf 59 | 60 | def render_text(self, outfd, data): 61 | for buf in data: 62 | outfd.write("{0}\n".format(buf)) 63 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/enumerate_files.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.linux.common as linux_common 29 | import volatility.plugins.linux.find_file as linux_find_file 30 | from volatility.renderers import TreeGrid 31 | from volatility.renderers.basic import Address 32 | 33 | class linux_enumerate_files(linux_common.AbstractLinuxCommand): 34 | """Lists files referenced by the filesystem cache""" 35 | 36 | def calculate(self): 37 | linux_common.set_plugin_members(self) 38 | 39 | for (_, _, file_path, file_dentry)in linux_find_file.linux_find_file(self._config).walk_sbs(): 40 | inode = file_dentry.d_inode 41 | 42 | yield inode, inode.i_ino, file_path 43 | 44 | def unified_output(self, data): 45 | return TreeGrid([("Inode Address", Address), ("Inode Number", int), ("Path", str)], 46 | self.generator(data)) 47 | 48 | def generator(self, data): 49 | for inode, inum, path in data: 50 | yield (0, [Address(inode.v()), int(inum), str(path)]) 51 | 52 | def render_text(self, outfd, data): 53 | self.table_header(outfd, [("Inode Address", "[addr]"), ("Inode Number", "25"), ("Path", "")]) 54 | for inode, inum, path in data: 55 | self.table_row(outfd, inode, inum, path) 56 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/lsof.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.mac.pstasks as pstasks 29 | import volatility.plugins.mac.common as common 30 | from volatility.renderers import TreeGrid 31 | 32 | class mac_lsof(pstasks.mac_tasks): 33 | """ Lists per-process opened files """ 34 | 35 | def unified_output(self, data): 36 | return TreeGrid([("PID",int), 37 | ("File Descriptor", int), 38 | ("File Path", str), 39 | ], self.generator(data)) 40 | 41 | def generator(self, data): 42 | for proc in data: 43 | for (_, filepath, fd) in proc.lsof(): 44 | if filepath: 45 | yield(0, [ 46 | int(proc.p_pid), 47 | int(fd), 48 | str(filepath), 49 | ]) 50 | 51 | def render_text(self, outfd, data): 52 | self.table_header(outfd, [("PID","8"), 53 | ("File Descriptor", "6"), 54 | ("File Path", ""), 55 | ]) 56 | 57 | for proc in data: 58 | for (_, filepath, fd) in proc.lsof(): 59 | if filepath: 60 | self.table_row(outfd, proc.p_pid, fd, filepath) 61 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/hpakinfo.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | import volatility.plugins.crashinfo as crashinfo 21 | import volatility.debug as debug 22 | 23 | class HPAKInfo(crashinfo.CrashInfo): 24 | """Info on an HPAK file""" 25 | 26 | target_as = ['HPAKAddressSpace'] 27 | 28 | def render_text(self, outfd, data): 29 | 30 | header = data.get_header() 31 | 32 | for section in header.Sections(): 33 | outfd.write("Header: {0}\n".format(section.Header)) 34 | outfd.write("Length: {0:#x}\n".format(section.Length)) 35 | outfd.write("Offset: {0:#x}\n".format(section.Offset)) 36 | outfd.write("NextOffset: {0:#x}\n".format(section.NextSection)) 37 | outfd.write("Name: {0}\n".format(section.Name)) 38 | outfd.write("Compressed: {0}\n".format(section.Compressed)) 39 | outfd.write("Comp. Size: {0:#x}\n".format(section.CompressedSize)) 40 | outfd.write("\n") 41 | 42 | class HPAKExtract(HPAKInfo): 43 | """Extract physical memory from an HPAK file""" 44 | 45 | def render_text(self, outfd, data): 46 | 47 | if not self._config.OUTPUT_FILE: 48 | debug.error("You must supply --output-file") 49 | 50 | data.convert_to_raw(outfd) 51 | 52 | print "Compressed: {0}".format("Yes" if data.physmem.Compressed == 1 else "No") 53 | print "Compressed Size: {0:#x}".format(data.physmem.CompressedSize) 54 | print "Final Size: {0:#x}".format(data.physmem.Length) -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/iomem.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License Version 2 as 8 | # published by the Free Software Foundation. You may not use, modify or 9 | # distribute this program under any other version of the GNU General 10 | # Public License. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | """ 22 | @author: Andrew Case 23 | @license: GNU General Public License 2.0 24 | @contact: atcuno@gmail.com 25 | @organization: 26 | """ 27 | 28 | import volatility.obj as obj 29 | import volatility.plugins.linux.common as linux_common 30 | 31 | class linux_iomem(linux_common.AbstractLinuxCommand): 32 | """Provides output similar to /proc/iomem""" 33 | 34 | def yield_resource(self, io_res, depth = 0): 35 | 36 | if not io_res: 37 | #print "null" 38 | return [] 39 | 40 | name = io_res.name.dereference_as("String", length = linux_common.MAX_STRING_LENGTH) 41 | start = io_res.start 42 | end = io_res.end 43 | 44 | output = [(depth, name, start, end)] 45 | 46 | output += self.yield_resource(io_res.child, depth + 1) 47 | output += self.yield_resource(io_res.sibling, depth) 48 | return output 49 | 50 | def calculate(self): 51 | linux_common.set_plugin_members(self) 52 | 53 | io_ptr = self.addr_space.profile.get_symbol("iomem_resource") 54 | io_res = obj.Object("resource", offset = io_ptr, vm = self.addr_space) 55 | 56 | for r in self.yield_resource(io_res.child): 57 | yield r 58 | 59 | def render_text(self, outfd, data): 60 | 61 | for output in data: 62 | depth, name, start, end = output 63 | outfd.write("{0:35s}\t0x{1:<16X}\t0x{2:<16X}\n".format((" " * depth) + name, start, end)) 64 | -------------------------------------------------------------------------------- /volatility/libapi.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (c) 2015 Michael Ligh 3 | # Copyright (c) 2016 Jamie Levy 4 | # 5 | # This file is part of Volatility. 6 | # 7 | # Volatility is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | import copy, StringIO, json 22 | import volatility.conf as conf 23 | import volatility.registry as registry 24 | import volatility.commands as commands 25 | import volatility.addrspace as addrspace 26 | import volatility.plugins.kdbgscan as kdbgscan 27 | 28 | registry.PluginImporter() 29 | 30 | def get_the_kdbg(config, profile): 31 | plugin = kdbgscan.KDBGScan(copy.deepcopy(config)) 32 | data = plugin.calculate() 33 | for suggestion, kdbg in data: 34 | try: 35 | if profile == suggestion and len(list(kdbg.processes())) > 0: 36 | return kdbg 37 | except AttributeError: 38 | pass 39 | return None 40 | 41 | def get_json(config, plugin_class): 42 | strio = StringIO.StringIO() 43 | plugin = plugin_class(copy.deepcopy(config)) 44 | plugin.render_json(strio, plugin.calculate()) 45 | return json.loads(strio.getvalue()) 46 | 47 | def get_text(config, plugin_class): 48 | strio = StringIO.StringIO() 49 | plugin = plugin_class(copy.deepcopy(config)) 50 | plugin.render_text(strio, plugin.calculate()) 51 | return strio.getvalue() 52 | 53 | def get_config(profile, target_path): 54 | config = conf.ConfObject() 55 | config.PROFILE = profile 56 | config.LOCATION = "file://{0}".format(target_path) 57 | registry.register_global_options(config, commands.Command) 58 | registry.register_global_options(config, addrspace.BaseAddressSpace) 59 | config.parse_options() 60 | return config 61 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/psenv.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.plugins.mac.pstasks as pstasks 28 | from volatility.renderers import TreeGrid 29 | 30 | class mac_psenv(pstasks.mac_tasks): 31 | """ Prints processes with environment in user land (**envp) """ 32 | 33 | def unified_output(self, data): 34 | return TreeGrid([("Pid", int), 35 | ("Name", str), 36 | ("Bits", str), 37 | ("Arguments", str), 38 | ], self.generator(data)) 39 | 40 | def generator(self, data): 41 | for proc in data: 42 | yield(0, [ 43 | int(proc.p_pid), 44 | str(proc.p_comm), 45 | str(proc.task.map.pmap.pm_task_map), 46 | str(proc.get_environment()), 47 | ]) 48 | 49 | def render_text(self, outfd, data): 50 | 51 | self.table_header(outfd, [("Pid", "8"), 52 | ("Name", "20"), 53 | ("Bits", "16"), 54 | ("Arguments", "")]) 55 | for proc in data: 56 | self.table_row(outfd, 57 | proc.p_pid, 58 | proc.p_comm, 59 | str(proc.task.map.pmap.pm_task_map or '')[9:], 60 | proc.get_environment()) 61 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/lsof.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | """ 25 | 26 | 27 | 28 | import volatility.plugins.linux.common as linux_common 29 | import volatility.plugins.linux.pslist as linux_pslist 30 | from volatility.renderers.basic import Address 31 | from volatility.renderers import TreeGrid 32 | 33 | class linux_lsof(linux_pslist.linux_pslist): 34 | """Lists file descriptors and their path""" 35 | 36 | def unified_output(self, data): 37 | return TreeGrid([("Offset",Address), 38 | ("Name",str), 39 | ("Pid", int), 40 | ("FD", int), 41 | ("Path", str)], 42 | self.generator(data)) 43 | 44 | def generator(self, data): 45 | for task in data: 46 | for filp, fd in task.lsof(): 47 | yield (0, [Address(task.obj_offset),str(task.comm),int(task.pid), int(fd), str(linux_common.get_path(task, filp))]) 48 | 49 | 50 | def render_text(self, outfd, data): 51 | self.table_header(outfd, [("Offset","#018x"), 52 | ("Name","30"), 53 | ("Pid", "8"), 54 | ("FD", "8"), 55 | ("Path", "")]) 56 | 57 | for task in data: 58 | for filp, fd in task.lsof(): 59 | self.table_row(outfd, Address(task.obj_offset), str(task.comm), task.pid, fd, linux_common.get_path(task, filp)) -------------------------------------------------------------------------------- /volatility/volatility/plugins/win10smglobals.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2019 Volatility Foundation 3 | # 4 | # Authors: 5 | # Blaine Stancill 6 | # 7 | # This file is part of Volatility. 8 | # 9 | # Volatility is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2 of the License, or 12 | # (at your option) any later version. 13 | # 14 | # Volatility is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with Volatility. If not, see . 21 | # 22 | 23 | import volatility.plugins.common as common 24 | import volatility.utils as utils 25 | import volatility.obj as obj 26 | 27 | 28 | class Win10SmGlobals(common.AbstractWindowsCommand): 29 | """Find the SmGlobals value for Windows 10""" 30 | 31 | def __init__(self, config, *args, **kwargs): 32 | common.AbstractWindowsCommand.__init__(self, config, *args, **kwargs) 33 | 34 | @staticmethod 35 | def register_options(config): 36 | config.add_option('SMGLOBALS', default = None, type = 'int', 37 | help = ("Specify the virtual address of nt!SmGlobals" 38 | " (valid for Windows 10 only)")) 39 | 40 | @staticmethod 41 | def is_valid_profile(profile): 42 | os = profile.metadata.get('os', '') 43 | major = profile.metadata.get('major', 0) 44 | minor = profile.metadata.get('minor', 0) 45 | build = profile.metadata.get('build', 0) 46 | return (major >= 6 47 | and minor >= 4 48 | and os == 'windows' 49 | and build in [14393, 15063, 16299, 17134, 17763, 18362]) 50 | 51 | def calculate(self): 52 | address_space = utils.load_as(self._config) 53 | 54 | return obj.VolMagic(address_space).SmGlobals.v() 55 | 56 | def render_text(self, outfd, data): 57 | if data: 58 | outfd.write("{0:#x}".format(data)) 59 | else: 60 | outfd.write("Unable to find nt!SmGlobals") 61 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/gui/vtypes/win2003.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # Copyright (C) 2010,2011,2012 Michael Hale Ligh 4 | # 5 | # This file is part of Volatility. 6 | # 7 | # Volatility is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | import volatility.obj as obj 22 | 23 | class Win2003x86GuiVTypes(obj.ProfileModification): 24 | """Apply the overlays for Windows 2003 x86 (builds on Windows XP x86)""" 25 | 26 | before = ["XP2003x86BaseVTypes"] 27 | 28 | conditions = {'os': lambda x: x == 'windows', 29 | 'memory_model': lambda x: x == '32bit', 30 | 'major': lambda x: x == 5, 31 | 'minor': lambda x: x == 2} 32 | 33 | def modification(self, profile): 34 | 35 | profile.merge_overlay({ 36 | 'tagWINDOWSTATION' : [ 0x54, { 37 | 'spwndClipOwner' : [ 0x18, ['pointer', ['tagWND']]], 38 | 'pGlobalAtomTable' : [ 0x3C, ['pointer', ['void']]], 39 | }], 40 | 'tagTHREADINFO' : [ None, { 41 | 'PtiLink' : [ 0xB0, ['_LIST_ENTRY']], 42 | 'fsHooks' : [ 0x9C, ['unsigned long']], 43 | 'aphkStart' : [ 0xF8, ['array', 16, ['pointer', ['tagHOOK']]]], 44 | }], 45 | 'tagDESKTOP' : [ None, { 46 | 'hsectionDesktop' : [ 0x3c, ['pointer', ['void']]], 47 | 'pheapDesktop' : [ 0x40, ['pointer', ['tagWIN32HEAP']]], 48 | 'ulHeapSize' : [ 0x44, ['unsigned long']], 49 | 'PtiList' : [ 0x60, ['_LIST_ENTRY']], 50 | }], 51 | 'tagSERVERINFO' : [ None, { 52 | 'cHandleEntries' : [ 4, ['unsigned long']], 53 | 'cbHandleTable' : [ 0x1b8, ['unsigned long']], 54 | }], 55 | }) 56 | 57 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/vboxinfo.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2009-2012 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | from volatility import renderers 20 | from volatility.commands import Command 21 | 22 | import volatility.plugins.crashinfo as crashinfo 23 | from volatility.renderers.basic import Address, Hex 24 | 25 | class VBoxInfo(crashinfo.CrashInfo): 26 | """Dump virtualbox information""" 27 | 28 | target_as = ['VirtualBoxCoreDumpElf64'] 29 | 30 | def unified_output(self, data): 31 | return renderers.TreeGrid([("FileOffset", Address), 32 | ("Memory Offset", Address), 33 | ("Size", Hex)], 34 | self.generator(data)) 35 | 36 | def generator(self, data): 37 | for memory_offset, file_offset, length in data.get_runs(): 38 | yield (0, [Address(file_offset), 39 | Address(memory_offset), 40 | Hex(length)]) 41 | 42 | def render_text(self, outfd, data): 43 | 44 | header = data.get_header() 45 | 46 | outfd.write("Magic: {0:#x}\n".format(header.u32Magic)) 47 | outfd.write("Format: {0:#x}\n".format(header.u32FmtVersion)) 48 | outfd.write("VirtualBox {0}.{1}.{2} (revision {3})\n".format( 49 | header.Major, 50 | header.Minor, header.Build, 51 | header.u32VBoxRevision)) 52 | outfd.write("CPUs: {0}\n\n".format(header.cCpus)) 53 | 54 | Command.render_text(self, outfd, data) 55 | 56 | class QemuInfo(VBoxInfo): 57 | """Dump Qemu information""" 58 | 59 | target_as = ['QemuCoreDumpElf'] 60 | 61 | def render_text(self, outfd, data): 62 | Command.render_text(self, outfd, data) -------------------------------------------------------------------------------- /volatility/volatility/plugins/multiscan.py: -------------------------------------------------------------------------------- 1 | import volatility.plugins.common as common 2 | import volatility.utils as utils 3 | import volatility.plugins.filescan as filescan 4 | import volatility.plugins.modscan as modscan 5 | import volatility.plugins.gui.atoms as atoms 6 | import volatility.plugins.gui.windowstations as windowstations 7 | import volatility.plugins.sockscan as sockscan 8 | import volatility.plugins.connscan as connscan 9 | import volatility.plugins.netscan as netscan 10 | import volatility.plugins.malware.callbacks as callbacks 11 | 12 | class MultiScan(common.AbstractScanCommand): 13 | """Scan for various objects at once""" 14 | 15 | def __init__(self, config, *args, **kwargs): 16 | common.AbstractScanCommand.__init__(self, config, *args, **kwargs) 17 | 18 | self.scanners = [ 19 | filescan.PoolScanFile, 20 | filescan.PoolScanDriver, 21 | filescan.PoolScanSymlink, 22 | filescan.PoolScanMutant, 23 | filescan.PoolScanProcess, 24 | modscan.PoolScanModule, 25 | modscan.PoolScanThread, 26 | atoms.PoolScanAtom, 27 | windowstations.PoolScanWind, 28 | ] 29 | 30 | def calculate(self): 31 | addr_space = utils.load_as(self._config) 32 | 33 | version = (addr_space.profile.metadata.get("major", 0), 34 | addr_space.profile.metadata.get("minor", 0)) 35 | 36 | if version < (6, 0): 37 | self.scanners.append(sockscan.PoolScanSocket) 38 | self.scanners.append(connscan.PoolScanConn) 39 | else: 40 | self.scanners.append(netscan.PoolScanUdpEndpoint) 41 | self.scanners.append(netscan.PoolScanTcpListener) 42 | self.scanners.append(netscan.PoolScanTcpEndpoint) 43 | self.scanners.append(callbacks.PoolScanDbgPrintCallback) 44 | self.scanners.append(callbacks.PoolScanRegistryCallback) 45 | self.scanners.append(callbacks.PoolScanPnp9) 46 | self.scanners.append(callbacks.PoolScanPnpD) 47 | self.scanners.append(callbacks.PoolScanPnpC) 48 | 49 | self.scanners.append(callbacks.PoolScanFSCallback) 50 | self.scanners.append(callbacks.PoolScanShutdownCallback) 51 | self.scanners.append(callbacks.PoolScanGenericCallback) 52 | 53 | 54 | for objct in self.scan_results(addr_space): 55 | yield objct 56 | 57 | def render_text(self, outfd, data): 58 | for objct in data: 59 | print objct -------------------------------------------------------------------------------- /volatility/tools/windows/parsesummary.py: -------------------------------------------------------------------------------- 1 | import json 2 | import sys 3 | import os 4 | 5 | """ 6 | Author: Gleeda 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License 10 | as published by the Free Software Foundation; either version 11 | 2 of the License, or (at your option) any later version. 12 | 13 | parsesummary.py [summary_file] 14 | Parses summary files created from the dumpfiles plugin 15 | 16 | """ 17 | 18 | def usage(name): 19 | print "{0} [summary_file]".format(name) 20 | 21 | def main(): 22 | try: 23 | summary = sys.argv[1] 24 | if os.path.isfile(summary): 25 | f = open(summary, "r") 26 | else: 27 | print summary, "is not a file!" 28 | usage(sys.argv[0]) 29 | return 30 | except: 31 | usage(sys.argv[0]) 32 | return 33 | 34 | heading = "*" * 80 35 | for line in f.readlines(): 36 | print heading 37 | item = json.loads(line.strip()) 38 | print "File: {0} -> {1}".format(item["name"], item["ofpath"]) 39 | print "\tPID: {0}".format(item["pid"]) 40 | print "\t_FILE_OBJECT offset: 0x{0:x}".format(item["fobj"]) 41 | print "\tType: {0}".format(item["type"]) 42 | vacbary = item.get("vacbary", []) 43 | if item["type"] == "SharedCacheMap" and vacbary != []: 44 | for vacb in vacbary: 45 | print "\tSize: {0}".format(vacb["size"]) 46 | present = vacb.get("present", None) 47 | padding = vacb.get("pad", None) 48 | if present != None: 49 | print "\tPresent Pages:" 50 | for page in present: 51 | print "\t\tOffset(V): 0x{0:x}, Length: {1}".format(page[0], page[1]) 52 | 53 | else: 54 | present = item.get("present", None) 55 | if present != None: 56 | print "\tPresent Pages:" 57 | if item["type"] != "SharedCacheMap": 58 | for page in present: 59 | print "\t\tOffset(P) 0x{0:x} FileOffset: 0x{1:x}, Size: {2}".format(page[0], page[1], page[2]) 60 | padding = item.get("pad", None) 61 | if padding != None: 62 | print "\tPadding:" 63 | for pad in padding: 64 | print "\t\tFileOffset: 0x{0:x} x 0x{1:x}".format(pad[0], pad[1]) 65 | print heading 66 | 67 | if __name__ == "__main__": 68 | main() 69 | -------------------------------------------------------------------------------- /volatility/volatility/renderers/html.py: -------------------------------------------------------------------------------- 1 | import StringIO 2 | from volatility.renderers.basic import Renderer 3 | 4 | try: 5 | import ujson as json 6 | except ImportError: 7 | import json 8 | 9 | __author__ = 'mike' 10 | 11 | class HTMLRenderer(Renderer): 12 | 13 | def __init__(self): 14 | pass 15 | 16 | def render(self, outfd, data): 17 | """Renders the treegrid to HTML""" 18 | column_titles = ", \n".join(["{ \"title\": \"" + column.name + "\"}" for column in data.columns]) 19 | json = StringIO.StringIO() 20 | JSONRenderer().render(json, data) 21 | outfd.write(""" 22 | 23 | 24 | 25 | 26 | 37 | 38 |
""" + "\n") 39 | 40 | class JSONRenderer(Renderer): 41 | def render_row(self, node, accumulator): 42 | return accumulator + [node.values] 43 | 44 | def render(self, outfd, data): 45 | """Renderers a treegrid as columns/row items in JSON format""" 46 | # TODO: Implement tree structure in JSON 47 | if data.max_depth() > 1: 48 | raise NotImplementedError("JSON output for trees has not yet been implemented") 49 | # TODO: Output (basic) type information in JSON 50 | json_input = {"columns": [column.name for column in data.columns], "rows": data.visit(None, self.render_row, [])} 51 | return outfd.write(json.dumps(json_input,ensure_ascii=False)) 52 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/dump_files.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.debug as debug 29 | import volatility.plugins.mac.common as common 30 | import volatility.plugins.mac.list_files as mac_list_files 31 | 32 | class mac_dump_file(common.AbstractMacCommand): 33 | """ Dumps a specified file """ 34 | 35 | def __init__(self, config, *args, **kwargs): 36 | common.AbstractMacCommand.__init__(self, config, *args, **kwargs) 37 | self._config.add_option('FILE-OFFSET', short_option = 'q', default = None, help = 'Virtual address of vnode structure from mac_list_files', action = 'store', type = 'int') 38 | self._config.add_option('OUTFILE', short_option = 'O', default = None, help = 'output file path', action = 'store', type = 'str') 39 | 40 | def calculate(self): 41 | common.set_plugin_members(self) 42 | 43 | outfile = self._config.outfile 44 | vnode_off = self._config.FILE_OFFSET 45 | 46 | if not outfile: 47 | debug.error("You must specify an output file (-O/--outfile)") 48 | 49 | if not vnode_off: 50 | debug.error("You must specificy a vnode address (-q/--file-offset) from mac_list_files") 51 | 52 | vnode = obj.Object("vnode", offset = vnode_off, vm = self.addr_space) 53 | 54 | wrote = common.write_vnode_to_file(vnode, outfile) 55 | 56 | yield vnode_off, outfile, wrote 57 | 58 | def render_text(self, outfd, data): 59 | for (vnode_off, outfile, wrote) in data: 60 | outfd.write("Wrote {0} bytes to {1} from vnode at address {2:x}\n".format(wrote, outfile, vnode_off)) 61 | 62 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/procdump.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License Version 2 as 8 | # published by the Free Software Foundation. You may not use, modify or 9 | # distribute this program under any other version of the GNU General 10 | # Public License. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | """ 22 | @author: Andrew Case 23 | @license: GNU General Public License 2.0 24 | @contact: atcuno@gmail.com 25 | @organization: 26 | """ 27 | import os 28 | 29 | import volatility.obj as obj 30 | import volatility.debug as debug 31 | import volatility.plugins.linux.common as linux_common 32 | import volatility.plugins.linux.pslist as linux_pslist 33 | 34 | class linux_procdump(linux_pslist.linux_pslist): 35 | """Dumps a process's executable image to disk""" 36 | 37 | def __init__(self, config, *args, **kwargs): 38 | linux_pslist.linux_pslist.__init__(self, config, *args, **kwargs) 39 | self._config.add_option('DUMP-DIR', short_option = 'D', default = None, help = 'Output directory', action = 'store', type = 'str') 40 | 41 | def render_text(self, outfd, data): 42 | if not self._config.DUMP_DIR: 43 | debug.error("-D/--dump-dir must given that specifies an existing directory") 44 | 45 | self.table_header(outfd, [("Offset", "[addrpad]"), 46 | ("Name", "20"), 47 | ("Pid", "15"), 48 | ("Address", "[addrpad]"), 49 | ("Output File", "")]) 50 | for task in data: 51 | if not task.mm: 52 | continue 53 | 54 | file_path = linux_common.write_elf_file(self._config.DUMP_DIR, task, task.mm.start_code) 55 | 56 | self.table_row(outfd, task.obj_offset, 57 | task.comm, 58 | str(task.pid), 59 | task.mm.start_code, 60 | file_path) 61 | 62 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/netstat.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import socket 28 | import volatility.obj as obj 29 | import volatility.plugins.linux.common as linux_common 30 | import volatility.plugins.linux.lsof as linux_lsof 31 | import volatility.plugins.linux.pslist as linux_pslist 32 | 33 | class linux_netstat(linux_pslist.linux_pslist): 34 | """Lists open sockets""" 35 | 36 | def __init__(self, config, *args, **kwargs): 37 | linux_pslist.linux_pslist.__init__(self, config, *args, **kwargs) 38 | self._config.add_option('IGNORE_UNIX', short_option = 'U', default = None, help = 'ignore unix sockets', action = 'store_true') 39 | 40 | # its a socket! 41 | def render_text(self, outfd, data): 42 | linux_common.set_plugin_members(self) 43 | 44 | if not self.addr_space.profile.has_type("inet_sock"): 45 | # ancient (2.6.9) centos kernels do not have inet_sock in debug info 46 | raise AttributeError, "Given profile does not have inet_sock, please file a bug if the kernel version is > 2.6.11" 47 | 48 | for task in data: 49 | for ents in task.netstat(): 50 | if ents[0] == socket.AF_INET: 51 | (_, proto, saddr, sport, daddr, dport, state) = ents[1] 52 | outfd.write("{0:8s} {1:<16}:{2:>5} {3:<16}:{4:>5} {5:<15s} {6:>17s}/{7:<5d}\n".format(proto, saddr, sport, daddr, dport, state, task.comm, task.pid)) 53 | 54 | elif ents[0] == 1 and not self._config.IGNORE_UNIX: 55 | (name, inum) = ents[1] 56 | outfd.write("UNIX {0:<8d} {1:>17s}/{2:<5d} {3:s}\n".format(inum, task.comm, task.pid, name)) 57 | 58 | 59 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/library_list.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 2 of the License, or (at 6 | # your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, but 9 | # WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | # General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program; if not, write to the Free Software 15 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 16 | 17 | """ 18 | @author: Andrew Case 19 | @license: GNU General Public License 2.0 20 | @contact: atcuno@gmail.com 21 | @organization: 22 | """ 23 | 24 | import volatility.obj as obj 25 | import volatility.debug as debug 26 | import volatility.plugins.linux.common as linux_common 27 | import volatility.plugins.linux.pslist as linux_pslist 28 | from volatility.renderers import TreeGrid 29 | from volatility.renderers.basic import Address 30 | 31 | class linux_library_list(linux_pslist.linux_pslist): 32 | """ Lists libraries loaded into a process """ 33 | 34 | def calculate(self): 35 | linux_common.set_plugin_members(self) 36 | 37 | tasks = linux_pslist.linux_pslist.calculate(self) 38 | 39 | for task in tasks: 40 | for mapping in task.get_libdl_maps(): 41 | if mapping.l_name == "" or mapping.l_addr == 0: 42 | continue 43 | 44 | yield task, mapping 45 | 46 | def unified_output(self, data): 47 | return TreeGrid([("Task", str), 48 | ("Pid", int), 49 | ("LoadAddress", Address), 50 | ("Path", str)], 51 | self.generator(data)) 52 | 53 | def generator(self, data): 54 | for task, mapping in data: 55 | yield (0, [str(task.comm), int(task.pid), Address(mapping.l_addr), str(mapping.l_name)]) 56 | 57 | def render_text(self, outfd, data): 58 | self.table_header(outfd, [("Task", "16"), 59 | ("Pid", "8"), 60 | ("Load Address", "[addrpad]"), 61 | ("Path", ""), 62 | ]) 63 | 64 | for task, mapping in data: 65 | self.table_row(outfd, task.comm, task.pid, mapping.l_addr, mapping.l_name) 66 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/mount.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.mac.common as common 29 | from volatility.renderers import TreeGrid 30 | 31 | class mac_mount(common.AbstractMacCommand): 32 | """ Prints mounted device information """ 33 | 34 | def calculate(self): 35 | common.set_plugin_members(self) 36 | 37 | mountlist_addr = self.addr_space.profile.get_symbol("_mountlist") 38 | mount = obj.Object("mount", offset = mountlist_addr, vm = self.addr_space) 39 | mount = mount.mnt_list.tqe_next 40 | 41 | while mount: 42 | yield mount 43 | mount = mount.mnt_list.tqe_next 44 | 45 | def unified_output(self, data): 46 | return TreeGrid ([ 47 | ("Device", str), 48 | ("Mount Point", str), 49 | ("Type", str), 50 | ], 51 | self.generator(data)) 52 | 53 | def generator(self, data): 54 | for mount in data: 55 | yield(0, [ 56 | str(mount.mnt_vfsstat.f_mntonname), 57 | str(mount.mnt_vfsstat.f_mntfromname), 58 | str(mount.mnt_vfsstat.f_fstypename), 59 | ]) 60 | 61 | def render_text(self, outfd, data): 62 | self.table_header(outfd, [("Device", "30"), ("Mount Point", "60"), ("Type", "")]) 63 | for mount in data: 64 | self.table_row(outfd, 65 | mount.mnt_vfsstat.f_mntonname, 66 | mount.mnt_vfsstat.f_mntfromname, 67 | mount.mnt_vfsstat.f_fstypename) 68 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/keyboard_notifiers.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # 3 | # This file is part of Volatility. 4 | # 5 | # Volatility is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License Version 2 as 7 | # published by the Free Software Foundation. You may not use, modify or 8 | # distribute this program under any other version of the GNU General 9 | # Public License. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Joe Sylve 22 | @license: GNU General Public License 2.0 23 | @contact: joe.sylve@gmail.com 24 | @organization: 504ENSICS Labs 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.debug as debug 29 | import volatility.plugins.linux.common as linux_common 30 | 31 | class linux_keyboard_notifiers(linux_common.AbstractLinuxCommand): 32 | """Parses the keyboard notifier call chain""" 33 | 34 | def calculate(self): 35 | linux_common.set_plugin_members(self) 36 | 37 | knl_addr = self.addr_space.profile.get_symbol("keyboard_notifier_list") 38 | 39 | if not knl_addr: 40 | debug.error("Symbol keyboard_notifier_list not found in kernel") 41 | 42 | knl = obj.Object("atomic_notifier_head", offset = knl_addr, vm = self.addr_space) 43 | 44 | symbol_cache = {} 45 | 46 | for call_back in linux_common.walk_internal_list("notifier_block", "next", knl.head): 47 | call_addr = call_back.notifier_call 48 | 49 | if symbol_cache.has_key(call_addr): 50 | sym_name = symbol_cache[call_addr] 51 | hooked = 0 52 | 53 | else: 54 | sym_name = self.profile.get_symbol_by_address("kernel", call_addr) 55 | if not sym_name: 56 | sym_name = "HOOKED" 57 | 58 | hooked = 1 59 | 60 | symbol_cache[call_addr] = sym_name 61 | 62 | yield call_addr, sym_name, hooked 63 | 64 | def render_text(self, outfd, data): 65 | self.table_header(outfd, [("Address", "[addrpad]"), ("Symbol", "<30")]) 66 | for call_addr, sym_name, _ in data: 67 | self.table_row(outfd, call_addr, sym_name) 68 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/dlyd_maps.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.mac.pstasks as pstasks 29 | import volatility.plugins.mac.common as common 30 | from volatility.renderers import TreeGrid 31 | from volatility.renderers.basic import Address 32 | 33 | class mac_dyld_maps(pstasks.mac_tasks): 34 | """ Gets memory maps of processes from dyld data structures """ 35 | 36 | def unified_output(self, data): 37 | common.set_plugin_members(self) 38 | 39 | return TreeGrid([("Pid", int), 40 | ("Name", str), 41 | ("Start", Address), 42 | ("Map Name", str), 43 | ], self.generator(data)) 44 | 45 | def generator(self, data): 46 | for proc in data: 47 | for map in proc.get_dyld_maps(): 48 | yield(0, [ 49 | int(proc.p_pid), 50 | str(proc.p_comm), 51 | Address(map.imageLoadAddress), 52 | str(map.imageFilePath), 53 | ]) 54 | 55 | def render_text(self, outfd, data): 56 | common.set_plugin_members(self) 57 | self.table_header(outfd, [("Pid", "8"), 58 | ("Name", "20"), 59 | ("Start", "#018x"), 60 | ("Map Name", "")]) 61 | 62 | for proc in data: 63 | for map in proc.get_dyld_maps(): 64 | self.table_row(outfd, 65 | str(proc.p_pid), 66 | proc.p_comm, 67 | map.imageLoadAddress, 68 | map.imageFilePath) 69 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/memdump.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | import os 21 | import volatility.plugins.mac.pstasks as pstasks 22 | import volatility.debug as debug 23 | 24 | class mac_memdump(pstasks.mac_tasks): 25 | """ Dump addressable memory pages to a file """ 26 | 27 | def __init__(self, config, *args, **kwargs): 28 | pstasks.mac_tasks.__init__(self, config, *args, **kwargs) 29 | self._config.add_option('DUMP-DIR', short_option = 'D', default = None, help = 'Output directory', action = 'store', type = 'str') 30 | 31 | def render_text(self, outfd, data): 32 | 33 | if (not self._config.DUMP_DIR or not 34 | os.path.isdir(self._config.DUMP_DIR)): 35 | debug.error("You must speficy a valid path with -D") 36 | 37 | for proc in data: 38 | name = "{0:X}.{1}.dmp".format(proc.obj_offset, proc.p_comm) 39 | path = os.path.join(self._config.DUMP_DIR, name) 40 | 41 | space = proc.get_process_address_space() 42 | if not space: 43 | outfd.write("Failed to acquire AS for: {0}\n".format(p_comm)) 44 | continue 45 | 46 | handle = open(path, "wb") 47 | if not handle: 48 | outfd.write("Failed to open file for writing: {0}\n".format(path)) 49 | continue 50 | 51 | bytes = 0 52 | 53 | try: 54 | for page, size in space.get_available_pages(): 55 | data = space.read(page, size) 56 | if not data: 57 | continue 58 | handle.write(data) 59 | bytes += size 60 | outfd.write("Wrote {0} bytes to {1}\n".format(bytes, path)) 61 | except IOError: 62 | outfd.write("Error dumping process: {0}\n".format(p_comm)) 63 | finally: 64 | handle.close() 65 | 66 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/overlays/windows/xp.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (c) 2008-2013 Volatility Foundation 3 | # Copyright (c) 2008 Brendan Dolan-Gavitt 4 | # 5 | # This file is part of Volatility. 6 | # 7 | # Volatility is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | """ 22 | @author: Brendan Dolan-Gavitt 23 | @license: GNU General Public License 2.0 24 | @contact: bdolangavitt@wesleyan.edu 25 | 26 | This file provides support for Windows XP. 27 | """ 28 | 29 | #pylint: disable-msg=C0111 30 | 31 | import volatility.debug as debug #pylint: disable-msg=W0611 32 | import volatility.obj as obj 33 | 34 | class XPOverlay(obj.ProfileModification): 35 | before = ['WindowsOverlay'] 36 | conditions = {'os': lambda x : x == 'windows', 37 | 'major': lambda x: x == 5, 38 | 'minor': lambda x: x == 1} 39 | 40 | def modification(self, profile): 41 | overlay = {'VOLATILITY_MAGIC': [ None, { 42 | 'DTBSignature' : [ None, ['VolatilityMagic', dict(value = "\x03\x00\x1b\x00")]], 43 | 'KDBGHeader' : [ None, ['VolatilityMagic', dict(value = '\x00\x00\x00\x00\x00\x00\x00\x00KDBG\x90\x02')]], 44 | 'HibrProcPage' : [ None, ['VolatilityMagic', dict(value = 0x2)]], 45 | 'HibrEntryCount' : [ None, ['VolatilityMagic', dict(value = 0xff)]], 46 | }], 47 | } 48 | profile.merge_overlay(overlay) 49 | 50 | class WinXPSP2x86(obj.Profile): 51 | """ A Profile for Windows XP SP2 x86 """ 52 | _md_major = 5 53 | _md_minor = 1 54 | _md_os = 'windows' 55 | _md_memory_model = '32bit' 56 | _md_vtype_module = 'volatility.plugins.overlays.windows.xp_sp2_x86_vtypes' 57 | _md_product = ["NtProductWinNt"] 58 | 59 | class WinXPSP3x86(obj.Profile): 60 | """ A Profile for Windows XP SP3 x86 """ 61 | _md_major = 5 62 | _md_minor = 1 63 | _md_os = 'windows' 64 | _md_memory_model = '32bit' 65 | _md_vtype_module = 'volatility.plugins.overlays.windows.xp_sp3_x86_vtypes' 66 | _md_product = ["NtProductWinNt"] 67 | 68 | 69 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/dentry_cache.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.plugins.linux.common as linux_common 28 | from volatility.plugins.linux.slab_info import linux_slabinfo 29 | 30 | class linux_dentry_cache(linux_common.AbstractLinuxCommand): 31 | """Gather files from the dentry cache""" 32 | 33 | def __init__(self, config, *args, **kwargs): 34 | linux_common.AbstractLinuxCommand.__init__(self, config, *args, **kwargs) 35 | self._config.add_option('UNALLOCATED', short_option = 'u', 36 | default = False, 37 | help = 'Show unallocated', 38 | action = 'store_true') 39 | 40 | def make_body(self, dentry): 41 | """Create a pipe-delimited bodyfile from a dentry structure. 42 | 43 | MD5|name|inode|mode_as_string|UID|GID|size|atime|mtime|ctime|crtime 44 | """ 45 | 46 | path = dentry.get_partial_path() or "" 47 | i = dentry.d_inode 48 | 49 | if i: 50 | ret = [0, path, i.i_ino, 0, i.i_uid, i.i_gid, i.i_size, i.i_atime, i.i_mtime, 0, i.i_ctime] 51 | else: 52 | ret = [0, path] + [0] * 8 53 | 54 | ret = "|".join([str(val) for val in ret]) 55 | return ret 56 | 57 | def calculate(self): 58 | linux_common.set_plugin_members(self) 59 | 60 | cache = linux_slabinfo(self._config).get_kmem_cache("dentry", self._config.UNALLOCATED) 61 | 62 | # support for old kernels 63 | if cache == []: 64 | cache = linux_slabinfo(self._config).get_kmem_cache("dentry_cache", self._config.UNALLOCATED, struct_name = "dentry") 65 | 66 | for dentry in cache: 67 | yield self.make_body(dentry) 68 | 69 | def render_text(self, outfd, data): 70 | 71 | for bodyline in data: 72 | outfd.write(bodyline + "\n") 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/addrspaces/osxpmemelf.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2014 Volatility Foundation 3 | # 4 | # Authors: 5 | # phil@teuwen.org (Philippe Teuwen) 6 | # espen@mrfjo.org (Espen Fjellvaer Olsen) 7 | # justincapella@gmail.com (Justin Capella) 8 | # michael.ligh@mnin.org (Michael Ligh) 9 | # 10 | # This file is part of Volatility. 11 | # 12 | # Volatility is free software; you can redistribute it and/or modify 13 | # it under the terms of the GNU General Public License as published by 14 | # the Free Software Foundation; either version 2 of the License, or 15 | # (at your option) any later version. 16 | # 17 | # Volatility is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | # GNU General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU General Public License 23 | # along with Volatility. If not, see . 24 | # 25 | # References: 26 | # VirtualBox core format: 27 | # http://www.virtualbox.org/manual/ch12.html#guestcoreformat 28 | # http://www.virtualbox.org/svn/vbox/trunk/include/VBox/vmm/dbgfcorefmt.h 29 | # http://www.virtualbox.org/svn/vbox/trunk/src/VBox/VMM/VMMR3/DBGFCoreWrite.cpp 30 | 31 | import volatility.obj as obj 32 | import volatility.addrspace as addrspace 33 | 34 | #pylint: disable-msg=C0111 35 | 36 | class OSXPmemELF(addrspace.AbstractRunBasedMemory): 37 | """ This AS supports VirtualBox ELF64 coredump format """ 38 | 39 | order = 90 40 | 41 | def __init__(self, base, config, **kwargs): 42 | ## We must have an AS below us 43 | self.as_assert(base, "No base Address Space") 44 | addrspace.AbstractRunBasedMemory.__init__(self, base, config, **kwargs) 45 | 46 | ## Quick test (before instantiating an object) 47 | ## for ELF64, little-endian - ELFCLASS64 and ELFDATA2LSB 48 | ## for ELF32, little-endian - ELFCLASS32 and ELFDATA2LSB 49 | self.as_assert(base.read(0, 6) in ['\x7fELF\x02\x01', '\x7fELF\x01\x01'], "ELF Header signature invalid") 50 | 51 | ## Base AS should be a file AS 52 | elf = obj.Object("elf_hdr", offset = 0, vm = base) 53 | 54 | ## The PT_NOTE core descriptor structure 55 | self.header = None 56 | 57 | for phdr in elf.program_headers(): 58 | 59 | # Only keep load segments with valid file sizes 60 | if (str(phdr.p_type) != 'PT_LOAD' or 61 | phdr.p_filesz == 0 or 62 | phdr.p_filesz != phdr.p_memsz): 63 | continue 64 | 65 | self.runs.append((int(phdr.p_paddr), 66 | int(phdr.p_offset), 67 | int(phdr.p_memsz))) 68 | 69 | self.as_assert(len(self.runs) > 0, "No PT_LOAD segments found") 70 | 71 | 72 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/gui/eventhooks.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # Copyright (C) 2010,2011,2012 Michael Hale Ligh 4 | # 5 | # This file is part of Volatility. 6 | # 7 | # Volatility is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | import volatility.plugins.gui.sessions as sessions 22 | 23 | class EventHooks(sessions.Sessions): 24 | """Print details on windows event hooks""" 25 | 26 | def render_text(self, outfd, data): 27 | 28 | for session in data: 29 | shared_info = session.find_shared_info() 30 | 31 | if not shared_info: 32 | continue 33 | 34 | filters = [lambda x : str(x.bType) == "TYPE_WINEVENTHOOK"] 35 | 36 | for handle in shared_info.handles(filters): 37 | 38 | outfd.write("Handle: {0:#x}, Object: {1:#x}, Session: {2}\n".format( 39 | handle.phead.h if handle.phead else 0, 40 | handle.phead.v(), 41 | session.SessionId)) 42 | 43 | outfd.write("Type: {0}, Flags: {1}, Thread: {2}, Process: {3}\n".format( 44 | handle.bType, 45 | handle.bFlags, 46 | handle.Thread.Cid.UniqueThread, 47 | handle.Process.UniqueProcessId, 48 | )) 49 | 50 | event_hook = handle.reference_object() 51 | 52 | outfd.write("eventMin: {0:#x} {1}\neventMax: {2:#x} {3}\n".format( 53 | event_hook.eventMin.v(), 54 | str(event_hook.eventMin), 55 | event_hook.eventMax.v(), 56 | str(event_hook.eventMax), 57 | )) 58 | 59 | outfd.write("Flags: {0}, offPfn: {1:#x}, idProcess: {2}, idThread: {3}\n".format( 60 | event_hook.dwFlags, 61 | event_hook.offPfn, 62 | event_hook.idProcess, 63 | event_hook.idThread, 64 | )) 65 | 66 | ## Work out the WindowStation\Desktop path by the handle 67 | ## owner (thread or process) 68 | 69 | outfd.write("ihmod: {0}\n".format(event_hook.ihmod)) 70 | outfd.write("\n") 71 | 72 | 73 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/malfind.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License Version 2 as 8 | # published by the Free Software Foundation. You may not use, modify or 9 | # distribute this program under any other version of the GNU General 10 | # Public License. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | """ 22 | @author: Andrew Case 23 | @license: GNU General Public License 2.0 24 | @contact: atcuno@gmail.com 25 | @organization: 26 | """ 27 | 28 | import volatility.obj as obj 29 | import volatility.utils as utils 30 | import volatility.plugins.malware.malfind as malfind 31 | import volatility.plugins.mac.common as mac_common 32 | import volatility.plugins.mac.pstasks as mac_pstasks 33 | 34 | class mac_malfind(mac_pstasks.mac_tasks): 35 | """Looks for suspicious process mappings""" 36 | 37 | def render_text(self, outfd, data): 38 | for task in data: 39 | proc_as = task.get_process_address_space() 40 | 41 | bit_string = str(task.task.map.pmap.pm_task_map or '')[9:] 42 | 43 | if bit_string == "64BIT": 44 | bits = '64bit' 45 | else: 46 | bits = '32bit' 47 | 48 | for map in task.get_proc_maps(): 49 | if map.is_suspicious(): 50 | fname = map.get_path() 51 | prots = map.get_perms() 52 | 53 | content = proc_as.zread(map.start, 64) 54 | 55 | outfd.write("Process: {0} Pid: {1} Address: {2:#x} File: {3}\n".format( 56 | task.p_comm, task.p_pid, map.start, fname)) 57 | 58 | outfd.write("Protection: {0}\n".format(prots)) 59 | 60 | outfd.write("\n") 61 | 62 | outfd.write("{0}\n".format("\n".join( 63 | ["{0:#010x} {1:<48} {2}".format(map.start + o, h, ''.join(c)) 64 | for o, h, c in utils.Hexdump(content) 65 | ]))) 66 | 67 | outfd.write("\n") 68 | outfd.write("\n".join( 69 | ["{0:#x} {1:<16} {2}".format(o, h, i) 70 | for o, i, h in malfind.Disassemble(content, map.start, bits = bits) 71 | ])) 72 | 73 | outfd.write("\n\n") 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/ldrmodules.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License Version 2 as 8 | # published by the Free Software Foundation. You may not use, modify or 9 | # distribute this program under any other version of the GNU General 10 | # Public License. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | """ 22 | @author: Andrew Case 23 | @license: GNU General Public License 2.0 24 | @contact: atcuno@gmail.com 25 | @organization: 26 | """ 27 | 28 | import volatility.obj as obj 29 | import volatility.plugins.linux.common as linux_common 30 | import volatility.plugins.linux.pslist as linux_pslist 31 | from volatility.renderers import TreeGrid 32 | from volatility.renderers.basic import Address 33 | 34 | class linux_ldrmodules(linux_pslist.linux_pslist): 35 | """Compares the output of proc maps with the list of libraries from libdl""" 36 | 37 | def unified_output(self, data): 38 | return TreeGrid([("Pid", int), 39 | ("Name", str), 40 | ("Start", Address), 41 | ("Path", str), 42 | ("Kernel", str), 43 | ("Libc", str)], 44 | self.generator(data)) 45 | 46 | def generator(self, data): 47 | for task in data: 48 | for vm_start, vma_name, pmaps, dmaps in task.ldrmodules(): 49 | yield (0, [int(task.pid), 50 | str(task.comm), 51 | Address(vm_start), 52 | str(vma_name), 53 | str(pmaps), 54 | str(dmaps)]) 55 | 56 | def render_text(self, outfd, data): 57 | self.table_header(outfd, [("Pid", "8"), 58 | ("Name", "16"), 59 | ("Start", "#018x"), 60 | ("File Path", "50"), 61 | ("Kernel", "6"), 62 | ("Libc", "6"), 63 | ]) 64 | 65 | for task in data: 66 | for vm_start, vma_name, pmaps, dmaps in task.ldrmodules(): 67 | self.table_row(outfd, 68 | task.pid, 69 | str(task.comm), 70 | vm_start, 71 | vma_name, 72 | pmaps, 73 | dmaps) 74 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/dead_sockets.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.mac.common as common 29 | import volatility.plugins.mac.list_zones as list_zones 30 | import volatility.plugins.mac.netstat as netstat 31 | 32 | class mac_dead_sockets(netstat.mac_netstat): 33 | """ Prints terminated/de-allocated network sockets """ 34 | 35 | def calculate(self): 36 | common.set_plugin_members(self) 37 | 38 | zones = list_zones.mac_list_zones(self._config).calculate() 39 | 40 | for zone in zones: 41 | name = str(zone.zone_name.dereference()) 42 | if name == "socket": 43 | sockets = zone.get_free_elements("socket") 44 | for socket in sockets: 45 | yield socket 46 | 47 | def render_text(self, outfd, data): 48 | self.table_header(outfd, [("Proto", "6"), 49 | ("Local IP", "20"), 50 | ("Local Port", "6"), 51 | ("Remote IP", "20"), 52 | ("Remote Port", "6"), 53 | ("State", "10")]) 54 | 55 | for socket in data: 56 | family = socket.family 57 | 58 | if family == 1: 59 | upcb = socket.so_pcb.dereference_as("unpcb") 60 | path = upcb.unp_addr.sun_path 61 | outfd.write("UNIX {0}\n".format(path)) 62 | elif family in [2, 30]: 63 | proto = socket.protocol 64 | state = socket.state 65 | 66 | ret = socket.get_connection_info() 67 | 68 | if ret: 69 | (lip, lport, rip, rport) = ret 70 | else: 71 | (lip, lport, rip, rport) = ("", "", "", "") 72 | 73 | self.table_row(outfd, proto, lip, lport, rip, rport, state) 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/ifconfig.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.mac.common as common 29 | 30 | class mac_ifconfig(common.AbstractMacCommand): 31 | """ Lists network interface information for all devices """ 32 | 33 | def calculate(self): 34 | common.set_plugin_members(self) 35 | 36 | list_head_addr = self.addr_space.profile.get_symbol("_ifnet_head") 37 | if list_head_addr == None: 38 | list_head_addr = self.addr_space.profile.get_symbol("_dlil_ifnet_head") 39 | 40 | list_head_ptr = obj.Object("Pointer", offset = list_head_addr, vm = self.addr_space) 41 | ifnet = list_head_ptr.dereference_as("ifnet") 42 | 43 | while ifnet: 44 | name = ifnet.if_name.dereference() 45 | unit = ifnet.if_unit 46 | prom = ifnet.if_flags & 0x100 == 0x100 # IFF_PROMISC 47 | 48 | addr_dl = ifnet.sockaddr_dl() 49 | 50 | if addr_dl.is_valid(): 51 | mac = addr_dl.v() 52 | else: 53 | mac = "" 54 | 55 | ifaddr = ifnet.if_addrhead.tqh_first 56 | ips = [] 57 | 58 | while ifaddr: 59 | ip = ifaddr.ifa_addr.get_address() 60 | if ip: 61 | ips.append(ip) 62 | 63 | ifaddr = ifaddr.ifa_link.tqe_next 64 | 65 | yield (name, unit, mac, prom, ips) 66 | ifnet = ifnet.if_link.tqe_next 67 | 68 | def render_text(self, outfd, data): 69 | self.table_header(outfd, [("Interface", "10"), ("IP Address", "32"), ("Mac Address", "20"), ("Promiscuous", "")]) 70 | 71 | for (name, unit, mac, prom, ips) in data: 72 | if ips: 73 | for ip in ips: 74 | self.table_row(outfd, "{0}{1}".format(name, unit), ip, mac, prom) 75 | else: 76 | # an interface with no IPs 77 | self.table_row(outfd, "{0}{1}".format(name, unit), "", mac, prom) 78 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/psaux.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.plugins.mac.pstasks as pstasks 28 | from volatility.renderers import TreeGrid 29 | from volatility.renderers.basic import Address 30 | 31 | class mac_psaux(pstasks.mac_tasks): 32 | """ Prints processes with arguments in user land (**argv) """ 33 | 34 | def unified_output(self, data): 35 | return TreeGrid([("Pid", int), 36 | ("Name", str), 37 | ("Bits", str), 38 | ("Stack", Address), 39 | ("Length", int), 40 | ("Argc", int), 41 | ("Arguments", str) 42 | ], self.generator(data)) 43 | 44 | def generator(self, data): 45 | for proc in data: 46 | yield(0, [ 47 | int(proc.p_pid), 48 | str(proc.p_comm), 49 | str(proc.task.map.pmap.pm_task_map), 50 | Address(proc.user_stack), 51 | int(proc.p_argslen), 52 | int(proc.p_argc), 53 | str(proc.get_arguments()), 54 | ]) 55 | 56 | def render_text(self, outfd, data): 57 | 58 | self.table_header(outfd, [("Pid", "8"), 59 | ("Name", "20"), 60 | ("Bits", "16"), 61 | ("Stack", "#018x"), 62 | ("Length", "8"), 63 | ("Argc", "8"), 64 | ("Arguments", "")]) 65 | for proc in data: 66 | self.table_row(outfd, 67 | proc.p_pid, 68 | proc.p_comm, 69 | str(proc.task.map.pmap.pm_task_map or '')[9:], 70 | proc.user_stack, 71 | proc.p_argslen, 72 | proc.p_argc, 73 | proc.get_arguments()) 74 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/elfs.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # Copyright (C) 2014 CrowdStrike, Inc. 4 | # 5 | # This file is part of Volatility. 6 | # 7 | # Volatility is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | """ 22 | @author: Georg Wicherski 23 | @license: GNU General Public License 2.0 24 | @contact: georg@crowdstrike.com 25 | @organization: CrowdStrike, Inc. 26 | """ 27 | 28 | import volatility.obj as obj 29 | import volatility.debug as debug 30 | import volatility.plugins.linux.common as linux_common 31 | import volatility.plugins.linux.pslist as linux_pslist 32 | import volatility.plugins.linux.dump_map as linux_dump_map 33 | from volatility.renderers import TreeGrid 34 | from volatility.renderers.basic import Address 35 | 36 | class linux_elfs(linux_pslist.linux_pslist): 37 | """Find ELF binaries in process mappings""" 38 | 39 | def calculate(self): 40 | linux_common.set_plugin_members(self) 41 | tasks = linux_pslist.linux_pslist.calculate(self) 42 | 43 | for task in tasks: 44 | for elf, elf_start, elf_end, soname, needed in task.elfs(): 45 | yield task, elf, elf_start, elf_end, soname, needed 46 | 47 | def unified_output(self, data): 48 | return TreeGrid([("Pid", int), 49 | ("Name", str), 50 | ("Start", Address), 51 | ("End", Address), 52 | ("Path", str), 53 | ("Needed", str)], 54 | self.generator(data)) 55 | 56 | def generator(self, data): 57 | for task, elf, start, end, soname, needed in data: 58 | yield (0, [int(task.pid), str(task.comm), Address(start), Address(end), str(soname), ",".join(needed)]) 59 | 60 | 61 | def render_text(self, outfd, data): 62 | self.table_header(outfd, [("Pid", "8"), 63 | ("Name", "17"), 64 | ("Start", "[addrpad]"), 65 | ("End", "[addrpad]"), 66 | ("Elf Path", "60"), 67 | ("Needed", "") 68 | ]) 69 | for task, elf, start, end, soname, needed in data: 70 | self.table_row(outfd, task.pid, task.comm, start, end, soname, ",".join(needed)) 71 | 72 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/cmdline.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | import volatility.plugins.taskmods as taskmods 21 | from volatility.renderers import TreeGrid 22 | 23 | class Cmdline(taskmods.DllList): 24 | """Display process command-line arguments""" 25 | def __init__(self, config, *args, **kwargs): 26 | taskmods.DllList.__init__(self, config, *args, **kwargs) 27 | config.add_option("VERBOSE", short_option = 'v', 28 | default = False, cache_invalidator = False, 29 | help = "Display full path of executable", 30 | action = "store_true") 31 | 32 | def unified_output(self, data): 33 | # blank header in case there is no shimcache data 34 | return TreeGrid([("Process", str), 35 | ("PID", int), 36 | ("CommandLine", str), 37 | ], self.generator(data)) 38 | 39 | def generator(self, data): 40 | for task in data: 41 | cmdline = "" 42 | name = str(task.ImageFileName) 43 | try: 44 | if self._config.VERBOSE and task.SeAuditProcessCreationInfo.ImageFileName.Name != None: 45 | name = str(task.SeAuditProcessCreationInfo.ImageFileName.Name) 46 | except AttributeError: 47 | pass 48 | if task.Peb: 49 | cmdline = "{0}".format(str(task.Peb.ProcessParameters.CommandLine or '')).strip() 50 | yield (0, [name, int(task.UniqueProcessId), str(cmdline)]) 51 | 52 | def render_text(self, outfd, data): 53 | for task in data: 54 | pid = task.UniqueProcessId 55 | name = str(task.ImageFileName) 56 | try: 57 | if self._config.VERBOSE and task.SeAuditProcessCreationInfo.ImageFileName.Name != None: 58 | name = str(task.SeAuditProcessCreationInfo.ImageFileName.Name) 59 | except AttributeError: 60 | pass 61 | 62 | outfd.write("*" * 72 + "\n") 63 | outfd.write("{0} pid: {1:6}\n".format(name, pid)) 64 | 65 | if task.Peb: 66 | outfd.write("Command line : {0}\n".format(str(task.Peb.ProcessParameters.CommandLine or ''))) 67 | 68 | -------------------------------------------------------------------------------- /volatility/contrib/plugins/example.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # 3 | # Authors: 4 | # Mike Auty 5 | # 6 | # This file is part of Volatility. 7 | # 8 | # Volatility is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # Volatility is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Volatility. If not, see . 20 | # 21 | 22 | import volatility.timefmt as timefmt 23 | import volatility.obj as obj 24 | import volatility.utils as utils 25 | import volatility.commands as commands 26 | 27 | #pylint: disable-msg=C0111 28 | 29 | class DateTime(commands.Command): 30 | """A simple example plugin that gets the date/time information from a Windows image""" 31 | def calculate(self): 32 | """Calculate and carry out any processing that may take time upon the image""" 33 | # Load the address space 34 | addr_space = utils.load_as(self._config) 35 | 36 | # Call a subfunction so that it can be used by other plugins 37 | return self.get_image_time(addr_space) 38 | 39 | def get_image_time(self, addr_space): 40 | """Extracts the time and date from the KUSER_SHARED_DATA area""" 41 | # Get the Image Datetime 42 | result = {} 43 | 44 | # Create a VOLATILITY_MAGIC object to look up the location of certain constants 45 | # Get the KUSER_SHARED_DATA location 46 | KUSER_SHARED_DATA = obj.VolMagic(addr_space).KUSER_SHARED_DATA.v() 47 | # Create the _KUSER_SHARED_DATA object at the appropriate offset 48 | k = obj.Object("_KUSER_SHARED_DATA", 49 | offset = KUSER_SHARED_DATA, 50 | vm = addr_space) 51 | 52 | # Start reading members from it 53 | result['ImageDatetime'] = k.SystemTime 54 | result['ImageTz'] = timefmt.OffsetTzInfo(-k.TimeZoneBias.as_windows_timestamp() / 10000000) 55 | 56 | # Return any results we got 57 | return result 58 | 59 | def render_text(self, outfd, data): 60 | """Renders the calculated data as text to outfd""" 61 | # Convert the result into a datetime object for display in local and non local format 62 | dt = data['ImageDatetime'].as_datetime() 63 | 64 | # Display the datetime in UTC as taken from the image 65 | outfd.write("Image date and time : {0}\n".format(data['ImageDatetime'])) 66 | # Display the datetime taking into account the timezone of the image itself 67 | outfd.write("Image local date and time : {0}\n".format(timefmt.display_datetime(dt, data['ImageTz']))) 68 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/gui/gahti.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # Copyright (C) 2010,2011,2012 Michael Hale Ligh 4 | # 5 | # This file is part of Volatility. 6 | # 7 | # Volatility is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | from volatility import renderers 21 | from volatility.renderers.basic import Address 22 | from volatility.renderers.text import TextRenderer 23 | 24 | import volatility.utils as utils 25 | import volatility.debug as debug 26 | import volatility.plugins.gui.constants as consts 27 | import volatility.plugins.gui.sessions as sessions 28 | 29 | class Gahti(sessions.Sessions): 30 | """Dump the USER handle type information""" 31 | 32 | def unified_output(self, data): 33 | 34 | return renderers.TreeGrid( 35 | [("Session", str), 36 | ("Type", str), 37 | ("Tag", str), 38 | ("fnDestroy", Address), 39 | ("Flags", str), 40 | ], self.generator(data)) 41 | 42 | def generator(self, data): 43 | profile = utils.load_as(self._config).profile 44 | 45 | # Get the OS version being analyzed 46 | version = (profile.metadata.get('major', 0), 47 | profile.metadata.get('minor', 0)) 48 | 49 | # Choose which USER handle enum to use 50 | if version >= (6, 1): 51 | handle_types = consts.HANDLE_TYPE_ENUM_SEVEN 52 | else: 53 | handle_types = consts.HANDLE_TYPE_ENUM 54 | 55 | for session in data: 56 | gahti = session.find_gahti() 57 | if gahti: 58 | for i, h in handle_types.items(): 59 | yield (0, 60 | [str(session.SessionId), 61 | str(h), 62 | str(gahti.types[i].dwAllocTag), 63 | Address(gahti.types[i].fnDestroy), 64 | str(gahti.types[i].bObjectCreateFlags)]) 65 | 66 | def render_text(self, outfd, data): 67 | output = self.unified_output(data) 68 | 69 | if isinstance(output, renderers.TreeGrid): 70 | tr = TextRenderer(self.text_cell_renderers, sort_column = self.text_sort_column) 71 | tr.render(outfd, output) 72 | else: 73 | raise TypeError("Unified Output must return a TreeGrid object") 74 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/psscan.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | import struct 27 | 28 | import volatility.obj as obj 29 | import volatility.utils as utils 30 | import volatility.poolscan as poolscan 31 | import volatility.debug as debug 32 | 33 | import volatility.plugins.linux.common as linux_common 34 | import volatility.plugins.linux.pslist as pslist 35 | 36 | from volatility.renderers import TreeGrid 37 | from volatility.renderers.basic import Address 38 | 39 | class linux_psscan(pslist.linux_pslist): 40 | """ Scan physical memory for processes """ 41 | 42 | def __init__(self, config, *args, **kwargs): 43 | linux_common.AbstractLinuxCommand.__init__(self, config, *args, **kwargs) 44 | self.wants_physical = True 45 | 46 | def calculate(self): 47 | linux_common.set_plugin_members(self) 48 | 49 | phys_addr_space = utils.load_as(self._config, astype = 'physical') 50 | 51 | if phys_addr_space.profile.metadata.get('memory_model', '32bit') == "32bit": 52 | fmt = " 5 | # 6 | # This file is part of Volatility. 7 | # 8 | # Volatility is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 2 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # Volatility is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with Volatility. If not, see . 20 | # 21 | 22 | """ General debugging framework """ 23 | import pdb 24 | import sys 25 | import inspect 26 | import logging 27 | import volatility.conf 28 | config = volatility.conf.ConfObject() 29 | 30 | config.add_option("DEBUG", short_option = 'd', default = 0, 31 | cache_invalidator = False, 32 | action = 'count', help = "Debug volatility") 33 | 34 | # Largest debug value used + 1 35 | MAX_DEBUG = 3 36 | 37 | def setup(level = 0): 38 | """Sets up the global logging environment""" 39 | formatstr = "%(levelname)-8s: %(name)-20s: %(message)s" 40 | logging.basicConfig(format = formatstr) 41 | rootlogger = logging.getLogger('') 42 | rootlogger.setLevel(logging.DEBUG + 1 - level) 43 | for i in range(1, 9): 44 | logging.addLevelName(logging.DEBUG - i, "DEBUG" + str(i)) 45 | 46 | def debug(msg, level = 1): 47 | """Logs a message at the DEBUG level""" 48 | log(msg, logging.DEBUG + 1 - level) 49 | 50 | def info(msg): 51 | """Logs a message at the INFO level""" 52 | log(msg, logging.INFO) 53 | 54 | def warning(msg): 55 | """Logs a message at the WARNING level""" 56 | log(msg, logging.WARNING) 57 | 58 | def error(msg): 59 | log(msg, logging.ERROR) 60 | sys.exit(1) 61 | 62 | def critical(msg): 63 | log(msg, logging.CRITICAL) 64 | sys.exit(1) 65 | 66 | def log(msg, level): 67 | modname = "volatility.py" 68 | try: 69 | frm = inspect.currentframe() 70 | modname = "volatility.debug" 71 | while modname == "volatility.debug": 72 | frm = frm.f_back 73 | mod = inspect.getfile(frm) 74 | modname = mod.__name__ 75 | except AttributeError: 76 | pass 77 | finally: 78 | del frm 79 | _log(msg, modname, level) 80 | 81 | def _log(msg, facility, loglevel): 82 | """Outputs a debugging message""" 83 | logger = logging.getLogger(facility) 84 | logger.log(loglevel, msg) 85 | 86 | def b(level = 1): 87 | """Enters the debugger at the call point""" 88 | if config.DEBUG >= level: 89 | pdb.set_trace() 90 | 91 | trace = b 92 | 93 | def post_mortem(level = 1): 94 | """Provides a command line interface to python after an exception's occurred""" 95 | if config.DEBUG >= level: 96 | pdb.post_mortem() 97 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/vma_cache.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.linux.common as linux_common 29 | from volatility.plugins.linux.slab_info import linux_slabinfo 30 | 31 | class linux_vma_cache(linux_common.AbstractLinuxCommand): 32 | """Gather VMAs from the vm_area_struct cache""" 33 | 34 | def __init__(self, config, *args, **kwargs): 35 | linux_common.AbstractLinuxCommand.__init__(self, config, *args, **kwargs) 36 | self._config.add_option('UNALLOCATED', short_option = 'u', 37 | default = False, 38 | help = 'Show unallocated', 39 | action = 'store_true') 40 | 41 | def calculate(self): 42 | linux_common.set_plugin_members(self) 43 | 44 | has_owner = self.profile.obj_has_member("mm_struct", "owner") 45 | 46 | cache = linux_slabinfo(self._config).get_kmem_cache("vm_area_struct", self._config.UNALLOCATED) 47 | 48 | for vm in cache: 49 | start = vm.vm_start 50 | end = vm.vm_end 51 | 52 | if has_owner and vm.vm_mm and vm.vm_mm.is_valid(): 53 | task = vm.vm_mm.owner 54 | (task_name, pid) = (task.comm, task.pid) 55 | else: 56 | (task_name, pid) = ("", "") 57 | 58 | if vm.vm_file and vm.vm_file.is_valid(): 59 | path = vm.vm_file.dentry.get_partial_path() 60 | else: 61 | path = "" 62 | 63 | yield task_name, pid, start, end, path 64 | 65 | def render_text(self, outfd, data): 66 | 67 | self.table_header(outfd, [("Process", "16"), 68 | ("PID", "6"), 69 | ("Start", "[addrpad]"), 70 | ("End", "[addrpad]"), 71 | ("Path", "")]) 72 | 73 | for task_name, pid, start, end, path in data: 74 | 75 | self.table_row(outfd, task_name, pid, start, end, path) 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/plthook.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # Copyright (C) 2014 CrowdStrike, Inc. 4 | # 5 | # This file is part of Volatility. 6 | # 7 | # Volatility is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | """ 22 | @author: Georg Wicherski 23 | @license: GNU General Public License 2.0 24 | @contact: georg@crowdstrike.com 25 | @organization: CrowdStrike, Inc. 26 | """ 27 | 28 | import volatility.obj as obj 29 | import volatility.plugins.linux.common as linux_common 30 | import volatility.plugins.linux.pslist as linux_pslist 31 | 32 | class linux_plthook(linux_pslist.linux_pslist): 33 | """Scan ELF binaries' PLT for hooks to non-NEEDED images""" 34 | 35 | def __init__(self, config, *args, **kwargs): 36 | linux_pslist.linux_pslist.__init__(self, config, *args, **kwargs) 37 | self._config.add_option( \ 38 | 'ALL', short_option = 'a', default = False, 39 | help = 'Display all PLT slots (incl. not hooked)', action = 'store_true') 40 | self._config.add_option( \ 41 | 'IGNORE', default = [ ], 42 | help = 'Ignore mappings backed by this path, ' \ 43 | +' useful for bad -l compiles (i.e. apache2 modules)', 44 | action = 'append') 45 | 46 | def render_text(self, outfd, data): 47 | linux_common.set_plugin_members(self) 48 | 49 | self.table_header(outfd, [("Task", "10"), 50 | ("ELF Start", "[addrpad]"), 51 | ("ELF Name", "24"), 52 | ("Symbol", "24"), 53 | ("Resolved Address", "[addrpad]"), 54 | ("H", "1"), 55 | ("Target Info", "")]) 56 | 57 | ignore = frozenset(self._config.IGNORE) 58 | 59 | for task in data: 60 | for soname, elf, elf_start, elf_end, addr, symbol_name, hookdesc, hooked in task.plt_hook_info(): 61 | if not hooked and not self._config.ALL: 62 | continue 63 | 64 | if hookdesc in ignore: 65 | continue 66 | 67 | if hookdesc == '[RTLD_LAZY]' and not self._config.ALL: 68 | continue 69 | 70 | self.table_row(outfd, task.pid, elf_start, soname if soname else '[main]', \ 71 | symbol_name, addr, '!' if hooked else ' ', hookdesc) 72 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/tty_check.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # 3 | # This file is part of Volatility. 4 | # 5 | # Volatility is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # Volatility is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with Volatility. If not, see . 17 | # 18 | 19 | """ 20 | @author: Joe Sylve 21 | @license: GNU General Public License 2.0 22 | @contact: joe.sylve@gmail.com 23 | @organization: 504ENSICS Labs 24 | """ 25 | 26 | import volatility.obj as obj 27 | import volatility.debug as debug 28 | import volatility.plugins.linux.common as linux_common 29 | import volatility.plugins.linux.lsmod as linux_lsmod 30 | 31 | class linux_check_tty(linux_common.AbstractLinuxCommand): 32 | """Checks tty devices for hooks""" 33 | 34 | def calculate(self): 35 | linux_common.set_plugin_members(self) 36 | 37 | modules = linux_lsmod.linux_lsmod(self._config).get_modules() 38 | 39 | tty_addr = self.addr_space.profile.get_symbol("tty_drivers") 40 | 41 | if not tty_addr: 42 | debug.error("Symbol tty_drivers not found in kernel") 43 | 44 | drivers = obj.Object("list_head", offset = tty_addr, vm = self.addr_space) 45 | 46 | sym_cache = {} 47 | 48 | for tty in drivers.list_of_type("tty_driver", "tty_drivers"): 49 | name = tty.name.dereference_as("String", length = linux_common.MAX_STRING_LENGTH) 50 | 51 | ttys = obj.Object("Array", targetType = "Pointer", vm = self.addr_space, offset = tty.ttys, count = tty.num) 52 | for tty_dev in ttys: 53 | if tty_dev == 0: 54 | continue 55 | 56 | tty_dev = tty_dev.dereference_as("tty_struct") 57 | name = tty_dev.name 58 | recv_buf = tty_dev.ldisc.ops.receive_buf 59 | 60 | known = self.is_known_address(recv_buf, modules) 61 | 62 | if not known: 63 | sym_name = "HOOKED" 64 | hooked = 1 65 | else: 66 | sym_name = self.profile.get_symbol_by_address("kernel", recv_buf) 67 | hooked = 0 68 | 69 | sym_cache[recv_buf] = sym_name 70 | 71 | yield (name, recv_buf, sym_name, hooked) 72 | 73 | def render_text(self, outfd, data): 74 | self.table_header(outfd, [("Name", "<16"), ("Address", "[addrpad]"), ("Symbol", "<30")]) 75 | for name, call_addr, sym_name, _hooked in data: 76 | self.table_row(outfd, name, call_addr, sym_name) 77 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/sk_buff_cache.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import os 28 | import volatility.debug as debug 29 | import volatility.plugins.linux.common as linux_common 30 | from volatility.plugins.linux.slab_info import linux_slabinfo 31 | 32 | class linux_sk_buff_cache(linux_common.AbstractLinuxCommand): 33 | """Recovers packets from the sk_buff kmem_cache""" 34 | 35 | def __init__(self, config, *args, **kwargs): 36 | self.edir = None 37 | linux_common.AbstractLinuxCommand.__init__(self, config, *args, **kwargs) 38 | self._config.add_option('UNALLOCATED', short_option = 'u', default = False, help = 'Show unallocated', action = 'store_true') 39 | self._config.add_option('DUMP-DIR', short_option = 'D', default = None, help = 'output directory for recovered packets', action = 'store', type = 'str') 40 | 41 | def write_sk_buff(self, s): 42 | pkt_len = s.len 43 | 44 | # keep sane sized packets 45 | if 0 < pkt_len < 0x6400000: 46 | 47 | start = s.data 48 | 49 | data = self.addr_space.zread(start, pkt_len) 50 | 51 | fname = "{0:x}".format(s.obj_offset) 52 | fd = open(os.path.join(self.edir, fname), "wb") 53 | fd.write(data) 54 | fd.close() 55 | 56 | yield "Wrote {0:d} bytes to {1:s}".format(pkt_len, fname) 57 | 58 | def walk_cache(self, cache_name): 59 | cache = linux_slabinfo(self._config).get_kmem_cache(cache_name, self._config.UNALLOCATED, struct_name = "sk_buff") 60 | 61 | if not cache: 62 | return 63 | 64 | for s in cache: 65 | for msg in self.write_sk_buff(s): 66 | yield msg 67 | 68 | def calculate(self): 69 | linux_common.set_plugin_members(self) 70 | 71 | self.edir = self._config.DUMP_DIR 72 | 73 | if not self.edir: 74 | debug.error("No output directory given.") 75 | 76 | for msg in self.walk_cache("skbuff_head_cache"): 77 | yield msg 78 | 79 | for msg in self.walk_cache("skbuff_fclone_cache"): 80 | yield msg 81 | 82 | def render_text(self, outfd, data): 83 | 84 | for msg in data: 85 | outfd.write("{0:s}\n".format(msg)) 86 | 87 | 88 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/overlays/windows/kpcr_vtypes.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # Copyright (c) 2012 Michael Ligh 4 | # 5 | # This file is part of Volatility. 6 | # 7 | # Volatility is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 2 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | import volatility.obj as obj 22 | 23 | class _KPCROnx86(obj.CType): 24 | """KPCR for 32bit windows""" 25 | 26 | def idt_entries(self): 27 | for i, entry in enumerate(self.IDT.dereference()): 28 | yield i, entry 29 | 30 | def gdt_entries(self): 31 | for i, entry in enumerate(self.GDT.dereference()): 32 | yield i, entry 33 | 34 | def get_kdbg(self): 35 | """Find this CPUs KDBG. 36 | 37 | Please note the KdVersionBlock pointer is NULL on 38 | all KPCR structures except the one for the first CPU. 39 | In some cases on x64, even the first CPU has a NULL 40 | KdVersionBlock, so this is really a hit-or-miss. 41 | """ 42 | DebuggerDataList = self.KdVersionBlock.dereference_as("_DBGKD_GET_VERSION64").DebuggerDataList 43 | 44 | # DebuggerDataList is a pointer to unsigned long on x86 45 | # and a pointer to unsigned long long on x64. The first 46 | # dereference() dereferences the pointer, and the second 47 | # dereference() dereferences the unsigned long or long long 48 | # as the actual KDBG address. 49 | return DebuggerDataList.dereference().dereference_as("_KDDEBUGGER_DATA64") 50 | 51 | @property 52 | def ProcessorBlock(self): 53 | return self.PrcbData 54 | 55 | class _KPCROnx64(_KPCROnx86): 56 | """KPCR for x64 windows""" 57 | 58 | @property 59 | def ProcessorBlock(self): 60 | return self.Prcb 61 | 62 | @property 63 | def IDT(self): 64 | return self.IdtBase 65 | 66 | @property 67 | def GDT(self): 68 | return self.GdtBase 69 | 70 | class KPCRProfileModification(obj.ProfileModification): 71 | before = ['WindowsObjectClasses'] 72 | 73 | conditions = {'os': lambda x: x == 'windows'} 74 | 75 | def modification(self, profile): 76 | 77 | if profile.metadata.get('memory_model', '32bit') == '32bit': 78 | kpcr_class = _KPCROnx86 79 | else: 80 | kpcr_class = _KPCROnx64 81 | 82 | profile.object_classes.update({'_KPCR': kpcr_class}) 83 | 84 | profile.merge_overlay({ 85 | '_KPRCB': [ None, { 86 | 'VendorString': [ None, ['String', dict(length = 13)]], 87 | }]}) 88 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/malfind.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License Version 2 as 8 | # published by the Free Software Foundation. You may not use, modify or 9 | # distribute this program under any other version of the GNU General 10 | # Public License. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | """ 22 | @author: Andrew Case 23 | @license: GNU General Public License 2.0 24 | @contact: atcuno@gmail.com 25 | @organization: 26 | """ 27 | 28 | import volatility.obj as obj 29 | import volatility.utils as utils 30 | import volatility.plugins.malware.malfind as malfind 31 | import volatility.plugins.linux.common as linux_common 32 | import volatility.plugins.linux.pslist as linux_pslist 33 | 34 | class linux_malfind(linux_pslist.linux_pslist): 35 | """Looks for suspicious process mappings""" 36 | 37 | def render_text(self, outfd, data): 38 | linux_common.set_plugin_members(self) 39 | 40 | if self.addr_space.profile.metadata.get('memory_model', '32bit') == '32bit': 41 | bits = '32bit' 42 | else: 43 | bits = '64bit' 44 | 45 | for task in data: 46 | proc_as = task.get_process_address_space() 47 | 48 | for vma in task.get_proc_maps(): 49 | 50 | if vma.is_suspicious(): 51 | fname = vma.vm_name(task) 52 | if fname == "[vdso]": 53 | continue 54 | 55 | prots = vma.protection() 56 | flags = vma.flags() 57 | 58 | content = proc_as.zread(vma.vm_start, 64) 59 | 60 | outfd.write("Process: {0} Pid: {1} Address: {2:#x} File: {3}\n".format( 61 | task.comm, task.pid, vma.vm_start, fname)) 62 | 63 | outfd.write("Protection: {0}\n".format(prots)) 64 | 65 | outfd.write("Flags: {0}\n".format(str(flags))) 66 | outfd.write("\n") 67 | 68 | outfd.write("{0}\n".format("\n".join( 69 | ["{0:#016x} {1:<48} {2}".format(vma.vm_start + o, h, ''.join(c)) 70 | for o, h, c in utils.Hexdump(content) 71 | ]))) 72 | 73 | outfd.write("\n") 74 | outfd.write("\n".join( 75 | ["{0:#x} {1:<16} {2}".format(o, h, i) 76 | for o, i, h in malfind.Disassemble(content, vma.vm_start, bits = bits) 77 | ])) 78 | 79 | outfd.write("\n\n") 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/check_creds.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.debug as debug 29 | import volatility.plugins.linux.common as linux_common 30 | import volatility.plugins.linux.pslist as linux_pslist 31 | from volatility.renderers import TreeGrid 32 | 33 | class linux_check_creds(linux_pslist.linux_pslist): 34 | """Checks if any processes are sharing credential structures""" 35 | 36 | def calculate(self): 37 | linux_common.set_plugin_members(self) 38 | 39 | if not self.profile.obj_has_member("task_struct", "cred"): 40 | debug.error("This command is not supported in this profile.") 41 | 42 | creds = {} 43 | 44 | tasks = linux_pslist.linux_pslist.calculate(self) 45 | 46 | for task in tasks: 47 | 48 | cred_addr = task.cred.v() 49 | 50 | if not cred_addr in creds: 51 | creds[cred_addr] = [] 52 | 53 | creds[cred_addr].append(task.pid) 54 | 55 | yield creds 56 | 57 | def unified_output(self, data): 58 | return TreeGrid([("PIDs", str)], 59 | self.generator(data)) 60 | 61 | def generator(self, data): 62 | # print out processes that are sharing cred structures 63 | for htable in data: 64 | for (addr, pids) in htable.items(): 65 | if len(pids) > 1: 66 | pid_str = "" 67 | for pid in pids: 68 | pid_str = pid_str + "{0:d}, ".format(pid) 69 | pid_str = pid_str[:-2] 70 | 71 | yield(0, [str(pid_str)]) 72 | 73 | def render_text(self, outfd, data): 74 | self.table_header(outfd, [("PIDs", "8")]) 75 | 76 | # print out processes that are sharing cred structures 77 | for htable in data: 78 | for (addr, pids) in htable.items(): 79 | if len(pids) > 1: 80 | pid_str = "" 81 | for pid in pids: 82 | pid_str = pid_str + "{0:d}, ".format(pid) 83 | pid_str = pid_str[:-2] 84 | 85 | self.table_row(outfd, pid_str) 86 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/bioskbd.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # 3 | # Authors: 4 | # Adam Boileau 5 | # Mike Auty 6 | # 7 | # This file is part of Volatility. 8 | # 9 | # Volatility is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2 of the License, or 12 | # (at your option) any later version. 13 | # 14 | # Volatility is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with Volatility. If not, see . 21 | # 22 | # *Heavily* based upon http://www.storm.net.nz/static/files/bioskbsnarf 23 | 24 | import struct 25 | import volatility.plugins.common as common 26 | import volatility.utils as utils 27 | import volatility.debug as debug 28 | from volatility.renderers import TreeGrid 29 | from volatility.renderers.basic import Address 30 | 31 | class BiosKbd(common.AbstractWindowsCommand): 32 | """Reads the keyboard buffer from Real Mode memory""" 33 | BASE = 0x400 34 | OFFSET = 0x17 35 | BUFOFFSET = 0x1e 36 | LEN = 39 37 | FORMAT = "?!"$%^&*()_+-=`\\|': 59 | return c 60 | return "." 61 | 62 | def calculate(self): 63 | """Calculate returns the results of the bios keyboard reading""" 64 | addr_space = utils.load_as(self._config, astype = 'physical') 65 | data = addr_space.read(self.BASE + self.OFFSET, self.LEN) 66 | if not data or len(data) != self.LEN: 67 | debug.error("Failed to read keyboard buffer, please check this is a physical memory image.") 68 | _shifta, _shiftb, _alt, readp, _writep, buf = struct.unpack(self.FORMAT, data) 69 | unringed = buf[readp - self.BUFOFFSET:] 70 | unringed += buf[:readp - self.BUFOFFSET] 71 | results = [] 72 | for i in range(0, len(unringed) - 2, 2): 73 | if ord(unringed[i]) != 0: 74 | results.append((unringed[i], ord(unringed[i + 1]))) 75 | 76 | return results 77 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/mac/proc_maps.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2 of the License, or 9 | # (at your option) any later version. 10 | # 11 | # Volatility is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with Volatility. If not, see . 18 | # 19 | 20 | """ 21 | @author: Andrew Case 22 | @license: GNU General Public License 2.0 23 | @contact: atcuno@gmail.com 24 | @organization: 25 | """ 26 | 27 | import volatility.obj as obj 28 | import volatility.plugins.mac.pstasks as pstasks 29 | import volatility.plugins.mac.common as common 30 | from volatility.renderers import TreeGrid 31 | from volatility.renderers.basic import Address 32 | 33 | class mac_proc_maps(pstasks.mac_tasks): 34 | """ Gets memory maps of processes """ 35 | 36 | def calculate(self): 37 | common.set_plugin_members(self) 38 | 39 | procs = pstasks.mac_tasks.calculate(self) 40 | 41 | for proc in procs: 42 | for map in proc.get_proc_maps(): 43 | yield proc, map 44 | 45 | def unified_output(self, data): 46 | return TreeGrid([("Pid", int), 47 | ("Name", str), 48 | ("Start", Address), 49 | ("End", Address), 50 | ("Perms", str), 51 | ("Map Name", str), 52 | ], self.generator(data)) 53 | 54 | def generator(self, data): 55 | for (proc, map) in data: 56 | path = map.get_path() 57 | if path == "": 58 | path = map.get_special_path() 59 | 60 | yield(0, [ 61 | int(proc.p_pid), 62 | str(proc.p_comm), 63 | Address(map.links.start), 64 | Address(map.links.end), 65 | str(map.get_perms()), 66 | str(path), 67 | ]) 68 | 69 | 70 | def render_text(self, outfd, data): 71 | self.table_header(outfd, [("Pid", "8"), 72 | ("Name", "20"), 73 | ("Start", "#018x"), 74 | ("End", "#018x"), 75 | ("Perms", "9"), 76 | ("Map Name", "")]) 77 | 78 | for (proc, map) in data: 79 | path = map.get_path() 80 | if path == "": 81 | path = map.get_special_path() 82 | 83 | self.table_row(outfd, 84 | str(proc.p_pid), proc.p_comm, 85 | map.links.start, 86 | map.links.end, 87 | map.get_perms(), 88 | path) 89 | -------------------------------------------------------------------------------- /volatility/volatility/plugins/linux/librarydump.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # This file is part of Volatility. 5 | # 6 | # Volatility is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License Version 2 as 8 | # published by the Free Software Foundation. You may not use, modify or 9 | # distribute this program under any other version of the GNU General 10 | # Public License. 11 | # 12 | # Volatility is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with Volatility. If not, see . 19 | # 20 | 21 | """ 22 | @author: Andrew Case 23 | @license: GNU General Public License 2.0 24 | @contact: atcuno@gmail.com 25 | @organization: 26 | """ 27 | import os 28 | 29 | import volatility.obj as obj 30 | import volatility.debug as debug 31 | import volatility.plugins.linux.common as linux_common 32 | import volatility.plugins.linux.pslist as linux_pslist 33 | import volatility.plugins.linux.procdump as linux_procdump 34 | 35 | class linux_librarydump(linux_pslist.linux_pslist): 36 | """Dumps shared libraries in process memory to disk""" 37 | 38 | def __init__(self, config, *args, **kwargs): 39 | linux_pslist.linux_pslist.__init__(self, config, *args, **kwargs) 40 | self._config.add_option('DUMP-DIR', short_option = 'D', default = None, help = 'Output directory', action = 'store', type = 'str') 41 | self._config.add_option('BASE', short_option = 'b', default = None, help = 'Dump driver with BASE address (in hex)', action = 'store', type = 'int') 42 | 43 | def render_text(self, outfd, data): 44 | if not self._config.DUMP_DIR: 45 | debug.error("-D/--dump-dir must given that specifies an existing directory") 46 | 47 | self.table_header(outfd, [("Offset", "[addrpad]"), 48 | ("Name", "20"), 49 | ("Pid", "15"), 50 | ("Address", "[addrpad]"), 51 | ("Output File", "")]) 52 | for task in data: 53 | if not task.mm: 54 | continue 55 | 56 | proc_as = task.get_process_address_space() 57 | 58 | for vma in task.get_proc_maps(): 59 | if self._config.BASE and vma.vm_start != self._config.BASE: 60 | continue 61 | 62 | elf_addr = vma.vm_start 63 | 64 | buf = proc_as.zread(elf_addr, 4) 65 | 66 | if buf != "\x7fELF": 67 | continue 68 | 69 | file_path = linux_common.write_elf_file(self._config.DUMP_DIR, task, elf_addr) 70 | 71 | self.table_row(outfd, task.obj_offset, 72 | task.comm, 73 | str(task.pid), 74 | elf_addr, 75 | file_path) 76 | 77 | --------------------------------------------------------------------------------