Updating the KnowledgeC Parser


I’ve just pushed up some changes to the amazing KnowledgeC plist extraction and parsing utility that I’ve been working on with Alexis Brignoni and wanted to describe them here.

iOS Version

The first change is that I’ve done away with there being two separate scripts for iOS11 and iOS12 and replaced it with a version flag that’s passed in at runtime. For the most part there’s only a couple of lines that are different. I could check the sqlite schema and identify which verison of iOS the database came from programatically but effort.

File Paths

Upon merging the two, I also added the ability to pass in a knowledgec database from anywhere so no more requirement to have it in the directory that you’re running the script from.

NSData Protobuf Decoding

Probably most importantly, I was playing around with the data within the “nsdata” field and identified that this was protobuf encoded. I should know this by now as protobuf encoding has shown up in a number of my projects. If you can see ASCII strings surrounded by random hex data then it could be protobuf.

As a result, I added the -d flag (which is default on so you don’t need to add it) that would spit out all of the nsdata sections of the clean plists into their own binary files. The exported files can then be run through the protoc with the –decode_raw flag to display the data in JSON format. Rather than using a system command I went scouring the internet for a Python library that would do the same thing. I found this one, which worked great but was Python2.

I attempted to update it myself, but after much swearing at the computer I put the call out to Twitter and Craig Rowland came to the rescue and updated the script to work for me. With a bit of tinkering I was able to get it to integrate into the script and now we can get even better context about what was happening in the knowledgec database.


Lastly, something that you notice when looking through the zstructuredmetadata table of the database is that records have an expiry time. I have found that the plists can be carved from the database, and the good thing is that with a bit of tinkering you can take the code from our script and present the data. The reason why this is important is that you can use it to parse the nsdate and nsdata values. This may assist your investigation in adding additional context.

On my to-do list is to write a carver that will pull out all of the plists from the file but I haven’t been able to dedicate the time to it yet. I’ve partially written one but it doesn’t always export functional plists so I’ll have to spend some more time on it at some point.

If anyone else would like to do that for me though, I wouldn’t say no 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s