Monday, 4 July 2016

Panel Beaten Monkey

FYI: A "Panel Beater" = Auto body mechanic in Monkeytown-ese
This Monkey was recently invited to shit himself sit on a SANS DFIR Summit panel discussing Innovation in Mobile Forensics with an All-Star cast of Andrew Hoog, Heather Mahalik, Cindy Murphy and Chris Crowley. While it rated well with the audience, personally (because its all about THIS monkey!) - it seemed that whenever I thought of something relevant, another panel member chirped up with a similar idea and/or the discussion moved on to the next question.
I felt it was kinda difficult to contribute something meaningful yet concise in a 30 second sound bite. Especially for my first open question speaking gig.
Monkey might need to decrease his deferential politeness and/or increase his use of assertive poo flinging in future panel discussions. Alternative suggestions are also welcome in the comments :)

Here's the synopsis of the panel from the DFIR Summit Program ...
Puzzle Solving and Science: The Secret Sauce of Innovation in Mobile Forensics
In today’s world, technology (especially mobile device technology) moves at a much faster pace than any of us can keep up with, and available training and research doesn’t always address the problems we encounter. As forensic examiners we face the daily challenges of new apps, new, updated and obscure operating systems, malware, secure apps, pass code and password protected phones, encoding and encryption problems, new artifacts, and broken hardware in order to obtain the evidence we need in a legally defensible and forensically sound manner.  In this session, learn from consistent and experienced innovators in the mobile forensics field the tips, tricks, and mindset that they bring to bear on the toughest problems and how to move beyond cookie cutter forensics towards an approach that allows you to successfully solve and own problems others might consider too hard to even try.

Anyhoo, the initial concept was to have several one word themed slides and discuss how these traits can help with innovation in mobile forensics.
Due to a panel format change, the original slides didn't get much play time so monkey thought he'd run through them now and present his thoughts with a focus on advice for those newer to mobile forensics. Some of the points made here may have been mentioned during the panel by other speakers but at least here I have time to elaborate and present my point of view. Bonus huh?

Now let's meet the panel ... Can you tell that we went for a superhero introductory theme?

Heather Mahalik!

Cindy Murphy!

Chris Crowley!

Andrew Hoog!

 And now onto the rest of the slides ...


This is what attracts most of us to forensics. How does "Stuff" work and given a set of resultant data, how can we reconstruct what happened?
Documenting your curiosity (via blog post, white paper, journal article) is a great way of both sharing knowledge with the community and demonstrating your ability to research and think independently.
In mobile forensics, curiosity will usually lead to hex diving especially when hunting for new artifacts.
Curiosity naturally leads to "Squirrel chasing" where one interesting artifact can lead you to many others. So you might start out with one focus and end up discovering a bunch of cool artifacts.


Our ability to create solutions depends on our paint set. The wider array of skills you have as a mobile forensic examiner, the more creative you can be - especially as mobile devices are a combination of both hardware and software.
For inspiration, background knowledge and anticipating future trends, read research papers, blogs, books, patents, mobile device service manuals/schematics and industry standards (eg eMMC JEDEC standard). Knowing the background details today will help you analyze tomorrow's device.
Start with a popular make/model and learn how a device works. Go to and the FCC website for pictures of device breakdowns. Read up on how eMMC Flash memory devices work. You don't have to be able to MacGyver a mobile device on a desert island but familiarize yourself with the fundamental concepts (eg eMMC memory has a NAND Controller acting as the interface to the actual NAND memory).
Look at how an SQLite database is structured. Most apps rely on these types of databases to store their data. The official website is a great place to start.
Develop/practise skills in soldering, chipoff, network forensics, malware reverse engineering, scripting for artifacts.
Know how to find/make/use automated tools. Tools can be used as intended/documented (eg NetworkMiner to read .pcaps) or in more novel ways (eg use an Android emulator to create app artifacts and save on rooting test devices/acquisition time).

Scientific Method

As mobile devices change (use of devices, underlying hardware, encryption, new apps/OS artifacts) we need to be able to record our observations in a structured, repeatable way and be able to communicate our findings to others.
The best way is to create your own data on a test device using a documented set of known actions. As Adam Savage from Mythbusters says: "Remember, kids, the only difference between screwing around and science is writing it down".
Also, as Mari Degrazia (and Meoware Kitty) showed us at the DFIR Summit, you should also "Trust But Verify" your tools.


Don't let failure discourage you if/when it comes.
You may need to use a different technique or change your assumptions. Or wait for new developments by someone else and revisit.
There may be more than one solution. Evaluate which is better or worse. The faster method is not always the most comprehensive.
You are not alone. Chances are someone else in the community may have the keys to your problem. Ask around Twitter, forensic forums and your professional network.


No one monkey knows ALL THE THINGS.
I find it helpful to email a trusted group of mobile forensic gurus and describe what I am seeing. Even if they are not able to help directly, it forces me to structure my thinking and help me question my approach.
Having a trusted group you can bounce ideas/findings off helps both yourself and potentially everyone in the group who may not have the time to otherwise investigate. The increased pool of experience and potential access to more varied test data are added bonuses as well. There is also an inherent double checking of your analysis.
Communicate your ideas often. Even if you start feeling like a spam monkey, realize that people can come up with amazing ideas/suggestions when prompted with the right stimulus.
Share your innovation with the community - they may be able to help you improve it and/or adapt it for another purpose that you never would have thought of.

Choose your team wisely though. There are some "One way transaction" types who you can help and then never hear from again. Be aware that it is a small community and word does get around about potential time wasters/bullshitters. 
Alternatively, you might be contacted by some rude farker after some free advice/labour - eg "You seem like you know what you are doing. Here's my problem ..."
Realize that being polite/considerate goes a long way to building the required level of trust. Recognize that you are probably asking someone to give up their free time for your cause.
Give team mates a default "opt out" of receiving your spam. For example, "If you wish to keep receiving these types of emails, please let me know. Otherwise, Thankyou for your time." and if you don't hear back, stop sending shit. Most people in forensics will be keen to discover new artifacts/research but be sure to try to organize your thoughts before hitting send.

Manage people's expectations. If you don't know or are not sure - it is better to under promise and over deliver later. Don't feel bad about saying "I don't know" or "I'm currently working on other things and don't have the time right now".


I believe that you can make your own "Luck" through being prepared when the opportunity presents itself.
For example, I had difficulties landing a forensics job after finishing my graduate studies in Forensic Computing. The market here in Monkeytown was relatively small compared to the US.
Through personal research projects that I blogged about and multiple US internships, I was able to land a rare and Monkeytown based forensic research dream job for which I am still counting my blessings. Having a documented prior body of work helped make the recruitment process so much easier (it also helped that there were technical people in charge of the recruiting).
Pure forensic research jobs seem to be rare in this industry - most positions seems to require a significant element of case work/billable hours. So I really appreciate the ability to pick an area or device and "research the shit out out of it".

On the other hand, occasionally in a case, you can have some plain old good fortune such as when Cindy Murphy and I were looking at a Windows Phone 8 device and we found an SMS stating "Da Code is ..." (which ended up being the PIN code for the phone).


I just included this slide because I think it was one of my better 'toons in the slide deck :)

Final Thoughts

Physical fitness and rest are also important factors in staying creative. In the past, I've had some difficulties sleeping which obviously had an adverse affect on my work. A light regimen of regular exercise (15 minutes x 3 times per week) on the stationary bike has worked wonders on my tiredness levels and aerobic fitness. The paunch still remains a work in progress however ;)
For those interested, check out Dr Michael Mosely and Peta Bee's excellent research book on High Intensity Training (HIT) called FastExercise. It shows how you don't have to spend a huge amount of time at the gym to start seeing some immediate health benefits.

So long as you remain committed to learning, the innovation will come. Don't sweat about the non creative periods.

Learning to script is a good way of forcing you to understand how data is stored at the binary level. Python is a popular choice in forensics for its readability, many existing code libraries and large user base.

A library of "most likely to be encountered" test devices can help you to create before/after reference data sets to validate your research. These may be sourced privately from online (eg eBay) or from previous cases.

When public speaking, I have to learn to project my voice more. Elgin from the SANS AV crew kindly took the time after the panel to advise me to speak more from the diaphragm in the future. Concrete feedback like this is the best way to improve my speaking ability. Having said that, maybe monkey also needs to dose up on the caffeine before the next panel so he can react quicker/with more urgency. I'm guessing experience is the best teacher though.

The 2016 SANS DFIR Summit Presentation Slides are now available from here. Get them while they're hot!

Special Thanks to Jennifer Santiago (Director of Content Development & SANS Summit Speaker Wrangler) for her patience in dealing with this first time speaker/panellist.
Special Thanks also to my fellow panellists Andrew, Chris, Cindy and Heather for welcoming this monkey as a peer rather than a curiosity.

Not to get all heavy and philosophical on you but I found this quote that pretty much sums up my thoughts on innovation. It is from Nguyen Quyen who apparently was a Vietnamese Anti-French Colonist from the early part of the 20th Century. Ain't Google great?

"Successful innovation is not a single breakthrough. It is not a sprint. It is not an event for the solo runner. Successful innovation is a team sport, it's a relay race."

Good luck quoting that on a panel and not sounding like a complete wanker though ;)

If anyone has some suggestions for how I can improve my panel talking skills or would like to share some tips on innovation in mobile forensics, please leave a comment. Thanks!

Sunday, 15 May 2016

The Chimp That Pimps And An Introduction to e.MMC Flash Memory Forensics

Pimpin Ain't Easy?

SANS is offering the top 3 referrers to its DFIR Summit 2016 website, an Amazon Echo smart speaker.
As of 11 May 2016, this Chimpy McPimpy was number 5 on the list.
Chimpy would very much like to win an Echo (echo, echo) so he can take it apart and share what forensic artifacts are left on the device.

The Echo is a smart speaker that can listen out for voice commands, play music, search the Internet and control Internet Of Shitty Things. Apparently, more than 3 million have been sold in the US since 2014.

Here's a (pretty meh) Superbowl commercial demonstrating some of the Echo's capabilities:

And here's the Wikipedia entry for the Amazon Echo just so monkey doesn't have to regurgitate any further (I already have enough body image issues).

The folks at Champlain College have also recently blogged about their Amazon Echo forensic research (here, here and here).
They have a report due out this month (May 2016).
From what this monkey can ascertain, their research focuses on network captures and the Amazon Echo Android App side of things. They also mentioned looking into "chipping off" the device but I'm not sure if this was a core part of their research as it wasn't mentioned in later posts.

So Monkey is proposing this - (if you haven't already) please follow this link to the SANS DFIR Summit website and if monkey manages to win an Amazon Echo, he will blog about getting to that sweet, sweet, echoey data from the internal Flash memory. See here  and here  for some background on Flash memory.

How do we know it uses Flash memory?
The awesome folks at have already performed a teardown which you can see here.

From's picture of the logic board (below), we notice the Flash memory component bearing the text SanDisk SDIN7DP2-4G (highlighted in yellow).

Amazon Echo's Logic board

Searching for the Flash storage component(s) on most devices (eg phones, tablets, GPS, answering machines, voice recorders) starts with Googling the various integrated circuit (IC) chip identifiers. The Flash memory component is normally located adjacent to the CPU (minimizes interference/timing issues).
In this case, the peeps have helpfully identified/provided a link to the 4 GB SanDisk Flash memory chip.
But if we didn't have that link, we would try Googling for "SanDisk SDIN7DP2-4G" and/or "SanDisk SDIN7DP2-4G +datasheet" to find out what type of IC it was.
According to this link - for the 4th quarter of 2015, Samsung's NAND revenue (33.8%) led Toshiba (18.6%), SanDisk (15.8%), Micron (13.9%), SK Hynix (10.1%) and Intel (8%). Other (smaller) manufacturers such as Phison, Sony, Spansion were not mentioned. Not sure how accurate these figures are but if you see one of these manufacturers logos/name on a chip, you have probably found a NAND memory chip of some kind (eg Flash, RAM).

Anyhoo, from the link that provided we can see the following text:
SDIN7DP2-4G,153FBGA 11.5X13 e.MMC 4.51
Here's what it all means:
153 FBGA (Fine pitched, Ball Grid Array) means there are 153 pin pads arranged in a standard way.
The 11.5X13 refers to the chips dimensions in millimetres.
The e.MMC 4.51 tells us the chip adheres to the Embedded Multi-Media Card (e.MMC) standard (version 4.51) for NAND Flash chip interfacing. We will discuss the e.MMC standard a little further on.

To double check's data link, we did some Googling and found this link which seems to confirm from multiple sites that the SanDisk Flash chip is 153 FBGA and 11.5 x 13.
Ideally, we would have found the actual datasheet from SanDisk but sometimes you just gotta make do ...

It is also worth noting that not all Flash memory chips are e.MMC compatible. Some devices may use their own proprietary NAND interface. Some chips might be NOR Flash (eg Boot ROM) and thus not really relevant to our quest for user data.
Additionally, the latest Flash memory chips may follow a newer (faster, duplex) standard called Universal Flash Storage (UFS). See here for more details on UFS.
So while it appears the days of e.MMC chips are numbered, there's still a LOT of e.MMC storage devices out there that can be potentially read.

When reading Flash storage for forensics, some key considerations are:
- Does it follow the e.MMC standard?
- Chip pin arrangement (number of pins and spacing)
- Chip dimensions (typically in mm)

The e.MMC standard is used by Flash memory chip manufacturers to provide a common infrastructure / command set for communicating. This way a board manufacturer can (hopefully) substitute one brand of eMMC chip with another brand (probably cheaper) of the same capacity. The standard focuses on the external eMMC chip interfacing and not the internal NAND implementation (which would be manufacturer specific). Having a e.MMC Flash chip makes reading a whole lot easier.

But don't just listen to me, JEDEC - the folks responsible for the eMMC standard (and UFS), state :
"Designed for a wide range of applications in consumer electronics, mobile phones, handheld computers, navigational systems and other industrial uses, e.MMC is an embedded non-volatile memory system, comprised of both flash memory and a flash memory controller, which simplifies the application interface design and frees the host processor from low-level flash memory management. This benefits product developers by simplifying the non-volatile memory interface design and qualification process – resulting in a reduction in time-to-market as well as facilitating support for future flash device offerings. Small BGA package sizes and low power consumption make e.MMC a viable, low-cost memory solution for mobile and other space-constrained products."

To get a copy of the e.MMC standard (free registration required), check out this link.

The e.MMC standard document provides this helpful diagram:

JEDEC e.MMC Electrical Standard v5.1

From this we can see that a "Device controller" handles any interfacing with the actual NAND storage ("Memory Array"). This includes things like reading/writing to NAND, paging, TRIM, error correction, password protection.

There are 4 signals/pins required when reading an e.MMC memory:
- CLK = Synchronizes the signals between the e.MMC chip and the "Host Controller" (ie CPU of device)
- CMD = For issuing commands/receiving command replies from/to the "Host Controller"
- DATA0 = For receiving the data at the "Host Controller"
- VCC / VCCQ = Power for the NAND memory / Power to the Device Controller. In some cases, this can be the same voltage (1.8 V)
- GND / VSS = Ground

It is not a co-incidence that these connections are also required for In-System Programming (ISP) Forensics. But that is probably a topic more suitable for a Part 2 (hint, hint).

We can see these pins labelled in this ForensicsWiki diagram of a BGA 153 e.MMC chip
BGA-153 Layout

Note: ForensicsWiki have labelled it as BGA169 but it does not show the extra 16 (typically unused) pins. Count the number of pins (I dare you!) - there's only 153. At any rate, our target SanDisk chip should look like the BGA153 diagram above. Most of the pins are unused / irrelevant for our reading purposes.
The ever helpful GSMhosting site shows us what a full BGA 169 looks like:

BGA-169 Layout - the extra 16 pins comprise the 2 arcs above/below the concentric squares

Other pin arrangements we've seen include BGA162/186 and BGA/eMCP221. Some Flash chips are combined in the same package as the RAM. These are called eMCP (Multi-Chip Package).
Control-F Digital Forensics have blogged an example list which matches some common devices with their e.MMC pin arrangement/size. They also note that the pitch (spacing between pins) for the previously mentioned layouts is 0.5 mm.

So here's what BGA-162 looks like:

BGA-162 Layout (Source:

And a BGA/eMCP221 looks like:

BGA/e.MCP221 Layout (Source:

Final Thoughts

Due to e.MMC standardisation, reading the data off an e.MMC Flash chip should be straight forward and repeatable - which is great for forensics. Interpreting the subsequent data dump artifacts is usually a more challenging task.
The e.MMC Flash memory content discussed in this post applies equally to Smartphones, Tablets etc.

UPDATE: For even more details on Flash Memory Forensics, check out the following papers:
Forensic Data Recovery from Flash Memory

By Marcel Breeuwsma, Martien de Jongh, Coert Klaver, Ronald van der Knijff and Mark Roeloffs


Theory and practice of flash memory mobile forensics (2009)
By Salvatore Fiorillo
Edith Cowan University, Western Australia

The paper by Breeuwsma et al. is probably THE paper on Flash memory Forensics.

Please don't forget to click on this link so Monkey can get his Precious Amazon Echo. You might like to do it from a VM if you're worried about security.
If, for whatever reason, monkey doesn't get an Echo - it's no big deal. Just thought it would make for an interesting exercise as we head towards the Internet of Lazy Fatties ... At the very least, we have learnt more about performing e.MMC Flash memory forensics.

In other news, in June 2016, this monkey will be:
- Attending his first SANS DFIR Summit
- Speaking on a "Innovation in Mobile Forensics" panel with Cindy Murphy, Heather Mahalik , Andrew Hoog and Chris Crowley. Monkey is still pinching himself about joining the collective brain power of that panel *GULP*
- Facilitating/Rockin' the Red Apron for SANS FOR585 Advanced Smartphone Forensics with Cindy Murphy (just after the DFIR Summit)

So if you see me around (probably hiding behind/near Cindy or Mari DeGrazia), feel free to say hello and let us know if this blog site has helped you ... I promise I'll try not to fling too much shit (while you're facing me anyway. Hint: Keep eye contact at all times!).

As always, please feel free to leave feedback regarding this post in the comments section below.

Monday, 25 April 2016

An Initial Peep at Windows 10 Mobile (Lumia 435)

Ooh! Yeah, show me where you keep your store.vol you dirty winphone you!

At first glance, the Windows 10 Mobile GUI looks a lot like Windows Phone 8. This post will focus on some key mobile communication artifacts (Calls, Contacts, SMS, MMS, pictures/video) and hopefully excrete a few noteworthy nuggets (of information!) along the way.

Special Thanks to @TheHexNinja and our resident "Robotic Organic Soldering System" for their assistance in obtaining the test phone and data.
Unfortunately, as it is from a work phone, we cannot share the data (so please don't ask). However, if you have artifacts that you are researching, we may be able to check our limited data set to help confirm your findings.

We started with a lower priced 8 GB Nokia Lumia 435 Dual Sim (RM-1068) which came with Windows Phone 8.1 installed. We then updated to the latest version of Windows Phone 8.1 before upgrading to Windows 10 Mobile. A few days after upgrading, Microsoft released another Windows 10 Mobile update so we updated again to version 10.0.10586.218. The initial Win 10 upgrade process took 2-3 hours and seems to have left the previous Windows Phone 8.1 directories intact but with zero sized files (at least for the files it no longer seems to use).

After populating the phone with a troglodytic hermit's amount of test data, a chip off was performed and the data read into a binary image file.
FTK Imager (free) and X-Ways Forensics (commercial) were then used to view/browse the data.
OSForensics ESEDB Viewer (trial) and Nirsoft's ESEDatabaseView (free) programs were used to view ESE databases. Both of these were recently updated for handling Windows 10 ESE databases.
MS Calculator and DCode (free) were used to translate MS FILETIME values.

Similarly to Windows Phone 8, there were 27 partitions. The last 2 partitions were the only ones larger than 32 MB:
- MainOS [1543 MB]
- Data [5783 MB]
These partitions were formatted to use NTFS.

The phone was not encrypted by default. There is a Device Encryption option in the Settings, System menu and Windows 10 Mobile devices can also be enrolled in a Mobile Device Management scheme (ie remotely enforce IT policies such as data encryption and/or content protection).
There is also a "Find My Phone" device setting to "Locate, ring, lock and erase your device from".

By default, there is no PIN set but if you want to encrypt the device, a PIN must be set. A brief look at the SOFTWARE hive (the Registry is still stored under MainOS:\Windows\system32\config) shows that Win10 Mobile does not use the same PIN hashing mechanism as seen in Windows Phone 8 (see Francesco Picasso's post here ) ... D'Oh!

Here's a pic of our lovely Windows 10 Mobile incubator Assistant ... One of them looks a little green to me!

It seems Microsoft/Nokia went for the "You're NOT gonna lose THIS phone!" colouring scheme.

 The Lumia 435 has 1 GB RAM and 8 GB flash storage (all combined on the one chip). There were no In-Service-Programming ports found, so for a physical acquisition, it was chipoff or nothing.
We inserted our own FAT32 formatted 4 GB SD card along with a GSM SIM card. The default settings are to install to the internal memory but upon inserting the SD card (and restarting), the user is prompted to choose where to save various types of data (either to SD card or internal memory). If Apps are set to install to the SD card, their data is obfuscated/encrypted. Twitter was installed from the MS App Store to the SD card and while some filenames were visible, the actual file contents were not in plain text.
The device is too cheap to does not support Windows Hello biometric (face/fingerprint/iris) unlocking.


Microsoft have created a default Messaging app (one app per SIM card) which conveniently aggregates SMS, MMS and Skype chats. These records are stored in a store.vol ESE database under:

Unfortunately, the Messaging app only displays times with a minute resolution. In store.vol however, records are timestamped using 8 byte MS FILETIME (the number of 100 nanosecond intervals since 1JAN1601).

SMS content is viewable from store.vol's "Message" table.
Because this table has tens of columns, it is not yet known how similar it is to Windows Phone 8.1.
Flag values seem consistent between Windows Phone 8 and 10 but if columns have been added/removed, this will affect the offsets between data fields (and hence any previous Windows Phone 8 scripts). Due to time constraints, we haven't been able to confirm if these offsets have changed so any diagrams in this post will purposely leave out offset information.

Here's some diagrams showing the key SMS fields ... For readability, several fields have been omitted (marked by yellow strips).

Received SMS "Message" table record

Sent SMS "Message" table record
Note1:  The weird hexadecimal strings above each box is the actual column name as observed in the "Message" table. The names in the boxes are human readable strings made up by this monkey to keep track of things.
Note2: The PHONE fields are blank for Sent SMS

For Sent/Received SMS messages, the "Message" table's "001a001f" column is set to IPM.SMStext.
Other possible values are:  
- IPM.SMSText.SIM (possibly SMS stored on SIM) 

- IPM.MMS (for MMS) 

- IPM.Note (for email)
- IPM.MSG (for chat and drafts)

Draft messages have a JSON encoded text string containing the body text in column "0037001f" (TEXT field).
Draft messages also have their "0e070013" column (FLAG field) set to 44 (decimal).

Potential values for the Message record FLAG field are:
- Sent = 33
- Received unread = 0
- Received read = 1
- Draft = 41

To find the destination phone number for sent SMS/MMS, we can use the Message record's MSGID field to find the corresponding Recipient record ("Message" table's "00010003" column = "Recipient" table's "20040013" column). The Recipient record contains the destination phone number (PHONE field) as seen below.

"Recipient" table record for SMS/MMS

Alternatively, we can match a Message record's timestamp "0e060040" column (FILETIME2) to a Recipient record's "0e060040" (FILETIME) column. This was the method we used  in our previous Windows Phone 8 scripts.

We also found XML like strings depicting SMS content in: 

This ESE database is new in Windows 10 and appears to be related to the SmsRouter service. My Google-Fu was not strong enough to find much on this service. If it does see/store all SMS, then it may provide access to SMS which have been otherwise deleted from store.vol.
OSForensics ESEDB Viewer had difficulty parsing the SmsInterceptStore.db "Messages" table (showed no entries). However, NirSoft ESE DatabaseView returned 1 entry.
Searching SmsInterceptStore.db with WinHex for the UTF16-LE string "MessageType>Text" found 3 instances of SMS versus the one instance returned by Nirsoft ESE DatabaseView. The extra records may have been deleted from the database but still resident in the file.
The SMS contents seems to be complete (ie they are not snippets).

MMS also store records in store.vol's "Message" and "Recipient" tables. Additionally, MMS store attachment information in the "Attachment" table and the attached files and MMS message text are stored under Data:\SharedData\Comms\Unistore\data\7\

We can use the filesystem "Date modified" time of the attachment files to sort and assign attachments to their corresponding MMS.

Here's a diagram showing the MMS relationship (not all fields shown):

The Windows 10 Mobile MMS relationship isn't exactly clear ... Paging Dr Phil!

Every MMS will have a "Message" table entry. If it's a sent MMS, there will be a corresponding "Recipient" table entry (containing the Destination Phone number and FILETIME3).
Every sent/received MMS Message will have at least 2 "Attachment" table entries - one for a "smil" message layout XML file and one for each attached file (eg one for each dick pic attached). If there's any text in the MMS, there will also be a "Text_0.txt" entry.
Each file attachment will be stored in its own .dat file which will have a similar filesystem "Last Modified" timestamp to the "smil" layout .dat file. This "Last Modified" timestamp will approximately equal the relevant MMS's FILETIME2 value (within 1-2 seconds).

So to locate all MMS, we search the "Message" table for any records with the column "001a001f" set to IPM.MMS.
When we find an MMS, we note the MSGID value (column "00010003" value) and the FILETIME2 value (column "0e060040" value).
We take that MSGID value and search for a match in the "Attachment" table's column "20040013".
There should be at least 2 entries - one for the attachment, one for the "Smil.txt" markup file. There may also be one for MMS text.
We can also use the FILETIME2 value to find .dat files with a similar "Last Modified" timestamp under:
A bit messy but it seems to work for our limited test data ...
For further details on MMS hunting, check out our previous Windows Phone 8.1 MMS post here.


Contact information can be accessed via the default People app. The contact info is stored in store.vol's "Contact" table. The first row entry corresponds to the device owner.
Here's a diagram showing some relevant fields. Its probably incomplete due to our basic test data but it can still give you an indication of the types of data stored. And the duplication ... *whispers* duplication!

"Contact" table record structure (incomplete)

Using a hex editor, we can see that each Contact record ends with the binary sequence 01040000008200E00074C5B7101A82E008. This is the same magic number observed for Windows Phone 8.1 contact records and a good way to way locate Contact records from raw hex (eg from ESE transaction log files or the pagefile at Data:\pagefile.sys).

We also observed 2 pipe separated plain text contact lists stored in:
These contained non-Skype contacts.

Call History

The call history can be accessed via the Phone app (for an overall summary) and/or the People app (per contact call history). There is one Phone app available per SIM.
The source of the call history appears to be the store.vol's "Callhistory" table.
Here's a diagram showing some relevant fields. Unlike other tables, "Callhistory" actually uses human readable column names!

"Callhistory" table record

Inbound Private numbers do not appear in the "RawNumber" or "RawNumberHash" or "ResolvedNumber" columns.
Missed Calls have the same "StartTime" and "EndTime" and their "Type" field set to 2.
The "Line" column contains a GUID (eg {B1776703-738E-437D-B891-44555CEB6669} ) for the phone line which made/received the call. On a device with multiple SIM cards, there may be than one GUID. From previous Windows Phone 8 observations, the example GUID seems constant across several devices and is a good way to locate Callhistory records in hex dumps (GUID string is encoded UTF16-LE).
Our test Skype calls had the "Line" value set to "Microsoft.Messaging_8wekyb3d8bbwe" instead of the GUID.

Pictures / Video

The Data:\Public folder appears to be the default location for saved pictures/video. The Data:\Public folder can contain documents, sound recordings, downloaded files, music, saved pictures/video and ringtones.

We found camera pictures/video under Data:\Users\Public\Pictures\Camera Roll\
eg1 WP_20160414_09_08_08_Pro.jpg
eg2 WP_20160414_09_46_55_Pro.mp4

We were able to save pictures from the MS Edge browser under
Data:\Users\Public\Pictures\Saved Pictures

Other possible storage locations for pictures/video include:
- the user's OneDrive cloud storage.
- the user's SD card. From our testing, by default, media files saved to the SD card are not encrypted.
- the OneNote app.

Final Thoughts

Since we dumped our 435, Microsoft has issued another Win 10 Mobile update so the information in this post may have changed.

In addition to store.vol, remember to check any ESE transaction log files (eg USStmp.log) for data which maybe no longer be present in store.vol. This will probably involve using a hex editor to search for various unique strings or values.

Plugging the 435 into a PC via USB will let the PC user see the Data:\Public folder. This can contain documents, sound recordings, downloaded files, Music, saved pictures, saved video and ringtones. However, Windows 7 did not recognise the 435 as a physical drive when (for shiggles) we tried imaging it via FTK Imager over USB.

Also bundled with Windows 10 Mobile are the following apps - OneDrive, Skype, MS Edge Browser, Facebook, Excel, Word, Powerpoint, OneNote and Cortana.
Cortana was not activated for this testing as there were difficulties activating it for our region (Australia).
Skype chats were observed in:
- store.vol
- the Messaging SQLite database at Data:\Users\DefApps\APPDATA\Local\Packages\Microsoft.Messaging_8wekyb3d8bbwe\LocalState\XXX\main.db
- the Skype SQLite database at Data:\Users\DefApps\APPDATA\Local\Packages\Microsoft.SkypeApp_kzf8qxf38zg5c\LocalState\XXX\main.db

Note: XXX= Mixed string containing the User's Microsoft Account ID.

Users don't need the SIM inserted to view Messaging, Outlook, Skype and Facebook apps. They can also view those apps when in Airplane mode although Outlook will not synch so may not display any messages.

For more information on Windows 10 Mobile please read the following:
Windows 10 Mobile security guide
Secure boot and device encryption overview

Interestingly, the second reference mentions hardware providers blowing any JTAG fuses before the device leaves the factory. Ahem ... This suggests that retailed Windows 10 Mobile devices will not be readable via JTAG.
Additionally, given the lack of In Service Programming (ISP) ports on the budget level Lumia 435, it is likely that the more expensive Lumias will also not expose any ISP points.
This could mean that chipoff may be the only option for physical acquisition of Windows 10 Mobile Lumias.
But don't take this Sky-Is-Falling Monkey's word - have a go yourself and let the community know if you find an alternative to chipoff.

Overall, it's nice that most of the artifacts we looked at have not changed THAT much since Windows Phone 8. The store.vol file is still the key artifact especially since they amalgated the Windows Phone 8 "Phone" database into it for Windows 10 Mobile. I'm thinking it shouldn't be too difficult to update our Windows Phone 8 scripts to handle Windows 10. Ah yes, "shouldn't be" ... methinks getting comprehensive test data will be the main bottleneck - especially if chipoff is required.

Sunday, 6 December 2015

Windows Phone 8.10 MMS (for Lumia 530) ...

Now with attachment info! Catch the excitement!

We recently noticed that while some commercial forensic tools show Windows Phone 8.10 MMS transaction information (eg Date, Phone number), they do not show or list the accompanying MMS file attachments. Welcome masochistic script monkey! May I take your "safe word"?
In Windows Phone 8.10, a user can send an MMS containing a picture (eg camera JPEG, PNG screen capture), a video (eg camera captured MP4), a Contact (via VCARD text) and/or a VoiceNote (via .AMR audio). These attachments are recopied/renamed/stored as weirdly named .dat files in various sub-directories (named "A" to "P") under Data:\SharedData\Comms\Unistore\data\7.
Received MMS are also stored as .dat files under the same location so it isn't immediately obvious what attachments go together and/or which were sent/received.

The main issue is finding a link between the MMS database transaction entries and the actual stored .dat file(s) which were sent/received.
There may be a more comprehensive link yet to be discovered, but the best link we've found so far is via the filesystem "Last Modified" timestamp of the .dat files and a timestamp found in the "Message" table of the store.vol database.
However, because file system modified times can vary by 1-2 seconds when compared to what is listed in the MMS database, we wrote two scripts - one to sort/print the filesystem's .dat attachment files in chronological order ( and a separate script ( to print the store.vol database MMS records in chronological order. The discerning simian analyst can then make the decision about which attachments go with which MMS based on the timestamp information, MMS total size, file types and individual file attachment sizes. Additionally, they can use the calculated SHA256 hash to locate any sent MMS files (received MMS files are initially stored only as .dat files).

The two scripts are available from my GitHub site and have been created/tested on Windows 7 PC running Python 2.7 using test data from a Nokia Lumia 530 running Windows Phone 8.10.


The "store.vol" database is an ESE database located in Data:/USERS/WPCOMMSERVICES/APPDATA/Local/Unistore/ that contains 3 tables of interest for MMS:
- Message (contains metadata of sent/received MMS)
- Recipient (contains sent MMS phone numbers)
- Attachment (contains metadata about sent/received MMS attachments)

These tables have weird combination numeric/letter strings used for their column/field names (eg "0037001f").
Therefore, throughout this blog post we will use alternative monkey monikers (eg Size, Flag, Filename0) to keep things sane.

Here's an overview of how the various tables and .dat files fit together.  
Note: Due space constraints, this relationship diagram does NOT include every field from each table.

So, are you seeing anyone right now? Oh ... it's complicated?

Every MMS will have a "Message" table entry. If it's a sent MMS, there will be a corresponding "Recipient" table entry (containing the Destination Phone number and Timestamp3).
Every sent/received MMS Message will have at least 2 "Attachment" table entries - one for a "smil" message layout XML file and one for each attached file (eg one for each picture).
Filename aliases (eg "FOT1234.jpg") for attached Images/Videos/Text/Voicenotes/VCARDs will appear in both the "smil" .dat file and in the corresponding "Attachment" table entry.
Each attachment's content will be stored in a separate .dat file with a similar filesystem "Last Modified" timestamp to the "smil" layout .dat file. This "Last Modified" timestamp will approximately equal the relevant MMS's Timestamp2 value in the "Message" table.

We recommend using OSForensics "ESEDB Viewer" to view "store.vol" as it seems to have more reliable search functionality (and possibly shows more table columns) than NirSoft's ESEDatabaseView.
It's one thing to view "store.vol" using a dedicated viewer but to script a solution (independent of third party libraries) we have to look at how each field of interest is stored in the raw hex.

For the "Message" table there are 2 variations of MMS record - one for Sent MMS and one for Received MMS.
Each Received MMS "Message" record looks like:

Received MMS format
Where X represents a number of bytes that we don't really know/care about. All strings are null-terminated UTF-16-LE encoded. Timestamps are LE 8 byte integers representing the number of 100 ns intervals since 1 JAN 1601 (MS FILETIME). The string "IPM.MMS" is actually "x49x00x50x00x4Dx00x2Ex00x4Dx00x4Dx00x53x00x00x00" in hex.

Each Sent MMS "Message" record (contains no phone numbers) looks like:

Sent MMS format

The important "Message" fields are colour highlighted in the diagrams:
- Msgid (Unique id number for each "Message" entry.)
- Flag (Sent (33 decimal) / Unread(0) / Read(1). Draft MMS are stored using a different Message record format which contains "IPM.MSG" (instead of "IPM.MMS") and their Flag is set to 41 decimal. They will not be discussed further in this post.)
- Size (Total MMS size in bytes. This will help when there are multiple file attachments per MMS.)
- Timestamp2 (File system Last Modified time (approximate). For sent MMS, this corresponds to the time of creation/last update and not the time actually sent.)
- Timestamp3 (Sent/Received time common to both "Message" / "Recipient" tables.)
- Phone0/Phone1/Phone2/Phone3 (Phone number for received MMS. These tend to be set to the same value when present. Sent message phone numbers have to be obtained from the "Recipient" table.)

Each "Recipient" table record looks like:

Recipient format

Where X represents a number of bytes that we don't really know/care about. All strings are null-terminated UTF-16-LE encoded. Timestamps are LE 8 byte integers representing the number of 100 ns intervals since 1 JAN 1601 (MS FILETIME). The string "@.SMS" is actually "x40x01x53x00x4dx00x53x00x00x00" in hex.
Each "Recipient" table record should correspond to a sent SMS/MMS. Our ass-umption here is that it's impossible to simultaneously send both SMS and MMS with the same Timestamp3 value. So if we find a "Recipient" table entry which has a Timestamp3 value that also occurs in a "Message" table "Sent Record", we can ass-ume that it is a sent MMS. Sent SMS have an "IPM.SMStext" value set instead of "IPM.MMS" in the "Recipient" table.

The important "Recipient" fields are:
- Msgid (Unique id number for each "Message" entry.)
- Timestamp3 (Sent/Received time common to both "Message" / "Recipient" tables.)
- DestPhone (Destination Phone number string.)

Each "Attachment" table record looks like:

Attachment format

Where X represents a number of bytes that we don't really know/care about. All strings are null-terminated UTF-16-LE encoded.
Filename0 has been observed to start with "<cidText" or "<cidSmil" or "<cidImage" or "<cidVideo" or "<cidAudio" or "<cidVCard". It has also been seen in the form "<123>" - where "<123>" represents a 3 digit number that increases with each "Rowid". MMS using the "<123>" alias format also had the fixed alias value of "<0000>" for the "smil" layout files.
Draft SMS/MMS do not use the "<>" method of enclosing aliases so cannot be found in the same manner.

The important "Attachment" fields are:
- Msgid (Unique id number for each Message entry.)
- Size (Attached file's size in bytes. There can be multiple file attachments per MMS. Adding all the "Attachment" sizes for a given "Msgid" should equal the "Message" table's size for that same "Msgid".)
- Filename0 (Alias enclosed by "<" and ">" characters. We can use it to identify MMS attachment entries (eg "<cidImage_FOT1234.JPG>").)
- Filename1 (Alias used in "smil" files. eg "FOT1234.JPG".)
- Filename2 (If it's a sent MMS, this will be the actual source Filename (eg WP_20151203_001.JPG). If it's a received MMS, this is typically set to the same value as Filename1.)
- Filetype (Description of the type of file.) 

The Filetype values have been observed as:
- "application/smil" (for the MMS layout)
- "text/plain" (for the MMS text content)
- "image/jpeg" and "image/png" (for attached camera/screenshot images)
- "audio/amr" (for attached VoiceNotes)
- "video/mp4" (for attached camera videos)
- "text/x-vcard" (for attached Contacts)

It's been briefly mentioned above but the last piece of the banana is that MMS .dat files are stored under "Data:\SharedData\Comms\Unistore\data\7". One .dat file is required for each sent/received file. Additionally, every MMS has a "smil" XML layout file which lists an alias to the attached file(s) (eg <img src="FOT1234.JPG" region="Image"/>). We can also find that alias mentioned in a corresponding "Attachment" table entry for that MMS.

Here's an example "smil" .dat file:
<smil><head><layout><region id="Text" height="50%" width="100%" left="0" top="50%" fit="scroll"/><region id="Image" height="50%" width="100%" left="0" top="0" fit="meet"/></layout></head><body><par dur="5000ms"><img src="FOT1234.JPG" region="Image"/><text src="Text_0.txt" region="Text"/></par></body></smil>

The "text src" consistently seems to be set to "Text_0.txt". During testing we did not try sending multiple images in the same MMS with each image having it's own accompanying text. However, we suspect that each text entity would then get its own "text src" element and unique alias (eg "Text_0.txt", "Text_1.txt"). With our current understanding, determining the order of these multiple texts would be difficult but we can still retrieve the text content.

Note: "Data:\SharedData\Comms\Unistore\data\7" has been observed to also contain Draft MMS (text content) and Received Email attachment .dat files.
Attached files for Draft MMS (eg pics) do not appear to be stored in .dat files under that directory. Editing a Draft MMS should update the "Last Modified" filesystem time on the .dat files.

You might also have noticed that the constant 0x07000000 value appears in each of the above records. Coincidentally(?), 7 is also the rowid corresponding to the "SMS" row in the "Store" table. This kinda makes sense as both SMS and MMS are grouped together under the same Messaging menu on a Windows Phone 8 device.
It seems there is a "Store" table row for each potential store location on the phone (eg Outlook, SMS, ExternalStore, OneDrive etc).

Scripting and Testing
Assuming the analyst has already exported the contents of "Data:\SharedData\Comms\Unistore\data\7" (eg using AccessData FTK Imager), we can write a Python script to create a clickable HTML table (sorted by "Last Modified" time) of .dat attachments. The script can also output the same data to a Tab Separated Variable (TSV) output file for importing into an analysis spreadsheet.

Here's the help for
Running v2015-11-24

Usage: -i inputfiledir -t output.tsv (Optional) -o output.html (Optional)

  -h, --help     show this help message and exit
  -i DIRNAME     Input Directory To Be Processed
  -t OUTPUTTSV   Output Tab Separated Variable (TSV) filename (Optional)
  -o OUTPUTHTML  Output HTML filename (Optional)

The script walks through each input directory and looks for filenames ending in "73701.dat". It then retrieves that file's "Last Modified" time and stores the filename and timestamp for later display.
For each of the stored filenames, the script reads the file contents and attempts to calculate what type of file it is, the file size, the SHA256 Hash of the file and if it's a "smil" file, it will list any file aliases used. It then prints the file information sorted chronologically by "Last Modified" time to the command line (SHA256 Hashes are NOT printed to command line) and/or HTML and/or TSV.
By grouping the .dat files by "Last Modified" time, it should make it easier to decide which .dat files belong together.

Here is some redacted example output:

c:\python27\python.exe -i 7 -t fsop.tsv -o fsop.html
Running v2015-11-24

Parsed 57 files

Mod. Timestamp  Filename        Size(bytes)     Type    Comments
2015-12-01T04:02:08     7\c\40000002000000073701.dat    7302    AMR
2015-12-01T04:02:08     7\d\40000003000000073701.dat    186     <smil>  aud = P__4987.amr
2015-12-01T04:03:08     7\f\40000005000000073701.dat    893237  MP4
2015-12-01T04:03:08     7\g\40000006000000073701.dat    366     <smil>  video =P__CD04.mp4
2015-12-01T04:05:04     7\h\40000007000000073701.dat    104     VCARD
2015-12-01T04:05:04     7\i\40000008000000073701.dat    386     <smil>  VCARD present
2015-12-01T04:07:04     7\j\40000009000000073701.dat    366     <smil>  video =P__BC3E.mp4
2015-12-01T04:07:04     7\k\4000000a000000073701.dat    899422  MP4
2015-12-01T04:08:20     7\l\4000000b000000073701.dat    186     <smil>  aud = P__7C25.amr
2015-12-01T04:08:20     7\m\4000000c000000073701.dat    5702    AMR
2015-12-02T20:30:20     7\n\4000000d000000073701.dat    616     <smil>  img = FOTDAD6.JPG, text = Text_0.txt
2015-12-02T20:30:20     7\o\4000000e000000073701.dat    624866  JPEG
2015-12-02T20:30:20     7\p\4000000f000000073701.dat    50      Unknown
2015-12-02T22:26:42     7\b\50000001000000073701.dat    52      Unknown
2015-12-02T22:26:42     7\c\50000002000000073701.dat    616     <smil>  img = FOTEB94.jpg, text = Text_0.txt
2015-12-02T22:26:44     7\a\50000000000000073701.dat    571938  JPEG
2015-12-03T02:57:10     7\f\50000005000000073701.dat    38303   PNG
2015-12-03T02:57:10     7\g\50000006000000073701.dat    22      Unknown
2015-12-03T02:57:10     7\h\50000007000000073701.dat    616     <smil>  img = FOT348F.png, text = Text_0.txt
2015-12-03T02:59:48     7\i\50000008000000073701.dat    616     <smil>  img = FOT3070.png, text = Text_0.txt
2015-12-03T02:59:48     7\j\50000009000000073701.dat    48870   PNG
2015-12-03T02:59:48     7\k\5000000a000000073701.dat    18      Unknown

Note1: Type "Unknown" Types possibly indicate MMS message text files

Note2: Not all .dat files may belong to an MMS message (eg Received Email Attachments, Drafts)

Finished processing MMS .dat files ... Exiting ...

The corresponding output TSV looks like:

Mod. Timestamp    Filename    Size(bytes)    Type    SHA256 Hash    Comments
2015-12-01T04:02:08    7\c\40000002000000073701.dat    7302    AMR    CAE79982FCAD00B09707FB24FAB0D226E54E4B2DB85F926B34166B5DC7D3DBDD   
2015-12-01T04:02:08    7\d\40000003000000073701.dat    186    smil    30614CF3267AD6C53B714E528F474B61C47CD10058CCB5838ACA55BA7E69C5C0    aud = P__4987.amr
2015-12-01T04:03:08    7\f\40000005000000073701.dat    893237    MP4    DC8200239F601FA8B14783BD97DDCE55E094CEA5E23D01DD3F4832A6F87A7CE2   
2015-12-01T04:03:08    7\g\40000006000000073701.dat    366    smil    68A4069FB3AF78B3C045D830FCF03E964AE043E2276AD059C00A9BBFF30CEB76    video = P__CD04.mp4
2015-12-01T04:05:04    7\h\40000007000000073701.dat    104    VCARD    C1DF9E80CDCB9140D2FFC427B6896BB2E67EF8F989068E6F9CCAF367D947D29B   
2015-12-01T04:05:04    7\i\40000008000000073701.dat    386    smil    C56C8A12E8E5E2536161B6AF52C3A20F244603F31CDF637B86B6F4AA74087A91    VCARD present
2015-12-01T04:07:04    7\j\40000009000000073701.dat    366    smil    77AEC99255C3234D2B0A1EAA5DD935D4C694255C6F4A4C821FCF0C62AC43DCE9    video = P__BC3E.mp4
2015-12-01T04:07:04    7\k\4000000a000000073701.dat    899422    MP4    D2DA77B80DC689460829C6B0F554BC0778348EA149DED1242E80787F005958D3   
2015-12-01T04:08:20    7\l\4000000b000000073701.dat    186    smil    2EF5F8BEBC9C03665DB666539F1F9CB595CF543C541537E8EB104A81C60659AE    aud = P__7C25.amr
2015-12-01T04:08:20    7\m\4000000c000000073701.dat    5702    AMR    50AD1A3004E4C1541F507B38DB867A9186237612FF312FDF7E2BE4370617F3E6   
2015-12-02T20:30:20    7\n\4000000d000000073701.dat    616    smil    AA2382E8BC8DEA7A7176F21C5FD58C4E52E54608404DE437B1C3299AF0206192    img = FOTDAD6.JPG, text = Text_0.txt
2015-12-02T20:30:20    7\o\4000000e000000073701.dat    624866    JPEG    4BA420B740F5C8DEF862690566195CE620C2495406CDD8383362713A2A38E562   
2015-12-02T20:30:20    7\p\4000000f000000073701.dat    50    Unknown    E2E39EA85A25B1C02FB287049F1179B51DED480B99896B4E8E70F773BD2D7158   
2015-12-02T22:26:42    7\b\50000001000000073701.dat    52    Unknown    7DE34A123DA5F220CD6346F8CE852036C255A4FE4C81C130EB465AC6378193C0   
2015-12-02T22:26:42    7\c\50000002000000073701.dat    616    smil    144753D485039158AB10A06D86A6D421983EC12D708E992A8DA408B079917020    img = FOTEB94.jpg, text = Text_0.txt
2015-12-02T22:26:44    7\a\50000000000000073701.dat    571938    JPEG    139A1E26E6D317F1BBC1C36A7B98AFD3875351B6254B4AEB336F684841F23759   
2015-12-03T02:57:10    7\f\50000005000000073701.dat    38303    PNG    D4DAA620FCF32FA0198CAE17AD55B3F847243617F034C4A0BB88356853C77662   
2015-12-03T02:57:10    7\g\50000006000000073701.dat    22    Unknown    1BDA3B8EF697CC23E5299068695114F67F7B03C0DD7A4BFEB72F553088AB4009   
2015-12-03T02:57:10    7\h\50000007000000073701.dat    616    smil    D28199571A7C838C52206E4DA69D4C2A02A44B851B57DF739DBE2E35F8B6C696    img = FOT348F.png, text = Text_0.txt
2015-12-03T02:59:48    7\i\50000008000000073701.dat    616    smil    4E2D452A0190125D1D44062DEB300B3E00FC2FD0F33E55392A12CCFC3925188E    img = FOT3070.png, text = Text_0.txt
2015-12-03T02:59:48    7\j\50000009000000073701.dat    48870    PNG    3360CD0D57820536D86841DCA94453049B6C4B3D95A3D3B25B91B4CD5ABD50E7   
2015-12-03T02:59:48    7\k\5000000a000000073701.dat    18    Unknown    094D1EA6F14A289EC08AF1F85CE1B55A2D95937915A67061FFA85DFCD4284B37   

Note1: "Unknown" Types possibly indicate MMS message text files
Note2: Not all .dat files may belong to an MMS message (eg Received Email Attachments, Drafts)

Apologies for the Blogger formatting - this is why we didn't print the SHA256 hash to the command line!
And here's what the corresponding HTML output looks like in a web browser:

HTML Output from ""

When we click on an HTML file link, we can view that attachment more readily. However, for the HTML links to work, the HTML file must be in the same directory as the extracted "7" directory.

In this example HTML output, we have the .dat files from a sent MMS containing two pictures (saved from the web) and a text set to "Funny? Don't remember that".

Sent MMS with text and 2 pictures
Note: The different timestamp values for .dat files from the same MMS.

When we click on the first row's file link (not circled) and open it via Notepad we see the text:
Funny? Don't remember that

Clicking on the "smil" file's link (circled in orange) and opening it via Notepad looks like:
<smil><head><layout><region id="Text" height="50%" width="100%" left="0" top="50%" fit="scroll"/><region id="Image" height="50%" width="100%" left="0" top="0" fit="meet"/></layout></head><body><par dur="5000ms"><img src="FOT66CB.jpg" region="Image"/></par><par dur="5000ms"><img src="FOT9241.jpg" region="Image"/><text src="Text_0.txt" region="Text"/></par></body></smil>

This tells us that there are 2 images (FOT66CB.jpg, FOT9241.jpg) and a text message associated with this MMS. To determine if this MMS is sent/received and/or the sent/received time and/or the phone number, we can process "store.vol" using the second script (

Clicking on the JPEG link (circled in green) displays this picture in the browser:


Clicking on the JPEG link (circled in red) displays this picture in the browser:

Do you Mind?!

Ah, what's the point in blogging if we can't share pictures of toilet trained monkeys?!
Ahem, continuing on ...
Assuming the analyst has already exported "Data:/USERS/WPCOMMSERVICES/APPDATA/Local/Unistore/store.vol", we can write another script ( to list MMS information for correlation with the output of Essentially, prints out the information for every MMS attachment (sorted by Timestamp2).

Here's the help for

Running v2015-11-14

Usage: -s store.vol -o output.tsv(Optional)

  -h, --help         show this help message and exit
  -s STOREFILE       store.vol file
  -o OUTPUTFILENAME  Output Tab Separated Variable filename (Optional)

Finding all MMS attachments requires searching "store.vol" for a slight variation of the Filename1 alias used in the "smil" file (eg "<cdImage_FOT1234.jpg>" instead of "FOT1234.jpg", "<123>" instead of "cid:123").
Note: It is thought that the "cid:123" style of alias operates in a similar manner to the "FOT1234.jpg" alias but we have not been able to generate the "cid:123" alias during testing.
Fortunately, we can generalise this to a search for a group of letters starting with "<cid" and/or a group of digits enclosed by "<" and ">". Once we have found a list of these hits, we can retrieve that "Attachment" row's values (Filename0, Filename1, Filename2, Type, Size) and store them in a dictionary (creatively called "attachments") keyed by "Msgid" for later use.

Similarly, we can find all "Recipient" table entries by searching for the "@.SMS" pattern mentioned earlier. We store the retrieved row data (Timestamp3, DestPhone) in another dictionary (called "recipients") keyed by "Msgid" for later use.

Next, we search for "Message" table entries by searching for the "IPM.MMS" pattern and store the retrieved data (Timestamp3, Timestamp2, Phone, Flag, Size) in a dictionary (called "mmsdict") keyed by "Msgid". If we don't find a Phone number in the "Message" record (ie Sent MMS), we use the retrieved "Msgid" to obtain the "DestPhone" number from the "recipients" dictionary populated earlier.

Finally, we can iterate through the "mmsdict" for each "Msgid" and retrieve the corresponding "attachments" info - there will usually be multiple attachments for each MMS dict entry.
The output will be printed to the command line (looks a bit cramped) and/or TSV file (optional).

Here's a redacted sample of the command line output. For brevity, we've edited the output to highlight the corporate fatcat/toilet monkey MMS message sent earlier. The command line output is pretty cramped so we recommend outputting to TSV.

c:\python27\python.exe -s store.vol -o store-op.tsv
Running v2015-11-14

Opening store.vol...

Processing Attachment table ...
57 Attachment "<cid" hits found in store.vol

0 Attachment "<d+>" hits found in store.vol

57 Total Attachment hits found in store.vol

Attachment ASIZE ERROR! at offset 0x12004c ... skipping this hit

Attachments sorted by msgid ...
No. Attachments = 4
msgid = 48 : (u'<cidText_0>', u'Text_0.txt', u'Text_0.txt', u'text/plain', 52)
msgid = 48 : (u'<cidSmil>', u'Smil.txt', u'Smil.txt', u'application/smil', 742)
msgid = 48 : (u'<cidImage_FOT66CB.jpg>', u'FOT66CB.jpg', u'Monkey throwing poo by SheriffBean on DeviantArt.jpg', u'image/jpeg', 37397)
msgid = 48 : (u'<cidImage_FOT9241.jpg>', u'FOT9241.jpg', u'Lolcats Funny Pictures Of Cats With Captions.jpg', u'image/jpeg', 34529)


Processed/Stored 56 out of 57 Attachment hits

Processing Recipient table ...
55 Recipient hits found in store.vol


Recipients sorted by msgid ...
msgid = 42 : ('2015-11-11T19:36:25', u'+12345678900')
msgid = 48 : ('2015-11-15T21:47:53', u'+12345678900')
msgid = 49 : ('2015-11-15T21:51:32', u'+12345678900')


Processed/Stored 54 out of 55 Recipient hits

Processing Message table ...
19 IPM.MMS Message hits found in store.vol

MMS sorted by msgid ...
msgid = 48 : ('2015-11-15T21:47:53', '2015-11-15T21:47:52', u'+12345678900', 33, 72720)


Processed/Stored 19 out of 19 Message hits

Printing finalized table sorted by Timestamp2 ...
Timestamp2  Msgid   Timestamp3  Phone   Flag    TotalSize   Type    Filesize    Filename0   Filename1   Filename2
2015-11-15T21:47:52 48  2015-11-15T21:47:53 +12345678900    33  72720   text/plain  52  <cidText_0> Text_0.txt  Text_0.txt

2015-11-15T21:47:52 48  2015-11-15T21:47:53 +12345678900    33  72720   application/smil    742 <cidSmil>   Smil.txt    Smil.txt

2015-11-15T21:47:52 48  2015-11-15T21:47:53 +12345678900    33  72720   image/jpeg  37397   <cidImage_FOT66CB.jpg>  FOT66CB.jpg Monkey throwing poo by SheriffBean on DeviantArt.jpg

2015-11-15T21:47:52 48  2015-11-15T21:47:53 +12345678900    33  72720   image/jpeg  34529   <cidImage_FOT9241.jpg>  FOT9241.jpg Lolcats Funny Pictures Of Cats With Captions.jpg

Finished processing store.vol ... Exiting ...

Looking at the "finalized table" results at the end, we can see that each attachment's Timestamp2 values are all equal to 2015-11-15T21:47:52. This does not correspond with our earlier results from (where the JPEG files had different "Last Modified" times to the "smil" and text files). Perhaps the Timestamp2 values in store.vol were written before the actual .dat files were written around the 52-53 second boundary?
Anyway, this shows that there can be some discrepancy between the .dat files "Last Modified" times and the Timestamp2 values recorded in "store.vol". Hence the need for a meat based decision maker!
We can also see that we can use the Msgid (eg 48) to group common MMS attachments together.
Timestamp3 is a common value to both "Message" and "Recipient" tables and seems to be the timestamp quoted for sent/received MMS by commercial forensic tools.
The Type value of 33 indicates that this is Sent MMS.
The TotalSize figure of 72720 equals the sum of each attachment's Filesize (52 + 742 + 37397 + 34529 = 72720).
Filename1 is the alias used for each attached file in the "smil" layout file (eg FOT66CB.jpg, FOT9241.jpg).
We can see that for saved pictures which were then sent via MMS, the original filename appears in Filename2 (eg "Monkey throwing poo by SheriffBean on DeviantArt.jpg").
By using the Filename1 alias, Timestamps and individual file sizes, we should be able to match these store.vol results with the previous .dat results.
That is, there are 4 files listed from store.vol (Text_0.txt, Smil.txt, FOT66CB.jpg, FOT9241.jpg) which have corresponding matches in the HTML output table produced by

For a given attachment, you might not find a file with the Filename2 name on a Windows Phone 8.10 device/SD card as it could be a received file and the Filename2 string was actually sourced from the sender.
In this case, the file will only exist as a .dat file (assuming it was not re-saved locally after reception).
Alternatively, after sending an MMS attachment, the user may delete it from the phone or it might have been sourced from an SD card. For a file stored on an SD card/another device, we should be able use the SHA256 hash calculated from the relevant .dat file to help confirm the external file's identity.

And here is the more conveniently formatted TSV output file contents from ...

Timestamp2    Msgid    Timestamp3    Phone    Flag    TotalSize    Type    Filesize    Filename0    Filename1    Filename2
2015-11-15T21:47:52    48    2015-11-15T21:47:53    +12345678900    33    72720    text/plain    52    <cidText_0>    Text_0.txt    Text_0.txt
2015-11-15T21:47:52    48    2015-11-15T21:47:53    +12345678900    33    72720    application/smil    742    <cidSmil>    Smil.txt    Smil.txt
2015-11-15T21:47:52    48    2015-11-15T21:47:53    +12345678900    33    72720    image/jpeg    37397    <cidImage_FOT66CB.jpg>    FOT66CB.jpg    Monkey throwing poo by SheriffBean on DeviantArt.jpg
2015-11-15T21:47:52    48    2015-11-15T21:47:53    +12345678900    33    72720    image/jpeg    34529    <cidImage_FOT9241.jpg>    FOT9241.jpg    Lolcats Funny Pictures Of Cats With Captions.jpg

Blogger formatting strikes again! Basically the TSV output is the same as the command line output but its easier to import into a spreadsheet.

For shiggles, the script was run against a Lumia 520 / Windows Phone 8.0 store.vol but it seems that the store.vol offsets used are different and so the script did not work as intended.
It is ass-umed this script will work with other Windows Phone 8.10 devices however because Monkey has to believe he didn't waste his time with some one-off scripts ... grrr!

Also please note that on Windows Phone 8 devices, the displayed Messaging timestamps do not list the seconds (only hours/minutes). So while we can say that Timestamp3 is accurate to the minute, we cannot definitively claim its accuracy in seconds.

Some Final Thoughts

The store.vol script relies on searching the table records for unique markers (eg "IPM.MMS", "@.SMS", "<cid") and then reading/storing the surrounding field values. That's why we can extract data without knowing the entire structure of each database record.
We could have used a third party library to query the store.vol database directly but this means users would have to install that library on their analysis PCs (which are usually isolated from the Internet). For those interested, Jon Glass has blogged about Python coding using Joachim Metz's libesedb and Alberto Solino's Impacket ESE libraries here.

Be aware there may be more .dat files than MMS attachment entries in "Data:\SharedData\Comms\Unistore\data\7" (eg Received email attachments and/or Draft text). Not every .dat file may have a corresponding MMS.

GPS and other EXIF metadata can be present on sent/received images/videos (depending on the sending phone's settings and/or if the original file had embedded metadata). This can help an analyst decide if a picture was originally taken with the target device and/or the time/location of the picture.

This post only looked at allocated MMS - deleted MMS is an area for further research. Upon MMS deletion, "Message" / "Attachment" / "Recipient" entries should be deleted/overwritten from "store.vol". However, ESE .log transaction files and/or pagefile.sys may still contain enough information from deleted MMS to recreate the "store.vol" records. Recovering the .dat file content and linking it to a MMS transaction would be more complicated however.

Sending a Location (via Messaging) does not utilize the "Attachment" table so these cannot be retrieved by the scripts in this post.
For Location messaging, an "IPM.SMStext" record entry is made in the "Message" table and it has a Windows Phone URL string in the content column ("0037001f"). Analysts can browse to that URL and view a map centered on the sent Location. This map also has a timestamp and what appears to be an accuracy radius.
The URL format looks like:

Where ZZZ = 13 character random code. Both of our test samples had 13 character codes starting with "CI" but your mileage may vary.
Theoretically, it should be possible to scan a store.vol (or pagefile.sys) for these types of URL and if found, they can tie a device to a specific location and time (assuming you can prove they were sent SMS).

And so finishes another glorious Windows Phone 8.10 post! For some reason, the phrases "One trick monkey" and "One off scripts" seem to be reverberating in monkey's caffeine addled brain ... Good! ;)