Instruction Trace Visualisation: Packers & Protectors

Published: Nov 14, 2021 by Nia Catlin

Software protectors can be a bit of a trial by fire for binary analysis tools - this post shows some visualisations of a few packers and protectors often used for malware. It’s intended to be a record for how rgat’s visualisation capabilities evolve - so expect the first entry to be a bit rough.

Versions are the latest demos available as of Nov 2021.

Original Binary

The visualisations below are traces of the packed ConsolePrint32 test - a tiny binary with 24 instructions and a few API calls.

Force directed node render of the original consoleprint binary Original unpacked binary

ASPack

At under 1000 nodes (147K instructions executed), ASPacked binaries lend themselves nicely to force directed graph layout (as nicely as the originals, anyway)

Cylinder heatmap Force-directed control-flow rendering Cylinder heatmap Force-directed heatmap rendering Cylinder heatmap Cylinder control rendering Cylinder heatmap Cylinder heatmap rendering

Themida 2

Main Thread

This trace consists of lots of junk-filled decryption loops interspersed with calls to the VM area. It also makes heavy use of exceptions (the cyan edges). Cylinder control flow Cylinder control-flow rendering

Cylinder heatmap Cylinder heatmap rendering

Cylinder initial control flow Zoomed in - the initial decryption and decompression stub, followed by the start of the obfuscated, exception-heavy control flow

Cylinder initial heatmap Heatmap rendering of the same area

Approaching 250M instructions executed (around 200K unique), this type of layout is a bit of a stretch for the force directed algorithm - both in terms of performance and how useful the layout is.

Force-Directed control flow Force directed block control flow

Force-Directed heatmap Force directed block heatmap

Degree rendering Force directed block degree rendering - just because I like the colours

Other Threads

Preview thread graphs

This spawns a lot of threads! Most of them are very simple - highlights here are debugger detection and multi-threaded unpacking

Themida 3

Themida 3 seems to have dispensed with the ‘kitchen sink of random obfuscation techniques’ protection and focused on a core of more reliable techniques. It detects Pin, so I had to disable debugger detection for this in lieu of an anti-anti-debugging sprint.

The main thread clocks in at just over 110K unique instructions - with 378M executed in total.

Cylinder control flow The cylinder suffers from the control flow graph being highly interconnected Cylinder heatmap Much Less useful heatmap

Force-directed control flow The force directed layout redeems itself a little Force-directed heatmap Loops!

Thread Previews This has far fewer threads - one of these is for the Demo UI

UPX

Any discussion of packers is incomplete without UPX - our test program was expanded to a graph with a mere 208 nodes (with 58K instructions executed)

Force-directed Control Flow Force directed block control flow rendering

Cylinder Heatmap Cylinder heatmap rendering

VMProtect

The VMP protected sample weighs in at over 2 billion instructions (110K~ unique) in its single thread, which makes it rather hefty. This is not a performance evaluation blog - but - if you are thinking of creating a fancy tech startup that revolves around shipping high-performance hello world binaries (with trade secrets in?) then you probably don’t want to use this.

Force-directed Control Flow Force directed block control flow rendering

Cylinder Heatmap Cylinder heatmap rendering

I also couldn’t gather this trace through remote tracing due (this bug) - it makes it to about 250M instructions before stopping - as well as the Pin named pipe bug, so that’s another thing on the list to fix.

Share