Python Registry Parser (regparse)

I released a tool called, Python Registry Parser (or regparse for short), which is a plugin based Windows Registry parser written in Python.

Main reasons for writing regparse

  • I don't like the output that current registry parsers (Gui/non-Gui) provide.
  • I like RegRipper, but didn't want to learn Perl.
  • I wanted to improve my Python skills.

Tool choice is subjective. There is no perfect tool for everyone. Most people just live with the shortfalls of tools and adjust their analysis process as needed. Whether it's poor output, Gui vs command line, paid vs. free, etc. That's really more or less why I started down this path. I wanted something that fit my needs and I don't know C/C++/C# or Perl so I couldn't modify some of the ones I did like. This is when I decided to leverage python-registry by Willi Ballenthin and build on-top of it.

So let's take a quick look at regparse and some of its features and you can decide for yourself if you think it's useful or not. If not, no harm, there are plenty of other really good registry tools out there.

Help -h

usage: [-h] [--plugin PLUGIN] [--listplugins] [--plugindetails]
[--hives [HIVES [HIVES ...]]]
[--search [SEARCH [SEARCH ...]]] [--format format]
[--format_file format_file]
Parse Windows Registry hives.
optional arguments:
-h, --help show this help message and exit
--plugin PLUGIN Specify plugin to run.
--listplugins Lists all of the available plugins.
--plugindetails Lists details available plugins.
--hives [HIVES [HIVES ...]]
Registry Hives.
--search [SEARCH [SEARCH ...]]
Provide a search value and search the hive(s).
--format format Custom output.
--format_file format_file
Custom output template.

Listing Plugins --listplugins


So far I have around 25+ plugins written. I am in the process of rewriting them to accept the new user defined output and I will be posting them as I update them. I'll post them on GitHub.

Plugin Details

To get details about the plugins you can do the following. --plugindetails


Author: 	Patrick Olsen
Version: 	0.5
Print Fields: 	"{{ last_write }}|{{ key_name }}|{{ stub_path }}"
Description: 	Parses the SOFTWARE hives and returns Active Setup entries.*


Plugin: 	APPINIT
Author: 	Patrick Olsen
Version: 	0.1
Print Fields: 	"{{ last_write }}|{{ key }}|{{ loadapp_data }}|{{ appinit_data }}"
Description: 	Parses the SOFTWARE hive and returns AppInitDLL entries.


Plugin: 	BHOS
Author: 	Patrick Olsen
Version: 	0.2
Print Fields: 	"{{ clsids_lastwrite }}|{{ value }}|{{ inproc_lastwrite }}|{{ data }}"
Description: 	Parses the SOFTWARE hive and returns Browser Helper Object entries.


Author: 	Patrick Olsen
Version: 	0.4
Print Fields: 	"{{ last_write }}|{{ name }}|{{ value }}"
Description: 	Parses the SYSTEM hive and returns Known DLLs.


Plugin: 	MOUNTS
Author: 	Patrick Olsen
Version: 	0.4
Print Fields: 	"{{ last_write }}|{{ name }}|{{ value }}"
Description: 	Parses the NTUSER and SYSTEM hives and returns mount points (MountPoints2, Map Network Drive MRU, & MountedDevices).


Author: 	Patrick Olsen
Version: 	0.2
Print Fields: 	"{{last_write}}|{{key_name}}|{{key}}|{{value}}|{{data}}"
Description: 	Parses the NTUSER hive and returns RecentDocs MRU entries.

Writing a plugin is very simple. Sometimes just a few lines of code. You can most likely copy 90% of existing plugins I have written. If you can't write one, or don't want to, but think one would be useful just add an issue via Github and I will write it for you. Plugin requests go to the top of the priority. If it's something unique I might need a sample hive. If that's the case I can sign a NDA if required. I have no problem with doing that.

Example Output

This section is going to be a bit longer because output was one of my biggest issues with some of the other tools available.

Coming to the realization that not everyone will be happy with any output I choose as the default I decided to use user defined output as the default.

What is user defined output you ask? It's exactly that. You (the user) defines what the output will look like.

I got the idea from Willi's list-mft.

We will use the services plugin as our example. If you do a --listplugins you will see that services has the following variables we can use:

{{ last_write }}|{{ key_name }}|{{ image_path }}|{{ type_name }}|{{ display_name }}|{{ start_type }}|{{ service_dll }}.

So in all for services you have a total of seven fields we can choose from and customize.

First up we can define the output as standard CSV format via commas. --plugin services --hives SYSTEM --format "{{ last_write }},{{ key_name }},{{ image_path }},{{ type_name }},{{ display_name }},{{ start_type }},{{ service_dll }}"

  • 2010-11-21 03:29:41.027386,1394ohci,systemrootsystem32drivers1394ohci.sys,1,1394 OHCI Compliant Host Controller,3,None
  • 2015-02-28 03:48:46.640400,ACPI,system32driversacpi.sys,1,Microsoft ACPI Driver,0,None
  • 2010-11-21 03:29:41.027386,AcpiPmi,systemrootsystem32driversacpipmi.sys,1,ACPI Power Meter Driver,3,None*

Let's say you want the last write of the service key, only the service dll path, and no entries that have system32. --plugin services --hives SYSTEM --format "{{ last_write }}|{{ service_dll }}" |egrep -v '(S|s)ystem32'

  • 2015-01-12 18:52:47.224211|%ProgramFiles%Windows Defendermpsvc.dll

Let's say you don't like commas and you want abcdefghijk between each value for some weird reason. Maybe it makes running awk -F'abcdefghijk' easier to run or something?? You simply define it at run time like this: --plugin services --hives SYSTEM --format "{{ last_write }}abcdefghijk{{ service_dll }}"

  • 2009-07-14 04:54:53.422861abcdefghijk%SystemRoot%System32dnsrslvr.dll
  • 2009-07-14 04:54:09.493183abcdefghijk%SystemRoot%System32dot3svc.dll
  • 2009-07-14 04:54:32.191223abcdefghijk%SystemRoot%system32dps.dll

Lastly, let's say you don't want to type anything into the command line for whatever reason. You can use a prebuilt, or (custom) template by using the --format_file templates/_name_you_pick>.html.

Here is an example of a simple html template I created for the runkeys plugin. As you can see with Jinja you are able to conduct loops, etc. within an HTML page and it will render as necessary the output as you will see.

<html lang="en">
<h2>Windows Registry - Runkeys Plugin</h2>
{% block body %}
{% for item in runkey_list %}
<strong>{{ item[0] }}</strong>
<p>{{ item[1]|indent(4, true) }} {{ item[2]|indent(4, true) }}</p>
<blockquote><li>{{ item[3]|indent(4, true) }}</li></blockquote>
{% endfor %}
{% endblock %}
</html> --plugin runkeys --hives SYSTEM NTUSER.DAT > test.html

Now all you need to do is open test.html and you have a rendered webpage with your runkeys plugin results. You could expand this to be a table, chat, etc. Pretty much anything you can add to a website you could include in your output template. Heck, if you have standard reporting templates you could have it generate the correct format for you on the fly. This is an area I plan to expand on when I get some spare time.

Silvrback blog image


Outside of that it's pretty self explanatory. It parses Windows registry hives.

If you want to help improve what I have so far I welcome you to do so. Just open up an issue on GitHub, and if you're not a GitHub user just hit me up offline. That goes for plugin ideas, plugin development, etc. too.

Happy hunting and I hope you find this useful.

If you find these blog posts useful, please consider donating at Patreon

If you find these posts useful and educational you can donate via PayPal.Me here: $1, $2, $3, $4, $5 or Custom.