WinPMEM - a kernel mode driver for gaining access to physical memory.
Version 1.3
Copyright 2012 Michael Cohen <scudette@gmail.com>

This is a physical memory imager which implements the following features:

- This code builds on 64 bit windows as well as 32 bit windows.

- A read device interface is used instead of writing the image from the kernel
  like some other imagers. This allows us to have complex userspace imager
  (e.g. copy across network, hash etc), as well as run analysis on the live
  system (e.g. rekall can be run directly on the device).

- The userspace component can write crash dumps of 32 and 64 bit systems.

- The image can be written to stdout (using an output filename of "-"). This can
  then be piped using the usual ways (netcat, ssh etc).


The files in this directory (Including the winpmem sources and signed binaries),
are available under the following license: Apache License, Version 2.0

How to use these drivers.
=========================

There are two user space programs that can be used to acquire memory images. The
python acquitision program demonstrates how to use the driver from python and
can be easily extended to handle the image in another way (e.g. compress, hash,
send across the network etc).

The winpmem_1.3.exe program is a self contained binary with both 32 and 64 bit
drivers embedded. It is the easiest and most recommended to use for incident
response since it requires no external dependencies, and automatically installs
the correct driver.

The Python acquitision tool winpmem.py
--------------------------------------

This release comes with signed binary drivers and a python program which uses
this driver to create raw images. (Note that in order to load the driver on 64
bit windows the driver _must_ be signed). Below we assume we are running on a 64
bit system. The driver for 32 bit systems can be found in
binaries\i386\winpmem_32.sys.

To get help about the acquisition tool:

c:\..> winpmem.py -h
Usage: winpmem.py [options]

Options:
  -h, --help            show this help message and exit
  -d FILE, --driver=FILE
                        The driver location (winpmem.sys)
  -f FILE, --filename=FILE
                        write image to FILE
  -n NAME, --name=NAME  The name of the device.
  -m MODE, --mode=MODE  The acquisition mode. Can be (physical or iospace)
  -l, --load            Only load the driver and immediately quit. (Useful
                        just before attaching with rekall)
  -u, --unload          Unload the driver and immediately quit.

To acquire memory into the file foobar.raw:
c:\..> winpmem.py -d binaries\amd64\winpmem_64.sys -f foobar.raw
CR3 = 0x187000
Memory ranges:
Start           Length
0x1000          0x9E000
0x100000                0x6F6FB000
Imaging to foo.raw

Padding from 0x0 to 0x1000


0000MB  .
Padding from 0x9F000 to 0x100000

................................................
0050MB  ..................................................
0100MB  ..................................................
0150MB  ..................................................
0200MB  ..................................................
0250MB  ..................................................

Note that CR3 and the valid physical memory ranges are reported.

Normally when acquiring memory we load the driver, acquire the memory, then
unload the driver. To use rekall on the raw memory we need to leave the
driver loaded:

c:\..> winpmem.py -d binaries\amd64\winpmem.sys -l
Loaded the winpmem driver. You can now attach rekall to \\.\pmem

and once we finished with it we can unload it (Make sure to exit rekall
before unloading the driver):

c:\..> winpmem.py -d binaries\amd64\winpmem.sys -u
(1073, 'CreateService', 'The specified service already exists.')
unloaded winpmem driver.


The self contained binary winpmem.exe
-------------------------------------

This program is easiest to use for incident response since it requires no other
dependencies than the executable itself. The program will load the correct
driver (32 bit or 64 bit) automatically.

c:\..> winpmem_1.3.exe -h
Winpmem - A memory imager for windows.
Copyright Michael Cohen (scudette@gmail.com) 2012.

Version 1.3. Built Nov 12 2012
Usage:
  winpmem_1.3.exe [option] [output path]

Option:
  -l    Load the driver and exit.
  -u    Unload the driver and exit.
  -h    Display this help.
  -w    Turn on/off write mode.
  -1    Use MmMapIoSpace method.
  -2    Use \\Device\PhysicalMemory method (Default).
  -d    Produce a crashdump file.


NOTE: an output filename of - will write the image to STDOUT.

Examples:
winpmem_1.3.exe physmem.raw
Writes a raw image to physmem.raw

winpmem_1.3.exe -d - | nc 192.168.1.1 80
Writes a crashdump file to netcat for network transport. Output is supressed
here because STDOUT is redirected.

To load the driver and exit:
c:\..> winpmem.exe -l
Loaded Driver.

To unload the driver and exit:
c:\..> winpmem.exe -u
Driver Unloaded.

To acquire a raw image using the MmMapIoSpace method:
c:\..> winpmem_1.3.exe -1 myimage.raw

The driver will be automatically unloaded after the image is acquired.

To acquire an image in crashdump format:

c:\..>winpmem_1.3.exe -d c:\temp\test.dmp
Driver Unloaded.
Loaded Driver C:\Users\mic\AppData\Local\Temp\win6C6.tmp.
Will write a crash dump file
CR3: 0x0000187000
 2 memory ranges:
Start 0x00001000 - Length 0x0009E000
Start 0x00100000 - Length 0x6F6FB000


00% 0x00001000 .

00% 0x00100000 ..................................................
02% 0x03300000 ..................................................
05% 0x06500000 ..................................................
...
92% 0x67300000 ..................................................
95% 0x6A500000 ..................................................
98% 0x6D700000 .................................
Driver Unloaded.

Experimental write support
--------------------------

As from Version 1.1, the winpmem drivers support writing to memory as well as
reading. This capability is a great learning tool since many rootkit hiding
techniques can be emulated by writing to memory directly. For example the
following Rekall session illustrates changing the name of the binary:

WinXPSP2x86:pmem 03:10:40> task = session.profile._EPROCESS(0x82079c18)
WinXPSP2x86:pmem 03:10:57> task.ImageFileName
                    Out<3>  [String:ImageFileName]: 'cmd.exe\x00'
WinXPSP2x86:pmem 03:11:15> task.ImageFileName = "foo.exe\x00"
WinXPSP2x86:pmem 03:11:21> task.ImageFileName
                    Out<6>  [String:ImageFileName]: 'foo.exe\x00'

NOTE: Since this is a rather dangerous capability, the signed binary drivers
have write support disabled. The unsigned binaries (really self signed with a
test certificate) can not load on a regular system due to them being test self
signed. You can allow the unsigned drivers to be loaded on a test system by
issuing (see
http://msdn.microsoft.com/en-us/library/windows/hardware/ff553484(v=vs.85).aspx):

Bcdedit.exe -set TESTSIGNING ON

and reboot. You will see a small "Test Mode" text on the desktop to remind you
that this machine is configured for test signed drivers.

Alternatively you can test this on XP or Vista32 which have no driver signing
restrictions.

Additionally, Write support must also be enabled at load time:

winpmem_1.3-write.exe -w -l

This will load the drivers and turn on write support. Then we can run rekall
interactively, as usual on the raw device:

vol.exe --profile Win7SP1x64 --file \\.\pmem

