Thursday, 30 April 2015

Trawling for Windows Phone 8 App Permissions

Trawling for Windows Phone App Permissions can be an Adventure! (Fishnets not mandatory ;)

A recent case had monkey researching how to determine which Windows Phone apps might store location data. Rather than manually opening/searching tens of app directories, wouldn't it be handy if we could auto-magically find the apps which allow our behaviours of interest?

It turns out each Windows Phone app has its own Application Manifest file (called "WMAppManifest.xml") which amongst other things, declares its allowed "Capability" permissions.
So under the "Data" partitition's "Programs" directory, there will be a bunch of Application specific sub-directories (eg Facebook) with each sub-directory having its own "WMAppManifest.xml" file.

For more details on Windows Phone 8 Capabilities (SW, HW and Functional) see here.

For an example of an App Manifest file see here.

You can get the "" script from here.

The Script

You can point this script ("") at a single "WMAppManifest.xml" file or at a parent directory (eg "Programs") containing multiple app directories. The script figures out if the given argument is a file or a directory and then calls its internal "Parse_Capabilities" function for each detected "WMAppManifest.xml" file.
The "Parse_Capabilities" function prints out the App Name, ProductID, Version, Description, Author and any declared App Capabilities to the command line. If its being called on a directory, the script will also print out the total number of "WMAppManifest.xml" files it has parsed and each directory path as they are parsed.
The script lists each Capability by their tag (eg ID_CAP_LOCATION) so users can then go here for (marginally) more detailed information.

I used this StackOverflow post as the basis for the XML parsing part of the script. Because why write your own XML parser when Python already has (several) existing implementations to choose from?
For the purposes of this script, we can say an XML document (or "ElementTree") is comprised of child "Elements".
These "Elements" can then have attributes.
So for the following simplified XML example:
<App xmlns="" Title="NewPhoneAppWP8" Version="" >

"App" is the Element and "Title" and "Version" are the attributes of that Element.

Using the Python xml.etree.ElementTree library/package is a multi-step process.
First you call the "parse" function to read the file, then you call "getroot" to find the root (top) element.
Once you have the root element, you can call "find" to return a particular child element and then call "get" to return the attribute of that element.
So in Python, we can say something like:
    tree = ET.parse(filename) # parses the file
    root = tree.getroot() # gets the root element
    AppTitle = root.find("App").get("Title") # finds "App" child element & retrieves the "Title" attribute value
Retrieving the "Capability"s is a little more complicated as they are nested further down and there are usually multiple "Capability"s declared. The "get" function as used above only returns the first attribute it finds - not all of them. Boo!
So instead, we can use the "iterfind" function combined with an XML path to tell Python that we want a list of elements which are stored under the "App/Capabilities/Capability" path. We can then loop thru this returned list and print the "Name" attribute for each.
This looks like:
    caps = root.iterfind("./App/Capabilities/Capability")
        for cap in caps:
The "." at the beginning of "./App/Capabilities/Capability" just means its a relative path to the element calling the "iterfind" function (ie the "root" element).

There's probably other ways of doing it but these code snippets worked well during testing.


The script has been tested on Windows 7 Pro 64-bit running Python 2.7.6 and was not designed to work on a raw phone image file. Its meant to be run against file system extractions/individual files only.
The test image (not shown in this post) was from a factory fresh Nokia Lumia 530 Phone running Windows Phone 8.1 which was imaged via an ATF JTAG box. X-Ways Forensics was then used to parse the image and export the "Data" partition's "Programs" directory (located on partition 27 in this case). There were 19 App sub directories with over 4000 files (295 MB) contained therein. A lot of potential data to trawl through eh?
Only the logical contents of the files were exported. Due to the way the Python XML library function parses files, having NULLS in the fileslack seemed to cause problems.
To minimize complaints when the script tries to open the file path (on MS Windows anyway), enclose the file path in double quotes ("), do not have commas in the filepath and do not leave a trailing \ at the end of the file path. Otherwise you will probably see an Exception message complaining about "invalid mode or filename".

To make testing easier, I copied the script, the example MS App Manifest XML file and a recursive test directory to the c:\wp8perms directory on my machine. Because I also have Python 3.4 installed on my PC, I am using the explicit path to my Python 2.7 executable (ie c:\python27\python.exe).

Here's the help output:
c:\wp8perms>c:\python27\python.exe -h
Running v2015-04-24
usage: [-h] target

Prints Windows phone 8 Capabilities from given App Manifest XML file (or directory of files).

positional arguments:
  target      File or directory of files to be parsed

optional arguments:
  -h, --help  show this help message and exit


Here's the output of running it against a single instance of the MS example file downloaded from here.

c:\wp8perms>c:\python27\python.exe WMAppManifest.xml
Running v2015-04-24

Attempting to open single file WMAppManifest.xml
App Name = NewPhoneAppWP8
App ProductID = {31a2f61a-4083-4250-9c0a-2d68740285b3}
App Version =
App Description = Sample description
App Author = NewPhoneAppWP8 author
App Capabilities =

For a list of Capability definitions see

Exiting ...


And here's what happens when we run it against a directory which is simulating a "Program" directory with 3 applications installed (ie app1, app2, app3). Note: All 3 App manifests have the same attribute values except for the "App Name".

c:\wp8perms>c:\python27\python.exe Test-App-Perms-Programs
Running v2015-04-24

Attempting to open Test-App-Perms-Programs\app1\WMAppManifest.xml
App Name = NewPhoneAppWP8-1
App ProductID = {31a2f61a-4083-4250-9c0a-2d68740285b3}
App Version =
App Description = Sample description
App Author = NewPhoneAppWP8 author
App Capabilities =

Attempting to open Test-App-Perms-Programs\app2\WMAppManifest.xml
App Name = NewPhoneAppWP8-2
App ProductID = {31a2f61a-4083-4250-9c0a-2d68740285b3}
App Version =
App Description = Sample description
App Author = NewPhoneAppWP8 author
App Capabilities =

Attempting to open Test-App-Perms-Programs\app3\WMAppManifest.xml
App Name = NewPhoneAppWP8-3
App ProductID = {31a2f61a-4083-4250-9c0a-2d68740285b3}
App Version =
App Description = Sample description
App Author = NewPhoneAppWP8 author
App Capabilities =

Parsed 3 WMAppManifest.xml files

For a list of Capability definitions see

Exiting ...


Final Thoughts

This script should help narrow down which Windows Phone 8 Apps are worthy of further investigation when faced with the question like "Can you find all the location data?" etc. Once you have found which apps require your permissions of interest, you can then go search for those app storage directories for the actual data of interest. Fun times!

While Windows Phone Store Apps store their program/install data in their respective directories on the "Data" partition under "\Programs", most of the user and/or app generated data will NOT be stored under that directory.
Instead, (on the "Data" partition) check the app specific directories under "\Users" and the "\SharedData" directory (data potentially shared between apps) as potential sources of app data. Also, don't forget to check any SD cards and think about any cloud based apps which might provide an alternative data source (they will probably require a subpoena/warrant however).
Analysts should also check the "MainOS" partition's "/Programs" directory for any app manifest files for programs which were installed by default (ie not via the Windows Phone Store).
Finally, just because an app has a certain Capability permission does not mean that it also logs/stores that data ... but we have to start somewhere right?

If this script helps you or if you have any comments/suggestions/other script ideas, please feel free to leave a comment below. Happy Trawling!

Sunday, 15 February 2015

Reversing Monkey

Reversing may also drive you bananas ...

When trying to recover/carve deleted data, some reverse engineering of the file format may be required. Without knowing how the data is stored, we cannot recover the data of interest - be it timestamps, messages, images, video or another type of data. This quick blog post is intended to give some basic tips that have been observed during monkey's latest travels into reverse engineering of file formats. It was done partly as a memory aid/thinking exercise but hopefully other monkeys will find it useful. This post assumes there's no obfuscation/encryption applied to the file and it does not cover reverse engineering malware exes (which is another kettle of bananas).  

Collect as much Background Information as possible

If you find yourself trying to reverse a file format, you probably have an idea of what type of target data it contains (eg text, image, picture). Familarising yourself with how your target file is organised at a conceptual level will help connect what your seeing at the hex level. The more you can find out about the file (eg encoding methods, typical file sizes, indexing arangements), the more "pointers" you will have.
Here's a handy reference for high level overviews of various common file formats:

How much do you need / Scope

You may not have to reverse the whole file if you are only after a subset of information (eg just the message field). Knowing what type of encoding was used beforehand will help. For example, for a message field, you can perform an ASCII string search for your target string.

Hex Editor

Reversing a file will require wading into the hex so make sure you're comfortable with your chosen Hex editor. Something that shows offsets in both hex/decimal (BE/LE) and can also interpret byte/word/multi-word values will help when the file has embedded offset addresses. Some people can think in hex exclusively, I am not one of them (yet?) - so why not let the computer do the conversions?
WinHex and HexWorkshop are a couple of editors that I have used in the past. Other people have mentioned using the 010 binary editor. Forensic guru and Faux-Photoshopper extroadinaire Brian Moran swears by HexWorkshop (he may also swear about other things but that's for another conversation). Some nice features about HexWorkshop are that it can detect binary differences between files as well as allow you to define your own templates so different fields can be color coded. It also allows for some statistical analysis - it will show you how many times a given byte value occurs in your sample set which is great for finding those repeated pesky 1 byte field markers (or suspected TrueCrypt containers).

Patience / experimentation

Be prepared to spend lots of time on it. Reversing doesn't appear to be a "one process fits all, I'll have it done in X hours" kinda thing (especially when you're starting out). Always work from a sample copy of the data so (if you have to) you can modify your working copy to confirm/deny your crazy theories (eg I think this is a timestamp field ... lets change it and see what is read/displayed back). Just don't forget that you've modified the file!

Sample data

The more varied, the merrier. Being able to compare multiple sets of data can help you confirm your suspicions about a particular set of bytes. For example, is it really a static field or is it a timestamp?
Alternatively, which fields stay the same and which fields change between sets of data? This is where having a hex editor capable of showing the differences between files can help.


Is the file written/used on a Big Endian (BE eg 0x12 0x34) or Little Endian (LE eg 0x34 0x12) system. If its running on Intel hardware, then it's probably Little Endian.


The file signature is the "magic number"/series of hex values which lets the reading software know it's "their kind of file". Gary Kessler keeps a handy index of file signatures here. Chances are, if it's a known file container format it will be in that listing.
Notice how I said container? With video files especially, there are various container formats (eg AVI, MP4) but these can contain encoded data (eg MJPG, H.264) which have their own rules/format.
Most files will have multiple bytes dedicated for the file signature. However, internal field markers may only use one or two bytes which will result in a lot of false hits when searching for those field markers amongst random looking data.

Byte boundaries

Are the files grouping data at the bit, byte, word etc level?
Knowing if your fields are grouped along particular size boundaries means that you can minimize wild goose/geese chases. For example, once you know that integers are written as 4 byte LE, it can make it easier to keep track of what is padding and what is data.

Padding / file slack

A bunch of zeros (or xFFs) can be a potential indicator that some padding has taken place so the data can fit into a certain (even/odd) number of bytes. If the file was written on the fly, it probably reserved more space than it needed for future use. If the file was not "closed" properly, you might then see these reserved/pad bytes with no easily discernible end of file marker.

Regular sized blocks of data or variable?

Detecting fixed sized blocks of data will be aided by comparing multiple data sets.
For variable sized data blocks, the length will probably be declared *somewhere* before the data so the reading software knows how much to read.
Alternatively, there may some sort of begin/end of data marker. For example, "0xFF 0xD8" marks the beginning of JPEG data and "0xFF xD9" marks the end. You are more likely to get trailers when the data size is not declared/known beforehand.


Are they Unicode (eg 2 bytes per character like UTF-16BE/LE) or ASCII (1 byte per character) encoded? Are they null terminated? If they are not null terminated, expect to see a size of string type field either directly before or *somewhere* before the actual string - again, the reading program needs to know how much to read before it calls for the read.


These are likely to exist in most file formats. Note: We're talking about internal timestamps here not filesystem ones. For carving, being able to ascertain a file's time period will help narrow down the search (assuming you know the relevant time period).
Becoming familar with the multitude of timestamp formats will help - Paul Sanderson's blog post on timestamps is a great starting point . From my travels, 4 byte integers listing the number of seconds since a given point (eg since 1JAN1970) are pretty common for anything non-Windows based (eg Android, iPhone devices). So searching your file for the 3 most significant bytes of a desired date range might lead you to some timestamps within your file. Digital Detective's DCode is a great free tool for calculating selected potential (Windows, *nix, Mac) timestamp values.


I am using this term to refer to the internal addressing mechanisms used to point the reading software to a certain point/byte in the file.
These can be:
- Relative to a certain point (eg go forward 100 bytes from this byte) or
- Absolute (eg 215 bytes from the start of the file).

Complicating matters are nested collections of offsets - so you might have a table of offsets referrring to more tables of offsets etc. Eventually, you should be able to follow the trail to find the relevant/target data. Hopefully, your eyesight and sanity are both still intact ;)
Matthew Ekenstedt has offered some great tips regarding offsets on his website. To paraphrase, he reckons the larger hex values you see are potential byte offsets relative to the beginning of the file. Smaller hex values could be relative offsets from a particular point (eg field headers). The smallest hex values (eg 1-2 bytes) will probably correspond to lengths of data fields.
So how big is too big for an offset? Knowing your file size will help you decide if a potential offset is realistic or not. For example, you're not likely to find a greater than 4 byte offset for a file (4 bytes = xFFFFFFFF = 4 GB).

Indexes (for want of a better description)

Some files (eg video) may not append a table of offsets until it is actually exported (eg user explicitly saves video). So when carving for un-exported (ie user has not chosen to save but the file was still written), this may result in finding files which do not have their final indexes recorded. Boo!
Don't let this deter you from trying to play the unexported file back though - if the recording software can read it, there must be sufficient indexing available to retrieve data. Which leads us to our last point ...

Windows file formats

In some cases, the file might come bundled in a Windows exe for playback (eg exported video) or it might use a Windows exe to read it. Because of this, we can use Sysinternals Process Monitor to show us how the file is being read (eg the order of file offsets as the file is read and the associated length of the reads). Note: Process Monitor outputs the file offsets in decimal so you'll have to convert it into hex before searching your file for those offsets/read lengths. Knowing how a file is being read can lead us to how the data is indexed/stored (eg an offset table refers to another offset table which contains the actual start offsets for certain data runs).

Final Words

Hopefully these tips were helpful. If you have any other tips that you'd like to share, please leave a comment below :)
And now that you know what I know about reverse engineering file formats, there really isn't anything else that I can suggest - so please don't ask me to reverse your funky file format :).
And to finish things off, here's an interesting paper which shows the value of all this hex diving - "Forensic analysis of video file formats"  by Thomas Gloe et al. 2014. Specifically, it shows how looking at the arrangement of image/video data fields can show if an image/video has been edited by software.

Good Luck and Happy Reversing!

Friday, 10 October 2014

Google-ei'd ?!

Hmmm ... I seem to be having some trouble focusing after this latest post

Ever looked closely at a Google search URL and seen a weird "ei" parameter in there?
While it doesn't seem to occur for every search, when it does, that "ei" parameter contains an encoded Unix UTC timestamp (and other things Google only knows). Interpreting this artifact can thus allow forensic analysts to date a particular search session.

This artifact has been observed at various times while testing (on Windows 8.1) in Firefox (v32.0.3), Chrome (v38.02125.101) and IE (v11.0.9600.16384). As it seems to be initiated by Google's servers, this browser independence makes sense.

Special Thanks to Phillip Moore (@phillmoore) who suggested this script idea and also helped test it.

The Python script ( is available from my GitHub page  and is based on the following 2013 reference written by Kevin Jones for the "Deed Poll Office Blog". This article also lists a PHP conversion script but more importantly, it shows an "ei" value conversion example which we can use to initially validate our script.

When does "ei" happen?

Whenever donkeys vote! Eee-ore! Eee-ore!

*DFIRcricket chirps* ... Ahem, moving along  ...

According to this discussion forum it was noticed around 31 August 2013 but Phillip had some test data which has dates going back to 2011.

It does not seem to matter if you use a country specific address (eg or the non-redirecting Google web address of The "ei" parameter occurs with both URLs.

Using Firefox on Windows 8.1, I went to and searched for "bananas".
The resultant URL displayed was "".

I then clicked on the "Images" search category and got the following URL:

Subsequent sub-category clicks results in different "ei" parameters being returned.

I then cleared the Firefox history, went to, searched for "bananas" and got the following URL:

I then clicked on the "Images" search category and got the following URL:

Note: It seems that the "sei" parameter seen initially also contains a similar timestamp mechanism as the "ei" parameter.

Similarly, using the Google search box in Firefox to search for "yellow bananas" resulted in:

Clicking on the subsequent "Images" search category returned:

The "ei" parameter is also returned in Firefox's Private Browser mode.

Writing the Script

The first thing to note is that the "ei" parameter is unpadded and URL safe base64 encoded.
Base64 encoding is a way of writing (binary) data using the ASCII alphabet (see here).
There should be 4 output bytes produced for every 3 input bytes. Therefore, the output string size should be a multiple of 4.
However, if the input size is not a multiple of 3 bytes, padding (ie adding "=" characters) is usually added after encoding to make the final size a multiple of 4.
Google apparently does not feel like providing this padding so we'll have to handle it using this algorithm ...

padlength = 4 - the remainder of ("ei"s size in bytes divided by 4)

or in Python-ese,
padlength = 4 - (len(ei) % 4)

So if "ei" is 21 bytes long, the extra padding required is 4 - (21 % 4) = 4 - 1 = 3
This makes the total size = 21 + 3 = 24 (which is a multiple of 4).

Note: Typically, "ei" is 22 bytes long (ie 2 bytes of padding is required) but it can be longer/shorter.
If "ei" is a multiple of 4 (ie remainder is 0), then padlength should be set to 0. For example, a 24 byte long "ei" does not require padding.

URL safe base64 encoding means substituting "-" instead of "+" and "_" instead of "/" after the base64 encoding has been performed. This is because "+" and "/" are reserved characters within URLs.
Conveniently, Python provides a library function to handle both the reverse substitution and base64 decoding - base64.urlsafe_b64decode.

So now we have our base64 decoded string, we can read the first 4 bytes and calculate the timestamp.
To do this requires a bit of background maths. Given a Little Endian 4 byte integer like this:

[Byte0 Byte1 Byte2 Byte3]

Byte0 is least significant. Byte3 is most significant. To make things easier to follow, we'll do some re-arranging ...

[Byte3 Byte2 Byte1 Byte0]

Each byte range is 256 times the previous byte's range.
For example:
0xFF = 255 decimal, 0xFF00 = 255 * 256 = 65280 decimal, xFF0000 = 255 * 256 *256 = 16711680 decimal

So our final 4 byte integer value can be calculated using an algorithm like:
Byte0 + Byte2*256 + Byte3*256*256 + Byte3*256*256*256

We can then call Python's datetime's utcfromtimestamp and strftime methods to convert/print out our human readable string.

Testing the Script

Here's the help usage text for the script.
Running v2014-10-10

Usage: -e EITERM -q OR -u URL -q

  -h, --help  show this help message and exit
  -e EITERM   Google search URLs EI parameter value
  -u URL      Complete Google search URL
  -q          (Optional) Quiet output (only outputs timestamp string)


The script takes either the "ei" term manually extracted from a URL (-e) OR the whole URL (-u) and returns a human readable timestamp string.
If you think the default output is too chatty and just want the answer (for scripting or just because you're a barbarian), you can use the -q argument.
It was developed and initially tested using Python 2.7 on a Window 7 PC. It has also been tested on SANS SIFT v3.

Here's an "ei" usage example:
c:\Python27>python -e tci4UszSJeLN7Ab9xYD4CQ
Running v2014-10-10

Input ei term = tci4UszSJeLN7Ab9xYD4CQ
Padded base64 string = tci4UszSJeLN7Ab9xYD4CQ==
Extracted timestamp = 1387841717
Human readable timestamp (UTC) = 2013-12-23T23:35:17


This example "ei" value was taken from the Deed Poll blog article and the script output matches their result.
And here's the "quiet" version equivalent of the above ...
c:\Python27>python -e tci4UszSJeLN7Ab9xYD4CQ -q


Here's a complete URL parsing example:
c:\Python27>python -u ""
Running v2014-10-10

URL's ei term = tci4UszSJeLN7Ab9xYD4CQ
Padded base64 string = tci4UszSJeLN7Ab9xYD4CQ==
Extracted timestamp = 1387841717
Human readable timestamp (UTC) = 2013-12-23T23:35:17


Note: Out of habit, I have enclosed the URL in quotes (") but it's probably not necessary ...

And here's the quiet version for the previous complete URL parsing example ...
c:\Python27>python -u "" -q


For shiggles, let's try our script with the "sei" parameter we noticed earlier ...
Using Firefox's Google search box, I typed "bananas gone wild" (pervert!) and got the following URL:

c:\Python27>python -e Sc82VJGYBsT58QXBgYLYAw
Running v2014-10-10

Input ei term = Sc82VJGYBsT58QXBgYLYAw
Padded base64 string = Sc82VJGYBsT58QXBgYLYAw==
Extracted timestamp = 1412878153
Human readable timestamp (UTC) = 2014-10-09T18:09:13


The output seems correct after taking into account the timezone and daylight savings time difference.
I've also tested it using other "ei" values from various searches I've done locally but there's not much point boring you any further with those.

Discrepancy Issue:
Phillip got the Deed Poll Office's PHP script function working however it's output differed with our script's output for some of the same input test data. Uh-oh!
Specifically, there was a discrepancy in the extracted timestamp values whenevever there's a "-" or "_" around the start of the input "ei" value.
I'm a complete novice to PHP but it looks like they might have their URL-friendly substitutions around the wrong way?
According to W3schools, the syntax for PHP's "str_replace" is
str_replace(find, replace, string, count)

find =  the value to find,
replace = the value to replace the value in find
string = the string to be searched
count = Optional. A variable that counts the number of replacements

And according to the PHP website entry for str_replace():
If find and replace are arrays, then str_replace() takes a value from each array and uses them to search and replace.

So it looks like this line at the start of the Deed Poll Office function:
 $ei = base64_decode(str_replace(array('_', '-'), array('+', '/'), $ei));
is replacing "_" with "+" and "-" with "/" before calling base64_decode.

According to Wikipedia's entry on base64 encoding mentioned earlier, modified Base64 for URL variants exist where:
 the '+' and '/' characters of standard Base64 are respectively replaced by '-' and '_'

So following that logic, decoding URL safe base64 (containing "-" and "_") would involve substituting "+" for "-" and "/" for "_". Which is not what the Deed Poll function seems to be doing ... Let us know in the comments if you disagree?

As our script uses Python's base64.urlsafe_b64decode function to perform the substitution and base64 decode, I'm quietly confident in it's output.

Anyhoo, be wary that any "ei" value containing "_" or "-" at the start of the string will result in that discrepancy.
When the "-" and/or "_" characters occur towards the end of the "ei" string, they don't seem to affect the timestamp (which occurs at the beginning of the string) and so the PHP script output seems to match our script's output.
When there's no "-" or "_" characters in the input "ei" string, the two script outputs also seem to match OK.

Because the "ei" value is based on a Google server's time, there doesn't appear to be an easy way to confirm which script is correct (from this end anyway).

Final Thoughts

Thanks to Phillip Moore's suggestion and testing, we now have a Python script that can take a Google search URL with an "ei" parameter and return a human readable timestamp of when that search occurred. The script also seems to extract valid timestamp values for Google "sei" parameters. More research about when the "ei" parameter occurs would be nice but just finding that "ei" parameter should allow you to date that search session.
There are also some discrepancies between what the Deed Poll Office PHP script outputs and what our script outputs whenever "_" and "-" characters are contained at the start of the "ei" input string.

Whew! Three blog posts in a week - a new personal best. Now if I could only stop going cross eyed ...

Tuesday, 7 October 2014

"Awesome" Windows Phone 8 Stuff

Mobile Forensics is AWESOME! Teamwork is AWESOME! Researching Windows Phone 8 is ... er, "no comment" ;)

Our previous Windows Phone posts here and here described the call history/SMS/contacts areas of Windows Phone 8.0 and provided their respective Python extraction scripts. Now that we've had some extra time to snoop around, we thought it would be a good time to relay some of our other Windows Phone findings.
Most of the observations in this post relate specifically to Nokia Lumia 520s running Windows 8.0 and are sourced from data sets provided by Brian McGarry (Garda, Ireland) and Cindy Murphy (Madison Police Department, USA). This information complements our recent research paper entitled "Windows Phone 8 Forensic Artifacts" that has been submitted for DFRWS EU 2015. The paper was co-authored by Cindy Murphy (Madison Police Department, USA), Maggie Gaffney (Teel Technologies, USA), Shafik G. Punja (Calgary Police Service, Canada), JoAnn Gibb (Ohio Attorney General’s Bureau of Criminal Investigation’s Cyber Crimes Unit, USA), Brian McGarry (An Garda Siochana, Ireland) and this awestruck little monkey.

So ... Let the brain dump begin! Warning: It's a bit of a long post ...

A Bit Of Background ...

Because it will help us understand our observations better, we will start by discussing how Windows Phone 8 fits together. Yes Jr, you have to eat your vegetables too!
Most of the information in this section is copied directly from this Microsoft Windows 8 Security Overview document.

Windows Phone 8 uses the same NT Kernel as Windows 8 and Windows Server 2012. It shares the same driver model, developer platform, security and networking stack, and graphics and media platform with the desktop operating systems.
It validates firmware images on Windows Phone devices before they are allowed to load the operating system (via Trusted Boot). All binaries must be signed by a trusted authority.
Windows Phone architecture uses a System-on-a-Chip (SoC) design provided by SoC vendors (eg Qualcomm). The SoC vendor and device manufactures provide the pre-UEFI boot loaders and the UEFI environment. Microsoft then provides the Windows Phone boot manager in the UEFI environment. After the pre-UEFI and UEFI components complete their boot processes, the Windows Phone boot manager completes the Windows Phone 8 boot process.

All code in the Windows Phone operating system is signed by Microsoft (eg drivers and applications). Applications that are added after manufacturing, or installed from the Windows Phone Store or a private enterprise store must be properly signed to execute.
Every app on Windows Phone runs in its own isolated chamber. A basic set of permissions is granted to all app chambers by default. However, the set of permissions for a chamber can be expanded by using "capabilities" that are granted during app installation. App permissions cannot be elevated at run time. No communication channels exist between apps on the phone. Apps are isolated from each other and cannot access memory used or data stored by other applications, including the keyboard cache.
All Windows Phone apps that are submitted to the store must be certified before they can be made available to users for downloading and installation. The certification process checks Windows Phone apps for inappropriate content, store policies, and security issues. Microsoft scans all apps for known viruses before publication. Apps must also be signed during the certification process before they can be installed and run on Windows Phones. (Note: Developers can register their phone devices so they can download/test their apps directly to/on their device without having to first submit to the store)

A user can set a PIN or password via the settings panel to lock their phone. IT departments can use Exchange ActiveSync policies to require users to set PINs or passwords, and also to configure additional password policies to manage password length, complexity, and other parameters. The Exchange Server Management Console and / or the Outlook Web App can initiate a remote wipe of the device. After registering their phone at, users can map the location of their phone, make it ring, and wipe its data if necessary.

Windows Phone 8 uses BitLocker technology to support the encryption of all internal data storage on the phone with AES 128. The encryption key is protected by the Trust Platform Module (TPM), which is bound to UEFI Trusted Boot to ensure that the encryption key will only be released to trusted boot components.

The Windows Phone operating system allows users to store only media files on SD cards (Note: More recent documentation claims Windows Phone 8.1 now allows apps to be stored). Although the Windows Phone 8 operating system and user data partitions can be encrypted, files that are stored on SD cards that are inserted in the phone are not encrypted.

According to this MS document:
Microsoft will support Windows Phone 8.0 for the 36 month period from December 2012 until December 2015.
Similarly, Windows Phone 8.1 will be supported from June 2014 until June 2017. So this post should remain relevant for a few years yet :)
And now we can actually start discussing our observations!


There were 28 partitions visible on our data sets from MPD and Garda. Various forensic toolkits can be used to parse the JTAG .bin image including X-Ways Forensics (V17), EnCase (v7), FTK (v5.4) and FTK Imager (v3.2). OS Forensics (v3.0) has also been used for both mounting individual partitions and for further examination using the in-built Registry Viewer.
Information (of varying detail) for each of the partitions can be seen from an XML file located on partition 27 labelled "MainOS". Here is the file location:

From our observations, the interesting user related data lies on 2 NTFS partitions - partition 27 "MainOS" and partition 28 "Data". For the Garda Nokia Lumia 520, "MainOS" was ~1.8 GB and "Data" was ~5 GB.
The other 26 partitions seem to be related to the QUALCOMM 8960 System On Chip (SOC) (eg bootloaders / backups).

The relevance of the MainOS and Data partitions is also highlighted by this MS document which shows:
Main OS (aka %SystemDrive%) is mapped to "C:\"
User Data (aka %DataDrive%) is mapped to "C:\Data"
Removable User Data (aka %RemovableUserData%) maps to "D:\"
probably describes the partitions in further detail but its only accessible to paying developers. :(

File System

MainOS seems to be the equivalent of the desktop Windows OS partition - for example, it contains Registry hives, a pagefile.sys and a System Volume Information folder.
MainOS has 2 folders under \USERS - called DEFAULT and PUBLIC but only DEFAULT contains an NTUSER.DAT
MainOS does not have:
- the \Windows\system32\winevt\Logs folder (for event logs)
- the \Prefetch folder
- the hiberfil.sys file
The MainOS & Data partitions do not have $RECYCLE.BIN files either.

According to this MS document, MainOS (%SystemDrive%)  follows this structure:

MainOS file system structure (Source: Microsoft)

The Data partition includes a Users folder containing various sub-folders per Application/Service. Each sub-folder has its own NTUSER.DAT. Each app runs in it's own chamber with the app's specific permissions so that is probably why each app gets it's own user profile. For the Garda data there were 25 such sub-folder profiles.

According to this MS document, Data (%DataDrive%) follows this structure:

Data file system structure (Source: Microsoft)

It also says:
The root folders are generated on the device during initial provisioning startup. The storage boot service creates any folders that must exist before the remainder of the system can operate. The root folders are:
\Programs = Contains Windows Phone Store application code.
\Users = Contains default user account, built-in services, and public data folders.
\SystemData = Contains systemwide files, such as logs and Device Update. The data contained in this folder is not applicable to a particular application.
\SharedData = Contains systemwide shared data, or data shared between multiple applications.
\Test = Contains test code and the data in its subdirectories.

Built-in applications, or applications that are “in-ROM” and are serviced by Device Update store their code and installation files in the (MainOS) %SystemDrive%\Programs directory. Windows Phone Store applications store their code and installation files in the (Data) %DataDrive%\Programs directory.
Both built-in applications and Store applications store their data in their own isolated storage folder.
The application data folder is separated into Local, Roaming, and Temp folders so that applications can state-separate their data. See the next section on App data storage for more details.

Applications can use the %DataDrive%\SharedData folder to share content, but Microsoft does not recommend this approach. Applications that create shared data must delete content when it is no longer required. Each component should create its own subfolder and put the appropriate ACL/capability in place to restrict access to it.

Public data does not exclusively belong to a single application. Public data is stored outside of the application isolated storage. Each folder has an ACL based on a capability, which can be assigned to an application through the package manifest.
%DataDrive%\Users\Public directory contains
\Music = Stores music
\Video = Stores videos
\Pictures = Stores pictures
\Documents = Stores Office documents

LocalService and NetworkService system services are apparently also stored in the %DataDrive%\Users directory but we did not observe these directories in the Garda data. User accounts for services are also apparently stored in %DataDrive%\Users.

App data storage

In Windows Phone 8, apps have two types of data to store - app data (specific to the app) and user data (user created/managed). This MSDN article says: 

App data includes runtime state, user preferences, reference content (such as the dictionary definitions in a dictionary app), and other settings. App data is tied to the existence of the app and is only meaningful to that app.

User data includes document or media files, email or communication transcripts, or database records holding content created by the user. Note that user-selected preferences or app configuration options are considered app data, not user data. User data may be useful or meaningful to more than one app (eg documents).

According to this MSDN article :

"You don't need to know where or how this data exists, because the system is responsible for managing the physical storage. Just use the app data API ..."

Er, thanks Microsoft! Anyway, it goes on to say that app data can be stored under several categories and if the app is removed, these data stores are deleted. The categories are:
local = Data that exists on the current device only and is backed up in the cloud.
roaming = Data that exists on all devices on which the user has installed the app.
temporary = Data that could be removed by the system at any time.
localcache = Persistent data that exists only on the current device.

Local app data should be used for any information that needs to be preserved between app sessions and is not suitable type or size wise, for roaming app data. Data that is not applicable on other devices should be stored here as well. There are no general size restrictions on local data stored.

Roaming app data keeps the app's app data in sync across multiple devices. If a user installs the app on multiple devices, the OS keeps the app data in sync, reducing the amount of setup work that the user needs to do for the app on their second device. Roaming also enables the users to continue a task, such as composing a list, right where they left off even on a different device. The OS replicates roaming data to the cloud when it is updated, and synchronizes the data to the other devices on which the app is installed.
The OS limits the size of the app data that each app may roam. If the app hits this limit, none of the app's app data will be replicated to the cloud until the app's total roamed app data is less than the limit again. For this reason, it is a best practice to use roaming data only for user preferences, links, and small data files.
Roaming data for an app is available in the cloud as long as it is accessed by the user from some device within the required time interval. If the user does not run an app for longer than this time interval, its roaming data is removed from the cloud. If a user uninstalls an app, its roaming data isn't automatically removed from the cloud, it's preserved. If the user reinstalls the app within the time interval, the roaming data is synchronized from the cloud. The current policy specifies that this time interval is 30 days.
The operating system roams app data opportunistically and doesn't guarantee an instant sync. In scenarios where a user is offline or on a high latency network, roaming could be delayed significantly.

By doing some snooping, we found these app storage areas in the various application sub-folders under "Data:\Users". Each app gets its own sub-folder which in turn has an APPDATA folder containing Local / LocalLow, ROAMING, and Temp folders. From our sample Garda data, we did not observe a localcache folder.

Additionally this MSDN article says that App data settings are stored in the registry (presumably meaning in the Software hive) and that App settings can also be local or roaming. The settings that the app adds to the local data store are present only on the local device. The system automatically synchronizes settings the app adds to the roaming data store on all devices on which the user has installed the app.

SD Card Access (Not Tested)

There have been some changes regarding SD card use between Windows Phone 8.0 and 8.1. This MSDN article says:
Windows Phone 8 supports read-only access to the SD card where as Windows Phone 8.1 provides read/write access.
Windows Phone 8.1 also lets users install apps on the SD card, or move apps that are already installed to the SD card.

SD Card files are stored in the %RemovableDataDrive% (D:\) using the following structure:

SD Card file system structure (Source: Microsoft)

The storage card stores content that is generated or downloaded onto the phone, in addition to content that is sideloaded by the user. Content that is generated on the phone follows a prescribed folder layout, which mirrors the Public data folder layout on internal storage. Sideloaded content can be in any folder layout, and any content requester needs to scan these folders. Windows Phone uses only one storage card, which is mounted on a separate drive (drive D).

According to this MS document, Windows Phone 8.1 supports the following content on SD cards:
Apps (new in Windows Phone 8.1)
Map data
Side loading application XAPs
Some app data, in particular, user content in non-system managed locations (for example, e-books)

SD cards do not support the following content:
Microsoft Office files
Text messages
Anything else not mentioned in the supported content list
This actually contradicts this MS document, which says that for Windows Phone 8.1:

%RemovableDataDrive%\Documents = Stores Office documents generated on or downloaded onto the device. The user also is able to sideload content into this directory.

Our data sets did not include SD card data so we are unable to figure out what MS actually means here ... :S

Another inconsistency regarding SD cards can be found here which says (dated August 25, 2014) that:
There is currently no method to move files between an SD card and the internal storage.

and yet there's a "Files" app in the Windows Phone Store here that purports to do just this ...


The Windows Phone 8 registry files are named/located similar to those from a Windows Desktop OS and there is a TON of potential squirrel chasing there.

Partition 28 MainOS: \Windows\System32\config contained the following hives (amongst others).
Software (3640 KB)
System (2884 KB)
Security (8 KB)
SAM (8 KB)

The Software and System hives contained the most useful data (in monkeys humble opinion).
The NTUSER.DAT and SAM hives were not very useful. Similarly, nothing obviously useful was found in the Security hive except for the ActiveSync value under Security:\Software\Microsoft\ActiveSync\MergedPolicy\RequireDeviceEncryption (set to 0).

There was also a ProvisionStore hive found which seems to define access controls for capabilities/files/directories/registry entries (ie links SIDs to permissions). It was the largest hive at approximately 10 MB for both MPD and Garda data.

Also observed in the MPD data was an extra NTUSER1.DAT (96 KB).
James Macfarlane's "" GUI tool (as installed on SIFT v2.14) was used to compare NTUSER.DAT with NTUSER1.DAT but nothing significant was found. This might be related to the phone being re-used/re-gifted by another person during its lifetime.

System:\Versions\ MajorVersion (eg 8) and System:\Versions\MinorVersion (eg 00) contains OS version information. Under System:\Versions\ there is also an associated TimeStamp value (eg 20131007-1506 for Garda, 20130513-1612 for MPD) and a Label value (eg WP8_CXE_GDR3 for Garda and WP8_CXE_GDR2 for MPD). Note: According to this article, GDR3 was an update issued on Oct 14 2013. So the Label can indicate how recently the phone was updated. The slightly different Label values possibly explains the discrepancies observed between MPD/Garda data sets.
In contrast,
Software:\Microsoft\Windows NT\CurrentVersion\CurrentVersion was set to 6.2 for BOTH MPD/Garda. They also had the same CurrentBuild, CurrentBuildNumber values but different BuildLab and BuildLabEx values.

System:\Platform\DeviceTargetingInfo contains several device related values such as PhoneFirmwareRevision, PhoneManufacturerModelName (eg RM-915_nam_usa_228), PhoneMobileOperatorName (ie service provider) and PhoneModelName (eg Lumia 520).

System:\ControlSet001\Control\ComputerName contains ActiveComputerName and ComputerName sub-keys which both had ComputerName values set to "Windows Phone".

System:\ControlSet001\Control\TimeZoneInformation contains TimeZoneKeyName (eg Pacific Standard Time) as well as ActiveTimeBias.
System:\State\DateTime contains DSTOverride, NetworkTime Enabled and NetworkTime Sync values.

System:\ControlSet001\Control\Windows\ShutdownTime appears to contain an MS FILETIME value for the last shutdown time. This will obviously depend on the phone's current time setting.

Phone Number

The device's phone number does not appear to be stored in the registry. A search was performed on the system hives but no data hits were found. Neither was the phone number found in the store.vol or Phone files.
StackOverflow claims its not programmatically possible to access the device's phone number.
Assuming its a GSM phone, you can determine the phone number from the SIM card. We did not have any CDMA phone datasets to see if they stored the phone number. If you do happen to know/find where its stored, please let us know in the comments section.

Phone PIN configuration

The PIN value seems to stored as a hash in the registry. A very dated (6/2/2010) Technet article for Win Mobile 6 says:

The PIN value is stored as a hash so there is no way to determine if an existing PIN satisfies the policy.

There's also a bunch of PIN related configuration stuff under:
which contains such values as AllowSimplePIN (set to 1 for MPD data), ExpirationPeriod (0), MinimumPasswordLength (4) and NumberOfPasswords(0).

For both Garda/MPD data sets, we observed data regarding this PIN hash at the following Software hive locations:
Software:\Microsoft\Comms\Security\DeviceLock\Object21\CredentialHash (which was a binary type)
Software:\Microsoft\Comms\Security\DeviceLock\Object21\CredentialActualLength (set to 8 for an 8 digit Garda PIN, set to 4 for 4 digit MPD PIN)

For Garda, the same credential hash value was observed at:
which also had an associated timestamp at:
This timestamp seems to be a MS FILETIME (eg binary value was 0x4043171AF184CE01 = Sat, 20 July 2013 02:30:30 UTC)
Note: After a factory reset, Object21 and Object22 keys were no longer present in the registry.

For MPD, the corresponding CurrentCredentialHash and CredentialSetupTime was located under:

For both Garda/MPD data sets, 
Software:\Microsoft\Comms\Security\DeviceLock\Object10 also has a DeviceWipeThreshold value (set to 0 for MPD/Garda data)
According to this Technet article, this setting's value is the number of incorrect password attempts to allow before the device's memory is erased. The value can be 1 through 4294967295 (0xFFFFFFFF). This registry key does not exist by default. If it does not exist, is set to zero (0), or is set to 4294967295 (0xFFFFFFFF), the local wipe feature is turned off.
So it might be handy to know if DeviceWipeThreshold is set to 0 or 0xFFFFFFFF as it might then be possible to brute force guess it if its only 4 digits ... its only 10000 combos LOL.

Encryption configuration

Regarding encryption, there are a few registry locations which may be informative:
Software:\Microsoft\DeviceEncryption\Enabled (set to 0 for MPD/Garda data which was not encrypted).
Software:\Microsoft\Provisioning\DeviceEncryption\Enabled (set to 0 for MPD/Garda data).
System:\ControlSet001\Control\FileSystem\NtfsDisableEncryption (set to 1 for MPD/Garda data)

File System configuration

The following keys might prove useful when looking at the file system:
System:\ControlSet001\Control\FileSystem\NtfsDisableLastAccessUpdate (set to 1 for MPD/Garda data which implies that filesystem access times are not updated)
System:\ControlSet001\Control\FileSystem\NtfsDisableEncryption (set to 1 for MPD/Garda)
System:\ControlSet001\Control\FileSystem\NtfsEncryptPagingFile (set to 0 for MPD/Garda)
System:\ControlSet001\Control\CrashControl which contains a DedicatedDumpFile value set to "c:\Data\SystemData\DedicatedDump.sys". So that file might have some forensic goodies in it if/when an app crashes.
System:\ControlSet001\Control\Session Manager\Memory Management has bunch of paging config parameters such as ClearPageFileAtShutdown (set to 0) and PagingFiles (set to "c:\pagefile.sys 256 256").

Note: We have observed/retrieved valid SMS data structures from the pagefile.sys.

MTP configuration

Software:\Microsoft\MTP lists a bunch of MTP (Media Transfer Protocol) keys/values which might be handy if you need to link a Windows Phone to a PC (eg media transfers). For example:
Software:\Microsoft\MTP \DataStore was set to "C:\Data\Users\PUBLIC".
MTPStorageName was set to "Phone".
There's also values for various MTP services and File types. Interested readers should refer to Nicole Ibrahim's SANS presentation for a more comprehensive discussion of MTP issues.

System Directory configuration

The following registry keys link various system placeholders with their respective file system directories:
Software:\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders (eg "Common Documents" set to "x:\Users\Public\Documents")
Software:\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders (eg "CommonPictures" set to " %PUBLIC%\Pictures")

Backups and Volume Shadow Copy configuration

According to this MSDN article, the FilesNotToBackup registry key can be used to specify the names of the files and directories that backup applications should not backup or restore. However, it does not exclude those files from shadow copies.
We found this key at:
We also found:
which would seem to imply Volume Shadow Copies. However, no volume shadow copy information was observed under the Garda's MainOS:\System Volume Information\. But perhaps the phone had not triggered a VSC yet...

Missing Desktop Windows Artifacts

Windows Phone 8 does not seem to utilize all of the same mechanisms as a Windows Desktop system.
There was:
- no Prefetch directory
- no hiberfil.sys
- no event logs (under the expected \Windows\system32\winevt\Logs)
- no shellbags

Regarding shellbags ...

NTUSER.DAT usually appears under c:\Users\<user>\
For the Garda data, there were 2 User profiles under MainOS:\Users.
MainOS:\Users\DEFAULT\NTUSER.DAT did not contain a Shell key under \Software\Microsoft\Windows
MainOS:\Users\Public did not have a NTUSER.DAT

Data:\Users\ contained a sub-folder for each app/service. Each sub-folder had an NTUSER.DAT but only two folders had sizes greater than 96 kBytes. These were the DefApps and the WPNETWORKPII folders (256kB each). They didn't store a Shell key under \Software\Microsoft\Windows and neither did the 96kB sized WPCOMMSERVICES\NTUSER.DAT.

UsrClass.dat hives usually appear under C:\Users\<user>\AppData\Local\Microsoft\Windows.
There was no \Local folder under MainOS:\Users\DEFAULT\APPDATA.

Data:\Users\DefApps\APPDATA\Local\Microsoft\Windows had a (768 kB) UsrClass.dat file
However it's
\Local Settings\Software\Microsoft\Windows key did not contain Shell or ShellNoRoam sub-keys.

Most other User profiles under Data:\Users\ had 256 kB UsrClass.dat files but some did not.
Inspecting selected UsrClass.dat files showed they also did not contain Shell or ShellNoRoam keys under \Local Settings\Software\Microsoft\Windows
This makes sense as most of the usernames under Data:\Users\ indicated services (ie contained SVC in their name).

Miscellaneous Stuff

Monkey wasn't sure where to fit some interesting stuff from this Windows Phone 8 Introduction, hence this section.

For web management of a Windows Phone go to:

and login to see how you can access your phone from the web. You’ll see links to your photos and documents on SkyDrive, a link to your Xbox info, and links to your inbox, contacts, and calendar on Hotmail. My Windows Phone also provides tools for finding and managing your phone, viewing/editing your account and billing info, and viewing and reinstalling your apps.

The document also lists some default apps in the appendix:





Help + Tips


Internet Explorer



Music + Videos









It appears that some of these default Apps data can be found under Data:/Users/DefApps/APPDATA/

Additionally, this MS article mentions preinstalling apps on the phone as part of the OS image so that they are available to customers when the phone first boots. These apps can be first-party applications, Microsoft apps, or third-party apps.
So it's likely that each phone/service provider combination will have it's own configuration of default apps.

Final Thoughts

This has been a pretty voluminous/vomitus post because it's the result of multiple days worth of Googling and trawling through the Windows Phone 8.0 registry and filesystem ("Make it stop!"). Whilst its not 100% definitive, it should give readers an initial understanding of how the Windows Phone 8 OS is structured without having to refer to multiple MS articles. It also provides a convenient outlet for some of the interesting stuff that might not have made it into our DFRWS research paper due to space constraints. At the very least, it ensures monkey can free up some space in his cluttered head for other awesome things ...

And remember ... EVERYTHING is AWESOME! (*For some things, awesome-ness is sold separately)
(Picture Source: