├── .gitattributes ├── .gitignore ├── AUTHORS.txt ├── CHANGELOG.txt ├── CREDITS.txt ├── LEGAL.txt ├── LICENSE.txt ├── MANIFEST.in ├── Makefile ├── PKG-INFO ├── README.txt ├── contrib └── plugins │ ├── aspaces │ ├── __init__.py │ └── ewf.py │ ├── disablewarnings.py │ ├── enumfunc.py │ ├── example.py │ ├── malware │ ├── poisonivy.py │ └── zeusscan.py │ ├── pagecheck.py │ ├── psdispscan.py │ └── scanprof.py ├── pyinstaller.spec ├── pyinstaller ├── hook-distorm3.py └── hook-volatility.py ├── resources ├── volatility.ico └── volatility.svg ├── setup.py ├── tools ├── linux │ ├── Makefile │ ├── kcore │ │ ├── Makefile │ │ ├── elf.h │ │ ├── getkcore.c │ │ └── getkcore.h │ ├── module.c │ └── pmem │ │ ├── Makefile │ │ └── pmem.c ├── mac │ ├── convert.py │ └── mac_create_all_profiles.py └── vtype_diff.py ├── vol.py └── volatility ├── __init__.py ├── addrspace.py ├── cache.py ├── commands.py ├── conf.py ├── constants.py ├── debug.py ├── dwarf.py ├── exceptions.py ├── fmtspec.py ├── obj.py ├── plugins ├── __init__.py ├── addrspaces │ ├── __init__.py │ ├── amd64.py │ ├── arm.py │ ├── crash.py │ ├── crashbmp.py │ ├── elfcoredump.py │ ├── hibernate.py │ ├── hpak.py │ ├── ieee1394.py │ ├── intel.py │ ├── lime.py │ ├── macho.py │ ├── osxpmemelf.py │ ├── paged.py │ ├── standard.py │ ├── vmem.py │ ├── vmware.py │ └── win32pmem.py ├── bigpagepools.py ├── bioskbd.py ├── cmdline.py ├── common.py ├── connections.py ├── connscan.py ├── crashinfo.py ├── dlldump.py ├── dumpcerts.py ├── dumpfiles.py ├── envars.py ├── evtlogs.py ├── fileparam.py ├── filescan.py ├── getservicesids.py ├── getsids.py ├── gui │ ├── __init__.py │ ├── atoms.py │ ├── clipboard.py │ ├── constants.py │ ├── desktops.py │ ├── eventhooks.py │ ├── gahti.py │ ├── gditimers.py │ ├── messagehooks.py │ ├── screenshot.py │ ├── sessions.py │ ├── userhandles.py │ ├── vtypes │ │ ├── __init__.py │ │ ├── vista.py │ │ ├── win2003.py │ │ ├── win7.py │ │ ├── win7_sp0_x64_vtypes_gui.py │ │ ├── win7_sp0_x86_vtypes_gui.py │ │ ├── win7_sp1_x64_vtypes_gui.py │ │ ├── win7_sp1_x86_vtypes_gui.py │ │ ├── win8.py │ │ └── xp.py │ ├── win32k_core.py │ ├── windows.py │ └── windowstations.py ├── handles.py ├── heaps.py ├── hibinfo.py ├── hpakinfo.py ├── iehistory.py ├── imagecopy.py ├── imageinfo.py ├── joblinks.py ├── kdbgscan.py ├── kpcrscan.py ├── linux │ ├── __init__.py │ ├── apihooks.py │ ├── arp.py │ ├── banner.py │ ├── bash.py │ ├── bash_hash.py │ ├── check_afinfo.py │ ├── check_creds.py │ ├── check_evt_arm.py │ ├── check_fops.py │ ├── check_idt.py │ ├── check_inline_kernel.py │ ├── check_modules.py │ ├── check_syscall.py │ ├── check_syscall_arm.py │ ├── common.py │ ├── cpuinfo.py │ ├── dentry_cache.py │ ├── dmesg.py │ ├── dump_map.py │ ├── elfs.py │ ├── enumerate_files.py │ ├── find_file.py │ ├── flags.py │ ├── hidden_modules.py │ ├── ifconfig.py │ ├── info_regs.py │ ├── iomem.py │ ├── kernel_opened_files.py │ ├── keyboard_notifiers.py │ ├── ldrmodules.py │ ├── libc_env.py │ ├── library_list.py │ ├── librarydump.py │ ├── lime.py │ ├── linux_strings.py │ ├── linux_truecrypt.py │ ├── linux_volshell.py │ ├── linux_yarascan.py │ ├── list_raw.py │ ├── lsmod.py │ ├── lsof.py │ ├── malfind.py │ ├── mount.py │ ├── mount_cache.py │ ├── netfiler.py │ ├── netstat.py │ ├── pidhashtable.py │ ├── pkt_queues.py │ ├── plthook.py │ ├── proc_maps.py │ ├── proc_maps_rb.py │ ├── procdump.py │ ├── process_hollow.py │ ├── process_info.py │ ├── process_stack.py │ ├── psaux.py │ ├── psenv.py │ ├── pslist.py │ ├── pslist_cache.py │ ├── pstree.py │ ├── psxview.py │ ├── recover_filesystem.py │ ├── route_cache.py │ ├── sk_buff_cache.py │ ├── slab_info.py │ ├── threads.py │ ├── tmpfs.py │ ├── tty_check.py │ └── vma_cache.py ├── mac │ ├── __init__.py │ ├── adiummsgs.py │ ├── apihooks.py │ ├── apihooks_kernel.py │ ├── arp.py │ ├── bash.py │ ├── bash_env.py │ ├── bash_hash.py │ ├── calendar.py │ ├── check_mig_table.py │ ├── check_syscall_shadow.py │ ├── check_syscall_table.py │ ├── check_sysctl.py │ ├── check_trap_table.py │ ├── common.py │ ├── contacts.py │ ├── dead_procs.py │ ├── dead_sockets.py │ ├── dead_vnodes.py │ ├── dlyd_maps.py │ ├── dmesg.py │ ├── dump_files.py │ ├── dump_map.py │ ├── find_aslr_shift.py │ ├── gkextmap.py │ ├── ifconfig.py │ ├── ip_filters.py │ ├── keychaindump.py │ ├── ldrmodules.py │ ├── librarydump.py │ ├── list_files.py │ ├── list_zones.py │ ├── lsmod.py │ ├── lsmod_iokit.py │ ├── lsof.py │ ├── mac_strings.py │ ├── mac_volshell.py │ ├── mac_yarascan.py │ ├── machine_info.py │ ├── malfind.py │ ├── memdump.py │ ├── moddump.py │ ├── mount.py │ ├── netconns.py │ ├── netstat.py │ ├── notesapp.py │ ├── notifiers.py │ ├── pgrp_hash_table.py │ ├── pid_hash_table.py │ ├── print_boot_cmdline.py │ ├── proc_maps.py │ ├── procdump.py │ ├── psaux.py │ ├── pslist.py │ ├── pstasks.py │ ├── pstree.py │ ├── psxview.py │ ├── recover_filesystem.py │ ├── route.py │ ├── session_hash_table.py │ ├── socket_filters.py │ ├── trustedbsd.py │ └── version.py ├── machoinfo.py ├── malware │ ├── __init__.py │ ├── apihooks.py │ ├── callbacks.py │ ├── cmdhistory.py │ ├── devicetree.py │ ├── idt.py │ ├── impscan.py │ ├── malfind.py │ ├── psxview.py │ ├── svcscan.py │ ├── threads.py │ └── timers.py ├── mbrparser.py ├── mftparser.py ├── moddump.py ├── modscan.py ├── modules.py ├── multiscan.py ├── netscan.py ├── notepad.py ├── objtypescan.py ├── overlays │ ├── __init__.py │ ├── basic.py │ ├── linux │ │ ├── __init__.py │ │ ├── elf.py │ │ └── linux.py │ ├── mac │ │ ├── __init__.py │ │ ├── mac.py │ │ └── macho.py │ ├── native_types.py │ └── windows │ │ ├── __init__.py │ │ ├── crash_vtypes.py │ │ ├── hibernate_vtypes.py │ │ ├── kdbg_vtypes.py │ │ ├── kpcr_vtypes.py │ │ ├── pe_vtypes.py │ │ ├── ssdt_vtypes.py │ │ ├── tcpip_vtypes.py │ │ ├── vad_vtypes.py │ │ ├── vista.py │ │ ├── vista_sp0_x64_syscalls.py │ │ ├── vista_sp0_x64_vtypes.py │ │ ├── vista_sp0_x86_syscalls.py │ │ ├── vista_sp0_x86_vtypes.py │ │ ├── vista_sp12_x64_syscalls.py │ │ ├── vista_sp12_x86_syscalls.py │ │ ├── vista_sp1_x64_vtypes.py │ │ ├── vista_sp1_x86_vtypes.py │ │ ├── vista_sp2_x64_vtypes.py │ │ ├── vista_sp2_x86_vtypes.py │ │ ├── win2003.py │ │ ├── win2003_sp0_x86_syscalls.py │ │ ├── win2003_sp0_x86_vtypes.py │ │ ├── win2003_sp12_x64_syscalls.py │ │ ├── win2003_sp12_x86_syscalls.py │ │ ├── win2003_sp1_x64_vtypes.py │ │ ├── win2003_sp1_x86_vtypes.py │ │ ├── win2003_sp2_x64_vtypes.py │ │ ├── win2003_sp2_x86_vtypes.py │ │ ├── win7.py │ │ ├── win7_sp01_x64_syscalls.py │ │ ├── win7_sp01_x86_syscalls.py │ │ ├── win7_sp0_x64_vtypes.py │ │ ├── win7_sp0_x86_vtypes.py │ │ ├── win7_sp1_x64_vtypes.py │ │ ├── win7_sp1_x86_vtypes.py │ │ ├── win8.py │ │ ├── win8_kdbg.py │ │ ├── win8_sp0_x64_syscalls.py │ │ ├── win8_sp0_x64_vtypes.py │ │ ├── win8_sp0_x86_syscalls.py │ │ ├── win8_sp0_x86_vtypes.py │ │ ├── win8_sp1_x64_syscalls.py │ │ ├── win8_sp1_x64_vtypes.py │ │ ├── win8_sp1_x86_syscalls.py │ │ ├── win8_sp1_x86_vtypes.py │ │ ├── windows.py │ │ ├── windows64.py │ │ ├── xp.py │ │ ├── xp_sp2_x86_syscalls.py │ │ ├── xp_sp2_x86_vtypes.py │ │ └── xp_sp3_x86_vtypes.py ├── patcher.py ├── patchguard.py ├── pooltracker.py ├── privileges.py ├── procdump.py ├── pstree.py ├── raw2dmp.py ├── registry │ ├── __init__.py │ ├── auditpol.py │ ├── dumpregistry.py │ ├── hivelist.py │ ├── hivescan.py │ ├── lsadump.py │ ├── printkey.py │ ├── registryapi.py │ ├── shellbags.py │ ├── shimcache.py │ └── userassist.py ├── sockets.py ├── sockscan.py ├── ssdt.py ├── strings.py ├── taskmods.py ├── tcaudit.py ├── timeliner.py ├── vadinfo.py ├── vboxinfo.py ├── verinfo.py ├── vmwareinfo.py └── volshell.py ├── poolscan.py ├── protos.py ├── registry.py ├── scan.py ├── timefmt.py ├── utils.py └── win32 ├── __init__.py ├── crashdump.py ├── domcachedump.py ├── hashdump.py ├── hive.py ├── lsasecrets.py ├── modules.py ├── network.py ├── rawreg.py ├── tasks.py └── xpress.py /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | *.swp 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Packages 9 | *.egg 10 | *.egg-info 11 | dist 12 | build 13 | eggs 14 | parts 15 | bin 16 | var 17 | sdist 18 | develop-eggs 19 | .installed.cfg 20 | lib 21 | lib64 22 | 23 | # Installer logs 24 | pip-log.txt 25 | 26 | # Unit test / coverage reports 27 | .coverage 28 | .tox 29 | nosetests.xml 30 | 31 | # Translations 32 | *.mo 33 | 34 | # Mr Developer 35 | .mr.developer.cfg 36 | .project 37 | .pydevproject 38 | 39 | .svn/ 40 | .DS_Store 41 | 42 | # compressed files 43 | *.zip 44 | *.7z 45 | *.rar 46 | *.tar.gz 47 | *.gz 48 | 49 | # common memory extensions: 50 | *.vmem 51 | *.mem 52 | *.img 53 | *.dmp 54 | *.sys 55 | *.bin 56 | *.001 57 | *.raw 58 | -------------------------------------------------------------------------------- /AUTHORS.txt: -------------------------------------------------------------------------------- 1 | =============================================== 2 | This file identifies core Volatility authors. 3 | 4 | All lists are alphabetical. 5 | =============================================== 6 | 7 | Volatility 2.0, 2.1, 2.2, and 2.3: 8 | ------------ 9 | 10 | Mike Auty 11 | Andrew Case 12 | Michael Cohen 13 | Brendan Dolan-Gavitt 14 | Michael Hale Ligh 15 | Jamie Levy 16 | AAron Walters 17 | 18 | Volatility 1.3: 19 | ------------ 20 | 21 | AAron Walters 22 | Volatile Systems LLC 23 | 24 | Brendan Dolan-Gavitt 25 | 26 | Volatools Basic authors: 27 | ------------ 28 | 29 | AAron Walters 30 | Komoku, Inc. 31 | 32 | Nick L. Petroni, Jr. 33 | Komoku, Inc. 34 | -------------------------------------------------------------------------------- /CREDITS.txt: -------------------------------------------------------------------------------- 1 | =============================================== 2 | We would like to acknowledge individuals that 3 | have made significant contributions, code, or 4 | ideas toward the respective volatility releases. 5 | 6 | All lists are alphabetical. 7 | 8 | These lists exclude the core Volatility authors, 9 | who are identified in AUTHORS.txt. 10 | 11 | If you believe you've been left off, it is not 12 | intentional. Please bring it to our attention! 13 | =============================================== 14 | 15 | Volatility 2.4: 16 | 17 | Justin Capella and Espen Olsen for their work on the Qemu ELF core dumps 18 | Sebastien Bourdon-Richard for his work on the VMware vmem/vmss split (with meta) AS 19 | Stewart McIntyre for extending apihooks for detecting JMP FAR instructions 20 | Matt McCormack for supplying a patch to rebase dumped PE files 21 | Kevin Marker for contributing over 160 standard build Linux profiles 22 | Steven Adair for assistance identifying a large memory PAE bug 23 | Cem Gurkok for help updating Mac OS X support for 10.9 24 | Raphaël Vinot for his patch to fix IPython within volshell 25 | synack33 for creating various Mac OS X profiles, including initial ones for 10.10 26 | 27 | Volatility 2.3: 28 | 29 | Cem Gurkok for his work on the privileges plugin for Windows 30 | Nir Izraeli for his work on the VMware snapshot address space (see also the vmsnparser project) 31 | @osxmem of the volafox project (Mac OS X & BSD Memory Analysis Toolkit) 32 | @osxreverser of reverse.put.as for his help with OSX memory analysis 33 | Carl Pulley for numerous bug reports, example patches, and plugin testing 34 | Andreas Schuster for his work on poison ivy plugins for Windows 35 | Joe Sylve for his work on the ARM address space and significant contributions to linux and mac capabilities 36 | Philippe Teuwen for his work on the virtual box address space 37 | Santiago Vicente for his work on the citadel plugins for Windows 38 | 39 | Volatility 2.2: 40 | ------------ 41 | 42 | Joe Sylve 43 | 44 | Volatility 2.1: 45 | ------------ 46 | 47 | --- 48 | 49 | Volatility 2.0: 50 | ------------ 51 | 52 | Frank Boldewin 53 | Carl Pulley 54 | Andreas Schuster 55 | Bradley Schatz 56 | 57 | Volatility 1.3: 58 | ------------ 59 | 60 | Harlan Carvey 61 | Michael Cohen 62 | David Collett 63 | Brendan Dolan-Gavitt 64 | Andreas Schuster 65 | Matthieu Suiche 66 | 67 | We would also like to acknowledge those who have provided valuable 68 | feedback, bug reports, and testing: 69 | 70 | Jide Abu 71 | Joseph Ayo Akinyele 72 | Tommaso Assandri 73 | Richard Austin 74 | Cameron C Caffee 75 | Eoghan Casey 76 | Angelo Cavallini 77 | Andre' DiMino 78 | Jon Evans 79 | Robert Guess 80 | Christian Herndler 81 | jeremie0 82 | Eugene Libster 83 | Erik Ligda 84 | Robert Lowe 85 | Tony Martin 86 | Timothy Morgan 87 | Bryan D. Payne 88 | Golden G. Richard III 89 | Wyatt Roersma 90 | RB 91 | Sam F. Stover 92 | Marko Thure 93 | -------------------------------------------------------------------------------- /LEGAL.txt: -------------------------------------------------------------------------------- 1 | Volatility 2 | =============== 3 | 4 | License 5 | ------- 6 | 7 | Copyright (C) 2007-2013 Volatility Foundation 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /contrib/plugins/aspaces/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botherder/volatility/5eb15741a095c5f0dec9bd771f6c4a63b06137c1/contrib/plugins/aspaces/__init__.py -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /contrib/plugins/pagecheck.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 | import volatility.commands as commands 20 | import volatility.utils as utils 21 | 22 | class PageCheck(commands.Command): 23 | """Reads the available pages and reports if any are inaccessible""" 24 | 25 | def render_text(self, outfd, data): 26 | """Displays any page errors""" 27 | found = False 28 | for page, vtop, size, pde, pte in data: 29 | found = True 30 | outfd.write("(V): 0x{0:08x} [PDE] 0x{3:08x} [PTE] 0x{4:08x} (P): 0x{1:08x} Size: 0x{2:08x}\n".format(page, vtop, size, pde, pte)) 31 | if not found: 32 | outfd.write("No page failures found!") 33 | 34 | def calculate(self): 35 | """Calculate returns the results of the available pages validity""" 36 | addr_space = utils.load_as(self._config) 37 | for page, size in addr_space.get_available_pages(): 38 | output = addr_space.read(page, size) 39 | if output == None: 40 | pde_value = addr_space.get_pde(page) 41 | pte_value = addr_space.get_pte(page, pde_value) 42 | yield page, addr_space.vtop(page), size, pde_value, pte_value 43 | -------------------------------------------------------------------------------- /contrib/plugins/scanprof.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 sys 23 | import itertools 24 | import timeit 25 | 26 | class ScanProfInstance(object): 27 | def __init__(self, func, *args): 28 | self.func = func 29 | self.args = args 30 | self.results = [] 31 | 32 | def __call__(self): 33 | self.results = self.func(*self.args) 34 | 35 | def permscan(self, address_space, offset = 0, maxlen = None): 36 | times = [] 37 | # Run a warm-up scan to ensure the file is cached as much as possible 38 | self.oldscan(address_space, offset, maxlen) 39 | 40 | perms = list(itertools.permutations(self.checks)) 41 | for i in range(len(perms)): 42 | self.checks = perms[i] 43 | print "Running scan {0}/{1}...".format(i + 1, len(perms)) 44 | profobj = ScanProfInstance(self.oldscan, address_space, offset, maxlen) 45 | value = timeit.timeit(profobj, number = self.repeats) 46 | times.append((value, len(list(profobj.results)), i)) 47 | 48 | print "Scan results" 49 | print "{0:20} | {1:7} | {2:6} | {3}".format("Time", "Results", "Perm #", "Ordering") 50 | for val, l, ordering in sorted(times): 51 | print "{0:20} | {1:7} | {2:6} | {3}".format(val, l, ordering, perms[ordering]) 52 | sys.exit(1) 53 | 54 | def ScanProfiler(cls, repeats = 3): 55 | cls.repeats = repeats 56 | cls.oldscan = cls.scan 57 | cls.scan = permscan 58 | return cls 59 | -------------------------------------------------------------------------------- /pyinstaller.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python -*- 2 | projpath = os.path.dirname(os.path.abspath(SPEC)) 3 | 4 | def get_plugins(list): 5 | for item in list: 6 | if item[0].startswith('volatility.plugins') and not (item[0] == 'volatility.plugins' and '__init__.py' in item[1]): 7 | yield item 8 | 9 | exeext = ".exe" if sys.platform.startswith("win") else "" 10 | 11 | a = Analysis([os.path.join(projpath, 'vol.py')], 12 | pathex = [HOMEPATH], 13 | hookspath = [os.path.join(projpath, 'pyinstaller')]) 14 | pyz = PYZ(a.pure) 15 | plugins = Tree(os.path.join(projpath, 'volatility', 'plugins'), 16 | os.path.join('plugins')) 17 | exe = EXE(pyz, 18 | a.scripts + [('u', '', 'OPTION')], 19 | a.binaries, 20 | a.zipfiles, 21 | a.datas, 22 | plugins, 23 | name = os.path.join(projpath, 'dist', 'pyinstaller', 'volatility' + exeext), 24 | debug = False, 25 | strip = False, 26 | upx = True, 27 | icon = os.path.join(projpath, 'resources', 'volatility.ico'), 28 | console = 1) 29 | -------------------------------------------------------------------------------- /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 | datas.append((os.path.join(path, "distorm3", "distorm3.dll"), "")) 19 | datas.append((os.path.join(path, "distorm3", "libdistorm3.so"), "")) 20 | 21 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /resources/volatility.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botherder/volatility/5eb15741a095c5f0dec9bd771f6c4a63b06137c1/resources/volatility.ico -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tools/linux/pmem/Makefile: -------------------------------------------------------------------------------- 1 | obj-m += pmem.o 2 | KDIR ?= / 3 | KVER ?= $(shell uname -r) 4 | 5 | -include version.mk 6 | 7 | all: pmem 8 | 9 | pmem: pmem.c 10 | $(MAKE) -C $(KDIR)/lib/modules/$(KVER)/build M=$(PWD) modules 11 | 12 | clean: 13 | $(MAKE) -C $(KDIR)/lib/modules/$(KVER)/build M=$(PWD) clean 14 | -------------------------------------------------------------------------------- /volatility/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /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.4" 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/debug.py: -------------------------------------------------------------------------------- 1 | # Volatility 2 | # 3 | # Authors: 4 | # Michael Cohen 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.getmodule(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/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/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/plugins/addrspaces/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botherder/volatility/5eb15741a095c5f0dec9bd771f6c4a63b06137c1/volatility/plugins/addrspaces/__init__.py -------------------------------------------------------------------------------- /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 | 70 | -------------------------------------------------------------------------------- /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 | 29 | class BiosKbd(common.AbstractWindowsCommand): 30 | """Reads the keyboard buffer from Real Mode memory""" 31 | BASE = 0x400 32 | OFFSET = 0x17 33 | BUFOFFSET = 0x1e 34 | LEN = 39 35 | FORMAT = "?!"$%^&*()_+-=`\\|': 46 | return c 47 | return "." 48 | 49 | def calculate(self): 50 | """Calculate returns the results of the bios keyboard reading""" 51 | addr_space = utils.load_as(self._config, astype = 'physical') 52 | data = addr_space.read(self.BASE + self.OFFSET, self.LEN) 53 | if not data or len(data) != self.LEN: 54 | debug.error("Failed to read keyboard buffer, please check this is a physical memory image.") 55 | _shifta, _shiftb, _alt, readp, _writep, buf = struct.unpack(self.FORMAT, data) 56 | unringed = buf[readp - self.BUFOFFSET:] 57 | unringed += buf[:readp - self.BUFOFFSET] 58 | results = [] 59 | for i in range(0, len(unringed) - 2, 2): 60 | if ord(unringed[i]) != 0: 61 | results.append((unringed[i], ord(unringed[i + 1]))) 62 | 63 | return results 64 | -------------------------------------------------------------------------------- /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 | 22 | class Cmdline(taskmods.DllList): 23 | """Display process command-line arguments""" 24 | 25 | def render_text(self, outfd, data): 26 | for task in data: 27 | pid = task.UniqueProcessId 28 | 29 | outfd.write("*" * 72 + "\n") 30 | outfd.write("{0} pid: {1:6}\n".format(task.ImageFileName, pid)) 31 | 32 | if task.Peb: 33 | outfd.write("Command line : {0}\n".format(str(task.Peb.ProcessParameters.CommandLine or ''))) -------------------------------------------------------------------------------- /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/plugins/gui/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botherder/volatility/5eb15741a095c5f0dec9bd771f6c4a63b06137c1/volatility/plugins/gui/__init__.py -------------------------------------------------------------------------------- /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/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 | 21 | import volatility.utils as utils 22 | import volatility.debug as debug 23 | import volatility.plugins.gui.constants as consts 24 | import volatility.plugins.gui.sessions as sessions 25 | 26 | class Gahti(sessions.Sessions): 27 | """Dump the USER handle type information""" 28 | 29 | def render_text(self, outfd, data): 30 | 31 | profile = utils.load_as(self._config).profile 32 | 33 | # Get the OS version being analyzed 34 | version = (profile.metadata.get('major', 0), 35 | profile.metadata.get('minor', 0)) 36 | 37 | # Choose which USER handle enum to use 38 | if version >= (6, 1): 39 | handle_types = consts.HANDLE_TYPE_ENUM_SEVEN 40 | else: 41 | handle_types = consts.HANDLE_TYPE_ENUM 42 | 43 | self.table_header(outfd, 44 | [("Session", "8"), 45 | ("Type", "20"), 46 | ("Tag", "8"), 47 | ("fnDestroy", "[addrpad]"), 48 | ("Flags", ""), 49 | ]) 50 | 51 | for session in data: 52 | gahti = session.find_gahti() 53 | if gahti: 54 | for i, h in handle_types.items(): 55 | self.table_row(outfd, 56 | session.SessionId, 57 | h, 58 | gahti.types[i].dwAllocTag, 59 | gahti.types[i].fnDestroy, 60 | gahti.types[i].bObjectCreateFlags) 61 | -------------------------------------------------------------------------------- /volatility/plugins/gui/vtypes/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botherder/volatility/5eb15741a095c5f0dec9bd771f6c4a63b06137c1/volatility/plugins/gui/vtypes/__init__.py -------------------------------------------------------------------------------- /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/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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | # 17 | 18 | import volatility.obj as obj 19 | 20 | #-------------------------------------------------------------------------------- 21 | # profile modifications 22 | #-------------------------------------------------------------------------------- 23 | 24 | class HeapModification(obj.ProfileModification): 25 | 26 | before = ["WindowsObjectClasses"] 27 | conditions = {'os': lambda x: x == 'windows'} 28 | 29 | def modification(self, profile): 30 | profile.merge_overlay({ 31 | '_PEB': [ None, { 32 | 'ProcessHeaps': [ None, ['pointer', ['array', lambda x : x.NumberOfHeaps, ['pointer', ['_HEAP']]]]], 33 | }], 34 | }) 35 | -------------------------------------------------------------------------------- /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/plugins/linux/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botherder/volatility/5eb15741a095c5f0dec9bd771f6c4a63b06137c1/volatility/plugins/linux/__init__.py -------------------------------------------------------------------------------- /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/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 | 32 | class linux_check_creds(linux_pslist.linux_pslist): 33 | """Checks if any processes are sharing credential structures""" 34 | 35 | def calculate(self): 36 | linux_common.set_plugin_members(self) 37 | 38 | if not self.profile.obj_has_member("task_struct", "cred"): 39 | debug.error("This command is not supported in this profile.") 40 | 41 | creds = {} 42 | 43 | tasks = linux_pslist.linux_pslist.calculate(self) 44 | 45 | for task in tasks: 46 | 47 | cred_addr = task.cred.v() 48 | 49 | if not cred_addr in creds: 50 | creds[cred_addr] = [] 51 | 52 | creds[cred_addr].append(task.pid) 53 | 54 | yield creds 55 | 56 | def render_text(self, outfd, data): 57 | 58 | self.table_header(outfd, [("PIDs", "8")]) 59 | 60 | # print out processes that are sharing cred structures 61 | for htable in data: 62 | 63 | for (addr, pids) in htable.items(): 64 | 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 | self.table_row(outfd, pid_str) 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /volatility/plugins/linux/check_idt.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 | 30 | class linux_check_idt(linux_common.AbstractLinuxCommand): 31 | """ Checks if the IDT has been altered """ 32 | 33 | def calculate(self): 34 | """ 35 | This works by walking the IDT table for the entries that Linux uses 36 | and verifies that each is a symbol in the kernel 37 | """ 38 | linux_common.set_plugin_members(self) 39 | 40 | tblsz = 256 41 | 42 | sym_addrs = self.profile.get_all_addresses() 43 | 44 | # hw handlers + system call 45 | check_idxs = list(range(0, 20)) + [128] 46 | 47 | if self.profile.metadata.get('memory_model', '32bit') == "32bit": 48 | idt_type = "desc_struct" 49 | else: 50 | idt_type = "gate_struct64" 51 | 52 | # this is written as a list b/c there are supposdly kernels with per-CPU IDTs 53 | # but I haven't found one yet... 54 | addrs = [self.addr_space.profile.get_symbol("idt_table")] 55 | 56 | for tableaddr in addrs: 57 | 58 | table = obj.Object(theType = 'Array', offset = tableaddr, vm = self.addr_space, targetType = idt_type, count = tblsz) 59 | 60 | for i in check_idxs: 61 | 62 | ent = table[i] 63 | 64 | if not ent: 65 | continue 66 | 67 | idt_addr = ent.Address 68 | 69 | if idt_addr != 0: 70 | if not idt_addr in sym_addrs: 71 | hooked = 1 72 | sym_name = "HOOKED" 73 | else: 74 | hooked = 0 75 | sym_name = self.profile.get_symbol_by_address("kernel", idt_addr) 76 | 77 | yield(i, ent, idt_addr, sym_name, hooked) 78 | 79 | def render_text(self, outfd, data): 80 | 81 | self.table_header(outfd, [("Index", "[addr]"), ("Address", "[addrpad]"), ("Symbol", "<30")]) 82 | 83 | for (i, _, idt_addr, sym_name, hooked) in data: 84 | self.table_row(outfd, i, idt_addr, sym_name) 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /volatility/plugins/linux/check_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 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.debug as debug 30 | import volatility.plugins.linux.lsmod as linux_lsmod 31 | import volatility.plugins.linux.common as linux_common 32 | 33 | class linux_check_modules(linux_common.AbstractLinuxCommand): 34 | """Compares module list to sysfs info, if available""" 35 | 36 | def get_kset_modules(self): 37 | module_kset_addr = self.profile.get_symbol("module_kset") 38 | if not module_kset_addr: 39 | debug.error("This command is not supported by this profile.") 40 | 41 | ret = {} 42 | 43 | module_kset = obj.Object("kset", offset = module_kset_addr, vm = self.addr_space) 44 | 45 | for kobj in module_kset.list.list_of_type("kobject", "entry"): 46 | kobj_off = self.profile.get_obj_offset("module_kobject", "kobj") 47 | mod_kobj = obj.Object("module_kobject", offset = kobj.v() - kobj_off, vm = self.addr_space) 48 | mod = mod_kobj.mod 49 | 50 | name = kobj.name.dereference_as("String", length = 32) 51 | if name.is_valid() and kobj.kref.refcount.counter > 2: 52 | ret[str(name)] = mod 53 | 54 | return ret 55 | 56 | def calculate(self): 57 | linux_common.set_plugin_members(self) 58 | 59 | kset_modules = self.get_kset_modules() 60 | 61 | lsmod_modules = set([str(module.name) for (module, params, sects) in linux_lsmod.linux_lsmod(self._config).calculate()]) 62 | 63 | for mod_name in set(kset_modules.keys()).difference(lsmod_modules): 64 | yield kset_modules[mod_name] 65 | 66 | def render_text(self, outfd, data): 67 | 68 | self.table_header(outfd, [("Module Address", "[address]"), ("Module Name", "24")]) 69 | for mod in data: 70 | self.table_row(outfd, mod.obj_offset, str(mod.name)) 71 | 72 | -------------------------------------------------------------------------------- /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/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 | 34 | class linux_elfs(linux_pslist.linux_pslist): 35 | """Find ELF binaries in process mappings""" 36 | 37 | def calculate(self): 38 | linux_common.set_plugin_members(self) 39 | tasks = linux_pslist.linux_pslist.calculate(self) 40 | 41 | for task in tasks: 42 | for elf, elf_start, elf_end, soname, needed in task.elfs(): 43 | yield task, elf, elf_start, elf_end, soname, needed 44 | 45 | def render_text(self, outfd, data): 46 | self.table_header(outfd, [("Pid", "8"), 47 | ("Name", "17"), 48 | ("Start", "[addrpad]"), 49 | ("End", "[addrpad]"), 50 | ("Elf Path", "60"), 51 | ("Needed", "") 52 | ]) 53 | for task, elf, start, end, soname, needed in data: 54 | self.table_row(outfd, task.pid, task.comm, start, end, soname, ",".join(needed)) 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /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 | 31 | class linux_enumerate_files(linux_common.AbstractLinuxCommand): 32 | """Lists files referenced by the filesystem cache""" 33 | 34 | def calculate(self): 35 | linux_common.set_plugin_members(self) 36 | 37 | for (_, _, file_path, _)in linux_find_file.linux_find_file(self._config).walk_sbs(): 38 | yield file_path 39 | 40 | def render_text(self, outfd, data): 41 | 42 | self.table_header(outfd, [("Path", "")]) 43 | for path in data: 44 | self.table_row(outfd, path) 45 | 46 | -------------------------------------------------------------------------------- /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/plugins/linux/hidden_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 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.lsmod as linux_lsmod 31 | 32 | class linux_hidden_modules(linux_common.AbstractLinuxCommand): 33 | """Carves memory to find hidden kernel modules""" 34 | 35 | def walk_modules_address_space(self, addr_space): 36 | mods = [x[0].obj_offset for x in linux_lsmod.linux_lsmod(self._config).calculate()] 37 | 38 | min_addr = obj.Object("unsigned long", offset = addr_space.profile.get_symbol("module_addr_min"), vm = addr_space) 39 | max_addr = obj.Object("unsigned long", offset = addr_space.profile.get_symbol("module_addr_max"), vm = addr_space) 40 | 41 | for cur_addr in range(min_addr, max_addr, 8): 42 | m = obj.Object("module", offset = cur_addr, vm = addr_space) 43 | 44 | if m.state.v() not in [0, 1, 2]: 45 | continue 46 | 47 | if m.core_size < 4096 or m.core_size > 1000000: 48 | continue 49 | 50 | if m.core_text_size < 4096 or m.core_text_size > 1000000: 51 | continue 52 | 53 | s = self.addr_space.read(m.name.obj_offset, 64) 54 | if not s: 55 | continue 56 | 57 | idx = s.find("\x00") 58 | 59 | if idx < 1: 60 | continue 61 | 62 | name = s[:idx] 63 | for n in name: 64 | if not (32 < ord(n) < 127): 65 | continue 66 | 67 | if not m.module_core.is_valid(): 68 | continue 69 | 70 | if m.obj_offset not in mods: 71 | yield m 72 | 73 | def calculate(self): 74 | linux_common.set_plugin_members(self) 75 | 76 | for mod in self.walk_modules_address_space(self.addr_space): 77 | yield mod 78 | 79 | def render_text(self, outfd, data): 80 | self.table_header(outfd, [("Offset (V)", "[addrpad]"), ("Name", "")]) 81 | 82 | for module in data: 83 | self.table_row(outfd, module.obj_offset, str(module.name)) 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /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/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 | module = obj.Object("module", offset = 0xffffffffa03a15d0, vm = self.addr_space) 59 | sym = module.get_symbol_for_address(call_addr) 60 | 61 | sym_name = "%s: %s/%s" % (sym_name, module.name, sym) 62 | 63 | hooked = 1 64 | 65 | symbol_cache[call_addr] = sym_name 66 | 67 | yield call_addr, sym_name, hooked 68 | 69 | def render_text(self, outfd, data): 70 | self.table_header(outfd, [("Address", "[addrpad]"), ("Symbol", "<30")]) 71 | for call_addr, sym_name, _ in data: 72 | self.table_row(outfd, call_addr, sym_name) 73 | -------------------------------------------------------------------------------- /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 | 32 | class linux_ldrmodules(linux_pslist.linux_pslist): 33 | """Compares the output of proc maps with the list of libraries from libdl""" 34 | 35 | def render_text(self, outfd, data): 36 | self.table_header(outfd, [("Pid", "8"), 37 | ("Name", "16"), 38 | ("Start", "#018x"), 39 | ("File Path", "50"), 40 | ("Kernel", "6"), 41 | ("Libc", "6"), 42 | ]) 43 | 44 | for task in data: 45 | for vm_start, vma_name, pmaps, dmaps in task.ldrmodules(): 46 | self.table_row(outfd, 47 | task.pid, 48 | str(task.comm), 49 | vm_start, 50 | vma_name, 51 | pmaps, 52 | dmaps) 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /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 bash's 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 | if task.comm.find("bash") == -1: 46 | continue 47 | 48 | varstr = "" 49 | 50 | for (key, val) in task.bash_environment(): 51 | varstr = varstr + "%s=%s " % (key, val) 52 | 53 | self.table_row(outfd, task.pid, task.comm, varstr) 54 | 55 | -------------------------------------------------------------------------------- /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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 | 29 | class linux_library_list(linux_pslist.linux_pslist): 30 | """ Lists libraries loaded into a process """ 31 | 32 | def calculate(self): 33 | linux_common.set_plugin_members(self) 34 | 35 | tasks = linux_pslist.linux_pslist.calculate(self) 36 | 37 | for task in tasks: 38 | for mapping in task.get_libdl_maps(): 39 | if mapping.l_name == "" or mapping.l_addr == 0: 40 | continue 41 | 42 | yield task, mapping 43 | 44 | def render_text(self, outfd, data): 45 | self.table_header(outfd, [("Task", "16"), 46 | ("Pid", "8"), 47 | ("Load Address", "[addrpad]"), 48 | ("Path", ""), 49 | ]) 50 | 51 | for task, mapping in data: 52 | self.table_row(outfd, task.comm, task.pid, mapping.l_addr, mapping.l_name) 53 | 54 | -------------------------------------------------------------------------------- /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/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 | @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_lsof(linux_pslist.linux_pslist): 32 | """Lists open files""" 33 | 34 | def render_text(self, outfd, data): 35 | 36 | self.table_header(outfd, [("Pid", "8"), 37 | ("FD", "8"), 38 | ("Path", "")]) 39 | 40 | for task in data: 41 | for filp, fd in task.lsof(): 42 | self.table_row(outfd, task.pid, fd, linux_common.get_path(task, filp)) 43 | -------------------------------------------------------------------------------- /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 | for task in data: 39 | proc_as = task.get_process_address_space() 40 | 41 | for vma in task.get_proc_maps(): 42 | 43 | if vma.is_suspicious(): 44 | fname = vma.vm_name(task) 45 | if fname == "[vdso]": 46 | continue 47 | 48 | prots = vma.protection() 49 | flags = vma.flags() 50 | 51 | content = proc_as.zread(vma.vm_start, 64) 52 | 53 | outfd.write("Process: {0} Pid: {1} Address: {2:#x} File: {3}\n".format( 54 | task.comm, task.pid, vma.vm_start, fname)) 55 | 56 | outfd.write("Protection: {0}\n".format(prots)) 57 | 58 | outfd.write("Flags: {0}\n".format(str(flags))) 59 | outfd.write("\n") 60 | 61 | outfd.write("{0}\n".format("\n".join( 62 | ["{0:#010x} {1:<48} {2}".format(vma.vm_start + o, h, ''.join(c)) 63 | for o, h, c in utils.Hexdump(content) 64 | ]))) 65 | 66 | outfd.write("\n") 67 | outfd.write("\n".join( 68 | ["{0:#x} {1:<16} {2}".format(o, h, i) 69 | for o, i, h in malfind.Disassemble(content, vma.vm_start) 70 | ])) 71 | 72 | outfd.write("\n\n") 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /volatility/plugins/linux/mount_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 | import volatility.plugins.linux.mount as linux_mount 28 | import volatility.plugins.linux.pslist as linux_pslist 29 | from volatility.plugins.linux.slab_info import linux_slabinfo 30 | 31 | class linux_mount_cache(linux_mount.linux_mount): 32 | """Gather mounted fs/devices from kmem_cache""" 33 | 34 | def __init__(self, config, *args, **kwargs): 35 | linux_mount.linux_mount.__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 | # newer kernels 45 | if self.profile.has_type("mount"): 46 | mnttype = "mount" 47 | 48 | cache = linux_slabinfo(self._config).get_kmem_cache(mnttype, self._config.UNALLOCATED) 49 | 50 | for task in linux_pslist.linux_pslist(self._config).calculate(): 51 | if task.pid == 1: 52 | ns = task.nsproxy.mnt_ns 53 | break 54 | else: 55 | cache = linux_slabinfo(self._config).get_kmem_cache("mnt_cache", self._config.UNALLOCATED, struct_name = "vfsmount") 56 | ns = None 57 | 58 | for mnt in cache: 59 | yield (mnt, ns) 60 | 61 | -------------------------------------------------------------------------------- /volatility/plugins/linux/netfiler.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.debug as debug 30 | import volatility.plugins.linux.common as linux_common 31 | import volatility.plugins.linux.lsmod as linux_lsmod 32 | 33 | class linux_netfilter(linux_common.AbstractLinuxCommand): 34 | """Lists Netfilter hooks""" 35 | 36 | def calculate(self): 37 | linux_common.set_plugin_members(self) 38 | 39 | hook_names = ["PRE_ROUTING", "LOCAL_IN", "FORWARD", "LOCAL_OUT", "POST_ROUTING"] 40 | proto_names = ["", "", "IPV4", "", "", "", "", "", "", "", "" , "", "", ""] 41 | 42 | # struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] 43 | # NFPROTO_NUMPROTO = 12 44 | # NF_MAX_HOOKS = 7 45 | 46 | nf_hooks_addr = self.addr_space.profile.get_symbol("nf_hooks") 47 | 48 | if nf_hooks_addr == None: 49 | debug.error("Unable to analyze NetFilter. It is either disabled or compiled as a module.") 50 | 51 | modules = linux_lsmod.linux_lsmod(self._config).get_modules() 52 | 53 | list_head_size = self.addr_space.profile.get_obj_size("list_head") 54 | 55 | for outer in range(13): 56 | arr = nf_hooks_addr + (outer * (list_head_size * 8)) 57 | 58 | for inner in range(7): 59 | list_head = obj.Object("list_head", offset = arr + (inner * list_head_size), vm = self.addr_space) 60 | 61 | for hook_ops in list_head.list_of_type("nf_hook_ops", "list"): 62 | if self.is_known_address(hook_ops.hook.v(), modules): 63 | hooked = "False" 64 | else: 65 | hooked = "True" 66 | 67 | yield proto_names[outer], hook_names[inner], hook_ops.hook.v(), hooked 68 | 69 | def render_text(self, outfd, data): 70 | self.table_header(outfd, [("Proto", "5"), ("Hook", "16"), ("Handler", "[addrpad]"), ("Is Hooked", "5")]) 71 | 72 | for outer, inner, hook_addr, hooked in data: 73 | self.table_row(outfd, outer, inner, hook_addr, hooked) 74 | 75 | 76 | -------------------------------------------------------------------------------- /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] == socket.AF_UNIX 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/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/plugins/linux/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.linux.common as linux_common 29 | import volatility.plugins.linux.pslist as linux_pslist 30 | 31 | class linux_proc_maps(linux_pslist.linux_pslist): 32 | """Gathers process maps for linux""" 33 | 34 | def calculate(self): 35 | linux_common.set_plugin_members(self) 36 | tasks = linux_pslist.linux_pslist.calculate(self) 37 | 38 | for task in tasks: 39 | if task.mm: 40 | for vma in task.get_proc_maps(): 41 | yield task, vma 42 | 43 | def render_text(self, outfd, data): 44 | self.table_header(outfd, [("Pid", "8"), 45 | ("Start", "#018x"), 46 | ("End", "#018x"), 47 | ("Flags", "6"), 48 | ("Pgoff", "[addr]"), 49 | ("Major", "6"), 50 | ("Minor", "6"), 51 | ("Inode", "10"), 52 | ("File Path", ""), 53 | ]) 54 | for task, vma in data: 55 | (fname, major, minor, ino, pgoff) = vma.info(task) 56 | 57 | self.table_row(outfd, task.pid, 58 | vma.vm_start, 59 | vma.vm_end, 60 | str(vma.vm_flags), 61 | pgoff, 62 | major, 63 | minor, 64 | ino, 65 | fname) 66 | -------------------------------------------------------------------------------- /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/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 | 29 | class linux_psaux(linux_pslist.linux_pslist): 30 | '''Gathers processes along with full command line and start time''' 31 | 32 | def render_text(self, outfd, data): 33 | 34 | outfd.write("{1:6s} {2:6s} {3:6s} {0:64s}\n".format("Arguments", "Pid", "Uid", "Gid")) 35 | 36 | for task in data: 37 | outfd.write("{1:6s} {2:6s} {3:6s} {0:64s}\n".format(task.get_commandline(), str(task.pid), str(task.uid), str(task.gid))) 38 | -------------------------------------------------------------------------------- /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 | 30 | class linux_psenv(linux_pslist.linux_pslist): 31 | '''Gathers processes along with their environment''' 32 | 33 | def render_text(self, outfd, data): 34 | outfd.write("{0:6s} {1:6s} {2:12s}\n".format("Name", "Pid", "Environment")) 35 | for task in data: 36 | outfd.write("{0:17s} {1:6s} {2:s}\n".format(str(task.comm), str(task.pid), task.get_environment())) 37 | -------------------------------------------------------------------------------- /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/plugins/linux/pstree.py: -------------------------------------------------------------------------------- 1 | # This file is part of Volatility. 2 | # Copyright (C) 2007-2013 Volatility Foundation 3 | # 4 | # Volatility is free software; you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation; either version 2 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # Volatility is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with Volatility. If not, see . 16 | # 17 | 18 | """ 19 | @author: Andrew Case 20 | @license: GNU General Public License 2.0 21 | @contact: atcuno@gmail.com 22 | @organization: 23 | """ 24 | 25 | import volatility.plugins.linux.pslist as linux_pslist 26 | 27 | class linux_pstree(linux_pslist.linux_pslist): 28 | '''Shows the parent/child relationship between processes''' 29 | 30 | def __init__(self, *args, **kwargs): 31 | self.procs = {} 32 | linux_pslist.linux_pslist.__init__(self, *args, **kwargs) 33 | 34 | def render_text(self, outfd, data): 35 | 36 | self.procs = {} 37 | outfd.write("{0:20s} {1:15s} {2:15s}\n".format("Name", "Pid", "Uid")) 38 | for task in data: 39 | self.recurse_task(outfd, task, 0) 40 | 41 | def recurse_task(self, outfd, task, level): 42 | 43 | if task.pid in self.procs: 44 | return 45 | 46 | if task.mm: 47 | proc_name = task.comm 48 | else: 49 | proc_name = "[" + task.comm + "]" 50 | 51 | proc_name = "." * level + proc_name 52 | outfd.write("{0:20s} {1:15s} {2:15s}\n".format(proc_name, str(task.pid), str(task.uid or ''))) 53 | self.procs[task.pid] = 1 54 | 55 | for child in task.children.list_of_type("task_struct", "sibling"): 56 | self.recurse_task(outfd, child, level + 1) 57 | 58 | -------------------------------------------------------------------------------- /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/plugins/linux/threads.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | 17 | """ 18 | @author: Edwin Smulders 19 | @license: GNU General Public License 2.0 or later 20 | @contact: mail@edwinsmulders.eu 21 | """ 22 | 23 | import volatility.plugins.linux.pslist as linux_pslist 24 | import volatility.plugins.linux.common as linux_common 25 | import volatility.obj as obj 26 | 27 | class linux_threads(linux_pslist.linux_pslist): 28 | """ Prints threads of processes """ 29 | 30 | def render_text(self, outfd, data): 31 | for task in data: 32 | outfd.write("\nProcess Name: {}\nProcess ID: {}\n".format(task.comm, task.tgid)) 33 | self.table_header(outfd, [('Thread PID', '13'), ('Thread Name', '16')]) 34 | for thread in task.threads(): 35 | self.table_row(outfd, str(thread.pid), thread.comm) 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /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/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/plugins/mac/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botherder/volatility/5eb15741a095c5f0dec9bd771f6c4a63b06137c1/volatility/plugins/mac/__init__.py -------------------------------------------------------------------------------- /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/plugins/mac/check_mig_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 | import volatility.obj as obj 27 | import volatility.plugins.mac.common as common 28 | import volatility.debug as debug 29 | 30 | class mac_check_mig_table(common.AbstractMacCommand): 31 | """ Lists entires in the kernel's MIG table """ 32 | 33 | def calculate(self): 34 | common.set_plugin_members(self) 35 | 36 | # we can't use an array as the size of mig_hash_entry 37 | # depends on if MAC_COUNTERS is set, which changes between kernels 38 | # mig_table_max_displ is declared directly after mig_buckets 39 | # which allows us to calculate the size of each entry dynamically 40 | 41 | di_addr = self.addr_space.profile.get_symbol("_mig_table_max_displ") 42 | mig_buckets_addr = self.addr_space.profile.get_symbol("_mig_buckets") 43 | 44 | ele_size = (di_addr - mig_buckets_addr) / 1024 45 | 46 | for i in range(1024): 47 | entry = obj.Object("mig_hash_entry", offset = mig_buckets_addr + (i * ele_size), vm = self.addr_space) 48 | 49 | if entry.routine == 0: 50 | continue 51 | 52 | rname = self.addr_space.profile.get_symbol_by_address("kernel", entry.routine) 53 | if not rname or rname == "": 54 | rname = "HOOKED" 55 | 56 | yield (entry.num, rname, entry.routine) 57 | 58 | def render_text(self, outfd, data): 59 | self.table_header(outfd, [("Index", "8"), 60 | ("Routine Name", "100"), 61 | ("Routine Handler", "[addrpad]")]) 62 | 63 | for (num, name, routine) in data: 64 | self.table_row(outfd, num, name, routine) 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /volatility/plugins/mac/contacts.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.obj as obj 21 | import volatility.plugins.mac.common as common 22 | import volatility.utils as utils 23 | import volatility.plugins.mac.pstasks as pstasks 24 | 25 | class mac_contacts(pstasks.mac_tasks): 26 | """Gets contact names from Contacts.app""" 27 | 28 | def calculate(self): 29 | common.set_plugin_members(self) 30 | 31 | procs = pstasks.mac_tasks.calculate(self) 32 | 33 | for proc in procs: 34 | space = proc.get_process_address_space() 35 | for map in proc.get_proc_maps(): 36 | 37 | # only read/write without filebacks 38 | if not (map.get_perms() == "rw-" and not map.get_path()): 39 | continue 40 | 41 | # check the header for sqlite3 signature 42 | header = space.zread(map.links.start, 32) 43 | if "SQLite format" not in header: 44 | continue 45 | 46 | # get the whole sqlite3 data now 47 | data = space.zread(map.links.start, 48 | map.links.end - map.links.start) 49 | 50 | for offset in utils.iterfind(data, ":ABPerson"): 51 | person = obj.Object("String", 52 | offset = map.links.start + offset, 53 | vm = space, encoding = "utf8", 54 | length = 256) 55 | yield proc, person 56 | 57 | def render_text(self, outfd, data): 58 | 59 | for (proc, person) in data: 60 | 61 | # strip the header from the string 62 | person = str(person)[len(":ABPerson"):] 63 | 64 | # take a maximum of eight parts 65 | items = " ".join(person.split(" ")[:8]) 66 | 67 | outfd.write("{0}\n".format(items)) -------------------------------------------------------------------------------- /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/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/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/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 | 31 | class mac_dyld_maps(pstasks.mac_tasks): 32 | """ Gets memory maps of processes from dyld data structures """ 33 | 34 | def render_text(self, outfd, data): 35 | common.set_plugin_members(self) 36 | 37 | self.table_header(outfd, [("Pid", "8"), 38 | ("Name", "20"), 39 | ("Start", "#018x"), 40 | ("Map Name", "")]) 41 | 42 | for proc in data: 43 | for map in proc.get_dyld_maps(): 44 | self.table_row(outfd, 45 | str(proc.p_pid), 46 | proc.p_comm, 47 | map.imageLoadAddress, 48 | map.imageFilePath) 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /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/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/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/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("_dlil_ifnet_head") 37 | list_head_ptr = obj.Object("Pointer", offset = list_head_addr, vm = self.addr_space) 38 | ifnet = list_head_ptr.dereference_as("ifnet") 39 | 40 | while ifnet: 41 | name = ifnet.if_name.dereference() 42 | unit = ifnet.if_unit 43 | ifaddr = ifnet.if_addrhead.tqh_first 44 | 45 | ips = [] 46 | 47 | while ifaddr: 48 | ip = ifaddr.ifa_addr.get_address() 49 | if ip: 50 | ips.append(ip) 51 | ifaddr = ifaddr.ifa_link.tqe_next 52 | 53 | yield (name, unit, ips) 54 | ifnet = ifnet.if_link.tqe_next 55 | 56 | def render_text(self, outfd, data): 57 | self.table_header(outfd, [("Interface", "10"), ("Address", "")]) 58 | 59 | for (name, unit, ips) in data: 60 | if ips: 61 | for ip in ips: 62 | self.table_row(outfd, "{0}{1}".format(name, unit), ip) 63 | else: 64 | # an interface with no IPs 65 | self.table_row(outfd, "{0}{1}".format(name, unit), "") 66 | -------------------------------------------------------------------------------- /volatility/plugins/mac/keychaindump.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 | ### based entirely on keychaindump from volafox 28 | 29 | import volatility.obj as obj 30 | import volatility.plugins.mac.pstasks as pstasks 31 | import volatility.plugins.mac.common as common 32 | 33 | class mac_keychaindump(pstasks.mac_tasks): 34 | """ Recovers possbile keychain keys. Use chainbreaker to open related keychain files """ 35 | 36 | def calculate(self): 37 | common.set_plugin_members(self) 38 | 39 | procs = pstasks.mac_tasks.calculate(self) 40 | 41 | if self.addr_space.profile.metadata.get('memory_model', '32bit') == "32bit": 42 | ptr_sz = 4 43 | else: 44 | ptr_sz = 8 45 | 46 | for proc in procs: 47 | if str(proc.p_comm) != "securityd": 48 | continue 49 | 50 | proc_as = proc.get_process_address_space() 51 | 52 | for map in proc.get_proc_maps(): 53 | if not (map.start > 0x00007f0000000000 and map.end < 0x00007fff00000000 and map.end - map.start == 0x100000): 54 | continue 55 | 56 | for address in range(map.start, map.end, ptr_sz): 57 | signature = obj.Object("unsigned int", offset = address, vm = proc_as) 58 | 59 | if not signature or signature != 0x18: 60 | continue 61 | 62 | key_buf_ptr = obj.Object("unsigned long", offset = address + ptr_sz, vm = proc_as) 63 | 64 | if map.start <= key_buf_ptr < map.end: 65 | yield proc_as, key_buf_ptr 66 | 67 | def render_text(self, outfd, data): 68 | self.table_header(outfd, [("Key", "")]) 69 | 70 | for (proc_as, key_buf_ptr) in data: 71 | key_buf = proc_as.read(key_buf_ptr, 24) 72 | if not key_buf: 73 | continue 74 | 75 | key = "".join('%02X'%ord(k) for k in key_buf) 76 | self.table_row(outfd, key) 77 | 78 | 79 | -------------------------------------------------------------------------------- /volatility/plugins/mac/list_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.mac.common as common 29 | import volatility.plugins.mac.mount as mac_mount 30 | 31 | class mac_list_files(common.AbstractMacCommand): 32 | """ Lists files in the file cache """ 33 | 34 | def calculate(self): 35 | common.set_plugin_members(self) 36 | 37 | mounts = mac_mount.mac_mount(self._config).calculate() 38 | 39 | for mount in mounts: 40 | vnode = mount.mnt_vnodelist.tqh_first 41 | 42 | while vnode: 43 | path = vnode.full_path() 44 | 45 | yield vnode, path 46 | 47 | vnode = vnode.v_mntvnodes.tqe_next 48 | 49 | def render_text(self, outfd, data): 50 | self.table_header(outfd, [("Offset (V)", "[addrpad]"), ("File Path", "")]) 51 | for vnode, path in data: 52 | self.table_row(outfd, vnode.v(), path) 53 | 54 | -------------------------------------------------------------------------------- /volatility/plugins/mac/list_zones.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_list_zones(common.AbstractMacCommand): 31 | """ Prints active zones """ 32 | 33 | def calculate(self): 34 | common.set_plugin_members(self) 35 | 36 | first_zone_addr = self.addr_space.profile.get_symbol("_first_zone") 37 | 38 | zone_ptr = obj.Object("Pointer", offset = first_zone_addr, vm = self.addr_space) 39 | zone = zone_ptr.dereference_as("zone") 40 | 41 | while zone: 42 | yield zone 43 | zone = zone.next_zone 44 | 45 | def render_text(self, outfd, data): 46 | self.table_header(outfd, [("Name", "30"), ("Active Count", ">10"), ("Free Count", ">10"), ("Element Size", ">10")]) 47 | for zone in data: 48 | name = zone.zone_name.dereference().replace(" ", ".") 49 | 50 | # sum_count was introduced in 10.8.x 51 | # do not want to overlay as 0 b/c we mess up subtraction 52 | if hasattr(zone, "sum_count"): 53 | sum_count = zone.sum_count - zone.count 54 | else: 55 | sum_count = "N/A" 56 | 57 | self.table_row(outfd, name, zone.count, sum_count, zone.elem_size) 58 | 59 | -------------------------------------------------------------------------------- /volatility/plugins/mac/lsmod.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_lsmod(common.AbstractMacCommand): 31 | """ Lists loaded kernel modules """ 32 | 33 | def __init__(self, config, *args, **kwargs): 34 | common.AbstractMacCommand.__init__(self, config, *args, **kwargs) 35 | 36 | config.add_option('ADDR', short_option = 'a', default = None, help = 'Show info on VAD at or containing this address', action = 'store', type = 'int') 37 | 38 | def calculate(self): 39 | common.set_plugin_members(self) 40 | 41 | p = self.addr_space.profile.get_symbol("_kmod") 42 | kmodaddr = obj.Object("Pointer", offset = p, vm = self.addr_space) 43 | kmod = kmodaddr.dereference_as("kmod_info") 44 | 45 | while kmod.is_valid(): 46 | if not self._config.ADDR or (kmod.address <= self._config.ADDR <= (kmod.address + kmod.m("size"))): 47 | yield kmod 48 | kmod = kmod.next 49 | 50 | def render_text(self, outfd, data): 51 | self.table_header(outfd, [("Offset (V)", "[addrpad]"), 52 | ("Module Address", "[addrpad]"), 53 | ("Size", "8"), 54 | ("Refs", "^8"), 55 | ("Version", "12"), 56 | ("Name", "")]) 57 | for kmod in data: 58 | self.table_row(outfd, 59 | kmod, 60 | kmod.address, 61 | kmod.m('size'), 62 | kmod.reference_count, 63 | kmod.version, 64 | kmod.name) 65 | 66 | 67 | -------------------------------------------------------------------------------- /volatility/plugins/mac/lsmod_iokit.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 | 31 | class mac_lsmod_iokit(common.AbstractMacCommand): 32 | """ Lists loaded kernel modules through IOkit """ 33 | 34 | def calculate(self): 35 | common.set_plugin_members(self) 36 | 37 | saddr = common.get_cpp_sym("sLoadedKexts", self.addr_space.profile) 38 | 39 | p = obj.Object("Pointer", offset = saddr, vm = self.addr_space) 40 | 41 | kOSArr = obj.Object("OSArray_class", offset = p, vm = self.addr_space) 42 | 43 | if kOSArr == None: 44 | debug.error("The OSArray_class type was not found in the profile. Please file a bug if you are running aginst Mac >= 10.7") 45 | 46 | kext_arr = obj.Object(theType = "Array", targetType = "Pointer", offset = kOSArr.array, count = kOSArr.capacity, vm = self.addr_space) 47 | 48 | for (i, kext) in enumerate(kext_arr): 49 | kext = kext.dereference_as("OSKext_class") 50 | if kext and kext.is_valid(): 51 | yield kext 52 | 53 | def render_text(self, outfd, data): 54 | self.table_header(outfd, [("Offset (V)", "[addrpad]"), 55 | ("Module Address", "[addrpad]"), 56 | ("Size", "8"), 57 | ("Refs", "^8"), 58 | ("Version", "12"), 59 | ("Name", "48"), 60 | ("Path", "")]) 61 | for kext in data: 62 | path = kext.path 63 | 64 | if path: 65 | path = str(path.dereference()) 66 | 67 | self.table_row(outfd, 68 | kext.kmod_info, 69 | kext.kmod_info.address, 70 | kext.kmod_info.m("size"), 71 | kext.kmod_info.reference_count, 72 | kext.version, 73 | kext.kmod_info.name, 74 | str(path)) 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /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 | 31 | class mac_lsof(pstasks.mac_tasks): 32 | """ Lists per-process opened files """ 33 | def calculate(self): 34 | common.set_plugin_members(self) 35 | 36 | procs = pstasks.mac_tasks(self._config).calculate() 37 | 38 | for proc in procs: 39 | num_fds = proc.p_fd.fd_lastfile 40 | if proc.p_fd.fd_nfiles > num_fds: 41 | num_fds = proc.p_fd.fd_nfiles 42 | 43 | fds = obj.Object('Array', offset = proc.p_fd.fd_ofiles, vm = self.addr_space, targetType = 'Pointer', count = proc.p_fd.fd_nfiles) 44 | 45 | for i, fd in enumerate(fds): 46 | f = fd.dereference_as("fileproc") 47 | if f: 48 | ftype = f.f_fglob.fg_type 49 | if ftype == 'DTYPE_VNODE': 50 | vnode = f.f_fglob.fg_data.dereference_as("vnode") 51 | path = vnode.full_path() 52 | else: 53 | path = "" 54 | 55 | yield proc, i, f, path 56 | 57 | def render_text(self, outfd, data): 58 | self.table_header(outfd, [("PID","8"), 59 | ("File Descriptor", "6"), 60 | ("File Path", ""), 61 | ]) 62 | 63 | for proc, i, f, path in data: 64 | if path: 65 | self.table_row(outfd, proc.p_pid, i, path) 66 | 67 | 68 | -------------------------------------------------------------------------------- /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/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.pslist as mac_pslist 33 | 34 | class mac_malfind(mac_pslist.mac_pslist): 35 | """Looks for suspicious process mappings""" 36 | 37 | def _is_suspicious(self, map): 38 | ret = False 39 | 40 | if map.get_perms() == "rwx": 41 | ret = True 42 | 43 | elif map.get_perms() == "r-x" and map.get_path() == "": 44 | ret = True 45 | 46 | return ret 47 | 48 | def render_text(self, outfd, data): 49 | for task in data: 50 | proc_as = task.get_process_address_space() 51 | 52 | for map in task.get_proc_maps(): 53 | if self._is_suspicious(map): 54 | fname = map.get_path() 55 | prots = map.get_perms() 56 | 57 | content = proc_as.zread(map.start, 64) 58 | 59 | outfd.write("Process: {0} Pid: {1} Address: {2:#x} File: {3}\n".format( 60 | task.p_comm, task.p_pid, map.start, fname)) 61 | 62 | outfd.write("Protection: {0}\n".format(prots)) 63 | 64 | outfd.write("\n") 65 | 66 | outfd.write("{0}\n".format("\n".join( 67 | ["{0:#010x} {1:<48} {2}".format(map.start + o, h, ''.join(c)) 68 | for o, h, c in utils.Hexdump(content) 69 | ]))) 70 | 71 | outfd.write("\n") 72 | outfd.write("\n".join( 73 | ["{0:#x} {1:<16} {2}".format(o, h, i) 74 | for o, i, h in malfind.Disassemble(content, map.start) 75 | ])) 76 | 77 | outfd.write("\n\n") 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /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/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 | 30 | class mac_mount(common.AbstractMacCommand): 31 | """ Prints mounted device information """ 32 | 33 | def calculate(self): 34 | common.set_plugin_members(self) 35 | 36 | mountlist_addr = self.addr_space.profile.get_symbol("_mountlist") 37 | mount = obj.Object("mount", offset = mountlist_addr, vm = self.addr_space) 38 | mount = mount.mnt_list.tqe_next 39 | 40 | while mount: 41 | yield mount 42 | mount = mount.mnt_list.tqe_next 43 | 44 | def render_text(self, outfd, data): 45 | self.table_header(outfd, [("Device", "30"), ("Mount Point", "60"), ("Type", "")]) 46 | for mount in data: 47 | self.table_row(outfd, 48 | mount.mnt_vfsstat.f_mntonname, 49 | mount.mnt_vfsstat.f_mntfromname, 50 | mount.mnt_vfsstat.f_fstypename) 51 | -------------------------------------------------------------------------------- /volatility/plugins/mac/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 volatility.obj as obj 28 | import volatility.plugins.mac.lsof as lsof 29 | 30 | class mac_netstat(lsof.mac_lsof): 31 | """ Lists active per-process network connections """ 32 | 33 | def render_text(self, outfd, data): 34 | 35 | self.table_header(outfd, [("Proto", "6"), 36 | ("Local IP", "20"), 37 | ("Local Port", "6"), 38 | ("Remote IP", "20"), 39 | ("Remote Port", "6"), 40 | ("State", "20"), 41 | ("Process", "24")]) 42 | 43 | for proc, i, fd, _path in data: 44 | if fd.f_fglob.fg_type == 'DTYPE_SOCKET': 45 | socket = fd.f_fglob.fg_data.dereference_as("socket") 46 | family = socket.family 47 | 48 | if family == 1: 49 | upcb = socket.so_pcb.dereference_as("unpcb") 50 | path = upcb.unp_addr.sun_path 51 | outfd.write("UNIX {0}\n".format(path)) 52 | elif family in [2, 30]: 53 | proto = socket.protocol 54 | state = socket.state 55 | 56 | (lip, lport, rip, rport) = socket.get_connection_info() 57 | 58 | self.table_row(outfd, proto, lip, lport, rip, rport, state, "{}/{}".format(proc.p_comm, proc.p_pid)) 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /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/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 46 | 47 | while p: 48 | yield p 49 | p = p.p_hash.le_next 50 | -------------------------------------------------------------------------------- /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 | 30 | class mac_print_boot_cmdline(common.AbstractMacCommand): 31 | """ Prints kernel boot arguments """ 32 | 33 | def calculate(self): 34 | common.set_plugin_members(self) 35 | 36 | pe_state_addr = self.addr_space.profile.get_symbol("_PE_state") 37 | pe_state = obj.Object("PE_state", offset = pe_state_addr, vm = self.addr_space) 38 | bootargs = pe_state.bootArgs.dereference_as("boot_args") 39 | 40 | yield bootargs.CommandLine 41 | 42 | def render_text(self, outfd, data): 43 | self.table_header(outfd, [("Command Line", "")]) 44 | for cmdline in data: 45 | self.table_row(outfd, cmdline) 46 | -------------------------------------------------------------------------------- /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 | 31 | class mac_proc_maps(pstasks.mac_tasks): 32 | """ Gets memory maps of processes """ 33 | 34 | def calculate(self): 35 | common.set_plugin_members(self) 36 | 37 | procs = pstasks.mac_tasks.calculate(self) 38 | 39 | for proc in procs: 40 | for map in proc.get_proc_maps(): 41 | yield proc, map 42 | 43 | def render_text(self, outfd, data): 44 | self.table_header(outfd, [("Pid", "8"), 45 | ("Name", "20"), 46 | ("Start", "#018x"), 47 | ("End", "#018x"), 48 | ("Perms", "9"), 49 | ("Map Name", "")]) 50 | 51 | for (proc, map) in data: 52 | path = map.get_path() 53 | if path == "": 54 | path = map.get_special_path() 55 | 56 | self.table_row(outfd, 57 | str(proc.p_pid), proc.p_comm, 58 | map.links.start, 59 | map.links.end, 60 | map.get_perms(), 61 | path) 62 | 63 | 64 | -------------------------------------------------------------------------------- /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 | 29 | class mac_psaux(pstasks.mac_tasks): 30 | """ Prints processes with arguments in user land (**argv) """ 31 | 32 | def render_text(self, outfd, data): 33 | 34 | self.table_header(outfd, [("Pid", "8"), 35 | ("Name", "20"), 36 | ("Bits", "16"), 37 | ("Stack", "#018x"), 38 | ("Length", "8"), 39 | ("Argc", "8"), 40 | ("Arguments", "")]) 41 | for proc in data: 42 | self.table_row(outfd, 43 | proc.p_pid, 44 | proc.p_comm, 45 | str(proc.task.map.pmap.pm_task_map or '')[9:], 46 | proc.user_stack, 47 | proc.p_argslen, 48 | proc.p_argc, 49 | proc.get_arguments()) 50 | -------------------------------------------------------------------------------- /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 | 36 | def allprocs(self): 37 | common.set_plugin_members(self) 38 | tasksaddr = self.addr_space.profile.get_symbol("_tasks") 39 | queue_entry = obj.Object("queue_entry", offset = tasksaddr, vm = self.addr_space) 40 | 41 | seen = [tasksaddr] 42 | 43 | for task in queue_entry.walk_list(list_head = tasksaddr): 44 | if (task.bsd_info and task.obj_offset not in seen): 45 | proc = task.bsd_info.dereference_as("proc") 46 | yield proc 47 | 48 | seen.append(task.obj_offset) 49 | 50 | def calculate(self): 51 | common.set_plugin_members(self) 52 | 53 | pidlist = None 54 | try: 55 | if self._config.PID: 56 | pidlist = [int(p) for p in self._config.PID.split(',')] 57 | except: 58 | pass 59 | 60 | for proc in self.allprocs(): 61 | if not pidlist or proc.p_pid in pidlist: 62 | yield proc 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /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/plugins/mac/session_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_list_sessions(pslist.mac_pslist): 32 | """ Enumerates sessions """ 33 | 34 | def calculate(self): 35 | common.set_plugin_members(self) 36 | 37 | shash_addr = self.addr_space.profile.get_symbol("_sesshash") 38 | shash = obj.Object("unsigned long", offset = shash_addr, vm = self.addr_space) 39 | 40 | shashtbl_addr = self.addr_space.profile.get_symbol("_sesshashtbl") 41 | shashtbl_ptr = obj.Object("Pointer", offset = shashtbl_addr, vm = self.addr_space) 42 | shash_array = obj.Object(theType = "Array", targetType = "sesshashhead", count = shash + 1, vm = self.addr_space, offset = shashtbl_ptr) 43 | 44 | for sess in shash_array: 45 | s = sess.lh_first 46 | 47 | while s: 48 | yield s 49 | s = s.s_hash.le_next 50 | 51 | def render_text(self, outfd, data): 52 | self.table_header(outfd, [("Leader (Pid)", "8"), 53 | ("Leader (Name)", "20"), 54 | ("Login Name", "25")]) 55 | 56 | for sess in data: 57 | if sess.s_leader: 58 | pid = sess.s_leader.p_pid 59 | pname = sess.s_leader.p_comm 60 | else: 61 | pid = -1 62 | pname = "" 63 | 64 | self.table_row(outfd, pid, pname, sess.s_login) 65 | 66 | -------------------------------------------------------------------------------- /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/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/plugins/malware/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botherder/volatility/5eb15741a095c5f0dec9bd771f6c4a63b06137c1/volatility/plugins/malware/__init__.py -------------------------------------------------------------------------------- /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 | 44 | self.scanners.append(callbacks.PoolScanFSCallback) 45 | self.scanners.append(callbacks.PoolScanShutdownCallback) 46 | self.scanners.append(callbacks.PoolScanGenericCallback) 47 | self.scanners.append(callbacks.PoolScanDbgPrintCallback) 48 | self.scanners.append(callbacks.PoolScanRegistryCallback) 49 | self.scanners.append(callbacks.PoolScanPnp9) 50 | self.scanners.append(callbacks.PoolScanPnpD) 51 | self.scanners.append(callbacks.PoolScanPnpC) 52 | 53 | for objct in self.scan_results(addr_space): 54 | yield objct 55 | 56 | def render_text(self, outfd, data): 57 | for objct in data: 58 | print objct -------------------------------------------------------------------------------- /volatility/plugins/objtypescan.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 | import volatility.plugins.common as common 20 | import volatility.utils as utils 21 | import volatility.poolscan as poolscan 22 | import volatility.obj as obj 23 | 24 | class ObjectTypeScanner(poolscan.PoolScanner): 25 | """Pool scanner for object type objects""" 26 | 27 | def __init__(self, address_space, **kwargs): 28 | poolscan.PoolScanner.__init__(self, address_space, **kwargs) 29 | 30 | self.struct_name = "_OBJECT_TYPE" 31 | self.object_type = "Type" 32 | self.pooltag = obj.VolMagic(address_space).ObjectTypePoolTag.v() 33 | size = 0xc8 # self.address_space.profile.get_obj_size("_OBJECT_TYPE") 34 | 35 | self.checks = [ 36 | ('CheckPoolSize', dict(condition = lambda x: x >= size)), 37 | ('CheckPoolType', dict(paged = False, non_paged = True, free = True)), 38 | #('CheckPoolIndex', dict(value = 0)), 39 | ] 40 | 41 | class ObjectTypeKeyModification(obj.ProfileModification): 42 | before = ['WindowsVTypes'] 43 | conditions = {'os': lambda x: x == 'windows'} 44 | 45 | def modification(self, profile): 46 | profile.merge_overlay({ 47 | '_OBJECT_TYPE': [ None, {'Key': [ None, ['String', dict(length = 4)]]}] 48 | }) 49 | 50 | class ObjTypeScan(common.AbstractScanCommand): 51 | """Scan for Windows object type objects""" 52 | 53 | scanners = [ObjectTypeScanner] 54 | 55 | def render_text(self, outfd, data): 56 | 57 | self.table_header(outfd, [("Offset", "[addrpad]"), 58 | ("nObjects", "[addr]"), 59 | ("nHandles", "[addr]"), 60 | ("Key", "8"), 61 | ("Name", "30"), 62 | ("PoolType", "20")]) 63 | for object_type in data: 64 | self.table_row(outfd, 65 | object_type.obj_offset, 66 | object_type.TotalNumberOfObjects, 67 | object_type.TotalNumberOfHandles, 68 | str(object_type.Key), 69 | str(object_type.Name or ''), 70 | object_type.TypeInfo.PoolType) -------------------------------------------------------------------------------- /volatility/plugins/overlays/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botherder/volatility/5eb15741a095c5f0dec9bd771f6c4a63b06137c1/volatility/plugins/overlays/__init__.py -------------------------------------------------------------------------------- /volatility/plugins/overlays/linux/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botherder/volatility/5eb15741a095c5f0dec9bd771f6c4a63b06137c1/volatility/plugins/overlays/linux/__init__.py -------------------------------------------------------------------------------- /volatility/plugins/overlays/mac/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botherder/volatility/5eb15741a095c5f0dec9bd771f6c4a63b06137c1/volatility/plugins/overlays/mac/__init__.py -------------------------------------------------------------------------------- /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, ' 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/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 | 58 | class WinXPSP3x86(obj.Profile): 59 | """ A Profile for Windows XP SP3 x86 """ 60 | _md_major = 5 61 | _md_minor = 1 62 | _md_os = 'windows' 63 | _md_memory_model = '32bit' 64 | _md_vtype_module = 'volatility.plugins.overlays.windows.xp_sp3_x86_vtypes' 65 | 66 | 67 | -------------------------------------------------------------------------------- /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(" 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: AAron Walters and Brendan Dolan-Gavitt 23 | @license: GNU General Public License 2.0 24 | @contact: awalters@4tphi.net,bdolangavitt@wesleyan.edu 25 | @organization: Volatility Foundation 26 | """ 27 | 28 | #pylint: disable-msg=C0111 29 | 30 | import volatility.utils as utils 31 | import volatility.poolscan as poolscan 32 | import volatility.plugins.common as common 33 | import volatility.plugins.bigpagepools as bigpools 34 | 35 | class PoolScanHive(poolscan.PoolScanner): 36 | """Pool scanner for registry hives""" 37 | 38 | def __init__(self, address_space): 39 | poolscan.PoolScanner.__init__(self, address_space) 40 | self.struct_name = "_CMHIVE" 41 | self.pooltag = "CM10" 42 | size = self.address_space.profile.get_obj_size("_CMHIVE") 43 | self.checks = [ 44 | ('CheckPoolSize', dict(condition = lambda x: x >= size)), 45 | ] 46 | 47 | class HiveScan(common.AbstractScanCommand): 48 | """Pool scanner for registry hives""" 49 | 50 | scanners = [PoolScanHive] 51 | # Declare meta information associated with this plugin 52 | 53 | meta_info = dict( 54 | author = 'Brendan Dolan-Gavitt', 55 | copyright = 'Copyright (c) 2007,2008 Brendan Dolan-Gavitt', 56 | contact = 'bdolangavitt@wesleyan.edu', 57 | license = 'GNU General Public License 2.0', 58 | url = 'http://moyix.blogspot.com/', 59 | os = 'WIN_32_XP_SP2', 60 | version = '1.0', 61 | ) 62 | 63 | def calculate(self): 64 | addr_space = utils.load_as(self._config) 65 | 66 | metadata = addr_space.profile.metadata 67 | version = (metadata.get("major", 0), metadata.get("minor", 0)) 68 | arch = metadata.get("memory_model", "32bit") 69 | 70 | if version >= (6, 3) and arch == "64bit": 71 | for pool in bigpools.BigPagePoolScanner(addr_space).scan(["CM10"]): 72 | yield pool.Va.dereference_as("_CMHIVE") 73 | else: 74 | for result in self.scan_results(addr_space): 75 | yield result 76 | 77 | def render_text(self, outfd, data): 78 | self.table_header(outfd, [('Offset(P)', '[addrpad]')]) 79 | for hive in data: 80 | self.table_row(outfd, hive.obj_offset) 81 | -------------------------------------------------------------------------------- /volatility/plugins/sockets.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 | #pylint: disable-msg=C0111 23 | 24 | import volatility.plugins.common as common 25 | import volatility.debug as debug 26 | import volatility.win32 as win32 27 | import volatility.utils as utils 28 | import volatility.protos as protos 29 | 30 | class Sockets(common.AbstractWindowsCommand): 31 | """Print list of open sockets""" 32 | def __init__(self, config, *args, **kwargs): 33 | common.AbstractWindowsCommand.__init__(self, config, *args, **kwargs) 34 | config.add_option("PHYSICAL-OFFSET", short_option = 'P', default = False, 35 | cache_invalidator = False, 36 | help = "Physical Offset", action = "store_true") 37 | 38 | @staticmethod 39 | def is_valid_profile(profile): 40 | return (profile.metadata.get('os', 'unknown') == 'windows' and 41 | profile.metadata.get('major', 0) == 5) 42 | 43 | def render_text(self, outfd, data): 44 | offsettype = "(V)" if not self._config.PHYSICAL_OFFSET else "(P)" 45 | self.table_header(outfd, 46 | [("Offset{0}".format(offsettype), "[addrpad]"), 47 | ("PID", ">8"), 48 | ("Port", ">6"), 49 | ("Proto", ">6"), 50 | ("Protocol", "15"), 51 | ("Address", "15"), 52 | ("Create Time", "") 53 | ]) 54 | 55 | for sock in data: 56 | if not self._config.PHYSICAL_OFFSET: 57 | offset = sock.obj_offset 58 | else: 59 | offset = sock.obj_vm.vtop(sock.obj_offset) 60 | 61 | self.table_row(outfd, offset, sock.Pid, sock.LocalPort, sock.Protocol, 62 | protos.protos.get(sock.Protocol.v(), "-"), 63 | sock.LocalIpAddress, sock.CreateTime) 64 | 65 | def calculate(self): 66 | addr_space = utils.load_as(self._config) 67 | 68 | if not self.is_valid_profile(addr_space.profile): 69 | debug.error("This command does not support the selected profile.") 70 | 71 | return win32.network.determine_sockets(addr_space) 72 | -------------------------------------------------------------------------------- /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 | 20 | import volatility.plugins.crashinfo as crashinfo 21 | 22 | class VBoxInfo(crashinfo.CrashInfo): 23 | """Dump virtualbox information""" 24 | 25 | target_as = ['VirtualBoxCoreDumpElf64'] 26 | 27 | def render_text(self, outfd, data): 28 | 29 | header = data.get_header() 30 | 31 | outfd.write("Magic: {0:#x}\n".format(header.u32Magic)) 32 | outfd.write("Format: {0:#x}\n".format(header.u32FmtVersion)) 33 | outfd.write("VirtualBox {0}.{1}.{2} (revision {3})\n".format( 34 | header.Major, 35 | header.Minor, header.Build, 36 | header.u32VBoxRevision)) 37 | outfd.write("CPUs: {0}\n\n".format(header.cCpus)) 38 | 39 | self.table_header(outfd, [("File Offset", "[addrpad]"), 40 | ("Memory Offset", "[addrpad]"), 41 | ("Size", "[addrpad]")]) 42 | 43 | for memory_offset, file_offset, length in data.get_runs(): 44 | self.table_row(outfd, file_offset, memory_offset, length) 45 | -------------------------------------------------------------------------------- /volatility/win32/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botherder/volatility/5eb15741a095c5f0dec9bd771f6c4a63b06137c1/volatility/win32/__init__.py -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------