From YobiWiki

Misc notes on physical RAM analysis

Volatility, for memory analysis of mainly Windows platforms (Linux support is in beta)

Volatilitux, for memory analysis of linux and Android platforms

Passware, a commercial tool mostly aiming at recovering passwords, including from memory dumps

RAM dump with VirtualBox: via ELF64 coredump

VMWare snapshots contain a .vmem which is basically a RAM dump, but for VirtualBox, it's not that easy...

Snapshot .sav files contain all machine state including memory but in a hardly exploitable format (even if VirtualBox is open-source...) and the few people having looked in that direction didn't succeed.

But there is another way to get a RAM dump with VirtualBox (I'm not talking about tools running in the guest as I don't want to interfere at all with the target):

See Ch8 of the manual about debugvm capabilities:

With dumpguestcore --filename <name>, you can create a system dump of the running VM, which will be written into the given file. This file will have the standard ELF core format (with custom sections);

The dump format itself is described here

So let's try:

VM has to run in order to be able to make the RAM dump, then:

$ vboxmanage debugvm "Win7" dumpguestcore --filename test.elf

We're interested into the first LOAD section, that's where main memory reference is:

$ readelf --program-headers test.elf|grep -m1 -A1 LOAD LOAD 0x0000000000000720 0x0000000000000000 0x0000000000000000 0x0000000040000000 0x0000000040000000 R 0

If I unwrap the info and label it, we have:

Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000720 0x0000000000000000 0x0000000000000000 0x0000000040000000 0x0000000040000000 R 0

So memory dump is in test.elf, starting at offset 0x720 and counting 0x40000000 bytes (1024Mb)

Alternatively, using objdump:

$ objdump -h test.elf|egrep -w "(Idx|load1)" Idx Name Size VMA LMA File off Algn 1 load1 40000000 0000000000000000 0000000000000000 00000720 2**0



Let's extract the RAM, getting rid of the first bytes.

size=0x40000000;off=0x720;head -c $(($size+$off)) test.elf|tail -c +$(($off+1)) > test.raw

Now using volatility on the obtained file:

$ ./vol.py -f test.raw --profile=Win7SP1x86 pslist Volatile Systems Volatility Framework 2.0 Offset(V) Name PID PPID Thds Hnds Time ---------- -------------------- ------ ------ ------ ------ ------------------- 0x83d33d40 System 4 0 69 506 2012-02-07 16:06:19 0x84c5c758 smss.exe 228 4 2 29 2012-02-07 16:06:19 0x85475030 csrss.exe 304 296 9 398 2012-02-07 16:06:30 0x83d9b108 wininit.exe 340 296 3 76 2012-02-07 16:06:41 0x83d70528 csrss.exe 352 332 7 103 2012-02-07 16:06:41 0x84d9c568 winlogon.exe 392 332 5 111 2012-02-07 16:06:42

etc

Volatility with VirtualBox: via ELF64 coredump

We just saw how to extract a RAM image but it would be nice if Volatility was able to read directly the VirtualBox core dump.

Thanks to the support of Mike Auty, I managed to write a plugin for Volatility.

You can download it as vboxelf.py

# Volatility # Copyright (C) 2007,2008 Volatile Systems # Copyright (C) 2005,2006,2007 4tphi Research # # Authors: # {npetroni,awalters}@4tphi.net (Nick Petroni and AAron Walters) # phil@teuwen.org (Philippe Teuwen) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ An AS for processing VirtualBox ELF64 coredumps """ # References: # VirtualBox core format: http://www.virtualbox.org/manual/ch12.html#guestcoreformat # ELF64 format: http://downloads.openwatcom.org/ftp/devel/docs/elf-64-gen.pdf import struct import volatility. plugins . addrspaces . standard as standard #pylint: disable-msg=C0111 class VirtualBoxCoreDumpElf64 ( standard. FileAddressSpace ) : """ This AS supports VirtualBox ELF64 coredump format """ order = 30 def __init__ ( self , base , config , **kwargs ) : ## We must have an AS below us self . as_assert ( base , "No base Address Space" ) # Testing for ELF64, little-endian: self . as_assert ( ( base. read ( 0 , 6 ) == ' \x 7fELF \x 02 \x 01' ) , "ELF64 Header signature invalid" ) self . as_assert ( ( base. read ( 0x10 , 2 ) == ' \x 04 \x 00' ) , "ELF64 type is not a Core file" ) ( phoff , ) = struct . unpack ( '<Q' , base. read ( 0x20 , 8 ) ) ( phentsize , phnum ) = struct . unpack ( '<HH' , base. read ( 0x36 , 4 ) ) found_note_vbcore = False found_load_ram = False for phptr in range ( phoff , phoff + ( phentsize * phnum ) , phentsize ) : ( stype , flags , offset , vaddr , paddr , filesz , memsz , align ) = struct . unpack ( '<IIQQQQQQ' , base. read ( phptr , phentsize ) ) # NOTE VBCORE segment? if ( ( not found_note_vbcore ) and ( stype == 4 ) ) : ( namesz , descsz , ntype ) = struct . unpack ( '<III' , base. read ( offset , 12 ) ) if ( base. read ( offset+ 12 , namesz ) == 'VBCORE' ) : found_note_vbcore = True self . as_assert ( ( descsz == 24 ) , 'Abnormal VBCORE size' ) # parsing DBGFCOREDESCRIPTOR: ( magic , fmtvers , selfsize , vbvers , vbrev , ncpus ) = struct . unpack ( '<IIIIII' , base. read ( offset+ 12 + ( ( ( ( namesz- 1 ) >> 3 ) + 1 ) << 3 ) , 24 ) ) self . as_assert ( ( magic == 0xc01ac0de ) , 'Could not find VBox core magic signature' ) self . as_assert ( ( fmtvers == 0x00010000 ) , 'Unknown VBox core format version' ) # For info: VirtualBox version and revision are available in vbvers & vbrev continue # LOAD RAM segment? if ( ( not found_load_ram ) and ( stype == 1 ) ) : # LOAD segments contain also other stuff such as video memory # but we're only interested into main RAM, starting at physical address 0 if paddr == 0x0000000000000000 : found_load_ram = True self . moffset = offset self . msize = filesz self . as_assert ( found_note_vbcore , 'ELF error: did not find any NOTE segment with VBCORE' ) self . as_assert ( found_load_ram , 'ELF error: did not find any LOAD segment with main RAM' ) standard. FileAddressSpace . __init__ ( self , base , config , layered = True , **kwargs ) self . fsize = min ( self . msize , self . fsize - self . moffset ) def read ( self , addr , length ) : return self . base . read ( addr + self . moffset , length ) def zread ( self , addr , length ) : return self . base . zread ( addr + self . moffset , length ) def read_long ( self , addr ) : return self . base . read_long ( addr + self . moffset ) def write ( self , addr , data ) : return self . base . write ( addr + self . moffset , data ) def is_valid_address ( self , addr ) : return self . base . is_valid_address ( addr + self . moffset )

To be placed in your Volatility installation under plugins/addrspaces or to be used via the --plugins option:

Place vboxelf.py in a zip file or in a directory and pass it.

Warning: --plugins option was recognised only if placed before -f option

./vol.py --plugins=/path/to/vboxelf.zip -f test.elf --profile=Win7SP1x86 pslist

Currently an issue was opened to discuss possible integration of this plugin into the core source.

Meanwhile the plugin is mentioned in the Volatility wiki.

Update: this has been integrated in branch 2.3-devel in r2667 to r2670

RAM dump with VirtualBox: via pgmphystofile

See https://www.virtualbox.org/ticket/10222

Start the VM with "VirtualBox --dbg --startvm <VM name>".

Click on the "Debug" menu -> "Command line...".

Then use .pgmphystofile filename to save the physical memory to the given file.

This file is directly the RAM image and can be read as such by Volatility.

So why using the first method if this method provides directly a memory dump?

It depends your needs, it is currently not possible to automate this second method from a command line or API.