Learning a New Language

Matthew Seyer
4 min readDec 19, 2016

--

I have really been digging Matt B’s Zeltser Challenge. He talked a big game on the Forensic Lunch about using Medium as his choice for blogging. Seeing as how its been a while since I have done any type of blogging, I thought it would be a good idea to check it out.

Lately, in my own little world, I have been exploring the new language of Rust. I have to say, I am extremely impressed with it. Its fast, safe, cross platform, has a package manager, and best of all, for a lower level language, you don’t have to manage pointers! This can’t go without a thanks to Eric Zimmerman for an introduction to the language. Obviously, if someone as smart as he is says something looks amazing, its my duty to check it out. It is a relatively new language and is under constant development, which can be a good and a bad thing, either way, I see tremendous potential in it. I won’t dive to much into it because other people can give you better detail then I ever can. Here is a good introduction presentation.

Needless to say, the only way to learn something is to do it! I have started a USN journal parser in Rust. You can track its progress on my github: https://github.com/forensicmatt/RustyUsn. This project does not exist to fill a gap in tools, as we all know there are plenty of tools out there that can parse the journal, but rather to be a starting point of concepts I wish to learn in Rust. Seeing as how the USN journal is a very simple format, it is a good candidate. So, what are the concepts I wish to learn in Rust?

  • Cross platform functionality
  • Utilizing Cargo (the packaging manager)
  • Command line interfacing (processing parameters)
  • Error handling
  • Parsing binary into structures
  • Dealing with DateTimes
  • Dealing with Unicode
  • Creating Python Bindings

This list will provide a basis of topics that I would like to cover this week.

But before we start going through each concept and how it maps out in code, lets look at where it is currently.

Lets first look at how to compile it. All you need to do is download the new version of Rust. Then download the RustyUsn repository. Once unzipped, you are ready to compile. For this we use cargo, Rust’s package manager (much like a pip for python). Give it a cargo install and you are good to go. Might look something like this:

D:\Dev\Rust\RustyUsn-master>cargo build
Downloading byteorder v0.5.3
Downloading chrono v0.2.25
Downloading clap v2.16.3
Downloading num v0.1.36
Downloading rustc-serialize v0.3.21
Downloading serde v0.8.17
Downloading time v0.1.35
Downloading num-traits v0.1.36
Downloading num-integer v0.1.32
Downloading num-iter v0.1.32
Downloading libc v0.2.17
Downloading kernel32-sys v0.2.2
Downloading winapi v0.2.8
Downloading winapi-build v0.1.1
Downloading vec_map v0.6.0
Downloading bitflags v0.7.0
Downloading unicode-width v0.1.3
Downloading ansi_term v0.9.0
Downloading strsim v0.5.1
Downloading unicode-segmentation v0.1.2
Downloading term_size v0.2.1
Compiling winapi v0.2.8
Compiling unicode-segmentation v0.1.2
Compiling unicode-width v0.1.3
Compiling rustc-serialize v0.3.21
Compiling vec_map v0.6.0
Compiling winapi-build v0.1.1
Compiling bitflags v0.7.0
Compiling strsim v0.5.1
Compiling byteorder v0.5.3
Compiling kernel32-sys v0.2.2
Compiling libc v0.2.17
Compiling serde v0.8.17
Compiling num-traits v0.1.36
Compiling ansi_term v0.9.0
Compiling num-integer v0.1.32
Compiling num-iter v0.1.32
Compiling num v0.1.36
Compiling time v0.1.35
Compiling term_size v0.2.1
Compiling clap v2.16.3
Compiling chrono v0.2.25
Compiling usntest v0.1.0 (file:///D:/Dev/Rust/RustyUsn-master)
Finished debug [unoptimized + debuginfo] target(s) in 50.66 secs

We can then go to its build directory which is ./target/debug. From here we can give it a run:

D:\Dev\Rust\RustyUsn-master\target\debug>usntest.exe -h
MyUsnApp 1.0
Matthew Seyer <matthew.seyer@gmail.com>
Parse USN records
USAGE:
usntest.exe --journal <FILE>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-j, --journal <FILE> The USN journal file to parse

Very simple. Lets give it a journal.

D:\Dev\Rust\RustyUsn-master\target\debug>usntest.exe -j D:\Testing\$UsnJrnl.$J
Journal to parse: D:\Testing\$UsnJrnl.$J
function: get_next_record() at offset: 0
USN structure 1: UsnRecordV2 {
record_length: 96,
major_version: 2,
minor_version: 0,
file_reference_number: 10477624533077459059,
parent_file_reference_number: 1970324837116475,
usn: 20342374400,
timestamp: 2013-10-19T12:16:53.276040,
reason: 2,
source_info: 0,
security_id: 0,
file_attributes: 8224,
file_name_length: 32,
file_name_offset: 60,
file_name: "BTDevManager.log"
}
function: get_next_record() at offset: 96
USN structure 2: UsnRecordV2 {
record_length: 96,
major_version: 2,
minor_version: 0,
file_reference_number: 10477624533077459059,
parent_file_reference_number: 1970324837116475,
usn: 20342374496,
timestamp: 2013-10-19T12:16:53.276040,
reason: 2147483650,
source_info: 0,
security_id: 0,
file_attributes: 8224,
file_name_length: 32,
file_name_offset: 60,
file_name: "BTDevManager.log"
}
...
function: get_next_record() at offset: 37686992
USN structure 367260: UsnRecordV2 {
record_length: 200,
major_version: 2,
minor_version: 0,
file_reference_number: 2814749767128558,
parent_file_reference_number: 281474976989994,
usn: 20380061392,
timestamp: 2013-10-23T11:34:39.839588,
reason: 2147484160,
source_info: 0,
security_id: 0,
file_attributes: 8228,
file_name_length: 138,
file_name_offset: 60,
file_name: "1a60b305567c1cf7f77dad5be80a8169_5b6de537-8036-4906-9cf1-ecfc4eabd13c"
}

Currently it just prints out the record structures. This is something we will need to change down the line. For now lets see how fast it. Let’s compile it as a Release (“ Release mode takes longer to compile, but the code will run faster.” — Cargo Guide). For this we use:

cargo build --release

Lets run this using powershell’s Measure-Command.

PS D:\Dev\Rust\RustyUsn-master\target\release> Measure-Command {.\usntest.exe -j D:\Testing\J}Days              : 0
Hours : 0
Minutes : 0
Seconds : 20
Milliseconds : 989
Ticks : 209891982
TotalDays : 0.000242930534722222
TotalHours : 0.00583033283333333
TotalMinutes : 0.34981997
TotalSeconds : 20.9891982
TotalMilliseconds : 20989.1982

For this test set, usntest.exe does not even get above 1MB in memory.

Here is some information about the journal file being used:

USN record count: 367260
File size: 35.9 MB (37,687,192 bytes)

So… now we know where we are at. Lets dig through the concepts and the code.

--

--