Address Spaces
An address space is a layer of abstraction between Volatility plugins and the underlying format or layout of the memory dump. If you've ever wondered how you can write a single plugin (for example to list processes) and automatically it works against Microsoft crash dumps, hibernation files, raw dd-style memory dumps, etc., despite those files all having drastically different formats - that is the work of address spaces. They provide a common and consistent API for finding, reading, and writing data in RAM along with translating addresses between layers. In fact, most of the time, you won't even know address spaces are there - their role is critical, yet often silent.
As we say in our training courses, memory analysis is like a box of chocolates - you never know what you're going to get. If you're not the one acquiring memory, you don't get to choose the tool being used to save the memory dump or the format its saved in. Without a tool like Volatility that provides a framework for interfacing with the various formats that memory dumps are frequently found in, most analysts would be SOL to say the least. If someone hands you a hibernation file and your tool only supports raw memory dumps, what are you going to do?
Today's MoVP II post introduces the Mach-O Address Space for Volatility. The Mach-O file format is similar to Microsoft's PE format and Linux's ELF format in that its a standard for binaries, but its specific to the Mac/BSD platform. Supporting the Mach-O file format is a major breakthrough in our ability to provide thorough support of Mac memory dumps. One of the most popular tools for acquiring physical memory on Mac systems is ATC-NY's MacMemoryReader. Although the tool can save memory in a raw/padded (-P) and raw/unpadded (-p) format given the proper command-line arguments, the default is Mach-O. Thus in most cases, if someone uses MacMemoryReader to dump memory, you will likely receive a Mach-O file.
Acquisition
Acquisition
Here is an example of the MacMemoryReader program's help menu:
$ ./MacMemoryReader ATC-NY Mac Marshal Mac Memory Reader 3.0.2 ($Revision: 1.24 $) Copyright (c) Architecture Technology Corporation. All rights reserved. Usage: ./MacMemoryReader [-g] [-d] [-H hashtype] [-r] [-p] [-P] [-k]-g print progress messages suitable for parsing by a GUI -d print verbose debugging information to stderr -H compute the given hash on the output data (where hashtype is one of MD5, SHA-1, SHA-256, or SHA-512); can be given multiple times; hash is printed on stderr -r also copy "reserved" areas of memory, such as that used by shared-memory graphics adapters; EXPERIMENTAL -p dump memory in plain raw DD format instead of Mach-O, then write a table of contents to stderr listing file offsets versus physical memory offsets -P dump memory in plain raw DD format, inserting zeros for un-mapped regions in the memory map; no table of contents is needed, because file offsets will correspond to physical memory offsets, but the resulting file may be much larger than RAM -k load the RAM dump kernel extension and set up /dev/mem and /dev/pmap, but do not dump memory; for EXPERTS ONLY dumps physical memory to in Mach-O (the default) or raw/DD format. The resulting file may be slightly larger than physical memory due to the Mach-O header and alignment constraints. If the filename is '-', memory is dumped to stdout.
If you plan to do analysis with Volatility, you must either use the default Mach-O or raw/padded. We do not, and never will, support raw/un-padded.
Please also note you must run MacMemoryReader as root to load the required kernel extension for dumping memory.
File Format
If your Mac memory dump is in the Mach-O format will begin with a mach_header or mach_header_64 structure, as shown below. The magic is MH_MAGIC (0xFEEDFACE) for mach_header and MH_MAGIC_64 (0xFEEDFACF) for mach_header_64.
Note: if you're not familiar with the dt() command or the layout of the data structures shown, see the volshell command.
>>> dt("mach_header_64") 'mach_header_64' (32 bytes) 0x0 : magic ['unsigned int'] 0x4 : cputype ['int'] 0x8 : cpusubtype ['int'] 0xc : filetype ['unsigned int'] 0x10 : ncmds ['unsigned int'] 0x14 : sizeofcmds ['unsigned int'] 0x18 : flags ['unsigned int'] 0x1c : reserved ['unsigned int']
Immediately following the header, one or more segment_command or segment_command_64 structures can be found. These describe the memory runs, in particular the virtual address and size of the run and the offset within the file where the data can be found.
>>> dt("segment_command_64") 'segment_command_64' (72 bytes) 0x0 : cmd ['unsigned int'] 0x4 : cmdsize ['unsigned int'] 0x8 : segname ['array', 16, ['char']] 0x18 : vmaddr ['unsigned long long'] 0x20 : vmsize ['unsigned long long'] 0x28 : fileoff ['unsigned long long'] 0x30 : filesize ['unsigned long long'] 0x38 : maxprot ['int'] 0x3c : initprot ['int'] 0x40 : nsects ['unsigned int'] 0x44 : flags ['unsigned int']
This is the information Volatility uses when a plugin tries to read a virtual address. First the virtual address is translated to a physical address by the Intel x86 or AMD x64 address space. The result is passed down to the next layer, which would be Mach-O. The Mach-O layer reads the segment_command structures and determines at which offset in the file we can find a physical memory block. Remember, since there are Mach-O specific headers, an offset in physical memory is not the same as an offset in the file. Finally, the lowest address space in the chain (FileAddressSpace) retrieves the requested data from the file.
Metadata
If you want to view some of the metadata nicely packed into the Mach-O file, you can use the machoinfo plugin.
Conclusion
If you want thorough support of memory dumps from Mac OSX systems, you must be able to understand and analyze the Mach-O file format, in addition to the traditional raw/dd-style. Don't get caught unprepared, not knowing what to do with a Mach-O file - it wastes valuable time during an investigation. Be ready, know your tools, and solve the questions before everyone else knows where to start looking.
Metadata
If you want to view some of the metadata nicely packed into the Mach-O file, you can use the machoinfo plugin.
$ ./vol.py --profile=MacMountainLion_10_8_3_AMDx64 -f mac.dmp machoinfo Volatile Systems Volatility Framework 2.3_alpha Magic: 0xfeedfacf Architecture: 64-bit File Offset Memory Offset Size Name ------------------ ------------------ ------------------ ---- 0x0000000000004000 0x0000000000000000 0x000000000008e000 available 0x0000000000092000 0x0000000000090000 0x0000000000010000 available 0x00000000000a2000 0x0000000000100000 0x000000000f200000 available 0x000000000f2a2000 0x000000000f300000 0x0000000000013000 LoaderData 0x000000000f2b5000 0x000000000f313000 0x00000000000ed000 available 0x000000000f3a2000 0x000000000f400000 0x0000000000535000 LoaderData 0x000000000f8d7000 0x000000000f935000 0x00000000000cb000 available 0x000000000f9a2000 0x000000000fa00000 0x00000000021f2000 LoaderData 0x0000000011b94000 0x0000000011bf2000 0x0000000000053000 RT_data 0x0000000011be7000 0x0000000011c45000 0x0000000000028000 RT_code [snip]
Conclusion
If you want thorough support of memory dumps from Mac OSX systems, you must be able to understand and analyze the Mach-O file format, in addition to the traditional raw/dd-style. Don't get caught unprepared, not knowing what to do with a Mach-O file - it wastes valuable time during an investigation. Be ready, know your tools, and solve the questions before everyone else knows where to start looking.
No comments:
Post a Comment